📄 domconfigurator.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.log4j.xml;import org.apache.log4j.Appender;import org.apache.log4j.Layout;import org.apache.log4j.Level;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;import org.apache.log4j.config.PropertySetter;import org.apache.log4j.helpers.FileWatchdog;import org.apache.log4j.helpers.Loader;import org.apache.log4j.helpers.LogLog;import org.apache.log4j.helpers.OptionConverter;import org.apache.log4j.or.RendererMap;import org.apache.log4j.spi.AppenderAttachable;import org.apache.log4j.spi.Configurator;import org.apache.log4j.spi.ErrorHandler;import org.apache.log4j.spi.Filter;import org.apache.log4j.spi.LoggerFactory;import org.apache.log4j.spi.LoggerRepository;import org.apache.log4j.spi.OptionHandler;import org.apache.log4j.spi.RendererSupport;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.FactoryConfigurationError;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.lang.reflect.Method;import java.net.URL;import java.util.Hashtable;import java.util.Properties;// Contributors: Mark Womack// Arun Katkere /** Use this class to initialize the log4j environment using a DOM tree. <p>The DTD is specified in <a href="log4j.dtd"><b>log4j.dtd</b></a>. <p>Sometimes it is useful to see how log4j is reading configuration files. You can enable log4j internal logging by defining the <b>log4j.debug</b> variable on the java command line. Alternatively, set the <code>debug</code> attribute in the <code>log4j:configuration</code> element. As in<pre> <log4j:configuration <b>debug="true"</b> xmlns:log4j="http://jakarta.apache.org/log4j/"> ... </log4j:configuration></pre> <p>There are sample XML files included in the package. @author Christopher Taylor @author Ceki Gülcü @author Anders Kristensen @since 0.8.3 */public class DOMConfigurator implements Configurator { static final String CONFIGURATION_TAG = "log4j:configuration"; static final String OLD_CONFIGURATION_TAG = "configuration"; static final String RENDERER_TAG = "renderer"; static final String APPENDER_TAG = "appender"; static final String APPENDER_REF_TAG = "appender-ref"; static final String PARAM_TAG = "param"; static final String LAYOUT_TAG = "layout"; static final String CATEGORY = "category"; static final String LOGGER = "logger"; static final String LOGGER_REF = "logger-ref"; static final String CATEGORY_FACTORY_TAG = "categoryFactory"; static final String LOGGER_FACTORY_TAG = "loggerFactory"; static final String NAME_ATTR = "name"; static final String CLASS_ATTR = "class"; static final String VALUE_ATTR = "value"; static final String ROOT_TAG = "root"; static final String ROOT_REF = "root-ref"; static final String LEVEL_TAG = "level"; static final String PRIORITY_TAG = "priority"; static final String FILTER_TAG = "filter"; static final String ERROR_HANDLER_TAG = "errorHandler"; static final String REF_ATTR = "ref"; static final String ADDITIVITY_ATTR = "additivity"; static final String THRESHOLD_ATTR = "threshold"; static final String CONFIG_DEBUG_ATTR = "configDebug"; static final String INTERNAL_DEBUG_ATTR = "debug"; private static final String RESET_ATTR = "reset"; static final String RENDERING_CLASS_ATTR = "renderingClass"; static final String RENDERED_CLASS_ATTR = "renderedClass"; static final String EMPTY_STR = ""; static final Class[] ONE_STRING_PARAM = new Class[] {String.class}; final static String dbfKey = "javax.xml.parsers.DocumentBuilderFactory"; // key: appenderName, value: appender Hashtable appenderBag; Properties props; LoggerRepository repository; protected LoggerFactory catFactory = null; /** No argument constructor. */ public DOMConfigurator () { appenderBag = new Hashtable(); } /** Used internally to parse appenders by IDREF name. */ protected Appender findAppenderByName(Document doc, String appenderName) { Appender appender = (Appender) appenderBag.get(appenderName); if(appender != null) { return appender; } else { // Doesn't work on DOM Level 1 : // Element element = doc.getElementById(appenderName); // Endre's hack: Element element = null; NodeList list = doc.getElementsByTagName("appender"); for (int t=0; t < list.getLength(); t++) { Node node = list.item(t); NamedNodeMap map= node.getAttributes(); Node attrNode = map.getNamedItem("name"); if (appenderName.equals(attrNode.getNodeValue())) { element = (Element) node; break; } } // Hack finished. if(element == null) { LogLog.error("No appender named ["+appenderName+"] could be found."); return null; } else { appender = parseAppender(element); appenderBag.put(appenderName, appender); return appender; } } } /** Used internally to parse appenders by IDREF element. */ protected Appender findAppenderByReference(Element appenderRef) { String appenderName = subst(appenderRef.getAttribute(REF_ATTR)); Document doc = appenderRef.getOwnerDocument(); return findAppenderByName(doc, appenderName); } /** * Delegates unrecognized content to created instance if * it supports UnrecognizedElementParser. * @since 1.2.15 * @param instance instance, may be null. * @param element element, may not be null. * @param props properties * @throws IOException thrown if configuration of owner object * should be abandoned. */ private static void parseUnrecognizedElement(final Object instance, final Element element, final Properties props) throws Exception { boolean recognized = false; if (instance instanceof UnrecognizedElementHandler) { recognized = ((UnrecognizedElementHandler) instance).parseUnrecognizedElement( element, props); } if (!recognized) { LogLog.warn("Unrecognized element " + element.getNodeName()); } } /** * Delegates unrecognized content to created instance if * it supports UnrecognizedElementParser and catches and * logs any exception. * @since 1.2.15 * @param instance instance, may be null. * @param element element, may not be null. * @param props properties */ private static void quietParseUnrecognizedElement(final Object instance, final Element element, final Properties props) { try { parseUnrecognizedElement(instance, element, props); } catch (Exception ex) { LogLog.error("Error in extension content: ", ex); } } /** Used internally to parse an appender element. */ protected Appender parseAppender (Element appenderElement) { String className = subst(appenderElement.getAttribute(CLASS_ATTR)); LogLog.debug("Class name: [" + className+']'); try { Object instance = Loader.loadClass(className).newInstance(); Appender appender = (Appender)instance; PropertySetter propSetter = new PropertySetter(appender); appender.setName(subst(appenderElement.getAttribute(NAME_ATTR))); NodeList children = appenderElement.getChildNodes(); final int length = children.getLength(); for (int loop = 0; loop < length; loop++) { Node currentNode = children.item(loop); /* We're only interested in Elements */ if (currentNode.getNodeType() == Node.ELEMENT_NODE) { Element currentElement = (Element)currentNode; // Parse appender parameters if (currentElement.getTagName().equals(PARAM_TAG)) { setParameter(currentElement, propSetter); } // Set appender layout else if (currentElement.getTagName().equals(LAYOUT_TAG)) { appender.setLayout(parseLayout(currentElement)); } // Add filters else if (currentElement.getTagName().equals(FILTER_TAG)) { parseFilters(currentElement, appender); } else if (currentElement.getTagName().equals(ERROR_HANDLER_TAG)) { parseErrorHandler(currentElement, appender); } else if (currentElement.getTagName().equals(APPENDER_REF_TAG)) { String refName = subst(currentElement.getAttribute(REF_ATTR)); if(appender instanceof AppenderAttachable) { AppenderAttachable aa = (AppenderAttachable) appender; LogLog.debug("Attaching appender named ["+ refName+ "] to appender named ["+ appender.getName()+"]."); aa.addAppender(findAppenderByReference(currentElement)); } else { LogLog.error("Requesting attachment of appender named ["+ refName+ "] to appender named ["+ appender.getName()+ "] which does not implement org.apache.log4j.spi.AppenderAttachable."); } } else { parseUnrecognizedElement(instance, currentElement, props); } } } propSetter.activate(); return 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("Could not create an Appender. Reported error follows.", oops); return null; } } /** Used internally to parse an {@link ErrorHandler} element. */ protected void parseErrorHandler(Element element, Appender appender) { ErrorHandler eh = (ErrorHandler) OptionConverter.instantiateByClassName( subst(element.getAttribute(CLASS_ATTR)), org.apache.log4j.spi.ErrorHandler.class, null); if(eh != null) { eh.setAppender(appender); PropertySetter propSetter = new PropertySetter(eh); NodeList children = element.getChildNodes(); final int length = children.getLength(); for (int loop = 0; loop < length; loop++) { Node currentNode = children.item(loop); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { Element currentElement = (Element) currentNode; String tagName = currentElement.getTagName(); if(tagName.equals(PARAM_TAG)) { setParameter(currentElement, propSetter); } else if(tagName.equals(APPENDER_REF_TAG)) { eh.setBackupAppender(findAppenderByReference(currentElement)); } else if(tagName.equals(LOGGER_REF)) { String loggerName = currentElement.getAttribute(REF_ATTR); Logger logger = (catFactory == null) ? repository.getLogger(loggerName) : repository.getLogger(loggerName, catFactory); eh.setLogger(logger); } else if(tagName.equals(ROOT_REF)) { Logger root = repository.getRootLogger(); eh.setLogger(root); } else { quietParseUnrecognizedElement(eh, currentElement, props); } } } propSetter.activate(); appender.setErrorHandler(eh); } } /** Used internally to parse a filter element. */ protected void parseFilters(Element element, Appender appender) { String clazz = subst(element.getAttribute(CLASS_ATTR));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -