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