/[xmltv_parser]/trunk/libxmltv/Core/XMLTVRuntimeInstance.cs
ViewVC logotype

Diff of /trunk/libxmltv/Core/XMLTVRuntimeInstance.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/libxmltv/Core/XMLTVInstance.cs	2013/03/08 08:51:10	54
+++ trunk/libxmltv/Core/XMLTVRuntimeInstance.cs	2013/03/09 09:29:40	72
@@ -6,114 +6,276 @@
 using System.ComponentModel;
 using System.Windows.Forms;
 using System.Threading;
+using System.Reflection;
+using System.Globalization;
+using System.Diagnostics;
 
 namespace libxmltv.Core
 {
     [Serializable]
-    internal class XMLTVRuntimeInstance : MarshalByRefObject, IXMLTVRuntimeInstance, ISerializer<XMLTVRuntimeInstance>, IGetCreatedInstanceEvent, ISetCreatedInstanceEvent, IDestroyInstance
+    internal class XMLTVRuntimeInstance : MarshalByRefObject, 
+        IXMLTVRuntimeInstance, 
+        ISerializer<XMLTVRuntimeInstance>, 
+        IGetCreatedInstanceEvent, 
+        ISetCreatedInstanceEvent, 
+        IDestroyInstance, 
+        IRuntimeInstanceLoader<XMLTVRuntimeInstance>
     {
+        [NonSerialized]
         Thread worker;
-        public XMLTVRuntimeInstance(string xmlfile) 
+        public XMLTVRuntimeInstance() { init(); }
+        public XMLTVRuntimeInstance(string xmlfile) : this(xmlfile, null) { }
+        public XMLTVRuntimeInstance(string xmlfile, EventHandler<EventArgs> handler)
+            : this()
         {
-            worker = new Thread(new ParameterizedThreadStart(CreateInstance));
-            //CreateInstance(xmlfile);
-            worker.Start(xmlfile);
+            this.OnInstanceCreated += handler;
+            worker = new Thread(new ParameterizedThreadStart(CreateInstance)); worker.Start(xmlfile);
         }
-        //public XMLTVRuntimeInstance(string xmlfile) : this(xmlfile, null) { }
-        //public XMLTVRuntimeInstance(string xmlfile, EventHandler<CancelEventArgs> t) { CreateInstance(xmlfile,t); }
         private void CreateInstance(object xmlfile)
-        {            
-            //CancelEvent = t;
-            using (XMLTVInstance instance = new XMLTVInstance(xmlfile.ToString(), this))
+        {
+            using (XMLTVInstance instance = new XMLTVInstance(xmlfile.ToString()))
             {
-                if (OnInstanceCreated != null)
-                {
-                    OnInstanceCreated.Invoke(this,new EventArgs());
-                }
+                this.LoadFromInstance(instance.GetInstance());
+                OnCreatedInstance(this, new EventArgs());
             }
         }
+        
 
-        //internal XMLTVInstance Instance { get; private set; }
-
-        #region IXMLTV_LOADER members
-        public System.IO.FileInfo XmlFile { get; set; }
-        public string XmlDoc { get; set; }
-        #endregion
-        #region IXMLTV_PARSER Members
-        public IXMLTVSource Source { get; set; }
-        public Dictionary<string, IXMLTVChannel> Channels { get; set; }
-        public Dictionary<int, IXMLTVProgram> Programs { get; set; }
-        #endregion   
-    
-        public EventHandler<EventArgs> OnInstanceCreated { get; set; }
-        public EventHandler<EventArgs> GetOnInstanceCreated() { return OnInstanceCreated; }
-        public void SetOnInstanceCreated(EventHandler<EventArgs> event_instance) { OnInstanceCreated = event_instance; }
+        private void OnCreatedInstance(object sender, EventArgs e)
+        {
+            if (OnInstanceCreated != null) { OnInstanceCreated.Invoke(sender, e); }
+        }
 
-        public IXMLTVSerializer<XMLTVRuntimeInstance> Serializer
+        private void init()
         {
-            get 
-            {
-                ///* We have to set CancelEvent to null, before returning a new instance of the serializer otherwise all subscribers to the event will have to be marked as serializeable.
-                //   Most subscribers will be of type: System.Windows.Forms which is not marked as serializable and will fail to serialize. */
-                //if (CancelEvent != null) { CancelEvent = null; }
-                return new XMLTVSerializer<XMLTVRuntimeInstance>(this); 
-            }
+            this.Source = new XMLTVSource();
+            this.Channels = new Dictionary<string, IXMLTVChannel>();
+            this.Programs = new Dictionary<int, IXMLTVProgram>();
+            this.XmlFile_Name = string.Empty;
+            this.XmlFile_FullName = string.Empty;
+            this.XmlDoc = string.Empty;
+            this.OnInstanceCreated = null;
         }
+
+        #region IXMLTVRuntimeInstance members
+        private bool _IsAborting;
+        public bool IsAborting { get { return _IsAborting; } private set { _IsAborting = value; } }
+
+
+        private string _XmlFile_Name;
+        public string XmlFile_Name { get { return _XmlFile_Name; } set { _XmlFile_Name = value; } }
+        private string _XmlFile_FullName;
+        public string XmlFile_FullName { get { return _XmlFile_FullName; } set { _XmlFile_FullName = value; } }
+
+        private string _XmlDoc;
+        public string XmlDoc { get { return _XmlDoc; } set { _XmlDoc = value; } }               
+        private IXMLTVSource _Source;
+        public IXMLTVSource Source { get { return _Source; } set { _Source = value; } }
+        private Dictionary<string, IXMLTVChannel> _Channels;
+        public Dictionary<string, IXMLTVChannel> Channels { get { return _Channels; } set { _Channels = value; } }
+        private Dictionary<int, IXMLTVProgram> _Programs;
+        public Dictionary<int, IXMLTVProgram> Programs { get { return _Programs; } set { _Programs = value; } }
+        #endregion       
+        #region IOnInstanceCreated members
+        [NonSerialized]
+        private EventHandler<EventArgs> _OnInstanceCreated;
+        public EventHandler<EventArgs> OnInstanceCreated { get { return _OnInstanceCreated; } set { _OnInstanceCreated = value; } }
+        #endregion
+        #region IGetCreatedInstanceEvent members
+        public EventHandler<EventArgs> GetOnInstanceCreated() { return OnInstanceCreated; }
+        #endregion
+        #region ISetCreatedInstanceEvent members
+        public void SetOnInstanceCreated(EventHandler<EventArgs> event_instance) { OnInstanceCreated = event_instance; }
+        #endregion
+        #region ISerializer<XMLTVRuntimeInstance> members
+        public IXMLTVSerializer<XMLTVRuntimeInstance> Serializer { get { return new XMLTVSerializer<XMLTVRuntimeInstance>(this); } }
+        #endregion
+        #region IDestroyInstance member
         public void DestroyInstance()
         {
-            xmltv_logger.Log.Debug.WriteLine("Destoying Instance of: '{0}'", this.GetType().Name);
+            xmltv_logger.Debug.WriteLine("Destoying Instance of: '{0}'", this.GetType().Name);
             this.IsAborting = true;
             if (worker == null)
             {
-                xmltv_logger.Log.Debug.WriteLine("Unable to destroy instance of: '{0}' - worker thread is null", this.GetType().Name);
+                xmltv_logger.Debug.WriteLine("Unable to destroy instance of: '{0}' - worker thread is null", this.GetType().Name);
                 return;
             }
             else
             {
                 if (worker.IsAlive)
                 {
-                    xmltv_logger.Log.Verbose.Debug.WriteLine("Requesting Instance to Abort...");
-                    while (worker.IsAlive)
+                    xmltv_logger.Verbose.Debug.WriteLine("Requesting Instance to Abort...");
+                    while (worker.IsAlive) { worker.Abort(); Application.DoEvents(); }
+                }
+                else { xmltv_logger.Debug.WriteLine("Instance of: '{0}'- already destroyed.", this.GetType().Name); }
+            }
+        }
+        #endregion
+        #region  IRuntimeInstanceLoader<XMLTVRuntimeInstance> member
+        public XMLTVRuntimeInstance LoadFromInstance(XMLTVRuntimeInstance instance)
+        {
+            if (instance == null)
+            {
+                throw new NullReferenceException("Failed to load from instance because the instance is null.");
+            }
+            CloneFromInstance(ref instance);
+            xmltv_logger.Debug.WriteLine("Loading from instance...");
+            if (this.Source != null)
+            {
+                xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Created by '{1}' - original source file: '{2}'", this.Source.SourceName, this.Source.GeneratorName, this.XmlFile_FullName);
+            }
+            else
+            {
+                xmltv_logger.Error.WriteLine("Source Property is null.");
+                throw new NullReferenceException("Source Property is null.");
+            }
+            if (this.Channels != null)
+            {
+                xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Channels from source '{1}'", this.Channels.Count, this.Source.SourceName);
+            }
+            else
+            {
+                xmltv_logger.Error.WriteLine("Channels Property is null.");
+                throw new NullReferenceException("Channels Property is null.");
+            }
+            if (this.Programs != null)
+            {
+                xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Programs from source '{1}'", this.Programs.Count, this.Source.SourceName);
+            }
+            else
+            {
+                xmltv_logger.Error.WriteLine("Programs Property is null.");
+                throw new NullReferenceException("Programs Property is null.");
+            }
+            xmltv_logger.Debug.WriteLine("Loaded from instance...");
+            return instance;
+        }
+        #endregion
+        #region CloneFromInstance
+        private void CloneFromInstance(ref XMLTVRuntimeInstance instance)
+        {
+            xmltv_logger.Debug.WriteLine("Cloning from instance...");
+            BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+            CultureInfo culture = CultureInfo.CurrentCulture;
+            Type t = typeof(XMLTVRuntimeInstance);
+            foreach (var field in t.GetFields(flags))
+            {
+                try
+                {
+                    if (field.IsNotSerialized) { continue; }                    
+                    var f = instance.GetType().GetField(field.Name, flags);                    
+                    var v = f.GetValue(instance);
+                    if (v != null)
+                    {
+                        field.SetValue(this, v);
+                    }
+                    else
                     {
-                        worker.Abort();
-                        Application.DoEvents();
+                        xmltv_logger.Debug.WriteLine("Attempted to set field: '{0}' with a null value.  The operation was aborted.", f.Name);
+                        continue;
                     }
                 }
-                else
+                catch (Exception ex)
                 {
-                    xmltv_logger.Log.Debug.WriteLine("Instance of: '{0}'- already destroyed.", this.GetType().Name);
+                    throw new Exception(string.Format("Unable to copy value for field: '{0}' from instance", field.Name), ex);
                 }
             }
+            foreach (var property in t.GetProperties(flags))
+            {
+                try
+                {
+                    var f = instance.GetType().GetProperty(property.Name);
+                    object value = null;
+                    try
+                    {
+                        value = f.GetValue(instance, null);
+                    }
+                    catch (ArgumentException ex) { if (ex.Message == "Property get method not found.") { Debug.WriteLine(ex.ToString()); } else { throw ex; } }
+                    try
+                    {
+                        if (value != null)
+                        {
+                            property.SetValue(this, value, null);
+                        }
+                        else
+                        {
+                            xmltv_logger.Debug.WriteLine("Attempted to set property: '{0}' with a null value.  The operation was aborted.", f.Name);
+                            continue;
+                        }
+                    }
+                    catch (ArgumentException ex) { if (ex.Message == "Property set method not found.") { Debug.WriteLine(ex.ToString()); } else { throw ex; } }
+
+                }
+                catch (Exception ex)
+                {
+                    throw new Exception(string.Format("Unable to copy value for property: '{0}' from instance", property.Name), ex);
+                }
+            }
+            xmltv_logger.Debug.WriteLine("Cloned from instance...");
         }
-        public bool IsAborting
-        {
-            get;
-            private set;
-        }        
+        #endregion
     }
 
-    internal class XMLTVInstance : IDisposable
+    internal class XMLTVInstance : IGetInstance<XMLTVRuntimeInstance>, IDisposable
     {
-        public XMLTVInstance(string xmlfile, XMLTVRuntimeInstance instance) 
-        { 
-            CreateLoader(xmlfile, instance);
-            CreateParser(instance);
+        private XMLTVRuntimeInstance gInstance;
+        public XMLTVRuntimeInstance GetInstance() { return gInstance; }
+        public XMLTVInstance(string xmlfile) 
+        {
+            try
+            {
+                CreateLoader(xmlfile);
+            }
+            catch (Exception ex)
+            {
+                xmltv_logger.Error.WriteLine(ex.ToString());
+            }
         }
 
-        private void CreateLoader(string xml_file, XMLTVRuntimeInstance instance)
+        private void CreateLoader(string xml_file)
         {
-            //XMLTVLoader loader = new XMLTVLoader(xml_file, instance);
-            XMLTVLoader.CreateInstance(xml_file, instance);
+            gInstance = new XMLTVRuntimeInstance();
+            bool bound_to_ctor = false;
+            object raw_instance = null;
+            Assembly asm = Assembly.GetExecutingAssembly();
+            var types = asm.GetTypes();
+
+            foreach (var type in types)
+            {
+                if (type.BaseType != null && type.BaseType == typeof(XMLTVBase<XMLTVRuntimeInstance>))
+                {
+                    xmltv_logger.Verbose.Debug.WriteLine("Type: '{0}' Base: '{1}'", type.Name, type.BaseType == null ? "none" : type.BaseType.Name);
+
+                    BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+                    CultureInfo culture = CultureInfo.CurrentCulture;
+                    object[] args = new object[] { xml_file, gInstance };
+                    try
+                    {
+                        raw_instance = Activator.CreateInstance(type, flags, null, args, culture);
+                        bound_to_ctor = true;
+                    }
+                    catch (Exception ex)
+                    {
+                        Debug.WriteLine(ex.ToString());
+                    }
+                }                
+            }
+            if (!bound_to_ctor) { throw new Exception("Unable to find a compatible XMLTV Data Loader."); }
+            if (raw_instance == null) { throw new NullReferenceException("Found a compatible XMLTV Data Loader, but it returned invalid data."); }
+            IGetInstance<XMLTVRuntimeInstance> getter_instance = (raw_instance as IGetInstance<XMLTVRuntimeInstance>);
+            if (getter_instance != null) { gInstance = getter_instance.GetInstance(); }
+            else { throw new Exception("Found a compatible XMLTV Data Loader, but was unable to obtain the instance holding the data"); }
         }
         private void CreateParser(XMLTVRuntimeInstance instance)
         {
-            //XMLTVParser parser = new XMLTVParser(instance);
-            XMLTVParser.CreateInstance(instance);
+
         }
 
         public void Dispose()
         {
             //throw new NotImplementedException();
         }
+
+        
     }
 }

 

  ViewVC Help
Powered by ViewVC 1.1.22