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