1 package com.atlassian.plugin.osgi;
2
3 import com.atlassian.plugin.DefaultModuleDescriptorFactory;
4 import com.atlassian.plugin.PluginArtifact;
5 import com.atlassian.plugin.event.PluginEventListener;
6 import com.atlassian.plugin.event.events.PluginModuleDisabledEvent;
7 import com.atlassian.plugin.event.events.PluginModuleEnabledEvent;
8 import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
9 import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
10 import com.atlassian.plugin.osgi.factory.OsgiPlugin;
11 import com.atlassian.plugin.test.PluginJarBuilder;
12 import com.atlassian.plugin.JarPluginArtifact;
13 import com.atlassian.plugin.ModuleDescriptor;
14 import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
15 import com.atlassian.plugin.util.WaitUntil;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.Collection;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.HashSet;
23
24 import my.FooModule;
25 import my.FooModuleDescriptor;
26 import org.osgi.framework.BundleContext;
27 import org.osgi.framework.ServiceRegistration;
28 import org.osgi.framework.ServiceReference;
29 import org.osgi.framework.Bundle;
30
31 public class TestDynamicPluginModule extends PluginInContainerTestBase
32 {
33 public void testDynamicPluginModule() throws Exception
34 {
35 initPluginManager(new HostComponentProvider()
36 {
37 public void provide(final ComponentRegistrar registrar)
38 {
39 }
40 });
41
42 final File pluginJar = new PluginJarBuilder("pluginType")
43 .addFormattedResource("atlassian-plugin.xml",
44 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
45 " <plugin-info>",
46 " <version>1.0</version>",
47 " </plugin-info>",
48 " <component key='factory' class='foo.MyModuleDescriptorFactory' public='true'>",
49 " <interface>com.atlassian.plugin.ModuleDescriptorFactory</interface>",
50 " </component>",
51 "</atlassian-plugin>")
52 .addFormattedJava("foo.MyModuleDescriptor",
53 "package foo;",
54 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
55 " public Object getModule(){return null;}",
56 "}")
57 .addFormattedJava("foo.MyModuleDescriptorFactory",
58 "package foo;",
59 "public class MyModuleDescriptorFactory extends com.atlassian.plugin.DefaultModuleDescriptorFactory {",
60 " public MyModuleDescriptorFactory() {",
61 " super();",
62 " addModuleDescriptor('foo', MyModuleDescriptor.class);",
63 " }",
64 "}")
65 .build();
66 final File pluginJar2 = buildDynamicModuleClientJar();
67
68 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
69 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
70 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
71 .getModuleDescriptors();
72 assertEquals(1, descriptors.size());
73 final ModuleDescriptor<?> descriptor = descriptors.iterator()
74 .next();
75 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
76 }
77
78 public void testDynamicPluginModuleUsingModuleTypeDescriptorWithReinstall() throws Exception
79 {
80 initPluginManager();
81
82 final File pluginJar = new PluginJarBuilder("pluginType")
83 .addFormattedResource("atlassian-plugin.xml",
84 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
85 " <plugin-info>",
86 " <version>1.0</version>",
87 " </plugin-info>",
88 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
89 "</atlassian-plugin>")
90 .addFormattedJava("foo.MyModuleDescriptor",
91 "package foo;",
92 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
93 " public Object getModule(){return null;}",
94 "}")
95 .build();
96 final File pluginJar2 = buildDynamicModuleClientJar();
97
98 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
99 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
100 assertTrue(waitForDynamicModuleEnabled());
101
102
103 pluginManager.uninstall(pluginManager.getPlugin("test.plugin.module"));
104 WaitUntil.invoke(new BasicWaitCondition()
105 {
106 public boolean isFinished()
107 {
108 ModuleDescriptor<?> descriptor = pluginManager.getPlugin("test.plugin")
109 .getModuleDescriptors()
110 .iterator()
111 .next();
112 boolean enabled = pluginManager.isPluginModuleEnabled(descriptor.getCompleteKey());
113 return descriptor
114 .getClass()
115 .getSimpleName()
116 .equals("UnrecognisedModuleDescriptor")
117 && !enabled;
118 }
119 });
120
121 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
122 assertTrue(waitForDynamicModuleEnabled());
123 }
124
125 public void testDynamicPluginModuleUsingModuleTypeDescriptorWithImmediateReinstall() throws Exception
126 {
127 initPluginManager();
128
129 final File pluginJar = new PluginJarBuilder("pluginType")
130 .addFormattedResource("atlassian-plugin.xml", "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>", " <plugin-info>", " <version>1.0</version>", " </plugin-info>", " <module-type key='foo' class='foo.MyModuleDescriptor' />", "</atlassian-plugin>")
131 .addFormattedJava("foo.MyModuleDescriptor",
132 "package foo;",
133 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
134 " public Object getModule(){return null;}",
135 "}")
136 .build();
137 final File pluginJar2 = buildDynamicModuleClientJar();
138
139 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
140 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
141 assertTrue(waitForDynamicModuleEnabled());
142
143 PluginModuleDisabledListener disabledListener = new PluginModuleDisabledListener("dum2");
144 PluginModuleEnabledListener enabledListener = new PluginModuleEnabledListener("dum2");
145 pluginEventManager.register(disabledListener);
146 pluginEventManager.register(enabledListener);
147
148
149 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
150 assertTrue(waitForDynamicModuleEnabled());
151
152 assertEquals(1, enabledListener.called);
153 assertEquals(1, disabledListener.called);
154 }
155
156 public void testDynamicPluginModuleUsingModuleTypeDescriptorWithImmediateReinstallOfBoth() throws Exception
157 {
158 initPluginManager();
159
160 final File pluginJar = new PluginJarBuilder("pluginType")
161 .addFormattedResource("atlassian-plugin.xml",
162 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
163 " <plugin-info>",
164 " <version>1.0</version>",
165 " </plugin-info>",
166 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
167 "</atlassian-plugin>")
168 .addFormattedJava("foo.MyModuleDescriptor",
169 "package foo;",
170 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
171 " public Object getModule(){return null;}",
172 "}")
173 .build();
174 final File pluginJar2 = buildDynamicModuleClientJar();
175
176 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
177 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
178
179 assertTrue(waitForDynamicModuleEnabled());
180
181 PluginModuleDisabledListener disabledListener = new PluginModuleDisabledListener("dum2");
182 PluginModuleEnabledListener enabledListener = new PluginModuleEnabledListener("dum2");
183 pluginEventManager.register(disabledListener);
184 pluginEventManager.register(enabledListener);
185
186
187 pluginManager.installPlugins(new JarPluginArtifact(pluginJar2), new JarPluginArtifact(pluginJar));
188 assertTrue(waitForDynamicModuleEnabled());
189
190 assertEquals(pluginManager.getPluginModule("test.plugin:dum2").getClass(), pluginManager.getPlugin("test.plugin.module").<Object>loadClass("foo.MyModuleDescriptor", null));
191
192 assertEquals(1, enabledListener.called);
193 assertEquals(1, disabledListener.called);
194 }
195
196 private File buildDynamicModuleClientJar() throws IOException
197 {
198 return new PluginJarBuilder("fooUser")
199 .addFormattedResource("atlassian-plugin.xml",
200 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
201 " <plugin-info>",
202 " <version>1.0</version>",
203 " </plugin-info>",
204 " <foo key='dum2'/>",
205 "</atlassian-plugin>")
206 .build();
207 }
208
209 private boolean waitForDynamicModuleEnabled()
210 {
211 return WaitUntil.invoke(new BasicWaitCondition()
212 {
213 public boolean isFinished()
214 {
215 return pluginManager.getPlugin("test.plugin").getModuleDescriptors().iterator().next().getClass().getSimpleName().equals("MyModuleDescriptor");
216 }
217 });
218 }
219
220 public void testUpgradeOfBundledPluginWithDynamicModule() throws Exception
221 {
222 final File pluginJar = new PluginJarBuilder("pluginType")
223 .addFormattedResource("atlassian-plugin.xml",
224 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
225 " <plugin-info>",
226 " <version>1.0</version>",
227 " </plugin-info>",
228 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
229 "</atlassian-plugin>")
230 .addFormattedJava("foo.MyModuleDescriptor",
231 "package foo;",
232 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
233 " public Object getModule(){return null;}",
234 "}")
235 .build();
236
237 final DefaultModuleDescriptorFactory factory = new DefaultModuleDescriptorFactory(hostContainer);
238 initBundlingPluginManager(factory, pluginJar);
239 assertEquals(1, pluginManager.getEnabledPlugins().size());
240
241 final File pluginClientOld = buildDynamicModuleClientJar();
242 final File pluginClientNew = new PluginJarBuilder("fooUser")
243 .addFormattedResource("atlassian-plugin.xml",
244 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
245 " <plugin-info>",
246 " <version>2.0</version>",
247 " </plugin-info>",
248 " <foo key='dum2'/>",
249 "</atlassian-plugin>")
250 .build();
251 pluginManager.installPlugins(new JarPluginArtifact(pluginClientOld), new JarPluginArtifact(pluginClientNew));
252
253 assertTrue(waitForDynamicModuleEnabled());
254
255 assertEquals(2, pluginManager.getEnabledPlugins().size());
256 assertEquals("2.0", pluginManager.getPlugin("test.plugin").getPluginInformation().getVersion());
257 }
258
259 public void testDynamicPluginModuleNotLinkToAllPlugins() throws Exception
260 {
261 new PluginJarBuilder("pluginType")
262 .addFormattedResource("atlassian-plugin.xml",
263 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
264 " <plugin-info>",
265 " <version>1.0</version>",
266 " </plugin-info>",
267 " <module-type key='foo' class='foo.MyModuleDescriptor'/>",
268 "</atlassian-plugin>")
269 .addFormattedJava("foo.MyModuleDescriptor",
270 "package foo;",
271 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
272 " public Object getModule(){return null;}",
273 "}")
274 .build(pluginsDir);
275 new PluginJarBuilder("fooUser")
276 .addFormattedResource("atlassian-plugin.xml",
277 "<atlassian-plugin name='Test 2' key='test.plugin' pluginsVersion='2'>",
278 " <plugin-info>",
279 " <version>1.0</version>",
280 " </plugin-info>",
281 " <foo key='dum2'/>",
282 "</atlassian-plugin>")
283 .build(pluginsDir);
284 new PluginJarBuilder("foootherUser")
285 .addPluginInformation("unusing.plugin", "Unusing plugin", "1.0")
286 .build(pluginsDir);
287
288 initPluginManager(new HostComponentProvider()
289 {
290 public void provide(final ComponentRegistrar registrar)
291 {
292 }
293 });
294
295 assertEquals("MyModuleDescriptor", pluginManager.getPlugin("test.plugin").getModuleDescriptor("dum2").getClass().getSimpleName());
296 Set<String> deps = findDependentBundles(((OsgiPlugin) pluginManager.getPlugin("test.plugin.module")).getBundle());
297 assertTrue(deps.contains("test.plugin"));
298 assertFalse(deps.contains("unusing.plugin"));
299 }
300
301 private Set<String> findDependentBundles(Bundle bundle)
302 {
303 Set<String> deps = new HashSet<String>();
304 final ServiceReference[] registeredServices = bundle.getRegisteredServices();
305 if (registeredServices == null)
306 {
307 return deps;
308 }
309
310 for (final ServiceReference serviceReference : registeredServices)
311 {
312 final Bundle[] usingBundles = serviceReference.getUsingBundles();
313 if (usingBundles == null)
314 {
315 continue;
316 }
317 for (final Bundle usingBundle : usingBundles)
318 {
319 deps.add(usingBundle.getSymbolicName());
320 }
321 }
322 return deps;
323 }
324
325 public void testDynamicPluginModuleUsingModuleTypeDescriptor() throws Exception
326 {
327 initPluginManager(new HostComponentProvider()
328 {
329 public void provide(final ComponentRegistrar registrar)
330 {
331 }
332 });
333
334 final File pluginJar = new PluginJarBuilder("pluginType")
335 .addFormattedResource("atlassian-plugin.xml",
336 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
337 " <plugin-info>",
338 " <version>1.0</version>",
339 " </plugin-info>",
340 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
341 "</atlassian-plugin>")
342 .addFormattedJava("foo.MyModuleDescriptor",
343 "package foo;",
344 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
345 " public Object getModule(){return null;}",
346 "}")
347 .build();
348 final File pluginJar2 = buildDynamicModuleClientJar();
349
350 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
351 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
352 WaitUntil.invoke(new BasicWaitCondition()
353 {
354 public boolean isFinished()
355 {
356 return pluginManager.getPlugin("test.plugin")
357 .getModuleDescriptor("dum2")
358 .getClass()
359 .getSimpleName()
360 .equals("MyModuleDescriptor");
361 }
362 });
363 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
364 .getModuleDescriptors();
365 assertEquals(1, descriptors.size());
366 final ModuleDescriptor<?> descriptor = descriptors.iterator()
367 .next();
368 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
369 }
370
371 public void testDynamicPluginModuleWithClientAndHostEnabledSimultaneouslyCheckEvents() throws Exception
372 {
373 initPluginManager();
374
375 final File pluginJar = new PluginJarBuilder("pluginType")
376 .addFormattedResource("atlassian-plugin.xml",
377 "<atlassian-plugin name='Test' key='host' pluginsVersion='2'>",
378 " <plugin-info>",
379 " <version>1.0</version>",
380 " </plugin-info>",
381 " <component key='foo' class='foo.MyModuleDescriptorFactory' public='true'>",
382 " <interface>com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory</interface>",
383 " </component>",
384 "</atlassian-plugin>")
385 .addFormattedJava("foo.MyModuleDescriptorFactory",
386 "package foo;",
387 "public class MyModuleDescriptorFactory extends com.atlassian.plugin.DefaultModuleDescriptorFactory ",
388 " implements com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory{",
389 " public MyModuleDescriptorFactory() throws Exception{",
390 " super();",
391 " Thread.sleep(500);",
392 " System.out.println('starting descriptor factory');",
393 " addModuleDescriptor('foo', com.atlassian.plugin.osgi.EventTrackingModuleDescriptor.class);",
394 " }",
395 " public java.util.Set getModuleDescriptorClasses() {",
396 " return java.util.Collections.singleton(com.atlassian.plugin.osgi.EventTrackingModuleDescriptor.class);",
397 " }",
398 "}")
399 .build();
400 final File pluginJar2 = new PluginJarBuilder("fooUser")
401 .addFormattedResource("atlassian-plugin.xml",
402 "<atlassian-plugin name='Test 2' key='client' pluginsVersion='2'>",
403 " <plugin-info>",
404 " <version>1.0</version>",
405 " </plugin-info>",
406 " <foo key='dum2'/>",
407 "</atlassian-plugin>")
408 .build();
409
410 pluginManager.installPlugins(new JarPluginArtifact(pluginJar), new JarPluginArtifact(pluginJar2));
411
412 WaitUntil.invoke(new BasicWaitCondition()
413 {
414 public boolean isFinished()
415 {
416 return pluginManager.getPlugin("client").getModuleDescriptor("dum2").getClass().getSimpleName().equals("EventTrackingModuleDescriptor");
417 }
418 });
419 EventTrackingModuleDescriptor desc = (EventTrackingModuleDescriptor) pluginManager.getPlugin("client").getModuleDescriptor("dum2");
420 assertEquals(1, desc.getEnabledCount());
421 }
422
423
424 public void testDynamicPluginModuleUsingModuleTypeDescriptorAndComponentInjection() throws Exception
425 {
426 initPluginManager(new HostComponentProvider()
427 {
428 public void provide(final ComponentRegistrar registrar)
429 {
430 }
431 });
432
433 final File pluginJar = new PluginJarBuilder("pluginType")
434 .addFormattedResource("atlassian-plugin.xml",
435 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
436 " <plugin-info>",
437 " <version>1.0</version>",
438 " </plugin-info>",
439 " <component key='comp' class='foo.MyComponent' />",
440 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
441 "</atlassian-plugin>")
442 .addFormattedJava("foo.MyComponent", "package foo;", "public class MyComponent {", "}")
443 .addFormattedJava("foo.MyModuleDescriptor",
444 "package foo;",
445 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
446 " public MyModuleDescriptor(MyComponent comp) {}",
447 " public Object getModule(){return null;}",
448 "}")
449
450 .build();
451 final File pluginJar2 = buildDynamicModuleClientJar();
452
453 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
454 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
455 assertTrue(waitForDynamicModuleEnabled());
456 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
457 .getModuleDescriptors();
458 assertEquals(1, descriptors.size());
459 final ModuleDescriptor<?> descriptor = descriptors.iterator()
460 .next();
461 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
462 }
463
464 public void testDynamicPluginModuleUsingModuleTypeDescriptorAfterTheFact() throws Exception
465 {
466 initPluginManager(new HostComponentProvider()
467 {
468 public void provide(final ComponentRegistrar registrar)
469 {
470 }
471 });
472
473 final File pluginJar = new PluginJarBuilder("pluginType")
474 .addFormattedResource("atlassian-plugin.xml",
475 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
476 " <plugin-info>",
477 " <version>1.0</version>",
478 " </plugin-info>",
479 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
480 "</atlassian-plugin>")
481 .addFormattedJava("foo.MyModuleDescriptor", "package foo;", "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {", " public Object getModule(){return null;}", "}")
482 .build();
483 final File pluginJar2 = buildDynamicModuleClientJar();
484
485 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
486 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
487 waitForDynamicModuleEnabled();
488
489 Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
490 .getModuleDescriptors();
491 assertEquals(1, descriptors.size());
492 ModuleDescriptor<?> descriptor = descriptors.iterator()
493 .next();
494 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
495
496 pluginManager.uninstall(pluginManager.getPlugin("test.plugin.module"));
497 WaitUntil.invoke(new BasicWaitCondition()
498 {
499 public boolean isFinished()
500 {
501 return pluginManager.getPlugin("test.plugin")
502 .getModuleDescriptors()
503 .iterator()
504 .next()
505 .getClass()
506 .getSimpleName()
507 .equals("UnrecognisedModuleDescriptor");
508 }
509 });
510 descriptors = pluginManager.getPlugin("test.plugin")
511 .getModuleDescriptors();
512 assertEquals(1, descriptors.size());
513 descriptor = descriptors.iterator()
514 .next();
515 assertEquals("UnrecognisedModuleDescriptor", descriptor.getClass().getSimpleName());
516
517 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
518 descriptors = pluginManager.getPlugin("test.plugin")
519 .getModuleDescriptors();
520 assertEquals(1, descriptors.size());
521 descriptor = descriptors.iterator()
522 .next();
523 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
524 }
525
526 public void testDynamicPluginModuleUsingModuleTypeDescriptorAfterTheFactWithException() throws Exception
527 {
528 initPluginManager(new HostComponentProvider()
529 {
530 public void provide(final ComponentRegistrar registrar)
531 {
532 }
533 });
534
535 final File pluginJar = new PluginJarBuilder("pluginType")
536 .addFormattedResource("atlassian-plugin.xml",
537 "<atlassian-plugin name='Test' key='test.plugin.module' pluginsVersion='2'>",
538 " <plugin-info>",
539 " <version>1.0</version>",
540 " </plugin-info>",
541 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
542 "</atlassian-plugin>")
543 .addFormattedJava("foo.MyModuleDescriptor",
544 "package foo;",
545 "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {",
546 " public MyModuleDescriptor() {",
547 " throw new RuntimeException('error loading module');",
548 " }",
549 " public Object getModule(){return null;}",
550 "}")
551 .build();
552 final File pluginJar2 = buildDynamicModuleClientJar();
553
554 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
555 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
556 assertTrue(WaitUntil.invoke(new BasicWaitCondition()
557 {
558 public boolean isFinished()
559 {
560 UnrecognisedModuleDescriptor des = (UnrecognisedModuleDescriptor) pluginManager.getPlugin("test.plugin").getModuleDescriptor("dum2");
561 return des.getErrorText().contains("error loading module");
562 }
563 }));
564
565 }
566
567 public void testDynamicPluginModuleUsingModuleTypeDescriptorInSamePlugin() throws Exception
568 {
569 initPluginManager(new HostComponentProvider()
570 {
571 public void provide(final ComponentRegistrar registrar)
572 {
573 }
574 });
575
576 final File pluginJar = new PluginJarBuilder("pluginType")
577 .addFormattedResource("atlassian-plugin.xml",
578 "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
579 " <plugin-info>",
580 " <version>1.0</version>",
581 " </plugin-info>",
582 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
583 " <foo key='dum2' />",
584 "</atlassian-plugin>")
585 .addFormattedJava("foo.MyModuleDescriptor", "package foo;", "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {", " public Object getModule(){return null;}", "}")
586 .build();
587
588 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
589 WaitUntil.invoke(new BasicWaitCondition() {
590 public boolean isFinished() {
591 return pluginManager.getPlugin("test.plugin")
592 .getModuleDescriptor("dum2")
593 .getClass()
594 .getSimpleName()
595 .equals("MyModuleDescriptor");
596 }
597 });
598 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
599 .getModuleDescriptors();
600 assertEquals(2, descriptors.size());
601 final ModuleDescriptor<?> descriptor = pluginManager.getPlugin("test.plugin")
602 .getModuleDescriptor("dum2");
603 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
604 }
605
606 public void testDynamicPluginModuleUsingModuleTypeDescriptorInSamePluginWithRestart() throws Exception
607 {
608 initPluginManager();
609
610 final File pluginJar = new PluginJarBuilder("pluginType")
611 .addFormattedResource("atlassian-plugin.xml",
612 "<atlassian-plugin name='Test' key='test.plugin' pluginsVersion='2'>",
613 " <plugin-info>",
614 " <version>1.0</version>",
615 " </plugin-info>",
616 " <module-type key='foo' class='foo.MyModuleDescriptor' />",
617 " <foo key='dum2' />",
618 "</atlassian-plugin>")
619 .addFormattedJava("foo.MyModuleDescriptor", "package foo;", "public class MyModuleDescriptor extends com.atlassian.plugin.descriptors.AbstractModuleDescriptor {", " public Object getModule(){return null;}", "}")
620 .build();
621
622 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
623 WaitUntil.invoke(new BasicWaitCondition()
624 {
625 public boolean isFinished()
626 {
627 return pluginManager.getPlugin("test.plugin")
628 .getModuleDescriptor("dum2")
629 .getClass()
630 .getSimpleName()
631 .equals("MyModuleDescriptor");
632 }
633 });
634 Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
635 .getModuleDescriptors();
636 assertEquals(2, descriptors.size());
637 ModuleDescriptor<?> descriptor = pluginManager.getPlugin("test.plugin")
638 .getModuleDescriptor("dum2");
639 assertEquals("MyModuleDescriptor", descriptor.getClass().getSimpleName());
640
641 PluginModuleDisabledListener disabledListener = new PluginModuleDisabledListener("dum2");
642 PluginModuleEnabledListener enabledListener = new PluginModuleEnabledListener("dum2");
643 pluginEventManager.register(disabledListener);
644 pluginEventManager.register(enabledListener);
645
646 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
647 WaitUntil.invoke(new BasicWaitCondition()
648 {
649 public boolean isFinished()
650 {
651 return pluginManager.getPlugin("test.plugin")
652 .getModuleDescriptor("dum2")
653 .getClass()
654 .getSimpleName()
655 .equals("MyModuleDescriptor");
656 }
657 });
658 descriptors = pluginManager.getPlugin("test.plugin")
659 .getModuleDescriptors();
660 assertEquals(2, descriptors.size());
661 ModuleDescriptor<?> newdescriptor = pluginManager.getPlugin("test.plugin")
662 .getModuleDescriptor("dum2");
663 assertEquals("MyModuleDescriptor", newdescriptor.getClass().getSimpleName());
664 assertTrue(descriptor.getClass() != newdescriptor.getClass());
665 assertEquals(1, disabledListener.called);
666 assertEquals(1, enabledListener.called);
667 }
668
669 public void testDynamicModuleDescriptor() throws Exception
670 {
671 initPluginManager(null);
672
673 final File pluginJar = new PluginJarBuilder("pluginType").addPluginInformation("test.plugin", "foo", "1.0")
674 .build();
675
676 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
677 final BundleContext ctx = ((OsgiPlugin) pluginManager.getPlugin("test.plugin")).getBundle()
678 .getBundleContext();
679 final ServiceRegistration reg = ctx.registerService(ModuleDescriptor.class.getName(), new DummyModuleDescriptorWithKey(), null);
680
681 final Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
682 .getModuleDescriptors();
683 assertEquals(1, descriptors.size());
684 final ModuleDescriptor<?> descriptor = descriptors.iterator()
685 .next();
686 assertEquals("DummyModuleDescriptorWithKey", descriptor.getClass().getSimpleName());
687 List<DummyModuleDescriptorWithKey> list = pluginManager.getEnabledModuleDescriptorsByClass(DummyModuleDescriptorWithKey.class);
688 assertEquals(1, list.size());
689 reg.unregister();
690 list = pluginManager.getEnabledModuleDescriptorsByClass(DummyModuleDescriptorWithKey.class);
691 assertEquals(0, list.size());
692 }
693
694 public void testDynamicModuleDescriptorIsolatedToPlugin() throws Exception
695 {
696 initPluginManager(null);
697
698 final File pluginJar = new PluginJarBuilder("pluginType").addPluginInformation("test.plugin", "foo", "1.0")
699 .build();
700
701 pluginManager.installPlugin(new JarPluginArtifact(pluginJar));
702 final BundleContext ctx = ((OsgiPlugin) pluginManager.getPlugin("test.plugin")).getBundle()
703 .getBundleContext();
704 ctx.registerService(ModuleDescriptor.class.getName(), new DummyModuleDescriptorWithKey(), null);
705
706 final File pluginJar2 = new PluginJarBuilder("pluginType").addPluginInformation("test.plugin2", "foo", "1.0")
707 .build();
708 pluginManager.installPlugin(new JarPluginArtifact(pluginJar2));
709 final BundleContext ctx2 = ((OsgiPlugin) pluginManager.getPlugin("test.plugin2")).getBundle()
710 .getBundleContext();
711 final ServiceRegistration reg2 = ctx2.registerService(ModuleDescriptor.class.getName(), new DummyModuleDescriptorWithKey(), null);
712
713 Collection<ModuleDescriptor<?>> descriptors = pluginManager.getPlugin("test.plugin")
714 .getModuleDescriptors();
715 assertEquals(1, descriptors.size());
716 final ModuleDescriptor<?> descriptor = descriptors.iterator()
717 .next();
718 assertEquals("DummyModuleDescriptorWithKey", descriptor.getClass().getSimpleName());
719 List<DummyModuleDescriptorWithKey> list = pluginManager.getEnabledModuleDescriptorsByClass(DummyModuleDescriptorWithKey.class);
720 assertEquals(2, list.size());
721 reg2.unregister();
722 list = pluginManager.getEnabledModuleDescriptorsByClass(DummyModuleDescriptorWithKey.class);
723 assertEquals(1, list.size());
724 descriptors = pluginManager.getPlugin("test.plugin")
725 .getModuleDescriptors();
726 assertEquals(1, descriptors.size());
727 }
728
729 public void testInstallUninstallInstallWithModuleTypePlugin() throws Exception {
730 final PluginArtifact moduleTypeProviderArtifact = new JarPluginArtifact(new PluginJarBuilder()
731 .addFormattedResource(
732 "atlassian-plugin.xml",
733 "<atlassian-plugin name='Foo Module Type Provider' key='test.fooModuleTypeProvider' pluginsVersion='2'>",
734 " <plugin-info>",
735 " <version>1.0</version>",
736 " <bundle-instructions>",
737 " <Export-Package>my</Export-Package>",
738 " </bundle-instructions>",
739 " </plugin-info>",
740 " <module-type key='foo-module' class='my.FooModuleDescriptor'/>",
741 "</atlassian-plugin>")
742 .addClass(FooModule.class)
743 .addClass(FooModuleDescriptor.class)
744 .build());
745 final PluginArtifact moduleTypeImplementerArtifact = new JarPluginArtifact(new PluginJarBuilder().addFormattedResource("atlassian-plugin.xml",
746 "<atlassian-plugin name='Foo Module Type Implementer' key='test.fooModuleTypeImplementer' pluginsVersion='2'>",
747 " <plugin-info>",
748 " <version>1.0</version>",
749 " <bundle-instructions>",
750 " <Import-Package>my</Import-Package>",
751 " </bundle-instructions>",
752 " </plugin-info>",
753 " <foo-module key='myFooModule' class='my.impl.FooModuleImpl'/>",
754 "</atlassian-plugin>")
755 .addFormattedJava(
756 "my.impl.FooModuleImpl",
757 "package my.impl;",
758 "",
759 "import my.FooModule;",
760 "",
761 "public class FooModuleImpl implements FooModule {",
762 "}")
763 .build());
764
765 initPluginManager();
766 pluginManager.installPlugin(moduleTypeProviderArtifact);
767 pluginManager.installPlugin(moduleTypeImplementerArtifact);
768
769 final long foo1InitialisationTime = assertFooImplEnabledAndGetInitialisationTime();
770
771 pluginManager.installPlugin(moduleTypeProviderArtifact);
772
773 final long foo2InitialisationTime = assertFooImplEnabledAndGetInitialisationTime();
774
775 assertTrue("FooModuleImpl implements old version of FooModule", foo2InitialisationTime > foo1InitialisationTime);
776
777 }
778
779 private long assertFooImplEnabledAndGetInitialisationTime() throws IllegalAccessException, NoSuchFieldException {
780 assertTrue(pluginManager.isPluginModuleEnabled("test.fooModuleTypeProvider:foo-module"));
781 assertTrue(pluginManager.isPluginModuleEnabled("test.fooModuleTypeImplementer:myFooModule"));
782 final ModuleDescriptor<?> fooDescriptor = pluginManager.getEnabledPluginModule("test.fooModuleTypeImplementer:myFooModule");
783 assertNotNull(fooDescriptor);
784 final Object foo = fooDescriptor.getModule();
785 assertNotNull(foo);
786 final Class<? extends Object> fooClass = foo.getClass();
787 assertTrue(fooClass.getName().equals("my.impl.FooModuleImpl"));
788 return fooClass.getField("INITIALISATION_TIME").getLong(foo);
789 }
790
791 public static class PluginModuleEnabledListener
792 {
793 public volatile int called;
794 private final String key;
795
796 public PluginModuleEnabledListener(String key)
797 {
798 this.key = key;
799 }
800
801 @PluginEventListener
802 public void onEnable(PluginModuleEnabledEvent event)
803 {
804 if (event.getModule().getKey().equals(key))
805 {
806 called++;
807 }
808 }
809 }
810
811 public static class PluginModuleDisabledListener
812 {
813 public volatile int called;
814 private final String key;
815
816 public PluginModuleDisabledListener(String key)
817 {
818 this.key = key;
819 }
820
821 @PluginEventListener
822 public void onDisable(PluginModuleDisabledEvent event)
823 {
824 if (event.getModule().getKey().equals(key))
825 {
826 called++;
827 }
828 }
829 }
830 }