1 package com.atlassian.plugin.osgi.factory.transform.stage;
2
3 import com.atlassian.plugin.JarPluginArtifact;
4 import com.atlassian.plugin.PluginAccessor;
5 import com.atlassian.plugin.osgi.SomeInterface;
6 import com.atlassian.plugin.osgi.container.OsgiContainerManager;
7 import com.atlassian.plugin.osgi.factory.transform.Barable;
8 import com.atlassian.plugin.osgi.factory.transform.FooChild;
9 import com.atlassian.plugin.osgi.factory.transform.Fooable;
10 import com.atlassian.plugin.osgi.factory.transform.StubHostComponentRegistration;
11 import com.atlassian.plugin.osgi.factory.transform.TransformContext;
12 import com.atlassian.plugin.osgi.factory.transform.model.SystemExports;
13 import com.atlassian.plugin.osgi.factory.transform.test.SomeClass;
14 import com.atlassian.plugin.osgi.hostcomponents.HostComponentRegistration;
15 import com.atlassian.plugin.osgi.hostcomponents.impl.MockRegistration;
16 import com.atlassian.plugin.test.PluginJarBuilder;
17 import junit.framework.TestCase;
18 import org.dom4j.DocumentException;
19 import org.osgi.framework.ServiceReference;
20
21 import javax.servlet.Servlet;
22 import javax.swing.table.TableModel;
23 import java.io.File;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.zip.ZipEntry;
29 import java.util.zip.ZipOutputStream;
30
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
33
34 public class TestHostComponentSpringStage extends TestCase
35 {
36
37 private HostComponentSpringStage transformer = new HostComponentSpringStage();
38 private File jar;
39 private SystemExports systemExports;
40 private OsgiContainerManager osgiContainerManager;
41
42 @Override
43 public void setUp() throws Exception
44 {
45 osgiContainerManager = mock(OsgiContainerManager.class);
46 when(osgiContainerManager.getRegisteredServices()).thenReturn(new ServiceReference[0]);
47 jar = new PluginJarBuilder()
48 .addFormattedJava("my.Foo",
49 "package my;",
50 "public class Foo {",
51 " public Foo(com.atlassian.plugin.osgi.SomeInterface bar) {}",
52 "}")
53 .addPluginInformation("my.plugin", "my.plugin", "1.0")
54 .addFormattedResource("META-INF/MANIFEST.MF",
55 "Manifest-Version: 1.0",
56 "Bundle-Version: 1.0",
57 "Bundle-SymbolicName: my.server",
58 "Bundle-ManifestVersion: 2",
59 "Bundle-ClassPath: .\n")
60 .build();
61 systemExports = new SystemExports("javax.servlet;version=\"2.3\",javax.servlet.http;version=\"2.3\"");
62 }
63
64 public void testTransformWithInnerJar() throws Exception, DocumentException
65 {
66 File outerjar = new PluginJarBuilder()
67 .addPluginInformation("my.plugin", "my.plugin", "1.0")
68 .addFormattedResource("META-INF/MANIFEST.MF",
69 "Manifest-Version: 1.0",
70 "Bundle-Version: 1.0",
71 "Bundle-SymbolicName: my.server",
72 "Bundle-ManifestVersion: 2",
73 "Bundle-ClassPath: .,foo.jar\n")
74 .addFile("foo.jar", jar)
75 .build();
76
77 SpringTransformerTestHelper.transform(
78 transformer,
79 outerjar,
80 new ArrayList<HostComponentRegistration>()
81 {
82 {
83 add(new StubHostComponentRegistration("foo", new SomeInterface()
84 {}, SomeInterface.class));
85 }
86 },
87 null,
88 "beans:bean[@id='foo']/beans:property[@name='filter']/@value='(&(bean-name=foo)(plugins-host=true))'");
89 }
90
91 public void testTransformWithInnerJarContainingInnerJar() throws Exception
92 {
93
94 final File embeddedJar = File.createTempFile("temp", ".jar", new File(System.getProperty("java.io.tmpdir")));
95 final ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(embeddedJar));
96 zout.putNextEntry(new ZipEntry("somefile"));
97 zout.write("somefile".getBytes());
98 zout.close();
99
100
101
102 jar = new PluginJarBuilder()
103 .addFormattedJava("my.Foo",
104 "package my;",
105 "public class Foo {",
106 " public Foo(com.atlassian.plugin.osgi.SomeInterface bar) {}",
107 "}")
108 .addPluginInformation("my.plugin", "my.plugin", "1.0")
109 .addFormattedResource("META-INF/MANIFEST.MF",
110 "Manifest-Version: 1.0",
111 "Bundle-Version: 1.0",
112 "Bundle-SymbolicName: my.server",
113 "Bundle-ManifestVersion: 2",
114 "Bundle-ClassPath: .\n")
115 .addFile("temp.jar", embeddedJar)
116 .build();
117
118
119 testTransformWithInnerJar();
120 }
121
122 public void testTransform() throws IOException, DocumentException
123 {
124 SpringTransformerTestHelper.transform(
125 transformer,
126 jar,
127 new ArrayList<HostComponentRegistration>()
128 {
129 {
130 add(new StubHostComponentRegistration("foo", new SomeInterface()
131 {}, SomeInterface.class));
132 }
133 },
134 null,
135 "beans:bean[@id='foo']/beans:property[@name='interfaces']/beans:list/beans:value='" + SomeInterface.class.getName() + "'",
136 "beans:bean[@id='foo']/beans:property[@name='filter']/@value='(&(bean-name=foo)(plugins-host=true))'");
137 }
138
139 public void testTransformWithProperNestedInferredImports() throws Exception
140 {
141 jar = new PluginJarBuilder().addFormattedJava("my.Foo", "package my;", "public class Foo {",
142 " public Foo(javax.swing.table.TableModel bar) {}", "}").addPluginInformation("my.plugin", "my.plugin", "1.0").build();
143
144 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
145 {
146 {
147 add(new MockRegistration("foo", TableModel.class));
148 }
149 };
150
151 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
152 transformer.execute(context);
153 assertTrue(context.getExtraImports().contains("javax.swing.event"));
154
155 }
156
157 public void testTransformWithProperNestedVersionedInferredImports() throws Exception
158 {
159 jar = new PluginJarBuilder()
160 .addFormattedJava("my.Foo",
161 "package my;",
162 "public class Foo {",
163 " public Foo(javax.servlet.Servlet servlet) {}",
164 "}")
165 .addPluginInformation("my.plugin", "my.plugin", "1.0")
166 .build();
167
168 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
169 {
170 {
171 add(new MockRegistration("foo", Servlet.class));
172 }
173 };
174
175 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
176 transformer.execute(context);
177 assertTrue(context.getExtraImports().contains("javax.servlet;version=\"[2.3,2.3]\""));
178
179 }
180
181 public void testTransformWithInferredImportsOfSuperInterfaces() throws Exception
182 {
183 jar = new PluginJarBuilder()
184 .addFormattedJava("my.Foo",
185 "package my;",
186 "public class Foo {",
187 " public Foo(com.atlassian.plugin.osgi.factory.transform.FooChild bar) {}",
188 "}")
189 .addPluginInformation("my.plugin", "my.plugin", "1.0")
190 .build();
191
192 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
193 {
194 {
195 add(new MockRegistration("foo", FooChild.class));
196 }
197 };
198
199 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
200 transformer.execute(context);
201 assertTrue(context.getExtraImports().contains(SomeClass.class.getPackage().getName()));
202
203 }
204
205 public void testTransformWithSuperClassThatUsesHostComponent() throws Exception
206 {
207 jar = new PluginJarBuilder()
208 .addFormattedJava("my.Foo",
209 "package my;",
210 "public class Foo extends " + AbstractFoo.class.getName() + " {",
211 "}")
212 .addPluginInformation("my.plugin", "my.plugin", "1.0")
213 .build();
214
215 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
216 {
217 {
218 add(new MockRegistration("foo", FooChild.class));
219 }
220 };
221
222 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
223 transformer.execute(context);
224 assertTrue(context.getExtraImports().contains(FooChild.class.getPackage().getName()));
225 }
226
227 public void testTransformWithSuperClassInJar() throws Exception
228 {
229 jar = new PluginJarBuilder()
230 .addFormattedJava("my.Foo",
231 "package my;",
232 "public class Foo {",
233 "}")
234 .addFormattedJava("my2.Bar",
235 "package my2;",
236 "public class Bar extends my.Foo {",
237 "}")
238 .addPluginInformation("my.plugin", "my.plugin", "1.0")
239 .build();
240
241 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
242 {
243 {
244 add(new MockRegistration("foo", FooChild.class));
245 }
246 };
247
248 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
249 transformer.execute(context);
250 assertEquals(0, context.getExtraImports().size());
251
252 }
253
254 public void testTransformWithSuperClassInOtherJar() throws Exception
255 {
256 PluginJarBuilder parent = new PluginJarBuilder()
257 .addFormattedJava("my.Foo",
258 "package my;",
259 "public class Foo {",
260 "}");
261
262 jar = new PluginJarBuilder("child", parent.getClassLoader())
263 .addFormattedJava("my2.Bar",
264 "package my2;",
265 "public class Bar extends my.Foo {",
266 "}")
267 .addPluginInformation("my.plugin", "my.plugin", "1.0")
268 .build();
269
270 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
271 {
272 {
273 add(new MockRegistration("foo", FooChild.class));
274 }
275 };
276
277 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
278 transformer.execute(context);
279 assertEquals(0, context.getExtraImports().size());
280
281 }
282
283 public void testTransformWithPoundSign() throws IOException, DocumentException
284 {
285 SpringTransformerTestHelper.transform(
286 transformer,
287 jar,
288 new ArrayList<HostComponentRegistration>()
289 {
290 {
291 add(new StubHostComponentRegistration("foo#1", new SomeInterface()
292 {}, SomeInterface.class));
293 }
294 },
295 null,
296 "beans:bean[@id='fooLB1']/beans:property[@name='filter']/@value='(&(bean-name=foo#1)(plugins-host=true))'");
297 }
298
299 public void testTransformNoMatches() throws Exception
300 {
301 final File jar = new PluginJarBuilder().addFormattedJava("my.Foo", "package my;", "public class Foo {", " public Foo(String bar) {}", "}").addPluginInformation(
302 "my.plugin", "my.plugin", "1.0").addResource("META-INF/MANIFEST.MF",
303 "Manifest-Version: 1.0\n" + "Bundle-Version: 1.0\n" + "Bundle-SymbolicName: my.server\n" + "Bundle-ManifestVersion: 2\n").build();
304
305
306 assertNull(SpringTransformerTestHelper.transform(transformer, jar, new ArrayList<HostComponentRegistration>()
307 {
308 {
309 add(new StubHostComponentRegistration("foo", SomeInterface.class));
310 }
311 }, null, "not(beans:bean[@id='foo'])"));
312 }
313
314 public void testTransformMatchInInnerJar() throws Exception
315 {
316 final File innerJar = new PluginJarBuilder().addFormattedJava("my.Foo", "package my;", "public class Foo {",
317 " public Foo(com.atlassian.plugin.osgi.SomeInterface bar) {}", "}").build();
318 final File jar = new PluginJarBuilder().addFile("META-INF/lib/inner.jar", innerJar).addResource(
319 "META-INF/MANIFEST.MF",
320 "Manifest-Version: 1.0\n" + "Bundle-Version: 1.0\n" + "Bundle-SymbolicName: my.server\n" + "Bundle-ManifestVersion: 2\n" + "Bundle-ClassPath: .,\n" + " META-INF/lib/inner.jar\n").addPluginInformation(
321 "my.plugin", "my.plugin", "1.0").build();
322
323
324 SpringTransformerTestHelper.transform(transformer, jar, new ArrayList<HostComponentRegistration>()
325 {
326 {
327 add(new StubHostComponentRegistration("foo", SomeInterface.class));
328 }
329 }, null, "beans:bean[@id='foo']");
330 }
331
332 public void testTransformWithExistingComponentImportName() throws Exception, DocumentException
333 {
334 jar = new PluginJarBuilder()
335 .addFormattedJava("my.Foo",
336 "package my;",
337 "public class Foo {",
338 " public Foo(com.atlassian.plugin.osgi.SomeInterface bar) {}",
339 "}")
340 .addFormattedResource("atlassian-plugin.xml",
341 "<atlassian-plugin>",
342 " <component-import key='foo' class='Foo' interface='Foo'/>",
343 "</atlassian-plugin>")
344 .addResource("META-INF/MANIFEST.MF",
345 "Manifest-Version: 1.0\n" +
346 "Bundle-Version: 1.0\n" +
347 "Bundle-SymbolicName: my.server\n" +
348 "Bundle-ManifestVersion: 2\n")
349 .build();
350
351 SpringTransformerTestHelper.transform(
352 transformer,
353 jar,
354 new ArrayList<HostComponentRegistration>()
355 {
356 {
357 assertTrue(add(new StubHostComponentRegistration("foo", new SomeInterface()
358 {}, SomeInterface.class)));
359 }
360 },
361 null,
362 "beans:bean[@id='foo0']/beans:property[@name='filter']/@value='(&(bean-name=foo)(plugins-host=true))'");
363 }
364
365 public void testTransformWithExistingComponentImportInterface() throws Exception, DocumentException
366 {
367 jar = new PluginJarBuilder()
368 .addFormattedJava("my.Foo",
369 "package my;",
370 "public class Foo {",
371 " public Foo(com.atlassian.plugin.osgi.SomeInterface bar) {}",
372 "}")
373 .addFormattedResource("atlassian-plugin.xml",
374 "<atlassian-plugin>",
375 " <component-import key='foobar'>",
376 " <interface>com.atlassian.plugin.osgi.SomeInterface</interface>",
377 " </component-import>",
378 "</atlassian-plugin>")
379 .addResource("META-INF/MANIFEST.MF",
380 "Manifest-Version: 1.0\n" +
381 "Bundle-Version: 1.0\n" +
382 "Bundle-SymbolicName: my.server\n" +
383 "Bundle-ManifestVersion: 2\n")
384 .build();
385
386 SpringTransformerTestHelper.transform(
387 transformer,
388 jar,
389 new ArrayList<HostComponentRegistration>()
390 {
391 {
392 assertTrue(add(new StubHostComponentRegistration("foo", new SomeInterface()
393 {}, SomeInterface.class)));
394 }
395 },
396 null,
397 "not(beans:bean[@id='foo']/beans:property[@name='filter']/@value='(&(bean-name=foo)(plugins-host=true))']");
398 }
399
400 public void testTransformWithExistingComponentImportInterfaceScopedToDifferentApplication() throws Exception, DocumentException
401 {
402 jar = new PluginJarBuilder()
403 .addFormattedJava("my.Foo",
404 "package my;",
405 "public class Foo {",
406 " public Foo(com.atlassian.plugin.osgi.SomeInterface bar) {}",
407 "}")
408 .addFormattedResource("atlassian-plugin.xml",
409 "<atlassian-plugin>",
410 " <component-import key='foobar' application='notfoo'>",
411 " <interface>com.atlassian.plugin.osgi.SomeInterface</interface>",
412 " </component-import>",
413 "</atlassian-plugin>")
414 .addResource("META-INF/MANIFEST.MF",
415 "Manifest-Version: 1.0\n" +
416 "Bundle-Version: 1.0\n" +
417 "Bundle-SymbolicName: my.server\n" +
418 "Bundle-ManifestVersion: 2\n")
419 .build();
420
421 assertNotNull("No file overrides!", SpringTransformerTestHelper.transform(
422 transformer,
423 jar,
424 new ArrayList<HostComponentRegistration>()
425 {
426 {
427 assertTrue(add(new StubHostComponentRegistration("foo", new SomeInterface()
428 {}, SomeInterface.class)));
429 }
430 },
431 null,
432 "beans:bean[@id='foo']/beans:property[@name='filter']/@value='(&(bean-name=foo)(plugins-host=true))'"));
433 }
434
435 public void testTransformWithExistingComponentImportInterfacePartialMatch() throws Exception, DocumentException
436 {
437 jar = new PluginJarBuilder()
438 .addFormattedJava("my.Foo",
439 "package my;",
440 "public class Foo {",
441 " public Foo(com.atlassian.plugin.osgi.factory.transform.Barable bar) {}",
442 "}")
443 .addFormattedResource("atlassian-plugin.xml",
444 "<atlassian-plugin>",
445 " <component-import key='foobar'>",
446 " <interface>com.atlassian.plugin.osgi.factory.transform.Barable</interface>",
447 " </component-import>",
448 "</atlassian-plugin>")
449 .addResource("META-INF/MANIFEST.MF",
450 "Manifest-Version: 1.0\n" +
451 "Bundle-Version: 1.0\n" +
452 "Bundle-SymbolicName: my.server\n" +
453 "Bundle-ManifestVersion: 2\n")
454 .build();
455
456 SpringTransformerTestHelper.transform(
457 transformer,
458 jar,
459 new ArrayList<HostComponentRegistration>()
460 {
461 {
462 assertTrue(add(new StubHostComponentRegistration("foo", new Fooable()
463 {
464 public SomeClass getSomeClass(Integer blah)
465 {
466 return null;
467 }
468 }, Barable.class, Fooable.class)));
469 }
470 },
471 null,
472 "not(beans:bean[@id='foo']/beans:property[@name='filter']/@value='(&(bean-name=foo)(plugins-host=true))']");
473 }
474
475 public void testTransformBeanTracking() throws Exception
476 {
477 jar = new PluginJarBuilder().addFormattedJava("my.Foo", "package my;", "public class Foo {",
478 " public Foo(javax.swing.table.TableModel bar) {}", "}").addPluginInformation("my.plugin", "my.plugin", "1.0").build();
479
480 final List<HostComponentRegistration> regs = new ArrayList<HostComponentRegistration>()
481 {
482 {
483 add(new MockRegistration("foo", TableModel.class));
484 }
485 };
486
487 final TransformContext context = new TransformContext(regs, systemExports, new JarPluginArtifact(jar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
488 transformer.execute(context);
489
490
491 assertTrue(context.beanExists("bean0"));
492 }
493 }