[slf4j-dev] svn commit: r198 - in slf4j/trunk/src/java/org/apache/commons/logging: . impl
ceki at slf4j.org
ceki at slf4j.org
Fri Aug 26 16:12:22 CEST 2005
Author: ceki
Date: Fri Aug 26 16:12:21 2005
New Revision: 198
Added:
slf4j/trunk/src/java/org/apache/commons/logging/impl/SLF4FLogFactory.java
slf4j/trunk/src/java/org/apache/commons/logging/impl/SLF4JLog.java
Modified:
slf4j/trunk/src/java/org/apache/commons/logging/LogFactory.java
Log:
Initial implementation of JCL on top of SLF4J
Modified: slf4j/trunk/src/java/org/apache/commons/logging/LogFactory.java
==============================================================================
--- slf4j/trunk/src/java/org/apache/commons/logging/LogFactory.java (original)
+++ slf4j/trunk/src/java/org/apache/commons/logging/LogFactory.java Fri Aug 26 16:12:21 2005
@@ -12,593 +12,219 @@
* 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;
-
+import org.apache.commons.logging.impl.SLF4FLogFactory;
/**
- * <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>
- *
+ * <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 $
+ * @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a>
*/
public abstract class LogFactory {
+ static LogFactory logFactory = new SLF4FLogFactory();
- // ----------------------------------------------------- Manifest Constants
-
+ /**
+ * 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 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.SLF4FLogFactory</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 {
+ return logFactory;
+ }
+
+ /**
+ * Convenience method to return a named logger, without the application having
+ * to care about factories.
+ *
+ * @param clazz
+ * Class from which a log name will be derived
+ *
+ * @exception LogConfigurationException
+ * if a suitable <code>Log</code> instance cannot be returned
+ */
+ public static Log getLog(Class clazz) throws LogConfigurationException {
+
+ return (getFactory().getInstance(clazz));
+ }
+
+ /**
+ * Convenience method to return a named logger, without the application having
+ * to care about factories.
+ *
+ * @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 static Log getLog(String name) throws LogConfigurationException {
+
+ return (getFactory().getInstance(name));
+
+ }
+
+ /**
+ * Release any internal references to previously created {@link LogFactory}
+ * instances that have been associated with the specified class loader (if
+ * any), after calling the instance method <code>release()</code> on each of
+ * them.
+ *
+ * @param classLoader
+ * ClassLoader for which to release the LogFactory
+ */
+ public static void release(ClassLoader classLoader) {
+ // since SLF4J based JCL does not make use of classloaders, there is nothing
+ // to do here
+ }
+
+ /**
+ * Release any internal references to previously created {@link LogFactory}
+ * instances, after calling the instance method <code>release()</code> on
+ * each of them. 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 static void releaseAll() {
+ // since SLF4J based JCL does not make use of classloaders, there is nothing
+ // to do here
+ }
- /**
- * 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 )
-
- if (factory == null && props != null) {
- String factoryClass = props.getProperty(FACTORY_PROPERTY);
- if (factoryClass != null) {
- factory = newFactory(factoryClass, contextClassLoader);
- }
- }
-
-
- // Fourth, try the fallback implementation class
-
- if (factory == null) {
- factory = newFactory(FACTORY_DEFAULT, LogFactory.class.getClassLoader());
- }
-
- if (factory != null) {
- /**
- * Always cache using context class loader.
- */
- cacheFactory(contextClassLoader, factory);
-
- if( props!=null ) {
- Enumeration names = props.propertyNames();
- while (names.hasMoreElements()) {
- String name = (String) names.nextElement();
- String value = props.getProperty(name);
- factory.setAttribute(name, value);
- }
- }
- }
-
- return factory;
- }
-
-
- /**
- * Convenience method to return a named logger, without the application
- * having to care about factories.
- *
- * @param clazz Class from which a log name will be derived
- *
- * @exception LogConfigurationException if a suitable <code>Log</code>
- * instance cannot be returned
- */
- public static Log getLog(Class clazz)
- throws LogConfigurationException {
-
- return (getFactory().getInstance(clazz));
-
- }
-
-
- /**
- * Convenience method to return a named logger, without the application
- * having to care about factories.
- *
- * @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 static Log getLog(String name)
- throws LogConfigurationException {
-
- return (getFactory().getInstance(name));
-
- }
-
-
- /**
- * Release any internal references to previously created {@link LogFactory}
- * instances that have been associated with the specified class loader
- * (if any), after calling the instance method <code>release()</code> on
- * each of them.
- *
- * @param classLoader ClassLoader for which to release the LogFactory
- */
- public static void release(ClassLoader classLoader) {
-
- synchronized (factories) {
- LogFactory factory = (LogFactory) factories.get(classLoader);
- if (factory != null) {
- factory.release();
- factories.remove(classLoader);
- }
- }
-
- }
-
-
- /**
- * Release any internal references to previously created {@link LogFactory}
- * instances, after calling the instance method <code>release()</code> on
- * each of them. 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 static void releaseAll() {
-
- synchronized (factories) {
- Enumeration elements = factories.elements();
- while (elements.hasMoreElements()) {
- LogFactory element = (LogFactory) elements.nextElement();
- element.release();
- }
- factories.clear();
- }
-
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Return the thread context class loader if available.
- * Otherwise return null.
- *
- * The thread context class loader is available for JDK 1.2
- * or later, if certain security conditions are met.
- *
- * @exception LogConfigurationException if a suitable class loader
- * cannot be identified.
- */
- protected static ClassLoader getContextClassLoader()
- throws LogConfigurationException
- {
- ClassLoader classLoader = null;
-
- try {
- // Are we running on a JDK 1.2 or later system?
- Method method = Thread.class.getMethod("getContextClassLoader", null);
-
- // Get the thread context class loader (if there is one)
- try {
- classLoader = (ClassLoader)method.invoke(Thread.currentThread(), null);
- } catch (IllegalAccessException e) {
- throw new LogConfigurationException
- ("Unexpected IllegalAccessException", e);
- } catch (InvocationTargetException e) {
- /**
- * InvocationTargetException is thrown by 'invoke' when
- * the method being invoked (getContextClassLoader) throws
- * an exception.
- *
- * getContextClassLoader() throws SecurityException when
- * the context class loader isn't an ancestor of the
- * calling class's class loader, or if security
- * permissions are restricted.
- *
- * In the first case (not related), we want to ignore and
- * keep going. We cannot help but also ignore the second
- * with the logic below, but other calls elsewhere (to
- * obtain a class loader) will trigger this exception where
- * we can make a distinction.
- */
- if (e.getTargetException() instanceof SecurityException) {
- ; // ignore
- } else {
- // Capture 'e.getTargetException()' exception for details
- // alternate: log 'e.getTargetException()', and pass back 'e'.
- throw new LogConfigurationException
- ("Unexpected InvocationTargetException", e.getTargetException());
- }
- }
- } catch (NoSuchMethodException e) {
- // Assume we are running on JDK 1.1
- classLoader = LogFactory.class.getClassLoader();
- }
-
- // Return the selected class loader
- return classLoader;
- }
-
- /**
- * Check cached factories (keyed by contextClassLoader)
- */
- private static LogFactory getCachedFactory(ClassLoader contextClassLoader)
- {
- LogFactory factory = null;
-
- if (contextClassLoader != null)
- factory = (LogFactory) factories.get(contextClassLoader);
-
- return factory;
- }
-
- private static void cacheFactory(ClassLoader classLoader, LogFactory factory)
- {
- if (classLoader != null && factory != null)
- factories.put(classLoader, factory);
- }
-
- /**
- * Return a new instance of the specified <code>LogFactory</code>
- * implementation class, loaded by the specified class loader.
- * If that fails, try the class loader used to load this
- * (abstract) LogFactory.
- *
- * @param factoryClass Fully qualified name of the <code>LogFactory</code>
- * implementation class
- * @param classLoader ClassLoader from which to load this class
- *
- * @exception LogConfigurationException if a suitable instance
- * cannot be created
- */
- protected static LogFactory newFactory(final String factoryClass,
- final ClassLoader classLoader)
- throws LogConfigurationException
- {
- Object result = AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- // This will be used to diagnose bad configurations
- // and allow a useful message to be sent to the user
- Class logFactoryClass = null;
- try {
- if (classLoader != null) {
- try {
- // First the given class loader param (thread class loader)
-
- // Warning: must typecast here & allow exception
- // to be generated/caught & recast properly.
- logFactoryClass = classLoader.loadClass(factoryClass);
- return (LogFactory) logFactoryClass.newInstance();
-
- } catch (ClassNotFoundException ex) {
- if (classLoader == LogFactory.class.getClassLoader()) {
- // Nothing more to try, onwards.
- throw ex;
- }
- // ignore exception, continue
- } catch (NoClassDefFoundError e) {
- if (classLoader == LogFactory.class.getClassLoader()) {
- // Nothing more to try, onwards.
- throw e;
- }
-
- } catch(ClassCastException e){
-
- if (classLoader == LogFactory.class.getClassLoader()) {
- // Nothing more to try, onwards (bug in loader implementation).
- throw e;
- }
- }
- // Ignore exception, continue
- }
-
- /* At this point, either classLoader == null, OR
- * classLoader was unable to load factoryClass.
- * Try the class loader that loaded this class:
- * LogFactory.getClassLoader().
- *
- * Notes:
- * a) LogFactory.class.getClassLoader() may return 'null'
- * if LogFactory is loaded by the bootstrap classloader.
- * b) The Java endorsed library mechanism is instead
- * Class.forName(factoryClass);
- */
- // Warning: must typecast here & allow exception
- // to be generated/caught & recast properly.
- logFactoryClass = Class.forName(factoryClass);
- return (LogFactory) logFactoryClass.newInstance();
- } catch (Exception e) {
- // Check to see if we've got a bad configuration
- if (logFactoryClass != null
- && !LogFactory.class.isAssignableFrom(logFactoryClass)) {
- return new LogConfigurationException(
- "The chosen LogFactory implementation does not extend LogFactory."
- + " Please check your configuration.",
- e);
- }
- return new LogConfigurationException(e);
- }
- }
- });
-
- if (result instanceof LogConfigurationException)
- throw (LogConfigurationException)result;
-
- return (LogFactory)result;
- }
-
- private static InputStream getResourceAsStream(final ClassLoader loader,
- final String name)
- {
- return (InputStream)AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- if (loader != null) {
- return loader.getResourceAsStream(name);
- } else {
- return ClassLoader.getSystemResourceAsStream(name);
- }
- }
- });
- }
-}
+}
\ No newline at end of file
Added: slf4j/trunk/src/java/org/apache/commons/logging/impl/SLF4FLogFactory.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/src/java/org/apache/commons/logging/impl/SLF4FLogFactory.java Fri Aug 26 16:12:21 2005
@@ -0,0 +1,265 @@
+/*
+ * 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.impl;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogConfigurationException;
+import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * Concrete subclass of {@link LogFactory}that implements the following
+ * algorithm to dynamically select a logging implementation class to instantiate
+ * a wrapper for.
+ * </p>
+ * <ul>
+ * <li>Use a factory configuration attribute named
+ * <code>org.apache.commons.logging.Log</code> to identify the requested
+ * implementation class.</li>
+ * <li>Use the <code>org.apache.commons.logging.Log</code> system property to
+ * identify the requested implementation class.</li>
+ * <li>If <em>Log4J</em> is available, return an instance of
+ * <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li>
+ * <li>If <em>JDK 1.4 or later</em> is available, return an instance of
+ * <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li>
+ * <li>Otherwise, return an instance of
+ * <code>org.apache.commons.logging.impl.SimpleLog</code>.</li>
+ * </ul>
+ *
+ * <p>
+ * If the selected {@link Log}implementation class has a
+ * <code>setLogFactory()</code> method that accepts a {@link LogFactory}
+ * parameter, this method will be called on each newly created instance to
+ * identify the associated factory. This makes factory configuration attributes
+ * available to the Log instance, if it so desires.
+ * </p>
+ *
+ * <p>
+ * This factory will remember previously created <code>Log</code> instances
+ * for the same name, and will return them on repeated requests to the
+ * <code>getInstance()</code> method. This implementation ignores any
+ * configured attributes.
+ * </p>
+ *
+ * @author Rod Waldhoff
+ * @author Craig R. McClanahan
+ * @author Richard A. Sitze
+ */
+
+public class SLF4FLogFactory extends LogFactory {
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * The {@link org.apache.commons.logging.Log}instances that have already been
+ * created, keyed by logger name.
+ */
+ Map loggerMap;
+
+ /**
+ * Public no-arguments constructor required by the lookup mechanism.
+ */
+ public SLF4FLogFactory() {
+ loggerMap = new HashMap();
+ }
+
+ // ----------------------------------------------------- Manifest Constants
+
+ /**
+ * The name of the system property identifying our {@link Log}implementation
+ * class.
+ */
+ public static final String LOG_PROPERTY = "org.apache.commons.logging.Log";
+
+ /**
+ * The deprecated system property used for backwards compatibility with the
+ * old {@link org.apache.commons.logging.LogSource}class.
+ */
+ protected static final String LOG_PROPERTY_OLD = "org.apache.commons.logging.log";
+
+ /**
+ * <p>
+ * The name of the {@link Log}interface class.
+ * </p>
+ */
+ private static final String LOG_INTERFACE = "org.apache.commons.logging.Log";
+
+ // ----------------------------------------------------- Instance Variables
+
+ /**
+ * Configuration attributes.
+ */
+ protected Hashtable attributes = new Hashtable();
+
+ /**
+ * Name of the class implementing the Log interface.
+ */
+ private String logClassName;
+
+ // --------------------------------------------------------- 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 Object getAttribute(String name) {
+
+ return (attributes.get(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 String[] getAttributeNames() {
+
+ Vector names = new Vector();
+ Enumeration keys = attributes.keys();
+ while (keys.hasMoreElements()) {
+ names.addElement((String) keys.nextElement());
+ }
+ String results[] = new String[names.size()];
+ for (int i = 0; i < results.length; i++) {
+ results[i] = (String) names.elementAt(i);
+ }
+ return (results);
+
+ }
+
+ /**
+ * 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 Log getInstance(Class clazz) throws LogConfigurationException {
+
+ return (getInstance(clazz.getName()));
+
+ }
+
+ /**
+ * <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 Log getInstance(String name) throws LogConfigurationException {
+
+ Log instance = (Log) loggerMap.get(name);
+ if (instance == null) {
+ instance = newInstance(name);
+ loggerMap.put(name, instance);
+ }
+ return (instance);
+
+ }
+
+ /**
+ * Release any internal references to previously created
+ * {@link org.apache.commons.logging.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 void release() {
+ throw new UnsupportedOperationException("SLF4J bound commons-logging does not need to implement 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 void removeAttribute(String name) {
+ attributes.remove(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 void setAttribute(String name, Object value) {
+
+ if (value == null) {
+ attributes.remove(name);
+ } else {
+ attributes.put(name, value);
+ }
+
+ }
+
+ // ------------------------------------------------------ Protected Methods
+
+ /**
+ * Create and return a new {@link org.apache.commons.logging.Log}instance for
+ * the specified name.
+ *
+ * @param name
+ * Name of the new logger
+ *
+ * @exception LogConfigurationException
+ * if a new instance cannot be created
+ */
+ protected Log newInstance(String name) throws LogConfigurationException {
+ Logger logger = LoggerFactory.getLogger(name);
+ return new SLF4JLog(logger);
+ }
+
+}
\ No newline at end of file
Added: slf4j/trunk/src/java/org/apache/commons/logging/impl/SLF4JLog.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/src/java/org/apache/commons/logging/impl/SLF4JLog.java Fri Aug 26 16:12:21 2005
@@ -0,0 +1,106 @@
+// TOTO
+
+package org.apache.commons.logging.impl;
+
+import org.apache.commons.logging.Log;
+import org.slf4j.Logger;
+
+/**
+ * Implementation of {@link Log} interface which delegates all processing to
+ * a {@link Logger} instance.
+ *
+ * <p>JCL's FATAL and TRACE levels are mapped to ERROR and DEBUG respectively. All
+ * other levels map one to one.
+ *
+ * @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a>
+ */
+public class SLF4JLog implements Log {
+
+ Logger logger;
+
+ SLF4JLog(Logger logger) {
+ this.logger = logger;
+ }
+
+ /**
+ * Delegate to org.slf4j.Logger instance.
+ */
+ public boolean isDebugEnabled() {
+ return logger.isDebugEnabled();
+ }
+
+ public boolean isErrorEnabled() {
+ return logger.isErrorEnabled();
+ }
+
+ public boolean isFatalEnabled() {
+ return logger.isErrorEnabled();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.commons.logging.Log#isInfoEnabled()
+ */
+ public boolean isInfoEnabled() {
+ return logger.isInfoEnabled();
+ }
+
+ public boolean isTraceEnabled() {
+ return logger.isDebugEnabled();
+ }
+
+ public boolean isWarnEnabled() {
+ return logger.isWarnEnabled();
+ }
+
+ public void trace(Object message) {
+ logger.debug(message.toString());
+ }
+
+ public void trace(Object message, Throwable t) {
+ logger.debug(message.toString(), t);
+ }
+
+ public void debug(Object message) {
+ logger.debug(message.toString());
+ }
+
+ public void debug(Object message, Throwable t) {
+ logger.debug(message.toString(), t);
+ }
+
+ public void info(Object message) {
+ logger.info(message.toString());
+ }
+
+ public void info(Object message, Throwable t) {
+ logger.info(message.toString(), t);
+ }
+
+ public void warn(Object message) {
+ logger.warn(message.toString());
+ }
+
+ public void warn(Object message, Throwable t) {
+ logger.warn(message.toString(), t);
+ }
+
+
+ public void error(Object message) {
+ logger.error(message.toString());
+ }
+
+ public void error(Object message, Throwable t) {
+ logger.error(message.toString(), t);
+ }
+
+ public void fatal(Object message) {
+ logger.error(message.toString());
+ }
+
+ public void fatal(Object message, Throwable t) {
+ logger.error(message.toString(), t);
+ }
+
+}
\ No newline at end of file
More information about the slf4j-dev
mailing list