001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.logging; 019 020import java.lang.reflect.Constructor; 021import java.util.Hashtable; 022 023import org.apache.commons.logging.impl.NoOpLog; 024 025/** 026 * Factory for creating {@link Log} instances. Applications should call 027 * the <code>makeNewLogInstance()</code> method to instantiate new instances 028 * of the configured {@link Log} implementation class. 029 * <p> 030 * By default, calling <code>getInstance()</code> will use the following 031 * algorithm: 032 * <ul> 033 * <li>If Log4J is available, return an instance of 034 * <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li> 035 * <li>If JDK 1.4 or later is available, return an instance of 036 * <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li> 037 * <li>Otherwise, return an instance of 038 * <code>org.apache.commons.logging.impl.NoOpLog</code>.</li> 039 * </ul> 040 * <p> 041 * You can change the default behavior in one of two ways: 042 * <ul> 043 * <li>On the startup command line, set the system property 044 * <code>org.apache.commons.logging.log</code> to the name of the 045 * <code>org.apache.commons.logging.Log</code> implementation class 046 * you want to use.</li> 047 * <li>At runtime, call <code>LogSource.setLogImplementation()</code>.</li> 048 * </ul> 049 * 050 * @deprecated Use {@link LogFactory} instead - The default factory 051 * implementation performs exactly the same algorithm as this class did 052 * 053 * @version $Id: LogSource.html 915605 2014-07-09 20:22:43Z tn $ 054 */ 055public 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 log4jIsAvailable = null != Class.forName("org.apache.log4j.Logger"); 077 } catch (Throwable t) { 078 log4jIsAvailable = false; 079 } 080 081 // Is JDK 1.4 Logging Available? 082 try { 083 jdk14IsAvailable = null != Class.forName("java.util.logging.Logger") && 084 null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"); 085 } catch (Throwable t) { 086 jdk14IsAvailable = false; 087 } 088 089 // Set the default Log implementation 090 String name = null; 091 try { 092 name = System.getProperty("org.apache.commons.logging.log"); 093 if (name == null) { 094 name = System.getProperty("org.apache.commons.logging.Log"); 095 } 096 } catch (Throwable t) { 097 } 098 if (name != null) { 099 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}