View Javadoc

1   package com.atlassian.plugin.osgi.factory;
2   
3   import org.apache.commons.collections.iterators.IteratorEnumeration;
4   import org.apache.commons.lang.Validate;
5   import org.apache.log4j.Logger;
6   import org.osgi.framework.Bundle;
7   
8   import java.io.IOException;
9   import java.net.URL;
10  import java.util.Arrays;
11  import java.util.Enumeration;
12  
13  import com.atlassian.plugin.util.resource.AlternativeResourceLoader;
14  import com.atlassian.plugin.util.resource.NoOpAlternativeResourceLoader;
15  
16  /**
17   * Utility methods for accessing a bundle as if it was a classloader.
18   */
19  class BundleClassLoaderAccessor
20  {
21      private static final Logger log = Logger.getLogger(BundleClassLoaderAccessor.class);
22  
23      static ClassLoader getClassLoader(final Bundle bundle, AlternativeResourceLoader alternativeResourceLoader)
24      {
25          return new BundleClassLoader(bundle, alternativeResourceLoader);
26      }
27  
28      static <T> Class<T> loadClass(final Bundle bundle, final String name, final Class<?> callingClass) throws ClassNotFoundException
29      {
30          Validate.notNull(bundle, "The bundle is required");
31          @SuppressWarnings("unchecked")
32          final Class<T> loadedClass = bundle.loadClass(name);
33          return loadedClass;
34      }
35  
36      ///CLOVER:OFF
37      /**
38       * Fake classloader that delegates to a bundle
39       */
40      private static class BundleClassLoader extends ClassLoader
41      {
42          private final Bundle bundle;
43          private final AlternativeResourceLoader altResourceLoader;
44  
45          public BundleClassLoader(final Bundle bundle, AlternativeResourceLoader altResourceLoader)
46          {
47              Validate.notNull(bundle, "The bundle must not be null");
48              if (altResourceLoader == null)
49              {
50                  altResourceLoader = new NoOpAlternativeResourceLoader();
51              }
52              this.altResourceLoader = altResourceLoader;
53              this.bundle = bundle;
54  
55          }
56  
57          @Override
58          public Class<?> findClass(final String name) throws ClassNotFoundException
59          {
60              return bundle.loadClass(name);
61          }
62  
63          @Override
64          public Enumeration<URL> findResources(final String name) throws IOException
65          {
66              @SuppressWarnings("unchecked")
67              Enumeration<URL> e = bundle.getResources(name);
68  
69              // For some reason, getResources() sometimes returns nothing, yet getResource() will return one.  This code
70              // handles that strange case
71              if (!e.hasMoreElements())
72              {
73                  final URL resource = findResource(name);
74                  if (resource != null)
75                  {
76                      e = new IteratorEnumeration(Arrays.asList(resource).iterator());
77                  }
78              }
79              return e;
80          }
81  
82          @Override
83          public URL findResource(final String name)
84          {
85              URL url = altResourceLoader.getResource(name);
86              if (url == null)
87              {
88                  url = bundle.getResource(name);
89              }
90              return url;
91          }
92      }
93  
94  }