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