LogFactory xref

View Javadoc

    1   /*
    2    * Copyright 2001-2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package org.apache.commons.logging;
    18
    19  import java.util.Hashtable;
    20
    21  import org.apache.commons.logging.impl.SLF4JLogFactory;
    22
    23  /**
    24   * <p>
    25   * Factory for creating {@link Log} instances, which always delegates to an
    26   * instance of {@link SLF4JLogFactory}.
    27   *
    28   * </p>
    29   *
    30   * @author Craig R. McClanahan
    31   * @author Costin Manolache
    32   * @author Richard A. Sitze
    33   * @author Ceki G&uuml;lc&uuml;
    34   */
    35
    36  public abstract class LogFactory {
    37
    38    static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";
    39
    40    static LogFactory logFactory = new SLF4JLogFactory();
    41
    42    /**
    43     * The name (<code>priority</code>) of the key in the config file used to
    44     * specify the priority of that particular config file. The associated value
    45     * is a floating-point number; higher values take priority over lower values.
    46     *
    47     * <p>
    48     * This property is not used but preserved here for compatibility.
    49     */
    50    public static final String PRIORITY_KEY = "priority";
    51
    52    /**
    53     * The name (<code>use_tccl</code>) of the key in the config file used to
    54     * specify whether logging classes should be loaded via the thread context
    55     * class loader (TCCL), or not. By default, the TCCL is used.
    56     *
    57     * <p>
    58     * This property is not used but preserved here for compatibility.
    59     */
    60    public static final String TCCL_KEY = "use_tccl";
    61
    62    /**
    63     * The name of the property used to identify the LogFactory implementation
    64     * class name.
    65     * <p>
    66     * This property is not used but preserved here for compatibility.
    67     */
    68    public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory";
    69
    70    /**
    71     * The fully qualified class name of the fallback <code>LogFactory</code>
    72     * implementation class to use, if no other can be found.
    73     *
    74     * <p>
    75     * This property is not used but preserved here for compatibility.
    76     */
    77    public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.SLF4JLogFactory";
    78
    79    /**
    80     * The name of the properties file to search for.
    81     * <p>
    82     * This property is not used but preserved here for compatibility.
    83     */
    84    public static final String FACTORY_PROPERTIES = "commons-logging.properties";
    85
    86
    87    /**
    88     * JDK1.3+ <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider">
    89     * 'Service Provider' specification</a>.
    90     * <p>
    91     * This property is not used but preserved here for compatibility.
    92     */
    93    protected static final String SERVICE_ID =
    94        "META-INF/services/org.apache.commons.logging.LogFactory";
    95
    96    /**
    97     * The name (<code>org.apache.commons.logging.diagnostics.dest</code>) of
    98     * the property used to enable internal commons-logging diagnostic output, in
    99     * order to get information on what logging implementations are being
    100    * discovered, what classloaders they are loaded through, etc.
    101    *
    102    * <p>
    103    * This property is not used but preserved here for compatibility.
    104    */
    105   public static final String DIAGNOSTICS_DEST_PROPERTY = "org.apache.commons.logging.diagnostics.dest";
    106
    107   /**
    108    * <p>
    109    * Setting this system property value allows the <code>Hashtable</code> used
    110    * to store classloaders to be substituted by an alternative implementation.
    111    * <p>
    112    * This property is not used but preserved here for compatibility.
    113    */
    114   public static final String HASHTABLE_IMPLEMENTATION_PROPERTY = "org.apache.commons.logging.LogFactory.HashtableImpl";
    115
    116   /**
    117    * The previously constructed <code>LogFactory</code> instances, keyed by
    118    * the <code>ClassLoader</code> with which it was created.
    119    *
    120    * <p>
    121    * This property is not used but preserved here for compatibility.
    122    */
    123   protected static Hashtable factories = null;
    124
    125   /**
    126    * <p>
    127    * This property is not used but preserved here for compatibility.
    128    */
    129   protected static LogFactory nullClassLoaderFactory = null;
    130
    131   /**
    132    * Protected constructor that is not available for public use.
    133    */
    134   protected LogFactory() {
    135   }
    136
    137   // --------------------------------------------------------- Public Methods
    138
    139   /**
    140    * Return the configuration attribute with the specified name (if any), or
    141    * <code>null</code> if there is no such attribute.
    142    *
    143    * @param name Name of the attribute to return
    144    * @return configuration attribute
    145    */
    146   public abstract Object getAttribute(String name);
    147
    148   /**
    149    * Return an array containing the names of all currently defined configuration
    150    * attributes. If there are no such attributes, a zero length array is
    151    * returned.
    152    *
    153    * @return names of all currently defined configuration attributes
    154    */
    155   public abstract String[] getAttributeNames();
    156
    157   /**
    158    * Convenience method to derive a name from the specified class and call
    159    * <code>getInstance(String)</code> with it.
    160    *
    161    * @param clazz
    162    *                Class for which a suitable Log name will be derived
    163    *
    164    * @exception LogConfigurationException
    165    *                    if a suitable <code>Log</code> instance cannot be
    166    *                    returned
    167    */
    168   public abstract Log getInstance(Class clazz) throws LogConfigurationException;
    169
    170   /**
    171    * <p>
    172    * Construct (if necessary) and return a <code>Log</code> instance, using
    173    * the factory's current set of configuration attributes.
    174    * </p>
    175    *
    176    * <p>
    177    * <strong>NOTE </strong>- Depending upon the implementation of the
    178    * <code>LogFactory</code> you are using, the <code>Log</code> instance
    179    * you are returned may or may not be local to the current application, and
    180    * may or may not be returned again on a subsequent call with the same name
    181    * argument.
    182    * </p>
    183    *
    184    * @param name
    185    *                Logical name of the <code>Log</code> instance to be
    186    *                returned (the meaning of this name is only known to the
    187    *                underlying logging implementation that is being wrapped)
    188    *
    189    * @exception LogConfigurationException
    190    *                    if a suitable <code>Log</code> instance cannot be
    191    *                    returned
    192    */
    193   public abstract Log getInstance(String name) throws LogConfigurationException;
    194
    195   /**
    196    * Release any internal references to previously created {@link Log}instances
    197    * returned by this factory. This is useful in environments like servlet
    198    * containers, which implement application reloading by throwing away a
    199    * ClassLoader. Dangling references to objects in that class loader would
    200    * prevent garbage collection.
    201    */
    202   public abstract void release();
    203
    204   /**
    205    * Remove any configuration attribute associated with the specified name. If
    206    * there is no such attribute, no action is taken.
    207    *
    208    * @param name
    209    *                Name of the attribute to remove
    210    */
    211   public abstract void removeAttribute(String name);
    212
    213   /**
    214    * Set the configuration attribute with the specified name. Calling this with
    215    * a <code>null</code> value is equivalent to calling
    216    * <code>removeAttribute(name)</code>.
    217    *
    218    * @param name
    219    *                Name of the attribute to set
    220    * @param value
    221    *                Value of the attribute to set, or <code>null</code> to
    222    *                remove any setting for this attribute
    223    */
    224   public abstract void setAttribute(String name, Object value);
    225
    226   // --------------------------------------------------------- Static Methods
    227
    228   /**
    229    * <p>
    230    * Construct (if necessary) and return a <code>LogFactory</code> instance,
    231    * using the following ordered lookup procedure to determine the name of the
    232    * implementation class to be loaded.
    233    * </p>
    234    * <ul>
    235    * <li>The <code>org.apache.commons.logging.LogFactory</code> system
    236    * property.</li>
    237    * <li>The JDK 1.3 Service Discovery mechanism</li>
    238    * <li>Use the properties file <code>commons-logging.properties</code>
    239    * file, if found in the class path of this class. The configuration file is
    240    * in standard <code>java.util.Properties</code> format and contains the
    241    * fully qualified name of the implementation class with the key being the
    242    * system property defined above.</li>
    243    * <li>Fall back to a default implementation class (
    244    * <code>org.apache.commons.logging.impl.SLF4FLogFactory</code>).</li>
    245    * </ul>
    246    *
    247    * <p>
    248    * <em>NOTE</em>- If the properties file method of identifying the
    249    * <code>LogFactory</code> implementation class is utilized, all of the
    250    * properties defined in this file will be set as configuration attributes on
    251    * the corresponding <code>LogFactory</code> instance.
    252    * </p>
    253    *
    254    * @exception LogConfigurationException
    255    *                    if the implementation class is not available or cannot
    256    *                    be instantiated.
    257    */
    258   public static LogFactory getFactory() throws LogConfigurationException {
    259     return logFactory;
    260   }
    261
    262   /**
    263    * Convenience method to return a named logger, without the application having
    264    * to care about factories.
    265    *
    266    * @param clazz
    267    *                Class from which a log name will be derived
    268    *
    269    * @exception LogConfigurationException
    270    *                    if a suitable <code>Log</code> instance cannot be
    271    *                    returned
    272    */
    273   public static Log getLog(Class clazz) throws LogConfigurationException {
    274     return (getFactory().getInstance(clazz));
    275   }
    276
    277   /**
    278    * Convenience method to return a named logger, without the application having
    279    * to care about factories.
    280    *
    281    * @param name
    282    *                Logical name of the <code>Log</code> instance to be
    283    *                returned (the meaning of this name is only known to the
    284    *                underlying logging implementation that is being wrapped)
    285    *
    286    * @exception LogConfigurationException
    287    *                    if a suitable <code>Log</code> instance cannot be
    288    *                    returned
    289    */
    290   public static Log getLog(String name) throws LogConfigurationException {
    291     return (getFactory().getInstance(name));
    292   }
    293
    294   /**
    295    * Release any internal references to previously created {@link LogFactory}
    296    * instances that have been associated with the specified class loader (if
    297    * any), after calling the instance method <code>release()</code> on each of
    298    * them.
    299    *
    300    * @param classLoader
    301    *                ClassLoader for which to release the LogFactory
    302    */
    303   public static void release(ClassLoader classLoader) {
    304     // since SLF4J based JCL does not make use of classloaders, there is nothing
    305     // to do here
    306   }
    307
    308   /**
    309    * Release any internal references to previously created {@link LogFactory}
    310    * instances, after calling the instance method <code>release()</code> on
    311    * each of them. This is useful in environments like servlet containers, which
    312    * implement application reloading by throwing away a ClassLoader. Dangling
    313    * references to objects in that class loader would prevent garbage
    314    * collection.
    315    */
    316   public static void releaseAll() {
    317     // since SLF4J based JCL does not make use of classloaders, there is nothing
    318     // to do here
    319   }
    320
    321   /**
    322    * Returns a string that uniquely identifies the specified object, including
    323    * its class.
    324    * <p>
    325    * The returned string is of form "classname@hashcode", ie is the same as the
    326    * return value of the Object.toString() method, but works even when the
    327    * specified object's class has overidden the toString method.
    328    *
    329    * @param o
    330    *                may be null.
    331    * @return a string of form classname@hashcode, or "null" if param o is null.
    332    * @since 1.1
    333    */
    334   public static String objectId(Object o) {
    335     if (o == null) {
    336       return "null";
    337     } else {
    338       return o.getClass().getName() + "@" + System.identityHashCode(o);
    339     }
    340   }
    341
    342   // protected methods which were added in JCL 1.1. These are not used
    343   // by SLF4JLogFactory
    344
    345   /**
    346    * This method exists to ensure signature compatibility.
    347    */
    348   protected static Object createFactory(String factoryClass, ClassLoader classLoader) {
    349     throw new UnsupportedOperationException(
    350         "Operation [factoryClass] is not supported in jcl-over-slf4j. See also "
    351             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    352   }
    353
    354   /**
    355    * This method exists to ensure signature compatibility.
    356    */
    357   protected static ClassLoader directGetContextClassLoader() {
    358     throw new UnsupportedOperationException(
    359         "Operation [directGetContextClassLoader] is not supported in jcl-over-slf4j. See also "
    360             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    361   }
    362
    363   /**
    364    * This method exists to ensure signature compatibility.
    365    */
    366   protected static ClassLoader getContextClassLoader()
    367       throws LogConfigurationException {
    368     throw new UnsupportedOperationException(
    369         "Operation [getContextClassLoader] is not supported in jcl-over-slf4j. See also "
    370             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    371   }
    372
    373   /**
    374    * This method exists to ensure signature compatibility.
    375    */
    376   protected static ClassLoader getClassLoader(Class clazz) {
    377     throw new UnsupportedOperationException(
    378         "Operation [getClassLoader] is not supported in jcl-over-slf4j. See also "
    379             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    380   }
    381
    382   /**
    383    * This method exists to ensure signature compatibility.
    384    */
    385   protected static boolean isDiagnosticsEnabled() {
    386     throw new UnsupportedOperationException(
    387         "Operation [isDiagnosticsEnabled] is not supported in jcl-over-slf4j. See also "
    388             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    389   }
    390
    391   /**
    392    * This method exists to ensure signature compatibility.
    393    */
    394   protected static void logRawDiagnostic(String msg) {
    395     throw new UnsupportedOperationException(
    396         "Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also "
    397             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    398   }
    399
    400   /**
    401    * This method exists to ensure signature compatibility.
    402    */
    403   protected static LogFactory newFactory(final String factoryClass,
    404       final ClassLoader classLoader, final ClassLoader contextClassLoader) {
    405     throw new UnsupportedOperationException(
    406         "Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also "
    407             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    408   }
    409
    410   /**
    411    * This method exists to ensure signature compatibility.
    412    */
    413   protected static LogFactory newFactory(final String factoryClass,
    414                                          final ClassLoader classLoader) {
    415     throw new UnsupportedOperationException(
    416         "Operation [newFactory] is not supported in jcl-over-slf4j. See also "
    417             + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J);
    418   }
    419
    420
    421 }