Lines 41-151
Link Here
|
41 |
|
41 |
|
42 |
import java.io.IOException; |
42 |
import java.io.IOException; |
43 |
import java.io.InputStream; |
43 |
import java.io.InputStream; |
44 |
import java.lang.reflect.Field; |
|
|
45 |
import java.net.URL; |
44 |
import java.net.URL; |
46 |
import java.util.Enumeration; |
45 |
import java.util.Enumeration; |
|
|
46 |
import java.util.HashMap; |
47 |
import java.util.Set; |
47 |
import java.util.Set; |
48 |
import java.util.concurrent.CopyOnWriteArraySet; |
48 |
import java.util.concurrent.CopyOnWriteArraySet; |
49 |
import java.util.logging.Level; |
49 |
import java.util.logging.Level; |
50 |
import org.apache.felix.framework.ModuleImpl; |
|
|
51 |
import org.apache.felix.framework.ModuleImpl.ModuleClassLoader; |
52 |
import org.netbeans.Module; |
50 |
import org.netbeans.Module; |
53 |
import org.openide.modules.ModuleInfo; |
51 |
import org.openide.modules.ModuleInfo; |
54 |
import org.osgi.framework.Bundle; |
52 |
import org.osgi.framework.Bundle; |
55 |
import org.osgi.framework.BundleActivator; |
|
|
56 |
import org.osgi.framework.BundleContext; |
57 |
import org.osgi.framework.BundleEvent; |
58 |
import org.osgi.framework.SynchronousBundleListener; |
59 |
|
53 |
|
60 |
/** |
54 |
/** |
61 |
* |
55 |
* |
62 |
* @author Jaroslav Tulach <jtulach@netbeans.org> |
56 |
* @author Jaroslav Tulach <jtulach@netbeans.org> |
63 |
*/ |
57 |
*/ |
64 |
final class NetigsoActivator |
58 |
final class NetigsoActivator extends HashMap<Bundle,ClassLoader> { |
65 |
implements BundleActivator, SynchronousBundleListener { |
59 |
private static final Set<Module> all = new CopyOnWriteArraySet<Module>(); |
66 |
private Set<Module> all = new CopyOnWriteArraySet<Module>(); |
|
|
67 |
|
60 |
|
68 |
public NetigsoActivator() { |
61 |
public NetigsoActivator() { |
69 |
} |
62 |
} |
70 |
private BundleContext m_context = null; |
|
|
71 |
|
63 |
|
72 |
public void start(BundleContext context) { |
64 |
@Override |
73 |
m_context = context; |
65 |
public ClassLoader get(Object o) { |
74 |
context.addBundleListener(this); |
66 |
if (o instanceof Bundle) { |
75 |
} |
67 |
String loc = ((Bundle)o).getLocation(); |
76 |
|
68 |
final String pref = "netigso://"; // NOI18N |
77 |
public void stop(BundleContext context) { |
69 |
if (loc != null && loc.startsWith(pref)) { |
78 |
context.removeBundleListener(this); |
70 |
String cnb = loc.substring(pref.length()); |
79 |
m_context = null; |
71 |
for (ModuleInfo mi : all) { |
80 |
} |
72 |
if (cnb.equals(mi.getCodeNameBase())) { |
81 |
|
73 |
return new DelegateLoader(mi); |
82 |
public Bundle[] getBundles() { |
74 |
} |
83 |
if (m_context != null) { |
75 |
} |
84 |
return m_context.getBundles(); |
76 |
} |
85 |
} |
77 |
} |
86 |
return null; |
78 |
return null; |
87 |
} |
79 |
} |
88 |
|
80 |
|
89 |
public void bundleChanged(BundleEvent ev) { |
81 |
static void register(Module m) { |
90 |
String loc = ev.getBundle().getLocation(); |
|
|
91 |
NetigsoModule.LOG.log(Level.FINER, "bundleChanged {0}", ev); |
92 |
final String pref = "netigso://"; // NOI18N |
93 |
if (ev.getType() == BundleEvent.RESOLVED && loc != null && loc.startsWith(pref)) { |
94 |
String cnb = loc.substring(pref.length()); |
95 |
for (ModuleInfo mi : all) { |
96 |
if (cnb.equals(mi.getCodeNameBase())) { |
97 |
join(ev.getBundle(), mi); |
98 |
return; |
99 |
} |
100 |
} |
101 |
NetigsoModule.LOG.warning("No join for " + cnb); |
102 |
} |
103 |
} |
104 |
|
105 |
void register(Module m) { |
106 |
NetigsoModule.LOG.log(Level.FINER, "register module {0}", m.getCodeNameBase()); |
82 |
NetigsoModule.LOG.log(Level.FINER, "register module {0}", m.getCodeNameBase()); |
107 |
all.add(m); |
83 |
all.add(m); |
108 |
} |
84 |
} |
109 |
|
85 |
private static final class DelegateLoader extends ClassLoader { |
110 |
|
|
|
111 |
/** Injects classloader of mi to Felix's bundle. |
112 |
*/ |
113 |
private void join(Bundle bundle, ModuleInfo mi) { |
114 |
try { |
115 |
Field modules = findField(bundle, "m_modules"); |
116 |
Object[] arr = (Object[])modules.get(bundle); |
117 |
Field loader = null; |
118 |
for (int i = 0; i < arr.length; i++) { |
119 |
ModuleImpl impl = (ModuleImpl)arr[i]; |
120 |
if (loader == null) { |
121 |
loader = findField(impl, "m_classLoader"); |
122 |
} |
123 |
loader.set(impl, new DelegateLoader(impl, mi)); |
124 |
} |
125 |
} catch (Exception ex) { |
126 |
throw new IllegalStateException(ex); |
127 |
} |
128 |
} |
129 |
private static Field findField(Object obj, String name) throws Exception { |
130 |
Exception first = null; |
131 |
Class<?> c = obj.getClass(); |
132 |
while (c != null) { |
133 |
try { |
134 |
Field m = c.getDeclaredField(name); |
135 |
m.setAccessible(true); |
136 |
return m; |
137 |
} catch (Exception e) { |
138 |
first = e; |
139 |
} |
140 |
c = c.getSuperclass(); |
141 |
} |
142 |
throw first; |
143 |
} |
144 |
|
145 |
private static final class DelegateLoader extends ModuleClassLoader { |
146 |
private final ModuleInfo mi; |
86 |
private final ModuleInfo mi; |
147 |
public DelegateLoader(ModuleImpl impl, ModuleInfo mi) { |
87 |
public DelegateLoader(ModuleInfo mi) { |
148 |
impl.super(null); |
|
|
149 |
this.mi = mi; |
88 |
this.mi = mi; |
150 |
} |
89 |
} |
151 |
|
90 |
|