1 /* 2 * $Id: LogFactory.java 21415 2011-03-02 17:00:09Z aperepel $ 3 * -------------------------------------------------------------------------------------- 4 * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com 5 * 6 * The software in this package is published under the terms of the CPAL v1.0 7 * license, a copy of which has been included with this distribution in the 8 * LICENSE.txt file. 9 */ 10 11 package org.apache.commons.logging; 12 13 import org.mule.module.logging.MuleLogFactory; 14 15 import java.util.Hashtable; 16 17 import org.apache.commons.logging.impl.SLF4JLogFactory; 18 19 /** 20 * <p> 21 * Factory for creating {@link Log} instances, which always delegates to an 22 * instance of {@link SLF4JLogFactory}. 23 * Binds statically to {@link MuleLogFactory} 24 * </p> 25 */ 26 27 public abstract class LogFactory 28 { 29 30 static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j"; 31 32 static LogFactory logFactory = new MuleLogFactory(); 33 34 /** 35 * The name (<code>priority</code>) of the key in the config file used to 36 * specify the priority of that particular config file. The associated value 37 * is a floating-point number; higher values take priority over lower values. 38 * <p/> 39 * <p/> 40 * This property is not used but preserved here for compatibility. 41 */ 42 public static final String PRIORITY_KEY = "priority"; 43 44 /** 45 * The name (<code>use_tccl</code>) of the key in the config file used to 46 * specify whether logging classes should be loaded via the thread context 47 * class loader (TCCL), or not. By default, the TCCL is used. 48 * <p/> 49 * <p/> 50 * This property is not used but preserved here for compatibility. 51 */ 52 public static final String TCCL_KEY = "use_tccl"; 53 54 /** 55 * The name of the property used to identify the LogFactory implementation 56 * class name. 57 * <p/> 58 * This property is not used but preserved here for compatibility. 59 */ 60 public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory"; 61 62 /** 63 * The fully qualified class name of the fallback <code>LogFactory</code> 64 * implementation class to use, if no other can be found. 65 * <p/> 66 * <p/> 67 * This property is not used but preserved here for compatibility. 68 */ 69 public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.SLF4JLogFactory"; 70 71 /** 72 * The name of the properties file to search for. 73 * <p/> 74 * This property is not used but preserved here for compatibility. 75 */ 76 public static final String FACTORY_PROPERTIES = "commons-logging.properties"; 77 78 79 /** 80 * JDK1.3+ <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider"> 81 * 'Service Provider' specification</a>. 82 * <p/> 83 * This property is not used but preserved here for compatibility. 84 */ 85 protected static final String SERVICE_ID = 86 "META-INF/services/org.apache.commons.logging.LogFactory"; 87 88 /** 89 * The name (<code>org.apache.commons.logging.diagnostics.dest</code>) of 90 * the property used to enable internal commons-logging diagnostic output, in 91 * order to get information on what logging implementations are being 92 * discovered, what classloaders they are loaded through, etc. 93 * <p/> 94 * <p/> 95 * This property is not used but preserved here for compatibility. 96 */ 97 public static final String DIAGNOSTICS_DEST_PROPERTY = "org.apache.commons.logging.diagnostics.dest"; 98 99 /** 100 * <p/> 101 * Setting this system property value allows the <code>Hashtable</code> used 102 * to store classloaders to be substituted by an alternative implementation. 103 * <p/> 104 * This property is not used but preserved here for compatibility. 105 */ 106 public static final String HASHTABLE_IMPLEMENTATION_PROPERTY = "org.apache.commons.logging.LogFactory.HashtableImpl"; 107 108 /** 109 * The previously constructed <code>LogFactory</code> instances, keyed by 110 * the <code>ClassLoader</code> with which it was created. 111 * <p/> 112 * <p/> 113 * This property is not used but preserved here for compatibility. 114 */ 115 protected static Hashtable factories = null; 116 117 /** 118 * <p/> 119 * This property is not used but preserved here for compatibility. 120 */ 121 protected static LogFactory nullClassLoaderFactory = null; 122 123 /** 124 * Protected constructor that is not available for public use. 125 */ 126 protected LogFactory() 127 { 128 } 129 130 // --------------------------------------------------------- Public Methods 131 132 /** 133 * Return the configuration attribute with the specified name (if any), or 134 * <code>null</code> if there is no such attribute. 135 * 136 * @param name Name of the attribute to return 137 */ 138 public abstract Object getAttribute(String name); 139 140 /** 141 * Return an array containing the names of all currently defined configuration 142 * attributes. If there are no such attributes, a zero length array is 143 * returned. 144 */ 145 public abstract String[] getAttributeNames(); 146 147 /** 148 * Convenience method to derive a name from the specified class and call 149 * <code>getInstance(String)</code> with it. 150 * 151 * @param clazz Class for which a suitable Log name will be derived 152 * @throws LogConfigurationException if a suitable <code>Log</code> instance cannot be 153 * returned 154 */ 155 public abstract Log getInstance(Class clazz) throws LogConfigurationException; 156 157 /** 158 * <p> 159 * Construct (if necessary) and return a <code>Log</code> instance, using 160 * the factory's current set of configuration attributes. 161 * </p> 162 * <p/> 163 * <p> 164 * <strong>NOTE </strong>- Depending upon the implementation of the 165 * <code>LogFactory</code> you are using, the <code>Log</code> instance 166 * you are returned may or may not be local to the current application, and 167 * may or may not be returned again on a subsequent call with the same name 168 * argument. 169 * </p> 170 * 171 * @param name Logical name of the <code>Log</code> instance to be 172 * returned (the meaning of this name is only known to the 173 * underlying logging implementation that is being wrapped) 174 * @throws LogConfigurationException if a suitable <code>Log</code> instance cannot be 175 * returned 176 */ 177 public abstract Log getInstance(String name) throws LogConfigurationException; 178 179 /** 180 * Release any internal references to previously created {@link Log}instances 181 * returned by this factory. This is useful in environments like servlet 182 * containers, which implement application reloading by throwing away a 183 * ClassLoader. Dangling references to objects in that class loader would 184 * prevent garbage collection. 185 */ 186 public abstract void release(); 187 188 /** 189 * Remove any configuration attribute associated with the specified name. If 190 * there is no such attribute, no action is taken. 191 * 192 * @param name Name of the attribute to remove 193 */ 194 public abstract void removeAttribute(String name); 195 196 /** 197 * Set the configuration attribute with the specified name. Calling this with 198 * a <code>null</code> value is equivalent to calling 199 * <code>removeAttribute(name)</code>. 200 * 201 * @param name Name of the attribute to set 202 * @param value Value of the attribute to set, or <code>null</code> to 203 * remove any setting for this attribute 204 */ 205 public abstract void setAttribute(String name, Object value); 206 207 // --------------------------------------------------------- Static Methods 208 209 /** 210 * <p> 211 * Construct (if necessary) and return a <code>LogFactory</code> instance, 212 * using the following ordered lookup procedure to determine the name of the 213 * implementation class to be loaded. 214 * </p> 215 * <ul> 216 * <li>The <code>org.apache.commons.logging.LogFactory</code> system 217 * property.</li> 218 * <li>The JDK 1.3 Service Discovery mechanism</li> 219 * <li>Use the properties file <code>commons-logging.properties</code> 220 * file, if found in the class path of this class. The configuration file is 221 * in standard <code>java.util.Properties</code> format and contains the 222 * fully qualified name of the implementation class with the key being the 223 * system property defined above.</li> 224 * <li>Fall back to a default implementation class ( 225 * <code>org.apache.commons.logging.impl.SLF4FLogFactory</code>).</li> 226 * </ul> 227 * <p/> 228 * <p> 229 * <em>NOTE</em>- If the properties file method of identifying the 230 * <code>LogFactory</code> implementation class is utilized, all of the 231 * properties defined in this file will be set as configuration attributes on 232 * the corresponding <code>LogFactory</code> instance. 233 * </p> 234 * 235 * @throws LogConfigurationException if the implementation class is not available or cannot 236 * be instantiated. 237 */ 238 public static LogFactory getFactory() throws LogConfigurationException 239 { 240 return logFactory; 241 } 242 243 /** 244 * Convenience method to return a named logger, without the application having 245 * to care about factories. 246 * 247 * @param clazz Class from which a log name will be derived 248 * @throws LogConfigurationException if a suitable <code>Log</code> instance cannot be 249 * returned 250 */ 251 public static Log getLog(Class clazz) throws LogConfigurationException 252 { 253 return (getFactory().getInstance(clazz)); 254 } 255 256 /** 257 * Convenience method to return a named logger, without the application having 258 * to care about factories. 259 * 260 * @param name Logical name of the <code>Log</code> instance to be 261 * returned (the meaning of this name is only known to the 262 * underlying logging implementation that is being wrapped) 263 * @throws LogConfigurationException if a suitable <code>Log</code> instance cannot be 264 * returned 265 */ 266 public static Log getLog(String name) throws LogConfigurationException 267 { 268 return (getFactory().getInstance(name)); 269 } 270 271 /** 272 * Release any internal references to previously created {@link LogFactory} 273 * instances that have been associated with the specified class loader (if 274 * any), after calling the instance method <code>release()</code> on each of 275 * them. 276 * 277 * @param classLoader ClassLoader for which to release the LogFactory 278 */ 279 public static void release(ClassLoader classLoader) 280 { 281 // since SLF4J based JCL does not make use of classloaders, there is nothing 282 // to do here 283 } 284 285 /** 286 * Release any internal references to previously created {@link LogFactory} 287 * instances, after calling the instance method <code>release()</code> on 288 * each of them. This is useful in environments like servlet containers, which 289 * implement application reloading by throwing away a ClassLoader. Dangling 290 * references to objects in that class loader would prevent garbage 291 * collection. 292 */ 293 public static void releaseAll() 294 { 295 // since SLF4J based JCL does not make use of classloaders, there is nothing 296 // to do here 297 } 298 299 /** 300 * Returns a string that uniquely identifies the specified object, including 301 * its class. 302 * <p/> 303 * The returned string is of form "classname@hashcode", ie is the same as the 304 * return value of the Object.toString() method, but works even when the 305 * specified object's class has overidden the toString method. 306 * 307 * @param o may be null. 308 * @return a string of form classname@hashcode, or "null" if param o is null. 309 * @since 1.1 310 */ 311 public static String objectId(Object o) 312 { 313 if (o == null) 314 { 315 return "null"; 316 } 317 else 318 { 319 return o.getClass().getName() + "@" + System.identityHashCode(o); 320 } 321 } 322 323 // protected methods which were added in JCL 1.1. These are not used 324 // by SLF4JLogFactory 325 326 /** 327 * This method exists to ensure signature compatibility. 328 */ 329 protected static Object createFactory(String factoryClass, ClassLoader classLoader) 330 { 331 throw new UnsupportedOperationException( 332 "Operation [factoryClass] is not supported in jcl-over-slf4j. See also " 333 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 334 } 335 336 /** 337 * This method exists to ensure signature compatibility. 338 */ 339 protected static ClassLoader directGetContextClassLoader() 340 { 341 throw new UnsupportedOperationException( 342 "Operation [directGetContextClassLoader] is not supported in jcl-over-slf4j. See also " 343 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 344 } 345 346 /** 347 * This method exists to ensure signature compatibility. 348 */ 349 protected static ClassLoader getContextClassLoader() 350 throws LogConfigurationException 351 { 352 throw new UnsupportedOperationException( 353 "Operation [getContextClassLoader] is not supported in jcl-over-slf4j. See also " 354 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 355 } 356 357 /** 358 * This method exists to ensure signature compatibility. 359 */ 360 protected static ClassLoader getClassLoader(Class clazz) 361 { 362 throw new UnsupportedOperationException( 363 "Operation [getClassLoader] is not supported in jcl-over-slf4j. See also " 364 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 365 } 366 367 /** 368 * This method exists to ensure signature compatibility. 369 */ 370 protected static boolean isDiagnosticsEnabled() 371 { 372 throw new UnsupportedOperationException( 373 "Operation [isDiagnosticsEnabled] is not supported in jcl-over-slf4j. See also " 374 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 375 } 376 377 /** 378 * This method exists to ensure signature compatibility. 379 */ 380 protected static void logRawDiagnostic(String msg) 381 { 382 throw new UnsupportedOperationException( 383 "Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also " 384 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 385 } 386 387 /** 388 * This method exists to ensure signature compatibility. 389 */ 390 protected static LogFactory newFactory(final String factoryClass, 391 final ClassLoader classLoader, final ClassLoader contextClassLoader) 392 { 393 throw new UnsupportedOperationException( 394 "Operation [logRawDiagnostic] is not supported in jcl-over-slf4j. See also " 395 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 396 } 397 398 /** 399 * This method exists to ensure signature compatibility. 400 */ 401 protected static LogFactory newFactory(final String factoryClass, 402 final ClassLoader classLoader) 403 { 404 throw new UnsupportedOperationException( 405 "Operation [newFactory] is not supported in jcl-over-slf4j. See also " 406 + UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J); 407 } 408 409 410 }