Home » apache-tomcat-6.0.26-src » org.apache » juli » logging » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */ 
   17   
   18   package org.apache.juli.logging;
   19   
   20   
   21   import java.util.Properties;
   22   import java.util.logging.LogManager;
   23   
   24   
   25   
   26   /**
   27    * Modified LogFactory: removed all discovery, hardcode a specific implementation
   28    * If you like a different logging implementation - use either the discovery-based
   29    * commons-logging, or better - another implementation hardcoded to your favourite
   30    * logging impl.
   31    * 
   32    * Why ? Each application and deployment can choose a logging implementation - 
   33    * that involves configuration, installing the logger jar and optional plugins, etc.
   34    * As part of this process - they can as well install the commons-logging implementation
   35    * that corresponds to their logger of choice. This completely avoids any discovery
   36    * problem, while still allowing the user to switch. 
   37    * 
   38    * Note that this implementation is not just a wrapper arround JDK logging ( like
   39    * the original commons-logging impl ). It adds 2 features - a simpler configuration
   40    * ( which is in fact a subset of log4j.properties ) and a formatter that is 
   41    * less ugly.   
   42    * 
   43    * The removal of 'abstract' preserves binary backward compatibility. It is possible
   44    * to preserve the abstract - and introduce another ( hardcoded ) factory - but I 
   45    * see no benefit. 
   46    * 
   47    * Since this class is not intended to be extended - and provides
   48    * no plugin for other LogFactory implementation - all protected methods are removed.
   49    * This can be changed - but again, there is little value in keeping dead code.
   50    * Just take a quick look at the removed code ( and it's complexity)  
   51    * 
   52    * --------------
   53    * 
   54    * Original comment:
   55    * <p>Factory for creating {@link Log} instances, with discovery and
   56    * configuration features similar to that employed by standard Java APIs
   57    * such as JAXP.</p>
   58    * 
   59    * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily
   60    * based on the SAXParserFactory and DocumentBuilderFactory implementations
   61    * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p>
   62    * 
   63    *
   64    * @author Craig R. McClanahan
   65    * @author Costin Manolache
   66    * @author Richard A. Sitze
   67    * @version $Revision: 899141 $ $Date: 2010-01-14 11:12:25 +0100 (Thu, 14 Jan 2010) $
   68    */
   69   public /* abstract */ class LogFactory {
   70   
   71       // ----------------------------------------------------- Manifest Constants
   72   
   73       /**
   74        * The name of the property used to identify the LogFactory implementation
   75        * class name.
   76        */
   77       public static final String FACTORY_PROPERTY =
   78           "org.apache.commons.logging.LogFactory";
   79   
   80       /**
   81        * The fully qualified class name of the fallback <code>LogFactory</code>
   82        * implementation class to use, if no other can be found.
   83        */
   84       public static final String FACTORY_DEFAULT =
   85           "org.apache.commons.logging.impl.LogFactoryImpl";
   86   
   87       /**
   88        * The name of the properties file to search for.
   89        */
   90       public static final String FACTORY_PROPERTIES =
   91           "commons-logging.properties";
   92       
   93       /**
   94        * <p>Setting this system property value allows the <code>Hashtable</code> used to store
   95        * classloaders to be substituted by an alternative implementation.
   96        * </p>
   97        * <p>
   98        * <strong>Note:</strong> <code>LogFactory</code> will print:
   99        * <code><pre>
  100        * [ERROR] LogFactory: Load of custom hashtable failed</em>
  101        * </code></pre>
  102        * to system error and then continue using a standard Hashtable.
  103        * </p>
  104        * <p>
  105        * <strong>Usage:</strong> Set this property when Java is invoked
  106        * and <code>LogFactory</code> will attempt to load a new instance 
  107        * of the given implementation class.
  108        * For example, running the following ant scriplet:
  109        * <code><pre>
  110        *  &lt;java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}"&gt;
  111        *     ...
  112        *     &lt;sysproperty 
  113        *        key="org.apache.commons.logging.LogFactory.HashtableImpl"
  114        *        value="org.apache.commons.logging.AltHashtable"/&gt;
  115        *  &lt;/java&gt;
  116        * </pre></code>
  117        * will mean that <code>LogFactory</code> will load an instance of
  118        * <code>org.apache.commons.logging.AltHashtable</code>.
  119        * </p>
  120        * <p>
  121        * A typical use case is to allow a custom
  122        * Hashtable implementation using weak references to be substituted.
  123        * This will allow classloaders to be garbage collected without
  124        * the need to release them (on 1.3+ JVMs only, of course ;)
  125        * </p>
  126        */
  127       public static final String HASHTABLE_IMPLEMENTATION_PROPERTY =
  128           "org.apache.commons.logging.LogFactory.HashtableImpl";
  129       
  130       private static LogFactory singleton=new LogFactory();
  131   
  132       Properties logConfig;
  133       
  134       // ----------------------------------------------------------- Constructors
  135   
  136   
  137       /**
  138        * Protected constructor that is not available for public use.
  139        */
  140       private LogFactory() {
  141           logConfig=new Properties();
  142       }
  143       
  144       // hook for syserr logger - class level
  145       void setLogConfig( Properties p ) {
  146           this.logConfig=p;
  147       }
  148       // --------------------------------------------------------- Public Methods
  149   
  150       // only those 2 methods need to change to use a different direct logger.
  151       
  152       /**
  153        * <p>Construct (if necessary) and return a <code>Log</code> instance,
  154        * using the factory's current set of configuration attributes.</p>
  155        *
  156        * <p><strong>NOTE</strong> - Depending upon the implementation of
  157        * the <code>LogFactory</code> you are using, the <code>Log</code>
  158        * instance you are returned may or may not be local to the current
  159        * application, and may or may not be returned again on a subsequent
  160        * call with the same name argument.</p>
  161        *
  162        * @param name Logical name of the <code>Log</code> instance to be
  163        *  returned (the meaning of this name is only known to the underlying
  164        *  logging implementation that is being wrapped)
  165        *
  166        * @exception LogConfigurationException if a suitable <code>Log</code>
  167        *  instance cannot be returned
  168        */
  169       public Log getInstance(String name)
  170           throws LogConfigurationException {
  171           return DirectJDKLog.getInstance(name);
  172       }
  173   
  174   
  175       /**
  176        * Release any internal references to previously created {@link Log}
  177        * instances returned by this factory.  This is useful in environments
  178        * like servlet containers, which implement application reloading by
  179        * throwing away a ClassLoader.  Dangling references to objects in that
  180        * class loader would prevent garbage collection.
  181        */
  182       public void release() {
  183           DirectJDKLog.release();
  184       }
  185   
  186       /**
  187        * Return the configuration attribute with the specified name (if any),
  188        * or <code>null</code> if there is no such attribute.
  189        *
  190        * @param name Name of the attribute to return
  191        */
  192       public Object getAttribute(String name) {
  193           return logConfig.get(name);
  194       }
  195   
  196   
  197       /**
  198        * Return an array containing the names of all currently defined
  199        * configuration attributes.  If there are no such attributes, a zero
  200        * length array is returned.
  201        */
  202       public String[] getAttributeNames() {
  203           String result[] = new String[logConfig.size()];
  204           return logConfig.keySet().toArray(result);
  205       }
  206   
  207       /**
  208        * Remove any configuration attribute associated with the specified name.
  209        * If there is no such attribute, no action is taken.
  210        *
  211        * @param name Name of the attribute to remove
  212        */
  213       public void removeAttribute(String name) {
  214           logConfig.remove(name);
  215        }   
  216   
  217   
  218       /**
  219        * Set the configuration attribute with the specified name.  Calling
  220        * this with a <code>null</code> value is equivalent to calling
  221        * <code>removeAttribute(name)</code>.
  222        *
  223        * @param name Name of the attribute to set
  224        * @param value Value of the attribute to set, or <code>null</code>
  225        *  to remove any setting for this attribute
  226        */
  227       public void setAttribute(String name, Object value) {
  228           logConfig.put(name, value);
  229       }
  230   
  231   
  232       /**
  233        * Convenience method to derive a name from the specified class and
  234        * call <code>getInstance(String)</code> with it.
  235        *
  236        * @param clazz Class for which a suitable Log name will be derived
  237        *
  238        * @exception LogConfigurationException if a suitable <code>Log</code>
  239        *  instance cannot be returned
  240        */
  241       public Log getInstance(Class clazz)
  242           throws LogConfigurationException {
  243           return getInstance( clazz.getName());
  244       }
  245   
  246   
  247       
  248   
  249   
  250       // ------------------------------------------------------- Static Variables
  251   
  252   
  253   
  254       // --------------------------------------------------------- Static Methods
  255   
  256   
  257       /**
  258        * <p>Construct (if necessary) and return a <code>LogFactory</code>
  259        * instance, using the following ordered lookup procedure to determine
  260        * the name of the implementation class to be loaded.</p>
  261        * <ul>
  262        * <li>The <code>org.apache.commons.logging.LogFactory</code> system
  263        *     property.</li>
  264        * <li>The JDK 1.3 Service Discovery mechanism</li>
  265        * <li>Use the properties file <code>commons-logging.properties</code>
  266        *     file, if found in the class path of this class.  The configuration
  267        *     file is in standard <code>java.util.Properties</code> format and
  268        *     contains the fully qualified name of the implementation class
  269        *     with the key being the system property defined above.</li>
  270        * <li>Fall back to a default implementation class
  271        *     (<code>org.apache.commons.logging.impl.LogFactoryImpl</code>).</li>
  272        * </ul>
  273        *
  274        * <p><em>NOTE</em> - If the properties file method of identifying the
  275        * <code>LogFactory</code> implementation class is utilized, all of the
  276        * properties defined in this file will be set as configuration attributes
  277        * on the corresponding <code>LogFactory</code> instance.</p>
  278        *
  279        * @exception LogConfigurationException if the implementation class is not
  280        *  available or cannot be instantiated.
  281        */
  282       public static LogFactory getFactory() throws LogConfigurationException {
  283           return singleton;
  284       }
  285   
  286   
  287       /**
  288        * Convenience method to return a named logger, without the application
  289        * having to care about factories.
  290        *
  291        * @param clazz Class from which a log name will be derived
  292        *
  293        * @exception LogConfigurationException if a suitable <code>Log</code>
  294        *  instance cannot be returned
  295        */
  296       public static Log getLog(Class clazz)
  297           throws LogConfigurationException {
  298           return (getFactory().getInstance(clazz));
  299   
  300       }
  301   
  302   
  303       /**
  304        * Convenience method to return a named logger, without the application
  305        * having to care about factories.
  306        *
  307        * @param name Logical name of the <code>Log</code> instance to be
  308        *  returned (the meaning of this name is only known to the underlying
  309        *  logging implementation that is being wrapped)
  310        *
  311        * @exception LogConfigurationException if a suitable <code>Log</code>
  312        *  instance cannot be returned
  313        */
  314       public static Log getLog(String name)
  315           throws LogConfigurationException {
  316           return (getFactory().getInstance(name));
  317   
  318       }
  319   
  320   
  321       /**
  322        * Release any internal references to previously created {@link LogFactory}
  323        * instances that have been associated with the specified class loader
  324        * (if any), after calling the instance method <code>release()</code> on
  325        * each of them.
  326        *
  327        * @param classLoader ClassLoader for which to release the LogFactory
  328        */
  329       public static void release(
  330               @SuppressWarnings("unused") ClassLoader classLoader) {
  331           // JULI's log manager looks at the current classLoader
  332           LogManager.getLogManager().reset();
  333       }
  334   
  335   
  336       /**
  337        * Release any internal references to previously created {@link LogFactory}
  338        * instances, after calling the instance method <code>release()</code> on
  339        * each of them.  This is useful in environments like servlet containers,
  340        * which implement application reloading by throwing away a ClassLoader.
  341        * Dangling references to objects in that class loader would prevent
  342        * garbage collection.
  343        */
  344       public static void releaseAll() {
  345           singleton.release();
  346       }
  347   
  348       /**
  349        * Returns a string that uniquely identifies the specified object, including
  350        * its class.
  351        * <p>
  352        * The returned string is of form "classname@hashcode", ie is the same as
  353        * the return value of the Object.toString() method, but works even when
  354        * the specified object's class has overidden the toString method.
  355        * 
  356        * @param o may be null.
  357        * @return a string of form classname@hashcode, or "null" if param o is null.
  358        */
  359       public static String objectId(Object o) {
  360           if (o == null) {
  361               return "null";
  362           } else {
  363               return o.getClass().getName() + "@" + System.identityHashCode(o);
  364           }
  365       }
  366   }

Home » apache-tomcat-6.0.26-src » org.apache » juli » logging » [javadoc | source]