?? logfactory.java
字號:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed 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.commons.logging;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;/** * <p>Factory for creating {@link Log} instances, with discovery and * configuration features similar to that employed by standard Java APIs * such as JAXP.</p> * * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily * based on the SAXParserFactory and DocumentBuilderFactory implementations * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p> * * @author Craig R. McClanahan * @author Costin Manolache * @author Richard A. Sitze * @version $Revision: 1.27 $ $Date: 2004/06/06 21:15:12 $ */public abstract class LogFactory { // ----------------------------------------------------- Manifest Constants /** * The name of the property used to identify the LogFactory implementation * class name. */ public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory"; /** * The fully qualified class name of the fallback <code>LogFactory</code> * implementation class to use, if no other can be found. */ public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.LogFactoryImpl"; /** * The name of the properties file to search for. */ public static final String FACTORY_PROPERTIES = "commons-logging.properties"; /** * JDK1.3+ <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider"> * 'Service Provider' specification</a>. * */ protected static final String SERVICE_ID = "META-INF/services/org.apache.commons.logging.LogFactory"; // ----------------------------------------------------------- Constructors /** * Protected constructor that is not available for public use. */ protected LogFactory() { } // --------------------------------------------------------- Public Methods /** * Return the configuration attribute with the specified name (if any), * or <code>null</code> if there is no such attribute. * * @param name Name of the attribute to return */ public abstract Object getAttribute(String name); /** * Return an array containing the names of all currently defined * configuration attributes. If there are no such attributes, a zero * length array is returned. */ public abstract String[] getAttributeNames(); /** * Convenience method to derive a name from the specified class and * call <code>getInstance(String)</code> with it. * * @param clazz Class for which a suitable Log name will be derived * * @exception LogConfigurationException if a suitable <code>Log</code> * instance cannot be returned */ public abstract Log getInstance(Class clazz) throws LogConfigurationException; /** * <p>Construct (if necessary) and return a <code>Log</code> instance, * using the factory's current set of configuration attributes.</p> * * <p><strong>NOTE</strong> - Depending upon the implementation of * the <code>LogFactory</code> you are using, the <code>Log</code> * instance you are returned may or may not be local to the current * application, and may or may not be returned again on a subsequent * call with the same name argument.</p> * * @param name Logical name of the <code>Log</code> instance to be * returned (the meaning of this name is only known to the underlying * logging implementation that is being wrapped) * * @exception LogConfigurationException if a suitable <code>Log</code> * instance cannot be returned */ public abstract Log getInstance(String name) throws LogConfigurationException; /** * Release any internal references to previously created {@link Log} * instances returned by this factory. This is useful in environments * like servlet containers, which implement application reloading by * throwing away a ClassLoader. Dangling references to objects in that * class loader would prevent garbage collection. */ public abstract void release(); /** * Remove any configuration attribute associated with the specified name. * If there is no such attribute, no action is taken. * * @param name Name of the attribute to remove */ public abstract void removeAttribute(String name); /** * Set the configuration attribute with the specified name. Calling * this with a <code>null</code> value is equivalent to calling * <code>removeAttribute(name)</code>. * * @param name Name of the attribute to set * @param value Value of the attribute to set, or <code>null</code> * to remove any setting for this attribute */ public abstract void setAttribute(String name, Object value); // ------------------------------------------------------- Static Variables /** * The previously constructed <code>LogFactory</code> instances, keyed by * the <code>ClassLoader</code> with which it was created. */ protected static Hashtable factories = new Hashtable(); // --------------------------------------------------------- Static Methods /** * <p>Construct (if necessary) and return a <code>LogFactory</code> * instance, using the following ordered lookup procedure to determine * the name of the implementation class to be loaded.</p> * <ul> * <li>The <code>org.apache.commons.logging.LogFactory</code> system * property.</li> * <li>The JDK 1.3 Service Discovery mechanism</li> * <li>Use the properties file <code>commons-logging.properties</code> * file, if found in the class path of this class. The configuration * file is in standard <code>java.util.Properties</code> format and * contains the fully qualified name of the implementation class * with the key being the system property defined above.</li> * <li>Fall back to a default implementation class * (<code>org.apache.commons.logging.impl.LogFactoryImpl</code>).</li> * </ul> * * <p><em>NOTE</em> - If the properties file method of identifying the * <code>LogFactory</code> implementation class is utilized, all of the * properties defined in this file will be set as configuration attributes * on the corresponding <code>LogFactory</code> instance.</p> * * @exception LogConfigurationException if the implementation class is not * available or cannot be instantiated. */ public static LogFactory getFactory() throws LogConfigurationException { // Identify the class loader we will be using ClassLoader contextClassLoader = (ClassLoader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return getContextClassLoader(); } }); // Return any previously registered factory for this class loader LogFactory factory = getCachedFactory(contextClassLoader); if (factory != null) return factory; // Load properties file. // Will be used one way or another in the end. Properties props=null; try { InputStream stream = getResourceAsStream(contextClassLoader, FACTORY_PROPERTIES); if (stream != null) { props = new Properties(); props.load(stream); stream.close(); } } catch (IOException e) { } catch (SecurityException e) { } // First, try the system property try { String factoryClass = System.getProperty(FACTORY_PROPERTY); if (factoryClass != null) { factory = newFactory(factoryClass, contextClassLoader); } } catch (SecurityException e) { ; // ignore } // Second, try to find a service by using the JDK1.3 jar // discovery mechanism. This will allow users to plug a logger // by just placing it in the lib/ directory of the webapp ( or in // CLASSPATH or equivalent ). This is similar to the second // step, except that it uses the (standard?) jdk1.3 location in the jar. if (factory == null) { try { InputStream is = getResourceAsStream(contextClassLoader, SERVICE_ID); if( is != null ) { // This code is needed by EBCDIC and other strange systems. // It's a fix for bugs reported in xerces BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is)); } String factoryClassName = rd.readLine(); rd.close(); if (factoryClassName != null && ! "".equals(factoryClassName)) { factory= newFactory( factoryClassName, contextClassLoader ); } } } catch( Exception ex ) { ; } } // Third try a properties file. // If the properties file exists, it'll be read and the properties // used. IMHO ( costin ) System property and JDK1.3 jar service // should be enough for detecting the class name. The properties // should be used to set the attributes ( which may be specific to // the webapp, even if a default logger is set at JVM level by a // system property )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -