View Javadoc

1   /*
2    * $Id: MuleLoggerFactory.java 22723 2011-08-24 07:31:58Z dirk.olmes $
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.mule.module.logging;
12  
13  import java.lang.ref.PhantomReference;
14  import java.lang.ref.ReferenceQueue;
15  import java.util.HashMap;
16  import java.util.Map;
17  import java.util.concurrent.ConcurrentHashMap;
18  import java.util.concurrent.ConcurrentMap;
19  
20  import org.apache.log4j.LogManager;
21  import org.slf4j.ILoggerFactory;
22  import org.slf4j.Logger;
23  
24  public class MuleLoggerFactory implements ILoggerFactory
25  {
26      protected static final Integer NO_CCL_CLASSLOADER = 0;
27  
28      protected ConcurrentMap<Integer, ConcurrentMap<String, Logger>> repository = new ConcurrentHashMap<Integer, ConcurrentMap<String, Logger>>();
29  
30      protected ReferenceQueue<ClassLoader> referenceQueue = new ReferenceQueue<ClassLoader>();
31      // map ref back to the classloader hash for cleanup of repository map, as both Weak- and SoftReference's get() return null by this time
32      protected Map<PhantomReference<ClassLoader>, Integer> refs = new HashMap<PhantomReference<ClassLoader>, Integer>();
33  
34      public MuleLoggerFactory()
35      {
36          new LoggerReferenceHandler("Mule.log.slf4j.ref.handler", referenceQueue, refs, repository);
37      }
38  
39      @Override
40      public Logger getLogger(String name)
41      {
42          final ClassLoader ccl = Thread.currentThread().getContextClassLoader();
43          return getLogger(name, ccl);
44      }
45  
46      public Logger getLogger(String name, ClassLoader classLoader)
47      {
48          ConcurrentMap<String, Logger> loggerMap = repository.get(classLoader == null ? NO_CCL_CLASSLOADER : classLoader.hashCode());
49  
50          if (loggerMap == null)
51          {
52              loggerMap = new ConcurrentHashMap<String, Logger>();
53              final ConcurrentMap<String, Logger> previous = repository.putIfAbsent(classLoader == null ? NO_CCL_CLASSLOADER : classLoader.hashCode(), loggerMap);
54              if (previous != null)
55              {
56                  loggerMap = previous;
57              }
58  
59              if (classLoader != null)
60              {
61                  // must save a strong ref to the PhantomReference in order for it to stay alive and work
62                  refs.put(new PhantomReference<ClassLoader>(classLoader, referenceQueue), classLoader.hashCode());
63              }
64          }
65  
66          Logger slf4jLogger = loggerMap.get(name);
67  
68          if (slf4jLogger == null)
69          {
70              org.apache.log4j.Logger log4jLogger;
71              if (name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME))
72              {
73                  log4jLogger = LogManager.getRootLogger();
74              }
75              else
76              {
77                  log4jLogger = LogManager.getLogger(name);
78              }
79              slf4jLogger = new DispatchingLogger(new AccessibleLog4jLoggerAdapter(log4jLogger), this);
80              final Logger previous = loggerMap.putIfAbsent(name, slf4jLogger);
81              if (previous != null)
82              {
83                  // someone got there before us
84                  slf4jLogger = previous;
85              }
86          }
87  
88          return slf4jLogger;
89      }
90  }