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

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » juli » logging » [javadoc | source]