View Javadoc
1   package com.atlassian.plugin.osgi.container.felix;
2   
3   import org.apache.felix.framework.Logger;
4   import org.apache.felix.framework.resolver.ResolveException;
5   import org.osgi.framework.BundleException;
6   
7   import java.util.Arrays;
8   import java.util.List;
9   
10  /**
11   * Bridges Felix logging messages with the Commons Logging
12   */
13  public class FelixLoggerBridge extends Logger {
14      private final org.slf4j.Logger log;
15  
16      private static final List<String> messagesToIgnore = Arrays.asList(
17              "BeanInfo",
18              "sun.beans.editors.",
19              "add an import for 'org.eclipse.gemini.blueprint.service.",
20              "Class 'org.springframework.util.Assert'",
21              "Class '[Lorg.eclipse.gemini.blueprint.service",
22              "org.springframework.core.InfrastructureProxy",
23              "org.springframework.aop.SpringProxy",
24              "org.springframework.aop.IntroductionInfo",
25              "Class 'org.apache.commons.logging.impl.Log4JLogger'",
26              "org.springframework.util.Assert",
27              "org.eclipse.gemini.blueprint.service.importer.ServiceReferenceProxy",
28              "org.eclipse.gemini.blueprint.service.importer.ImportedOsgiServiceProxy",
29              "org.eclipse.gemini.blueprint.service.importer.support.ImportContextClassLoaderEditor",
30              "[Lorg.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener;Editor"
31      );
32  
33      public FelixLoggerBridge(org.slf4j.Logger log) {
34          this.log = log;
35          setLogLevel(
36                  log.isDebugEnabled() ? Logger.LOG_DEBUG :
37                          log.isInfoEnabled() ? Logger.LOG_WARNING :
38                                  log.isWarnEnabled() ? Logger.LOG_WARNING :
39                                          Logger.LOG_ERROR);
40      }
41  
42      protected void doLog(org.osgi.framework.ServiceReference serviceReference, int level, java.lang.String message, java.lang.Throwable throwable) {
43          if (serviceReference != null)
44              message = "Service " + serviceReference + ": " + message;
45  
46          switch (level) {
47              case LOG_DEBUG:
48  
49                  // helps debug resolution errors when there are multiple constraint violations (final exception just
50                  // reports the last one)
51                  if (throwable != null && throwable instanceof ResolveException) {
52                      log.debug(message, throwable);
53                  } else {
54                      log.debug(message);
55                  }
56                  break;
57              case LOG_ERROR:
58                  if (throwable != null) {
59                      if ((throwable instanceof BundleException) &&
60                              (((BundleException) throwable).getNestedException() != null)) {
61                          throwable = ((BundleException) throwable).getNestedException();
62                      }
63                      log.error(message, throwable);
64                  } else
65                      log.error(message);
66                  break;
67              case LOG_INFO:
68                  logInfoUnlessLame(message);
69                  break;
70              case LOG_WARNING:
71                  // Handles special class loader errors from felix that have quite useful information
72                  if (throwable != null) {
73                      if (throwable instanceof ClassNotFoundException && isClassNotFoundsWeCareAbout(throwable)) {
74                          log.debug("Class not found in bundle: " + message);
75                      } else if (throwable instanceof BundleException) {
76                          // Felix logs these when resolution fails, and it's useful to know why
77                          log.warn(message + ": " + throwable.getMessage());
78                      }
79                  } else {
80                      logInfoUnlessLame(message);
81                  }
82                  break;
83              default:
84                  log.debug("UNKNOWN[" + level + "]: " + message);
85          }
86      }
87  
88      protected void logInfoUnlessLame(String message) {
89          if (message != null) {
90              // I'm really, really sick of these stupid messages
91              for (String dumbBit : messagesToIgnore)
92                  if (message.contains(dumbBit))
93                      return;
94          }
95          log.info(message);
96      }
97  
98      public boolean isClassNotFoundsWeCareAbout(Throwable t) {
99          if (t instanceof ClassNotFoundException) {
100             String className = t.getMessage();
101             if (className.contains("***") && t.getCause() instanceof ClassNotFoundException) {
102                 className = t.getCause().getMessage();
103             }
104             if (!className.startsWith("org.springframework") && !className.endsWith("BeanInfo") && !className.endsWith("Editor")) {
105                 return true;
106             }
107         }
108         return false;
109     }
110 }