--- trunk/libxmltv/Core/XMLTVRuntimeInstance.cs 2013/03/09 09:29:40 72 +++ trunk/libxmltv/Core/XMLTVRuntimeInstance.cs 2013/03/09 11:28:41 77 @@ -9,6 +9,7 @@ using System.Reflection; using System.Globalization; using System.Diagnostics; +using System.Xml.Linq; namespace libxmltv.Core { @@ -40,7 +41,6 @@ } } - private void OnCreatedInstance(object sender, EventArgs e) { if (OnInstanceCreated != null) { OnInstanceCreated.Invoke(sender, e); } @@ -49,8 +49,8 @@ private void init() { this.Source = new XMLTVSource(); - this.Channels = new Dictionary(); - this.Programs = new Dictionary(); + this.Channels = new List(); + this.Programs = new List(); this.XmlFile_Name = string.Empty; this.XmlFile_FullName = string.Empty; this.XmlDoc = string.Empty; @@ -68,13 +68,13 @@ public string XmlFile_FullName { get { return _XmlFile_FullName; } set { _XmlFile_FullName = value; } } private string _XmlDoc; - public string XmlDoc { get { return _XmlDoc; } set { _XmlDoc = value; } } + public string XmlDoc { get { return _XmlDoc; } set { _XmlDoc = value; } } private IXMLTVSource _Source; public IXMLTVSource Source { get { return _Source; } set { _Source = value; } } - private Dictionary _Channels; - public Dictionary Channels { get { return _Channels; } set { _Channels = value; } } - private Dictionary _Programs; - public Dictionary Programs { get { return _Programs; } set { _Programs = value; } } + private List _Channels; + public List Channels { get { return _Channels; } set { _Channels = value; } } + private List _Programs; + public List Programs { get { return _Programs; } set { _Programs = value; } } #endregion #region IOnInstanceCreated members [NonSerialized] @@ -118,8 +118,9 @@ { throw new NullReferenceException("Failed to load from instance because the instance is null."); } - CloneFromInstance(ref instance); xmltv_logger.Debug.WriteLine("Loading from instance..."); + CloneFromInstance(ref instance); + xmltv_logger.Debug.WriteLine("Loaded 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); @@ -146,8 +147,7 @@ { 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 @@ -218,6 +218,11 @@ internal class XMLTVInstance : IGetInstance, IDisposable { + public void Dispose() + { + //throw new NotImplementedException(); + } + private XMLTVRuntimeInstance gInstance; public XMLTVRuntimeInstance GetInstance() { return gInstance; } public XMLTVInstance(string xmlfile) @@ -225,6 +230,7 @@ try { CreateLoader(xmlfile); + CreateParser(); } catch (Exception ex) { @@ -266,16 +272,110 @@ 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) + private void CreateParser() { + var doc = XDocument.Parse(this.GetInstance().XmlDoc); + var root_element = doc.Root; + CreateHandlerForRootNode(root_element); + var nodes = doc.Root.Elements().ToList(); + double total_nodes = nodes.Count; + double node_index = 0; + double progress = 0; + foreach(var node in nodes) + { + if (!CreateHandlerForNode(node)) { xmltv_logger.Verbose.Debug.WriteLine("Unable to create handler for node: '{0}'", node.Name.ToString()); } + node_index++; + progress = 100.0 * (node_index / total_nodes); + xmltv_logger.ReportProgress(this, new Enterprise.Logging.ReportProgressEventArgs((int)progress)); + Application.DoEvents(); + } } - public void Dispose() - { - //throw new NotImplementedException(); + + private void CreateHandlerForRootNode(XElement root) + { + if (root == null) { throw new NullReferenceException("Root element is null"); } + if (root.Name == null) { throw new NullReferenceException("Root element's Name is null"); } + var root_name = root.Name.ToString(); + xmltv_logger.Verbose.Debug.WriteLine("Creating handler for root: '{0}'", root_name.ToString()); + 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)) + { + 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_name) + { + handler_type = type; + break; + } + } + } + } + catch (Exception) { } + } + } + if (handler_type == null) { throw new Exception("Unable to find a compatible handler to parse document root."); } + xmltv_logger.Verbose.Debug.WriteLine("Created handler for root: '{0}'", root_name.ToString()); + raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] { gInstance }, culture); } + private bool CreateHandlerForNode(XElement node) + { + if (node == null) { throw new NullReferenceException("Node element is null"); } + if (node.Name == null) { throw new NullReferenceException("Node element's Name is null"); } + var node_name = node.Name.ToString(); + + xmltv_logger.Verbose.Debug.WriteLine("Creating handler for node: '{0}'", node_name.ToString()); + 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)) + { + 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() == node_name) + { + handler_type = type; + break; + } + } + } + } + catch (Exception) { } + } + } + if (handler_type == null) { throw new Exception("Unable to find a compatible handler to parse document root."); } + xmltv_logger.Verbose.Debug.WriteLine("Created handler for node: '{0}'", node_name.ToString()); + raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] { gInstance, node }, culture); + return true; + } } }