1 package com.atlassian.plugin.osgi;
2
3 import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
4 import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
5 import com.atlassian.plugin.osgi.factory.OsgiPlugin;
6 import com.atlassian.plugin.test.PluginJarBuilder;
7 import com.atlassian.plugin.JarPluginArtifact;
8 import com.atlassian.plugin.ModuleDescriptor;
9 import com.atlassian.plugin.Plugin;
10 import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
11 import com.atlassian.plugin.web.descriptors.WebItemModuleDescriptor;
12 import com.atlassian.plugin.util.WaitUntil;
13
14 import java.io.File;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.Collections;
19 import java.util.HashSet;
20
21 import org.osgi.framework.BundleContext;
22 import org.osgi.framework.ServiceRegistration;
23 import org.osgi.framework.ServiceReference;
24 import org.osgi.framework.Bundle;
25
26 public class TestDynamicPluginModule extends PluginInContainerTestBase
27 {
28 public void testDynamicPluginModule() throws Exception
29 {
30 initPluginManager(new HostComponentProvider()
31 {
32 public void provide(final ComponentRegistrar registrar)
33 {
34 }
35 });
36
37 final File pluginJar = new PluginJarBuilder("pluginType")
38 .addFormattedResource("atlassian-plugin.xml",
39 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
40 " <plugin-info>",
41 " <version>1.0</version>",
42 " </plugin-info>",
43 " <component key='factory' class='foo.MyModuleDescriptorFactory' public='true'>",
44 " <interface>com.atlassian.plugin.ModuleDescriptorFactory</interface>",
45 " </component>",
46 "</atlassian-plugin>")
47 .addFormattedJava("foo.MyModuleDescriptor",
48 "package foo;",
49 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
50 " public Object getModule(){return null;}",
51 "}")
52 .addFormattedJava("foo.MyModuleDescriptorFactory",
53 "package foo;",
54 "public class MyModuleDescriptorFactory extends com.atlassian.plugin.DefaultModuleDescriptorFactory {",
55 " public MyModuleDescriptorFactory() {",
56 " super();",
57 " addModuleDescriptor('foo', MyModuleDescriptor.class);",
58 " }",
59 "}")
60 .build();
61 final File pluginJar2 = new PluginJarBuilder("fooUser")
62 .addFormattedResource("atlassian-plugin.xml",
63 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
64 " <plugin-info>",
65 " <version>1.0</version>",
66 " </plugin-info>",
67 " <foo key='dum2'/>",
68 "</atlassian-plugin>")
69 .build();
70
71 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
72 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
73 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
74 .getModuleDescriptors();
75 assertEquals(1, descriptors.size());
76 final ModuleDescriptor<?> descriptor = descriptors.iterator()
77 .next();
78 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
79 }
80
81 public void testDynamicPluginModuleNotLinkToAllPlugins() throws Exception
82 {
83 new PluginJarBuilder("pluginType")
84 .addFormattedResource("atlassian-plugin.xml",
85 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
86 " <plugin-info>",
87 " <version>1.0</version>",
88 " </plugin-info>",
89 " <module-type key='foo' class='foo.MyModuleDescriptor'/>",
90 "</atlassian-plugin>")
91 .addFormattedJava("foo.MyModuleDescriptor",
92 "package foo;",
93 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
94 " public Object getModule(){return null;}",
95 "}")
96 .build(pluginsDir);
97 new PluginJarBuilder("fooUser")
98 .addFormattedResource("atlassian-plugin.xml",
99 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
100 " <plugin-info>",
101 " <version>1.0</version>",
102 " </plugin-info>",
103 " <foo key='dum2'/>",
104 "</atlassian-plugin>")
105 .build(pluginsDir);
106 new PluginJarBuilder("foootherUser")
107 .addPluginInformation("unusing.plugin", "Unusing plugin", "1.0")
108 .build(pluginsDir);
109
110 initPluginManager(new HostComponentProvider()
111 {
112 public void provide(final ComponentRegistrar registrar)
113 {
114 }
115 });
116
117 assertEquals("MyModuleDescriptor", pluginManager.getPlugin("test.plugin").getModuleDescriptor("dum2").getClass().getSimpleName());
118 Set<String> deps = findDependentBundles(((OsgiPlugin) pluginManager.getPlugin("test.plugin.module")).getBundle());
119 assertTrue(deps.contains("test.plugin"));
120 assertFalse(deps.contains("unusing.plugin"));
121 }
122
123 private Set<String> findDependentBundles(Bundle bundle)
124 {
125 Set<String> deps = new HashSet<String>();
126 final ServiceReference[] registeredServices = bundle.getRegisteredServices();
127 if (registeredServices == null)
128 {
129 return deps;
130 }
131
132 for (final ServiceReference serviceReference : registeredServices)
133 {
134 final Bundle[] usingBundles = serviceReference.getUsingBundles();
135 if (usingBundles == null)
136 {
137 continue;
138 }
139 for (final Bundle usingBundle : usingBundles)
140 {
141 deps.add(usingBundle.getSymbolicName());
142 }
143 }
144 return deps;
145 }
146
147 public void testDynamicPluginModuleUsingModuleTypeDescriptor() throws Exception
148 {
149 initPluginManager(new HostComponentProvider()
150 {
151 public void provide(final ComponentRegistrar registrar)
152 {
153 }
154 });
155
156 final File pluginJar = new PluginJarBuilder("pluginType")
157 .addFormattedResource("atlassian-plugin.xml",
158 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
159 " <plugin-info>",
160 " <version>1.0</version>",
161 " </plugin-info>",
162 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
163 "</atlassian-plugin>")
164 .addFormattedJava("foo.MyModuleDescriptor",
165 "package foo;",
166 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
167 " public Object getModule(){return null;}",
168 "}")
169 .build();
170 final File pluginJar2 = new PluginJarBuilder("fooUser")
171 .addFormattedResource("atlassian-plugin.xml",
172 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
173 " <plugin-info>",
174 " <version>1.0</version>",
175 " </plugin-info>",
176 " <foo key='dum2'/>",
177 "</atlassian-plugin>")
178 .build();
179
180 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
181 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
182 WaitUntil.invoke(new BasicWaitCondition()
183 {
184 public boolean isFinished()
185 {
186 return pluginManager.getPlugin("test.plugin")
187 .getModuleDescriptor("dum2")
188 .getClass()
189 .getSimpleName()
190 .equals("MyModuleDescriptor");
191 }
192 });
193 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
194 .getModuleDescriptors();
195 assertEquals(1, descriptors.size());
196 final ModuleDescriptor<?> descriptor = descriptors.iterator()
197 .next();
198 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
199 }
200
201
202 public void testDynamicPluginModuleUsingModuleTypeDescriptorAndComponentInjection() throws Exception
203 {
204 initPluginManager(new HostComponentProvider()
205 {
206 public void provide(final ComponentRegistrar registrar)
207 {
208 }
209 });
210
211 final File pluginJar = new PluginJarBuilder("pluginType")
212 .addFormattedResource("atlassian-plugin.xml",
213 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
214 " <plugin-info>",
215 " <version>1.0</version>",
216 " </plugin-info>",
217 " <component key='comp' class='foo.MyComponent' />",
218 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
219 "</atlassian-plugin>")
220 .addFormattedJava("foo.MyComponent",
221 "package foo;",
222 "public class MyComponent {",
223 "}")
224 .addFormattedJava("foo.MyModuleDescriptor",
225 "package foo;",
226 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
227 " public MyModuleDescriptor(MyComponent comp) {}",
228 " public Object getModule(){return null;}",
229 "}")
230
231 .build();
232 final File pluginJar2 = new PluginJarBuilder("fooUser")
233 .addFormattedResource("atlassian-plugin.xml",
234 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
235 " <plugin-info>",
236 " <version>1.0</version>",
237 " </plugin-info>",
238 " <foo key='dum2'/>",
239 "</atlassian-plugin>")
240 .build();
241
242 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
243 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
244 WaitUntil.invoke(new BasicWaitCondition()
245 {
246 public boolean isFinished()
247 {
248 return pluginManager.getPlugin("test.plugin")
249 .getModuleDescriptors()
250 .iterator()
251 .next()
252 .getClass()
253 .getSimpleName()
254 .equals("MyModuleDescriptor");
255 }
256 });
257 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
258 .getModuleDescriptors();
259 assertEquals(1, descriptors.size());
260 final ModuleDescriptor<?> descriptor = descriptors.iterator()
261 .next();
262 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
263 }
264
265 public void testDynamicPluginModuleUsingModuleTypeDescriptorAfterTheFact() throws Exception
266 {
267 initPluginManager(new HostComponentProvider()
268 {
269 public void provide(final ComponentRegistrar registrar)
270 {
271 }
272 });
273
274 final File pluginJar = new PluginJarBuilder("pluginType")
275 .addFormattedResource("atlassian-plugin.xml",
276 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
277 " <plugin-info>",
278 " <version>1.0</version>",
279 " </plugin-info>",
280 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
281 "</atlassian-plugin>")
282 .addFormattedJava("foo.MyModuleDescriptor",
283 "package foo;",
284 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
285 " public Object getModule(){return null;}",
286 "}")
287 .build();
288 final File pluginJar2 = new PluginJarBuilder("fooUser")
289 .addFormattedResource("atlassian-plugin.xml",
290 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
291 " <plugin-info>",
292 " <version>1.0</version>",
293 " </plugin-info>",
294 " <foo key='dum2'/>",
295 "</atlassian-plugin>")
296 .build();
297
298 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
299 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
300 WaitUntil.invoke(new BasicWaitCondition()
301 {
302 public boolean isFinished()
303 {
304 return pluginManager.getPlugin("test.plugin")
305 .getModuleDescriptors()
306 .iterator()
307 .next()
308 .getClass()
309 .getSimpleName()
310 .equals("MyModuleDescriptor");
311 }
312 });
313
314 Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
315 .getModuleDescriptors();
316 assertEquals(1, descriptors.size());
317 ModuleDescriptor<?> descriptor = descriptors.iterator()
318 .next();
319 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
320
321 pluginManager.uninstall(pluginManager.getPlugin("test.plugin.module"));
322 WaitUntil.invoke(new BasicWaitCondition()
323 {
324 public boolean isFinished()
325 {
326 return pluginManager.getPlugin("test.plugin")
327 .getModuleDescriptors()
328 .iterator()
329 .next()
330 .getClass()
331 .getSimpleName()
332 .equals("UnrecognisedModuleDescriptor");
333 }
334 });
335 descriptors = pluginManager.getPlugin("test.plugin")
336 .getModuleDescriptors();
337 assertEquals(1, descriptors.size());
338 descriptor = descriptors.iterator()
339 .next();
340 assertEquals("UnrecognisedModuleDescriptor", descriptor.getClass().getSimpleName());
341
342 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
343 descriptors = pluginManager.getPlugin("test.plugin")
344 .getModuleDescriptors();
345 assertEquals(1, descriptors.size());
346 descriptor = descriptors.iterator()
347 .next();
348 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
349 }
350
351 public void testDynamicPluginModuleUsingModuleTypeDescriptorAfterTheFactWithException() throws Exception
352 {
353 initPluginManager(new HostComponentProvider()
354 {
355 public void provide(final ComponentRegistrar registrar)
356 {
357 }
358 });
359
360 final File pluginJar = new PluginJarBuilder("pluginType")
361 .addFormattedResource("atlassian-plugin.xml",
362 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
363 " <plugin-info>",
364 " <version>1.0</version>",
365 " </plugin-info>",
366 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
367 "</atlassian-plugin>")
368 .addFormattedJava("foo.MyModuleDescriptor",
369 "package foo;",
370 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
371 " public MyModuleDescriptor() {",
372 " throw new RuntimeException('error loading module');",
373 " }",
374 " public Object getModule(){return null;}",
375 "}")
376 .build();
377 final File pluginJar2 = new PluginJarBuilder("fooUser")
378 .addFormattedResource("atlassian-plugin.xml",
379 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
380 " <plugin-info>",
381 " <version>1.0</version>",
382 " </plugin-info>",
383 " <foo key='dum2'/>",
384 "</atlassian-plugin>")
385 .build();
386
387 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
388 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
389 assertTrue(WaitUntil.invoke(new BasicWaitCondition()
390 {
391 public boolean isFinished()
392 {
393 UnrecognisedModuleDescriptor des = (UnrecognisedModuleDescriptor) pluginManager.getPlugin("test.plugin").getModuleDescriptor("dum2");
394 return des.getErrorText().contains("error loading module");
395 }
396 }));
397
398 }
399
400 public void testDynamicPluginModuleUsingModuleTypeDescriptorInSamePlugin() throws Exception
401 {
402 initPluginManager(new HostComponentProvider()
403 {
404 public void provide(final ComponentRegistrar registrar)
405 {
406 }
407 });
408
409 final File pluginJar = new PluginJarBuilder("pluginType")
410 .addFormattedResource("atlassian-plugin.xml",
411 "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
412 " <plugin-info>",
413 " <version>1.0</version>",
414 " </plugin-info>",
415 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
416 " <foo key='dum2' />",
417 "</atlassian-plugin>")
418 .addFormattedJava("foo.MyModuleDescriptor",
419 "package foo;",
420 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
421 " public Object getModule(){return null;}",
422 "}")
423 .build();
424
425 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
426 WaitUntil.invoke(new BasicWaitCondition()
427 {
428 public boolean isFinished()
429 {
430 return pluginManager.getPlugin("test.plugin")
431 .getModuleDescriptor("dum2")
432 .getClass()
433 .getSimpleName()
434 .equals("MyModuleDescriptor");
435 }
436 });
437 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
438 .getModuleDescriptors();
439 assertEquals(2, descriptors.size());
440 final ModuleDescriptor<?> descriptor = pluginManager.getPlugin("test.plugin")
441 .getModuleDescriptor("dum2");
442 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
443 }
444
445 public void testDynamicModuleDescriptor() throws Exception
446 {
447 initPluginManager(null);
448
449 final File pluginJar = new PluginJarBuilder("pluginType").addPluginInformation("test.plugin", "foo", "1.0")
450 .build();
451
452 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
453 final BundleContext ctx = ((OsgiPlugin) pluginManager.getPlugin("test.plugin")).getBundle()
454 .getBundleContext();
455 final ServiceRegistration reg = ctx.registerService(ModuleDescriptor.class.getName(), new DummyWebItemModuleDescriptor(), null);
456
457 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
458 .getModuleDescriptors();
459 assertEquals(1, descriptors.size());
460 final ModuleDescriptor<?> descriptor = descriptors.iterator()
461 .next();
462 assertEquals("DummyWebItemModuleDescriptor", descriptor.getClass().getSimpleName());
463 List<WebItemModuleDescriptor> list = pluginManager.getEnabledModuleDescriptorsByClass(WebItemModuleDescriptor.class);
464 assertEquals(1, list.size());
465 reg.unregister();
466 list = pluginManager.getEnabledModuleDescriptorsByClass(WebItemModuleDescriptor.class);
467 assertEquals(0, list.size());
468 }
469
470 public void testDynamicModuleDescriptorIsolatedToPlugin() throws Exception
471 {
472 initPluginManager(null);
473
474 final File pluginJar = new PluginJarBuilder("pluginType").addPluginInformation("test.plugin", "foo", "1.0")
475 .build();
476
477 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
478 final BundleContext ctx = ((OsgiPlugin) pluginManager.getPlugin("test.plugin")).getBundle()
479 .getBundleContext();
480 ctx.registerService(ModuleDescriptor.class.getName(), new DummyWebItemModuleDescriptor(), null);
481
482 final File pluginJar2 = new PluginJarBuilder("pluginType").addPluginInformation("test.plugin2", "foo", "1.0")
483 .build();
484 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
485 final BundleContext ctx2 = ((OsgiPlugin) pluginManager.getPlugin("test.plugin2")).getBundle()
486 .getBundleContext();
487 final ServiceRegistration reg2 = ctx2.registerService(ModuleDescriptor.class.getName(), new DummyWebItemModuleDescriptor(), null);
488
489 Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
490 .getModuleDescriptors();
491 assertEquals(1, descriptors.size());
492 final ModuleDescriptor<?> descriptor = descriptors.iterator()
493 .next();
494 assertEquals("DummyWebItemModuleDescriptor", descriptor.getClass().getSimpleName());
495 List<WebItemModuleDescriptor> list = pluginManager.getEnabledModuleDescriptorsByClass(WebItemModuleDescriptor.class);
496 assertEquals(2, list.size());
497 reg2.unregister();
498 list = pluginManager.getEnabledModuleDescriptorsByClass(WebItemModuleDescriptor.class);
499 assertEquals(1, list.size());
500 descriptors = pluginManager.getPlugin("test.plugin")
501 .getModuleDescriptors();
502 assertEquals(1, descriptors.size());
503 }
504 }