View Javadoc

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.commons.logging;
19  
20  
21  import java.lang.reflect.Constructor;
22  import java.util.Hashtable;
23  
24  import org.apache.commons.logging.impl.NoOpLog;
25  
26  
27  /**
28   * <p>Factory for creating {@link Log} instances.  Applications should call
29   * the <code>makeNewLogInstance()</code> method to instantiate new instances
30   * of the configured {@link Log} implementation class.</p>
31   *
32   * <p>By default, calling <code>getInstance()</code> will use the following
33   * algorithm:</p>
34   * <ul>
35   * <li>If Log4J is available, return an instance of
36   *     <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li>
37   * <li>If JDK 1.4 or later is available, return an instance of
38   *     <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li>
39   * <li>Otherwise, return an instance of
40   *     <code>org.apache.commons.logging.impl.NoOpLog</code>.</li>
41   * </ul>
42   *
43   * <p>You can change the default behavior in one of two ways:</p>
44   * <ul>
45   * <li>On the startup command line, set the system property
46   *     <code>org.apache.commons.logging.log</code> to the name of the
47   *     <code>org.apache.commons.logging.Log</code> implementation class
48   *     you want to use.</li>
49   * <li>At runtime, call <code>LogSource.setLogImplementation()</code>.</li>
50   * </ul>
51   *
52   * @deprecated Use {@link LogFactory} instead - The default factory
53   *  implementation performs exactly the same algorithm as this class did
54   *
55   * @author Rod Waldhoff
56   * @version $Id: LogSource.java 424107 2006-07-20 23:15:42Z skitching $
57   */
58  public class LogSource {
59  
60      // ------------------------------------------------------- Class Attributes
61  
62      static protected Hashtable logs = new Hashtable();
63  
64      /** Is log4j available (in the current classpath) */
65      static protected boolean log4jIsAvailable = false;
66  
67      /** Is JDK 1.4 logging available */
68      static protected boolean jdk14IsAvailable = false;
69  
70      /** Constructor for current log class */
71      static protected Constructor logImplctor = null;
72  
73  
74      // ----------------------------------------------------- Class Initializers
75  
76      static {
77  
78          // Is Log4J Available?
79          try {
80              if (null != Class.forName("org.apache.log4j.Logger")) {
81                  log4jIsAvailable = true;
82              } else {
83                  log4jIsAvailable = false;
84              }
85          } catch (Throwable t) {
86              log4jIsAvailable = false;
87          }
88  
89          // Is JDK 1.4 Logging Available?
90          try {
91              if ((null != Class.forName("java.util.logging.Logger")) &&
92                  (null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"))) {
93                  jdk14IsAvailable = true;
94              } else {
95                  jdk14IsAvailable = false;
96              }
97          } catch (Throwable t) {
98              jdk14IsAvailable = false;
99          }
100 
101         // Set the default Log implementation
102         String name = null;
103         try {
104             name = System.getProperty("org.apache.commons.logging.log");
105             if (name == null) {
106                 name = System.getProperty("org.apache.commons.logging.Log");
107             }
108         } catch (Throwable t) {
109         }
110         if (name != null) {
111             try {
112                 setLogImplementation(name);
113             } catch (Throwable t) {
114                 try {
115                     setLogImplementation
116                             ("org.apache.commons.logging.impl.NoOpLog");
117                 } catch (Throwable u) {
118                     ;
119                 }
120             }
121         } else {
122             try {
123                 if (log4jIsAvailable) {
124                     setLogImplementation
125                             ("org.apache.commons.logging.impl.Log4JLogger");
126                 } else if (jdk14IsAvailable) {
127                     setLogImplementation
128                             ("org.apache.commons.logging.impl.Jdk14Logger");
129                 } else {
130                     setLogImplementation
131                             ("org.apache.commons.logging.impl.NoOpLog");
132                 }
133             } catch (Throwable t) {
134                 try {
135                     setLogImplementation
136                             ("org.apache.commons.logging.impl.NoOpLog");
137                 } catch (Throwable u) {
138                     ;
139                 }
140             }
141         }
142 
143     }
144 
145 
146     // ------------------------------------------------------------ Constructor
147 
148 
149     /** Don't allow others to create instances */
150     private LogSource() {
151     }
152 
153 
154     // ---------------------------------------------------------- Class Methods
155 
156 
157     /**
158      * Set the log implementation/log implementation factory
159      * by the name of the class.  The given class
160      * must implement {@link Log}, and provide a constructor that
161      * takes a single {@link String} argument (containing the name
162      * of the log).
163      */
164     static public void setLogImplementation(String classname) throws
165             LinkageError, ExceptionInInitializerError,
166             NoSuchMethodException, SecurityException,
167             ClassNotFoundException {
168         try {
169             Class logclass = Class.forName(classname);
170             Class[] argtypes = new Class[1];
171             argtypes[0] = "".getClass();
172             logImplctor = logclass.getConstructor(argtypes);
173         } catch (Throwable t) {
174             logImplctor = null;
175         }
176     }
177 
178 
179     /**
180      * Set the log implementation/log implementation factory
181      * by class.  The given class must implement {@link Log},
182      * and provide a constructor that takes a single {@link String}
183      * argument (containing the name of the log).
184      */
185     static public void setLogImplementation(Class logclass) throws
186             LinkageError, ExceptionInInitializerError,
187             NoSuchMethodException, SecurityException {
188         Class[] argtypes = new Class[1];
189         argtypes[0] = "".getClass();
190         logImplctor = logclass.getConstructor(argtypes);
191     }
192 
193 
194     /** Get a <code>Log</code> instance by class name */
195     static public Log getInstance(String name) {
196         Log log = (Log) (logs.get(name));
197         if (null == log) {
198             log = makeNewLogInstance(name);
199             logs.put(name, log);
200         }
201         return log;
202     }
203 
204 
205     /** Get a <code>Log</code> instance by class */
206     static public Log getInstance(Class clazz) {
207         return getInstance(clazz.getName());
208     }
209 
210 
211     /**
212      * Create a new {@link Log} implementation, based
213      * on the given <i>name</i>.
214      * <p>
215      * The specific {@link Log} implementation returned
216      * is determined by the value of the
217      * <tt>org.apache.commons.logging.log</tt> property.
218      * The value of <tt>org.apache.commons.logging.log</tt> may be set to
219      * the fully specified name of a class that implements
220      * the {@link Log} interface.  This class must also
221      * have a public constructor that takes a single
222      * {@link String} argument (containing the <i>name</i>
223      * of the {@link Log} to be constructed.
224      * <p>
225      * When <tt>org.apache.commons.logging.log</tt> is not set,
226      * or when no corresponding class can be found,
227      * this method will return a Log4JLogger
228      * if the log4j Logger class is
229      * available in the {@link LogSource}'s classpath, or a
230      * Jdk14Logger if we are on a JDK 1.4 or later system, or
231      * NoOpLog if neither of the above conditions is true.
232      *
233      * @param name the log name (or category)
234      */
235     static public Log makeNewLogInstance(String name) {
236 
237         Log log = null;
238         try {
239             Object[] args = new Object[1];
240             args[0] = name;
241             log = (Log) (logImplctor.newInstance(args));
242         } catch (Throwable t) {
243             log = null;
244         }
245         if (null == log) {
246             log = new NoOpLog(name);
247         }
248         return log;
249 
250     }
251 
252 
253     /**
254      * Returns a {@link String} array containing the names of
255      * all logs known to me.
256      */
257     static public String[] getLogNames() {
258         return (String[]) (logs.keySet().toArray(new String[logs.size()]));
259     }
260 
261 
262 }