001: /*
002: * Copyright 2001-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.commons.logging;
018:
019: import java.lang.reflect.Constructor;
020: import java.util.Hashtable;
021:
022: import org.apache.commons.logging.impl.NoOpLog;
023:
024: /**
025: * <p>Factory for creating {@link Log} instances. Applications should call
026: * the <code>makeNewLogInstance()</code> method to instantiate new instances
027: * of the configured {@link Log} implementation class.</p>
028: *
029: * <p>By default, calling <code>getInstance()</code> will use the following
030: * algorithm:</p>
031: * <ul>
032: * <li>If Log4J is available, return an instance of
033: * <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li>
034: * <li>If JDK 1.4 or later is available, return an instance of
035: * <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li>
036: * <li>Otherwise, return an instance of
037: * <code>org.apache.commons.logging.impl.NoOpLog</code>.</li>
038: * </ul>
039: *
040: * <p>You can change the default behavior in one of two ways:</p>
041: * <ul>
042: * <li>On the startup command line, set the system property
043: * <code>org.apache.commons.logging.log</code> to the name of the
044: * <code>org.apache.commons.logging.Log</code> implementation class
045: * you want to use.</li>
046: * <li>At runtime, call <code>LogSource.setLogImplementation()</code>.</li>
047: * </ul>
048: *
049: * @deprecated Use {@link LogFactory} instead - The default factory
050: * implementation performs exactly the same algorithm as this class did
051: *
052: * @author Rod Waldhoff
053: * @version $Id: LogSource.java 155426 2005-02-26 13:10:49Z dirkv $
054: */
055: public class LogSource {
056:
057: // ------------------------------------------------------- Class Attributes
058:
059: static protected Hashtable logs = new Hashtable();
060:
061: /** Is log4j available (in the current classpath) */
062: static protected boolean log4jIsAvailable = false;
063:
064: /** Is JDK 1.4 logging available */
065: static protected boolean jdk14IsAvailable = false;
066:
067: /** Constructor for current log class */
068: static protected Constructor logImplctor = null;
069:
070: // ----------------------------------------------------- Class Initializers
071:
072: static {
073:
074: // Is Log4J Available?
075: try {
076: if (null != Class.forName("org.apache.log4j.Logger")) {
077: log4jIsAvailable = true;
078: } else {
079: log4jIsAvailable = false;
080: }
081: } catch (Throwable t) {
082: log4jIsAvailable = false;
083: }
084:
085: // Is JDK 1.4 Logging Available?
086: try {
087: if ((null != Class.forName("java.util.logging.Logger"))
088: && (null != Class
089: .forName("org.apache.commons.logging.impl.Jdk14Logger"))) {
090: jdk14IsAvailable = true;
091: } else {
092: jdk14IsAvailable = false;
093: }
094: } catch (Throwable t) {
095: jdk14IsAvailable = false;
096: }
097:
098: // Set the default Log implementation
099: String name = null;
100: try {
101: name = System.getProperty("org.apache.commons.logging.log");
102: if (name == null) {
103: name = System
104: .getProperty("org.apache.commons.logging.Log");
105: }
106: } catch (Throwable t) {
107: }
108: if (name != null) {
109: try {
110: setLogImplementation(name);
111: } catch (Throwable t) {
112: try {
113: setLogImplementation("org.apache.commons.logging.impl.NoOpLog");
114: } catch (Throwable u) {
115: ;
116: }
117: }
118: } else {
119: try {
120: if (log4jIsAvailable) {
121: setLogImplementation("org.apache.commons.logging.impl.Log4JLogger");
122: } else if (jdk14IsAvailable) {
123: setLogImplementation("org.apache.commons.logging.impl.Jdk14Logger");
124: } else {
125: setLogImplementation("org.apache.commons.logging.impl.NoOpLog");
126: }
127: } catch (Throwable t) {
128: try {
129: setLogImplementation("org.apache.commons.logging.impl.NoOpLog");
130: } catch (Throwable u) {
131: ;
132: }
133: }
134: }
135:
136: }
137:
138: // ------------------------------------------------------------ Constructor
139:
140: /** Don't allow others to create instances */
141: private LogSource() {
142: }
143:
144: // ---------------------------------------------------------- Class Methods
145:
146: /**
147: * Set the log implementation/log implementation factory
148: * by the name of the class. The given class
149: * must implement {@link Log}, and provide a constructor that
150: * takes a single {@link String} argument (containing the name
151: * of the log).
152: */
153: static public void setLogImplementation(String classname)
154: throws LinkageError, ExceptionInInitializerError,
155: NoSuchMethodException, SecurityException,
156: ClassNotFoundException {
157: try {
158: Class logclass = Class.forName(classname);
159: Class[] argtypes = new Class[1];
160: argtypes[0] = "".getClass();
161: logImplctor = logclass.getConstructor(argtypes);
162: } catch (Throwable t) {
163: logImplctor = null;
164: }
165: }
166:
167: /**
168: * Set the log implementation/log implementation factory
169: * by class. The given class must implement {@link Log},
170: * and provide a constructor that takes a single {@link String}
171: * argument (containing the name of the log).
172: */
173: static public void setLogImplementation(Class logclass)
174: throws LinkageError, ExceptionInInitializerError,
175: NoSuchMethodException, SecurityException {
176: Class[] argtypes = new Class[1];
177: argtypes[0] = "".getClass();
178: logImplctor = logclass.getConstructor(argtypes);
179: }
180:
181: /** Get a <code>Log</code> instance by class name */
182: static public Log getInstance(String name) {
183: Log log = (Log) (logs.get(name));
184: if (null == log) {
185: log = makeNewLogInstance(name);
186: logs.put(name, log);
187: }
188: return log;
189: }
190:
191: /** Get a <code>Log</code> instance by class */
192: static public Log getInstance(Class clazz) {
193: return getInstance(clazz.getName());
194: }
195:
196: /**
197: * Create a new {@link Log} implementation, based
198: * on the given <i>name</i>.
199: * <p>
200: * The specific {@link Log} implementation returned
201: * is determined by the value of the
202: * <tt>org.apache.commons.logging.log</tt> property.
203: * The value of <tt>org.apache.commons.logging.log</tt> may be set to
204: * the fully specified name of a class that implements
205: * the {@link Log} interface. This class must also
206: * have a public constructor that takes a single
207: * {@link String} argument (containing the <i>name</i>
208: * of the {@link Log} to be constructed.
209: * <p>
210: * When <tt>org.apache.commons.logging.log</tt> is not set,
211: * or when no corresponding class can be found,
212: * this method will return a Log4JLogger
213: * if the log4j Logger class is
214: * available in the {@link LogSource}'s classpath, or a
215: * Jdk14Logger if we are on a JDK 1.4 or later system, or
216: * NoOpLog if neither of the above conditions is true.
217: *
218: * @param name the log name (or category)
219: */
220: static public Log makeNewLogInstance(String name) {
221:
222: Log log = null;
223: try {
224: Object[] args = new Object[1];
225: args[0] = name;
226: log = (Log) (logImplctor.newInstance(args));
227: } catch (Throwable t) {
228: log = null;
229: }
230: if (null == log) {
231: log = new NoOpLog(name);
232: }
233: return log;
234:
235: }
236:
237: /**
238: * Returns a {@link String} array containing the names of
239: * all logs known to me.
240: */
241: static public String[] getLogNames() {
242: return (String[]) (logs.keySet()
243: .toArray(new String[logs.size()]));
244: }
245:
246: }
|