1 package com.atlassian.plugin.osgi.util;
2
3 import com.atlassian.plugin.util.resource.AlternativeResourceLoader;
4 import com.atlassian.plugin.util.resource.NoOpAlternativeResourceLoader;
5 import org.apache.commons.collections.iterators.IteratorEnumeration;
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.Collections;
12 import java.util.Enumeration;
13
14 import static com.atlassian.fugue.Option.option;
15 import static com.google.common.base.Preconditions.checkNotNull;
16
17
18
19
20
21
22 public class BundleClassLoaderAccessor
23 {
24
25
26
27
28
29
30 public static ClassLoader getClassLoader(final Bundle bundle, final AlternativeResourceLoader alternativeResourceLoader)
31 {
32 return new BundleClassLoader(bundle, alternativeResourceLoader);
33 }
34
35
36
37
38
39
40
41
42
43 public static <T> Class<T> loadClass(final Bundle bundle, final String name) throws ClassNotFoundException
44 {
45 @SuppressWarnings ({ "unchecked", "UnnecessaryLocalVariable" })
46 final Class<T> loadedClass = (Class<T>) checkNotNull(bundle, "The bundle is required").loadClass(name);
47 return loadedClass;
48 }
49
50
51
52
53
54 private static class BundleClassLoader extends ClassLoader
55 {
56 private final Bundle bundle;
57 private final AlternativeResourceLoader altResourceLoader;
58
59 public BundleClassLoader(final Bundle bundle, AlternativeResourceLoader altResourceLoader)
60 {
61 super(null);
62 this.bundle = checkNotNull(bundle, "The bundle must not be null");
63 this.altResourceLoader = option(altResourceLoader).getOrElse(new NoOpAlternativeResourceLoader());
64 }
65
66 @Override
67 public Class<?> findClass(final String name) throws ClassNotFoundException
68 {
69 return bundle.loadClass(name);
70 }
71
72 @SuppressWarnings("unchecked")
73 @Override
74 public Enumeration<URL> findResources(final String name) throws IOException
75 {
76 Enumeration<URL> e = bundle.getResources(name);
77
78 if (e == null)
79 {
80 e = new IteratorEnumeration(Collections.emptyList().iterator());
81 }
82 else
83 {
84
85
86 if (!e.hasMoreElements())
87 {
88 final URL resource = findResource(name);
89 if (resource != null)
90 {
91 e = new IteratorEnumeration(Arrays.asList(resource).iterator());
92 }
93 }
94 }
95 return e;
96 }
97
98 @Override
99 public URL findResource(final String name)
100 {
101 URL url = altResourceLoader.getResource(name);
102 if (url == null)
103 {
104 url = bundle.getResource(name);
105 }
106 return url;
107 }
108
109 @Override
110 public String toString()
111 {
112 final String sym = bundle.getSymbolicName();
113 return "BundleClassLoader@" + Integer.toHexString(System.identityHashCode(this)) + "[bundle=" +
114 ((sym != null) ? sym : "") + " [" + bundle.getBundleId() + "]]";
115 }
116 }
117
118 }