Parent Directory
|
Revision Log
|
Patch
--- trunk/libxmltv/Core/XMLTVInstance.cs 2013/03/08 12:20:50 58 +++ trunk/libxmltv/Core/XMLTVRuntimeInstance.cs 2013/03/09 10:27:39 73 @@ -9,6 +9,7 @@ using System.Reflection; using System.Globalization; using System.Diagnostics; +using System.Xml.Linq; namespace libxmltv.Core { @@ -23,62 +24,73 @@ { [NonSerialized] Thread worker; - public XMLTVRuntimeInstance() + public XMLTVRuntimeInstance() { init(); } + public XMLTVRuntimeInstance(string xmlfile) : this(xmlfile, null) { } + public XMLTVRuntimeInstance(string xmlfile, EventHandler<EventArgs> handler) + : this() { + this.OnInstanceCreated += handler; + worker = new Thread(new ParameterizedThreadStart(CreateInstance)); worker.Start(xmlfile); } - public XMLTVRuntimeInstance(string xmlfile) - { - worker = new Thread(new ParameterizedThreadStart(CreateInstance)); - //CreateInstance(xmlfile); - 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()); } } + + private void OnCreatedInstance(object sender, EventArgs e) + { + if (OnInstanceCreated != null) { OnInstanceCreated.Invoke(sender, e); } + } - //internal XMLTVInstance Instance { get; private set; } + private void init() + { + this.Source = new List<IXMLTVSource>(); + this.Channels = new List<IXMLTVChannel>(); + this.Programs = new List<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; } } - #region IXMLTV_LOADER members - private System.IO.FileInfo _XmlFile; - public System.IO.FileInfo XmlFile { get { return _XmlFile; } set { _XmlFile = value; } } private string _XmlDoc; public string XmlDoc { get { return _XmlDoc; } set { _XmlDoc = value; } } - #endregion - #region IXMLTV_PARSER Members - 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 - + private List<IXMLTVSource> _Source; + public List<IXMLTVSource> Source { get { return _Source; } set { _Source = value; } } + private List<IXMLTVChannel> _Channels; + public List<IXMLTVChannel> Channels { get { return _Channels; } set { _Channels = value; } } + private List<IXMLTVProgram> _Programs; + public List<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; } - - public IXMLTVSerializer<XMLTVRuntimeInstance> Serializer - { - 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); - } - } + #endregion + #region ISerializer<XMLTVRuntimeInstance> members + public IXMLTVSerializer<XMLTVRuntimeInstance> Serializer { get { return new XMLTVSerializer<XMLTVRuntimeInstance>(this); } } + #endregion + #region IDestroyInstance member public void DestroyInstance() { xmltv_logger.Debug.WriteLine("Destoying Instance of: '{0}'", this.GetType().Name); @@ -93,76 +105,56 @@ if (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); + while (worker.IsAlive) { worker.Abort(); Application.DoEvents(); } } + else { xmltv_logger.Debug.WriteLine("Instance of: '{0}'- already destroyed.", this.GetType().Name); } } } - private bool _IsAborting; - public bool IsAborting - { - get { return _IsAborting; } - private set { _IsAborting = value; } - } + #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."); } - - if (instance.Source != null) + CloneFromInstance(ref instance); + xmltv_logger.Debug.WriteLine("Loading from instance..."); + if (this.Source != null) { - xmltv_logger.Debug.WriteLine("Loading from instance..."); - xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Created by '{1}' - original source file: '{2}'", instance.Source.SourceName, instance.Source.GeneratorName, instance.XmlFile.FullName); + xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Created by '{1}' - original source file: '{2}'", this.Source.FirstOrDefault().SourceName, this.Source.FirstOrDefault().GeneratorName, this.XmlFile_FullName); } else { - xmltv_logger.Error.WriteLine("The Instance's Source Property is null."); - throw new NullReferenceException("The Instance's Source Property is null."); + xmltv_logger.Error.WriteLine("Source Property is null."); + throw new NullReferenceException("Source Property is null."); } - if (instance.Channels != null) + if (this.Channels != null) { - xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Channels from source '{1}'", instance.Channels.Count, instance.Source.SourceName); + xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Channels from source '{1}'", this.Channels.Count, this.Source.FirstOrDefault().SourceName); } else { - xmltv_logger.Error.WriteLine("The Instance's Channels Property is null."); - throw new NullReferenceException("The Instance's Channels Property is null."); + xmltv_logger.Error.WriteLine("Channels Property is null."); + throw new NullReferenceException("Channels Property is null."); } - if (instance.Programs != null) + if (this.Programs != null) { - xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Programs from source '{1}", instance.Programs.Count, instance.Source.SourceName); + xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Programs from source '{1}'", this.Programs.Count, this.Source.FirstOrDefault().SourceName); } else { - xmltv_logger.Error.WriteLine("The Instance's Programs Property is null."); - throw new NullReferenceException("The Instance's Programs Property is null."); + xmltv_logger.Error.WriteLine("Programs Property is null."); + throw new NullReferenceException("Programs Property is null."); } - CloneFromInstance(ref instance); - //if (OnInstanceCreated != null) - //{ - // OnInstanceCreated.Invoke(this, new EventArgs()); - //} + xmltv_logger.Debug.WriteLine("Loaded from instance..."); return instance; } + #endregion + #region CloneFromInstance private void CloneFromInstance(ref XMLTVRuntimeInstance instance) { - //if (!instance.GetType().IsSerializable) - //{ - // throw new ArgumentException("Loaded instance is not serializable.", "instance"); - //} - //if (Object.ReferenceEquals(instance, null)) - //{ - // throw new NullReferenceException("Failed to load from instance because the instance is null."); - //} + xmltv_logger.Debug.WriteLine("Cloning from instance..."); BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; CultureInfo culture = CultureInfo.CurrentCulture; Type t = typeof(XMLTVRuntimeInstance); @@ -170,15 +162,18 @@ { try { - if (field.IsNotSerialized) + 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 { + xmltv_logger.Debug.WriteLine("Attempted to set field: '{0}' with a null value. The operation was aborted.", f.Name); continue; } - - var f = instance.GetType().GetField(field.Name, flags); - - var v = f.GetValue(instance); - field.SetValue(this, v); } catch (Exception ex) { @@ -189,13 +184,8 @@ { try { - //if (property.Attributes.HasFlag(FieldAttributes.NotSerialized)) - //{ - // continue; - //} var f = instance.GetType().GetProperty(property.Name); object value = null; - try { value = f.GetValue(instance, null); @@ -203,7 +193,15 @@ catch (ArgumentException ex) { if (ex.Message == "Property get method not found.") { Debug.WriteLine(ex.ToString()); } else { throw ex; } } try { - property.SetValue(this, value, null); + 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; } } @@ -213,31 +211,115 @@ throw new Exception(string.Format("Unable to copy value for property: '{0}' from instance", property.Name), ex); } } + xmltv_logger.Debug.WriteLine("Cloned from instance..."); } + #endregion } - internal class XMLTVInstance : IDisposable + internal class XMLTVInstance : IGetInstance<XMLTVRuntimeInstance>, IDisposable { - public XMLTVInstance(string xmlfile, XMLTVRuntimeInstance instance) - { - CreateLoader(xmlfile, instance); - CreateParser(instance); + public void Dispose() + { + //throw new NotImplementedException(); } - private void CreateLoader(string xml_file, XMLTVRuntimeInstance instance) + private XMLTVRuntimeInstance gInstance; + public XMLTVRuntimeInstance GetInstance() { return gInstance; } + public XMLTVInstance(string xmlfile) { - //XMLTVLoader loader = new XMLTVLoader(xml_file, instance); - XMLTVLoader.CreateInstance(xml_file, instance); + try + { + CreateLoader(xmlfile); + CreateParser(); + } + catch (Exception ex) + { + xmltv_logger.Error.WriteLine(ex.ToString()); + } } - private void CreateParser(XMLTVRuntimeInstance instance) + + private void CreateLoader(string xml_file) { - //XMLTVParser parser = new XMLTVParser(instance); - XMLTVParser.CreateInstance(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() + { + var doc = XDocument.Parse(this.GetInstance().XmlDoc); + var root_element = doc.Root.Name; + if (root_element == null) { throw new NullReferenceException("Root element is null"); } + CreateRootHandler(root_element.ToString()); - public void Dispose() + var nodes = doc.Root.Elements().ToList(); + + } + + + private void CreateRootHandler(string root_element) { - //throw new NotImplementedException(); + object raw_instance = null; + BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + CultureInfo culture = CultureInfo.CurrentCulture; + Assembly asm = Assembly.GetExecutingAssembly(); + var types = asm.GetTypes(); + Type handler_type = null; + foreach (var type in types) + { + if (type.BaseType != null && type.BaseType == typeof(XMLTVBase<XMLTVRuntimeInstance>)) + { + try + { + var handler_prop = type.GetProperty("Handler"); + if (handler_prop != null) + { + raw_instance = Activator.CreateInstance(type, flags, null, new object[0], culture); + if (raw_instance != null) + { + object handler_value = handler_prop.GetValue(raw_instance, null); + if (handler_value != null && handler_value.ToString() == root_element) + { + handler_type = type; + break; + } + } + } + } + catch (Exception) { } + } + } + if (handler_type == null) { throw new Exception("Unable to find a compatible handler to parse document root."); } + raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] { gInstance }, culture); } + + } }
ViewVC Help | |
Powered by ViewVC 1.1.22 |