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