📄 domconfigurator.java
字号:
/* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software * License version 1.1, a copy of which has been included with this * distribution in the LICENSE.txt file. */package org.apache.log4j.xml;import java.util.*;import java.net.URL;import org.w3c.dom.*;import java.lang.reflect.Method;import org.apache.log4j.*;import org.apache.log4j.spi.*;import org.apache.log4j.or.RendererMap;import org.apache.log4j.helpers.*;import org.apache.log4j.config.PropertySetter;import org.xml.sax.InputSource;import java.io.FileInputStream;import java.io.InputStream;import java.io.Reader;import java.io.IOException;import java.net.URL;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.FactoryConfigurationError;// 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="doc-files/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 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"; 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; /** 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); } /** 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."); } } } } 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 = repository.getLogger(loggerName); eh.setLogger(logger); } else if(tagName.equals(ROOT_REF)) { Logger root = repository.getRootLogger(); eh.setLogger(root); } } } 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)); Filter filter = (Filter) OptionConverter.instantiateByClassName(clazz, Filter.class, null); if(filter != null) { PropertySetter propSetter = new PropertySetter(filter); 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); } } } propSetter.activate(); LogLog.debug("Adding filter of type ["+filter.getClass() +"] to appender named ["+appender.getName()+"]."); appender.addFilter(filter); } } /** Used internally to parse an category element. */ protected void parseCategory (Element loggerElement) { // Create a new org.apache.log4j.Category object from the <category> element. String catName = subst(loggerElement.getAttribute(NAME_ATTR)); Logger cat; String className = subst(loggerElement.getAttribute(CLASS_ATTR)); if(EMPTY_STR.equals(className)) { LogLog.debug("Retreiving an instance of org.apache.log4j.Logger."); cat = repository.getLogger(catName); } else { LogLog.debug("Desired logger sub-class: ["+className+']'); try { Class clazz = Loader.loadClass(className); Method getInstanceMethod = clazz.getMethod("getLogger", ONE_STRING_PARAM); cat = (Logger) getInstanceMethod.invoke(null, new Object[] {catName}); } catch (Exception oops) { LogLog.error("Could not retrieve category ["+catName+ "]. Reported error follows.", oops); return; } } // Setting up a category needs to be an atomic operation, in order // to protect potential log operations while category // configuration is in progress. synchronized(cat) { boolean additivity = OptionConverter.toBoolean( subst(loggerElement.getAttribute(ADDITIVITY_ATTR)), true); LogLog.debug("Setting ["+cat.getName()+"] additivity to ["+additivity+"]."); cat.setAdditivity(additivity); parseChildrenOfLoggerElement(loggerElement, cat, false); } } /** Used internally to parse the category factory element. */ protected void parseCategoryFactory(Element factoryElement) { String className = subst(factoryElement.getAttribute(CLASS_ATTR)); if(EMPTY_STR.equals(className)) { LogLog.error("Category Factory tag " + CLASS_ATTR + " attribute not found."); LogLog.debug("No Category Factory configured."); } else { LogLog.debug("Desired category factory: ["+className+']'); Object catFactory = OptionConverter.instantiateByClassName(className, LoggerFactory.class, null); PropertySetter propSetter = new PropertySetter(catFactory); Element currentElement = null; Node currentNode = null; NodeList children = factoryElement.getChildNodes(); final int length = children.getLength(); for (int loop=0; loop < length; loop++) { currentNode = children.item(loop); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { currentElement = (Element)currentNode; if (currentElement.getTagName().equals(PARAM_TAG)) { setParameter(currentElement, propSetter); } } } } } /** Used internally to parse the roor category element. */ protected void parseRoot (Element rootElement) { Logger root = repository.getRootLogger(); // category configuration needs to be atomic synchronized(root) { parseChildrenOfLoggerElement(rootElement, root, true); } } /** Used internally to parse the children of a category element. */ protected void parseChildrenOfLoggerElement(Element catElement, Logger cat, boolean isRoot) { PropertySetter propSetter = new PropertySetter(cat); // Remove all existing appenders from cat. They will be // reconstructed if need be. cat.removeAllAppenders(); NodeList children = catElement.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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -