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 return new BundleClassLoader(bundle, alternativeResourceLoader);
32 }
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 @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
45 final Class<T> loadedClass = (Class<T>) checkNotNull(bundle, "The bundle is required").loadClass(name);
46 return loadedClass;
47 }
48
49
50
51
52
53
54 private static class BundleClassLoader extends ClassLoader {
55 private final Bundle bundle;
56 private final AlternativeResourceLoader altResourceLoader;
57
58 public BundleClassLoader(final Bundle bundle, AlternativeResourceLoader altResourceLoader) {
59 super(null);
60 this.bundle = checkNotNull(bundle, "The bundle must not be null");
61 this.altResourceLoader = option(altResourceLoader).getOrElse(new NoOpAlternativeResourceLoader());
62 }
63
64 @Override
65 public Class<?> findClass(final String name) throws ClassNotFoundException {
66 return bundle.loadClass(name);
67 }
68
69 @SuppressWarnings("unchecked")
70 @Override
71 public Enumeration<URL> findResources(final String name) throws IOException {
72 Enumeration<URL> e = bundle.getResources(name);
73
74 if (e == null) {
75 e = new IteratorEnumeration(Collections.emptyList().iterator());
76 } else {
77
78
79 if (!e.hasMoreElements()) {
80 final URL resource = findResource(name);
81 if (resource != null) {
82 e = new IteratorEnumeration(Arrays.asList(resource).iterator());
83 }
84 }
85 }
86 return e;
87 }
88
89 @Override
90 public URL findResource(final String name) {
91 URL url = altResourceLoader.getResource(name);
92 if (url == null) {
93 url = bundle.getResource(name);
94 }
95 return url;
96 }
97
98 @Override
99 public String toString() {
100 final String sym = bundle.getSymbolicName();
101 return "BundleClassLoader@" + Integer.toHexString(System.identityHashCode(this)) + "[bundle=" +
102 ((sym != null) ? sym : "") + " [" + bundle.getBundleId() + "]]";
103 }
104 }
105
106 }