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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] Log}implementation class has a + * <code>setLogFactory()</code> method that accepts a [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] org.apache.commons.logging.LogSource}class. + */ + protected static final String LOG_PROPERTY_OLD = "org.apache.commons.logging.log"; + + /** + * <p> + * The name of the [EMAIL PROTECTED] 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 + * [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] Log} interface which delegates all processing to + * a [EMAIL PROTECTED] 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 _______________________________________________ dev mailing list [email protected] http://slf4j.org/mailman/listinfo/dev
