📄 logfactory.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.commons.logging;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
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: 593798 $ $Date: 2007-11-10 18:40:43 +0100 $
*/
public abstract class LogFactory {
// Implementation note re AccessController usage
//
// It is important to keep code invoked via an AccessController to small
// auditable blocks. Such code must carefully evaluate all user input
// (parameters, system properties, config file contents, etc). As an
// example, a Log implementation should not write to its logfile
// with an AccessController anywhere in the call stack, otherwise an
// insecure application could configure the log implementation to write
// to a protected file using the privileges granted to JCL rather than
// to the calling application.
//
// Under no circumstance should a non-private method return data that is
// retrieved via an AccessController. That would allow an insecure app
// to invoke that method and obtain data that it is not permitted to have.
//
// Invoking user-supplied code with an AccessController set is not a major
// issue (eg invoking the constructor of the class specified by
// HASHTABLE_IMPLEMENTATION_PROPERTY). That class will be in a different
// trust domain, and therefore must have permissions to do whatever it
// is trying to do regardless of the permissions granted to JCL. There is
// a slight issue in that untrusted code may point that environment var
// to another trusted library, in which case the code runs if both that
// lib and JCL have the necessary permissions even when the untrusted
// caller does not. That's a pretty hard route to exploit though.
// ----------------------------------------------------- Manifest Constants
/**
* The name (<code>priority</code>) of the key in the config file used to
* specify the priority of that particular config file. The associated value
* is a floating-point number; higher values take priority over lower values.
*/
public static final String PRIORITY_KEY = "priority";
/**
* The name (<code>use_tccl</code>) of the key in the config file used
* to specify whether logging classes should be loaded via the thread
* context class loader (TCCL), or not. By default, the TCCL is used.
*/
public static final String TCCL_KEY = "use_tccl";
/**
* The name (<code>org.apache.commons.logging.LogFactory</code>) of the property
* used to identify the LogFactory implementation
* class name. This can be used as a system property, or as an entry in a
* configuration properties file.
*/
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 (<code>commons-logging.properties</code>) 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";
/**
* The name (<code>org.apache.commons.logging.diagnostics.dest</code>)
* of the property used to enable internal commons-logging
* diagnostic output, in order to get information on what logging
* implementations are being discovered, what classloaders they
* are loaded through, etc.
* <p>
* If a system property of this name is set then the value is
* assumed to be the name of a file. The special strings
* STDOUT or STDERR (case-sensitive) indicate output to
* System.out and System.err respectively.
* <p>
* Diagnostic logging should be used only to debug problematic
* configurations and should not be set in normal production use.
*/
public static final String DIAGNOSTICS_DEST_PROPERTY =
"org.apache.commons.logging.diagnostics.dest";
/**
* When null (the usual case), no diagnostic output will be
* generated by LogFactory or LogFactoryImpl. When non-null,
* interesting events will be written to the specified object.
*/
private static PrintStream diagnosticsStream = null;
/**
* A string that gets prefixed to every message output by the
* logDiagnostic method, so that users can clearly see which
* LogFactory class is generating the output.
*/
private static String diagnosticPrefix;
/**
* <p>Setting this system property
* (<code>org.apache.commons.logging.LogFactory.HashtableImpl</code>)
* value allows the <code>Hashtable</code> used to store
* classloaders to be substituted by an alternative implementation.
* </p>
* <p>
* <strong>Note:</strong> <code>LogFactory</code> will print:
* <code><pre>
* [ERROR] LogFactory: Load of custom hashtable failed</em>
* </pre></code>
* to system error and then continue using a standard Hashtable.
* </p>
* <p>
* <strong>Usage:</strong> Set this property when Java is invoked
* and <code>LogFactory</code> will attempt to load a new instance
* of the given implementation class.
* For example, running the following ant scriplet:
* <code><pre>
* <java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}">
* ...
* <sysproperty
* key="org.apache.commons.logging.LogFactory.HashtableImpl"
* value="org.apache.commons.logging.AltHashtable"/>
* </java>
* </pre></code>
* will mean that <code>LogFactory</code> will load an instance of
* <code>org.apache.commons.logging.AltHashtable</code>.
* </p>
* <p>
* A typical use case is to allow a custom
* Hashtable implementation using weak references to be substituted.
* This will allow classloaders to be garbage collected without
* the need to release them (on 1.3+ JVMs only, of course ;)
* </p>
*/
public static final String HASHTABLE_IMPLEMENTATION_PROPERTY =
"org.apache.commons.logging.LogFactory.HashtableImpl";
/** Name used to load the weak hashtable implementation by names */
private static final String WEAK_HASHTABLE_CLASSNAME =
"org.apache.commons.logging.impl.WeakHashtable";
/**
* A reference to the classloader that loaded this class. This is the
* same as LogFactory.class.getClassLoader(). However computing this
* value isn't quite as simple as that, as we potentially need to use
* AccessControllers etc. It's more efficient to compute it once and
* cache it here.
*/
private static ClassLoader thisClassLoader;
// ----------------------------------------------------------- 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -