--- log4net-1.2.0-beta8\src\Repository\Hierarchy\DOMHierarchyConfigurator.cs 2003-07-07 21:41:10.000000000 +0200 +++ log4net-1.2.0-beta8.local\src\Repository\Hierarchy\DOMHierarchyConfigurator.cs 2005-03-07 13:48:41.503298300 +0100 @@ -209,19 +209,9 @@ // Find the element with that id XmlElement element = null; - if (appenderName != null && appenderName.Length > 0) - { - foreach (XmlNode node in appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG)) - { - if (((XmlElement)node).GetAttribute("name") == appenderName) - { - element = (XmlElement)node; - break; - } - } - } + element = FindAppenderElementByReference(appenderRef, appenderName); - if (element == null) + if (element == null) { LogLog.Error("DOMConfigurator: No appender named [" + appenderName + "] could be found."); return null; @@ -238,6 +228,24 @@ } } + private static XmlElement FindAppenderElementByReference(XmlElement appenderRef, string appenderName) + { + XmlElement element = null; + if (appenderName != null && appenderName.Length > 0) + { + foreach (XmlNode node in appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG)) + { + if (((XmlElement)node).GetAttribute("name") == appenderName) + { + element = (XmlElement)node; + break; + } + } + } + return element; + } + + /// /// Parses an appender element. /// @@ -245,13 +253,52 @@ /// The appender instance or null when parsing failed. protected IAppender ParseAppender(XmlElement appenderElement) { + IAppender appender = null; + ParseAppender(appenderElement, ref appender, true); + return appender; + } + + + /// + /// Parses an appender element. + /// + /// The appender element. + /// The appender to modify. + /// Set to FALSE if appender options should not be activated (yet) + /// + /// If no appender is passed, a new appender is created from the type attribute. + /// If the appender contains an "extends" attribute, the appender which is extended is parsed first. + /// Only the top level appender needs to specify a type attribute. + /// + protected void ParseAppender(XmlElement appenderElement, ref IAppender appender, bool activateOptions) + { string appenderName = appenderElement.GetAttribute(NAME_ATTR); string typeName = appenderElement.GetAttribute(TYPE_ATTR); + string extendsAppenderName = appenderElement.GetAttribute(EXTENDS_ATTR); - LogLog.Debug("DOMConfigurator: Loading Appender [" + appenderName + "] type: [" + typeName + "]"); try { - IAppender appender = (IAppender)SystemInfo.GetTypeFromString(typeName, true, true).GetConstructor(SystemInfo.EmptyTypes).Invoke(BindingFlags.Public | BindingFlags.Instance, null, new object[0], CultureInfo.InvariantCulture); + if (extendsAppenderName != string.Empty) + { + LogLog.Debug("DOMConfigurator: Loading Appender [" + appenderName + "] extends appender: [" + extendsAppenderName + "]"); + XmlElement extendsFromAppender = FindAppenderElementByReference(appenderElement, extendsAppenderName); + if (extendsFromAppender != null) + ParseAppender(extendsFromAppender, ref appender, false); + else + LogLog.Error("DOMConfigurator: Unable to locate appender " + extendsAppenderName); + } + + // Create new appender if we're not modifying an existing one. + if (appender == null && typeName != string.Empty) + { + LogLog.Debug("DOMConfigurator: Loading Appender [" + appenderName + "] type: [" + typeName + "]"); + appender = (IAppender)SystemInfo.GetTypeFromString(typeName, true, true).GetConstructor(SystemInfo.EmptyTypes).Invoke(BindingFlags.Public | BindingFlags.Instance, null, new object[0], CultureInfo.InvariantCulture); + } + + // Bail if no appender was found + if (appender == null) + return; + appender.Name = appenderName; foreach (XmlNode currentNode in appenderElement.ChildNodes) @@ -287,19 +334,16 @@ } } } - if (appender is IOptionHandler) + if (activateOptions && appender is IOptionHandler) { ((IOptionHandler) appender).ActivateOptions(); + LogLog.Debug("DOMConfigurator: Created Appender [" + appenderName + "]"); } - - LogLog.Debug("DOMConfigurator: Created Appender [" + appenderName + "]"); - return appender; } - /* Yes, it's ugly. But all of these exceptions point to the same problem: we can't create an Appender */ + /* Yes, it's ugly. But all of these exceptions point to the same problem: we can't create an Appender */ catch (Exception oops) { LogLog.Error("DOMConfigurator: Could not create Appender [" + appenderName + "] of type [" + typeName + "]. Reported error follows.", oops); - return null; } } @@ -756,6 +800,7 @@ private const string LOGGER_TAG = "logger"; private const string NAME_ATTR = "name"; private const string TYPE_ATTR = "type"; + private const string EXTENDS_ATTR = "extends"; private const string VALUE_ATTR = "value"; private const string ROOT_TAG = "root"; private const string LEVEL_TAG = "level";