View Javadoc

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          // creates the jar file that is to be embedded in the inner jar
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         // create the inner jar embedding the jar file created in the previous step
101         // this should be exactly the same as in the setUp() method, except for the temp.jar file entry.
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         // delegates to the test method that tests transformation with inner jar, the assertions should be the same
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         // host component with name
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         // host component with name
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         // the bean should exist. With no name explicitly given to the host component name, the bean name is auto-generated.
491         assertTrue(context.beanExists("bean0"));
492     }
493 }