--- trunk/libxmltv/Core/XMLTVRuntimeInstance.cs 2013/03/09 11:40:15 79 +++ trunk/libxmltv/Core/XMLTVRuntimeInstance.cs 2013/03/09 12:41:07 83 @@ -241,33 +241,47 @@ private void CreateLoader(string xml_file) { + xmltv_logger.Verbose.Debug.WriteLine("Creating loader handle"); gInstance = new XMLTVRuntimeInstance(); - bool bound_to_ctor = false; 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)) { - 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; + //xmltv_logger.Verbose.Debug.WriteLine("Type: '{0}' Base: '{1}'", type.Name, type.BaseType == null ? "none" : type.BaseType.Name); object[] args = new object[] { xml_file, gInstance }; - try - { - raw_instance = Activator.CreateInstance(type, flags, null, args, culture); - bound_to_ctor = true; - } - catch (Exception ex) + var iface = type.GetInterface("IXMLTVHandler", true); + if (iface != null) { - Debug.WriteLine(ex.ToString()); + var handler_prop = type.GetProperty("Handler"); + if (handler_prop != null) + { + var ctors = type.GetConstructors(flags); + bool has_string_ctor = false; + foreach (var ctor in ctors) { if (ctor.GetParameters().Count() == 1 && ctor.GetParameters()[0].ParameterType == typeof(string)) { has_string_ctor = true; } } + if (!has_string_ctor) { continue; } + raw_instance = Activator.CreateInstance(type, flags, null, new object[] { xml_file}, culture); + if (raw_instance != null) + { + object handler_value = handler_prop.GetValue(raw_instance, null); + if (handler_value != null && handler_value.ToString() == xml_file) + { + handler_type = type; + break; + } + } + } } } } - if (!bound_to_ctor) { throw new Exception("Unable to find a compatible XMLTV Data Loader."); } + if (handler_type == null) { throw new Exception("Unable to find a compatible XMLTV Data Loader."); } + xmltv_logger.Verbose.Debug.WriteLine("Created loader handle"); + raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] {xml_file , gInstance }, culture); if (raw_instance == null) { throw new NullReferenceException("Found a compatible XMLTV Data Loader, but it returned invalid data."); } IGetInstance getter_instance = (raw_instance as IGetInstance); if (getter_instance != null) { gInstance = getter_instance.GetInstance(); } @@ -313,12 +327,17 @@ foreach (var type in types) { if (type.BaseType != null && type.BaseType == typeof(XMLTVBase)) - { - try + { + var iface = type.GetInterface("IXMLTVHandler", true); + if (iface != null) { var handler_prop = type.GetProperty("Handler"); if (handler_prop != null) { + var ctors = type.GetConstructors(flags); + bool has_default_ctor = false; + foreach (var ctor in ctors) { if (ctor.GetParameters().Count() == 0) { has_default_ctor = true; } } + if (!has_default_ctor) { continue; } raw_instance = Activator.CreateInstance(type, flags, null, new object[0], culture); if (raw_instance != null) { @@ -328,13 +347,19 @@ handler_type = type; break; } - } + } } } - catch (Exception) { } } } - if (handler_type == null) { throw new Exception("Unable to find a compatible handler to parse document root."); } + if (handler_type == null) + { + StringBuilder node_builder = new StringBuilder(); + node_builder.AppendFormat("<{0} ", root.Name); + if (root.HasAttributes) { foreach (var attribute in root.Attributes()) { node_builder.AppendFormat("{0}=\"{1}\" ", attribute.Name, attribute.Value); } } + string node_text = string.Format("{0}>", node_builder.ToString().TrimEnd(new char[] { ' ' })); + throw new Exception(string.Format("Unable to find a compatible handler to parse node: {0}", node_text)); + } 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); } @@ -356,11 +381,16 @@ { if (type.BaseType != null && type.BaseType == typeof(XMLTVBase)) { - try + var iface = type.GetInterface("IXMLTVHandler", true); + if (iface != null) { var handler_prop = type.GetProperty("Handler"); if (handler_prop != null) { + var ctors = type.GetConstructors(flags); + bool has_default_ctor = false; + foreach (var ctor in ctors) { if (ctor.GetParameters().Count() == 0) { has_default_ctor = true; } } + if (!has_default_ctor) { continue; } raw_instance = Activator.CreateInstance(type, flags, null, new object[0], culture); if (raw_instance != null) { @@ -373,10 +403,16 @@ } } } - catch (Exception) { } } } - if (handler_type == null) { throw new Exception("Unable to find a compatible handler to parse document root."); } + if (handler_type == null) + { + StringBuilder node_builder = new StringBuilder(); + node_builder.AppendFormat("<{0} ", node.Name); + if (node.HasAttributes) { foreach (var attribute in node.Attributes()) { node_builder.AppendFormat("{0}=\"{1}\" ", attribute.Name, attribute.Value); } } + string node_text = string.Format("{0}>", node_builder.ToString().TrimEnd(new char[] { ' ' })); + throw new Exception(string.Format("Unable to find a compatible handler to parse node: {0}", node_text)); + } 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;