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