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.PluginArtifact;
6   import com.atlassian.plugin.osgi.container.OsgiContainerManager;
7   import com.atlassian.plugin.osgi.factory.transform.TransformContext;
8   import com.atlassian.plugin.osgi.factory.transform.model.SystemExports;
9   import com.atlassian.plugin.test.PluginJarBuilder;
10  import com.atlassian.plugin.util.validation.ValidationException;
11  import com.mockobjects.dynamic.C;
12  import com.mockobjects.dynamic.Mock;
13  import org.dom4j.DocumentException;
14  import org.dom4j.DocumentHelper;
15  import org.dom4j.Element;
16  import org.junit.Test;
17  import org.osgi.framework.Constants;
18  import org.osgi.framework.ServiceReference;
19  
20  import java.io.ByteArrayInputStream;
21  import java.io.File;
22  import java.io.IOException;
23  
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertFalse;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  import static org.mockito.Mockito.mock;
29  import static org.mockito.Mockito.when;
30  
31  public class TestComponentSpringStage {
32  
33      @Test
34      public void testTransform() throws IOException, DocumentException {
35          ComponentSpringStage transformer = new ComponentSpringStage();
36  
37          // private component
38          Element pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
39          Element component = pluginRoot.addElement("component");
40          component.addAttribute("key", "foo");
41          component.addAttribute("class", "my.Foo");
42          component.addAttribute("alias", "hohoho");
43          SpringTransformerTestHelper.transform(transformer, pluginRoot, "beans:bean[@id='foo' and @class='my.Foo']",
44                  "beans:alias[@name='foo' and @alias='hohoho']");
45  
46          // public component, interface
47          pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
48          component = pluginRoot.addElement("component");
49          component.addAttribute("key", "foo");
50          component.addAttribute("class", "my.Foo");
51          component.addAttribute("public", "true");
52          Element inf = component.addElement("interface");
53          inf.setText("my.IFoo");
54          SpringTransformerTestHelper.transform(transformer, pluginRoot, "beans:bean[@id='foo' and @class='my.Foo']",
55                  "osgi:service[@id='foo_osgiService' and @ref='foo']",
56                  "//osgi:interfaces",
57                  "//beans:value[.='my.IFoo']");
58  
59          // public component, interface as attribute
60          pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
61          component = pluginRoot.addElement("component");
62          component.addAttribute("key", "foo");
63          component.addAttribute("class", "my.Foo");
64          component.addAttribute("public", "true");
65          component.addAttribute("interface", "my.IFoo");
66          SpringTransformerTestHelper.transform(transformer, pluginRoot, "beans:bean[@id='foo' and @class='my.Foo']",
67                  "osgi:service[@id='foo_osgiService' and @ref='foo']",
68                  "//osgi:interfaces",
69                  "//beans:value[.='my.IFoo']");
70      }
71  
72      @Test
73      public void testTransformWithServiceProperties() throws IOException, DocumentException {
74          ComponentSpringStage transformer = new ComponentSpringStage();
75  
76          Element pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
77          Element component = pluginRoot.addElement("component");
78          component.addAttribute("key", "foo");
79          component.addAttribute("class", "my.Foo");
80          component.addAttribute("public", "true");
81          component.addAttribute("interface", "my.IFoo");
82  
83          Element svcprops = component.addElement("service-properties");
84          Element prop = svcprops.addElement("entry");
85          prop.addAttribute("key", "foo");
86          prop.addAttribute("value", "bar");
87          SpringTransformerTestHelper.transform(transformer, pluginRoot, "beans:bean[@id='foo' and @class='my.Foo']",
88                  "osgi:service[@id='foo_osgiService']/osgi:service-properties",
89                  "osgi:service[@id='foo_osgiService']/osgi:service-properties/beans:entry[@key='foo' and @value='bar']",
90                  "//osgi:interfaces",
91                  "//beans:value[.='my.IFoo']");
92  
93          svcprops.clearContent();
94          try {
95              SpringTransformerTestHelper.transform(transformer, pluginRoot, "beans:bean[@id='foo' and @class='my.Foo']",
96                      "osgi:service[@id='foo_osgiService']/osgi:service-properties",
97                      "//osgi:interfaces",
98                      "//beans:value[.='my.IFoo']");
99              fail("Validation exception should have been thrown");
100         } catch (ValidationException ex) {
101             // expected
102         }
103     }
104 
105     @Test
106     public void testTransformForOneApp() throws IOException, DocumentException {
107         ComponentSpringStage transformer = new ComponentSpringStage();
108 
109         // public component, interface
110         Element pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
111         Element component = pluginRoot.addElement("component");
112         component.addAttribute("key", "foo");
113         component.addAttribute("class", "my.Foo");
114         component.addAttribute("public", "true");
115         component.addAttribute("application", "bar");
116         Element inf = component.addElement("interface");
117         inf.setText("my.IFoo");
118         SpringTransformerTestHelper.transform(transformer, pluginRoot, "not(beans:bean[@id='foo' and @class='my.Foo'])");
119 
120         pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
121         component = pluginRoot.addElement("component");
122         component.addAttribute("key", "foo");
123         component.addAttribute("class", "my.Foo");
124         component.addAttribute("public", "true");
125         component.addAttribute("application", "foo");
126         inf = component.addElement("interface");
127         inf.setText("my.IFoo");
128         SpringTransformerTestHelper.transform(transformer, pluginRoot, "beans:bean[@id='foo' and @class='my.Foo']");
129 
130     }
131 
132     @Test
133     public void testExportsAdded() throws IOException {
134         ComponentSpringStage transformer = new ComponentSpringStage();
135         Element pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
136         Element component = pluginRoot.addElement("component");
137         component.addAttribute("key", "foo");
138         component.addAttribute("class", "my.Foo");
139         component.addAttribute("public", "true");
140         Element inf = component.addElement("interface");
141         inf.setText("my.IFoo");
142 
143         Mock mockPluginArtifact = new Mock(PluginArtifact.class);
144         mockPluginArtifact.matchAndReturn("toFile", new PluginJarBuilder().build());
145         mockPluginArtifact.expectAndReturn("getResourceAsStream", C.args(C.eq("foo")),
146                 new ByteArrayInputStream(SpringTransformerTestHelper.elementToString(pluginRoot).getBytes()));
147         mockPluginArtifact.expectAndReturn("doesResourceExist", C.args(C.eq("my/IFoo.class")), true);
148         OsgiContainerManager osgiContainerManager = mock(OsgiContainerManager.class);
149         when(osgiContainerManager.getRegisteredServices()).thenReturn(new ServiceReference[0]);
150         TransformContext ctx = new TransformContext(null, SystemExports.NONE, (PluginArtifact) mockPluginArtifact.proxy(), null, "foo", osgiContainerManager);
151         transformer.execute(ctx);
152 
153         assertTrue(ctx.getExtraExports().contains("my"));
154 
155         // the generated bean should be tracked.
156         assertTrue(ctx.beanExists("foo"));
157 
158         mockPluginArtifact.verify();
159     }
160 
161     @Test
162     public void testExportsNotInJar() throws IOException {
163         ComponentSpringStage transformer = new ComponentSpringStage();
164         Element pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
165         Element component = pluginRoot.addElement("component");
166         component.addAttribute("key", "foo");
167         component.addAttribute("class", "my.Foo");
168         component.addAttribute("public", "true");
169         Element inf = component.addElement("interface");
170         inf.setText("my.IFoo");
171 
172         Mock mockPluginArtifact = new Mock(PluginArtifact.class);
173         mockPluginArtifact.matchAndReturn("toFile", new PluginJarBuilder().build());
174         mockPluginArtifact.expectAndReturn("getResourceAsStream", C.args(C.eq("foo")),
175                 new ByteArrayInputStream(SpringTransformerTestHelper.elementToString(pluginRoot).getBytes()));
176         mockPluginArtifact.expectAndReturn("doesResourceExist", C.args(C.eq("my/IFoo.class")), false);
177         OsgiContainerManager osgiContainerManager = mock(OsgiContainerManager.class);
178         when(osgiContainerManager.getRegisteredServices()).thenReturn(new ServiceReference[0]);
179         TransformContext ctx = new TransformContext(null, SystemExports.NONE, (PluginArtifact) mockPluginArtifact.proxy(), null, "foo", osgiContainerManager);
180         transformer.execute(ctx);
181 
182         assertFalse(ctx.getExtraExports().contains("my"));
183         // the generated bean should be tracked.
184         assertTrue(ctx.beanExists("foo"));
185 
186         mockPluginArtifact.verify();
187     }
188 
189     @Test
190     public void testExportsExist() throws IOException {
191         ComponentSpringStage transformer = new ComponentSpringStage();
192         Element pluginRoot = DocumentHelper.createDocument().addElement("atlassian-plugin");
193         Element component = pluginRoot.addElement("component");
194         component.addAttribute("key", "foo");
195         component.addAttribute("class", "my.Foo");
196         component.addAttribute("public", "true");
197         Element inf = component.addElement("interface");
198         inf.setText("my.IFoo");
199 
200         Mock mockPluginArtifact = new Mock(PluginArtifact.class);
201         mockPluginArtifact.matchAndReturn("toFile", new PluginJarBuilder().build());
202         mockPluginArtifact.expectAndReturn("getResourceAsStream", C.args(C.eq("foo")),
203                 new ByteArrayInputStream(SpringTransformerTestHelper.elementToString(pluginRoot).getBytes()));
204         OsgiContainerManager osgiContainerManager = mock(OsgiContainerManager.class);
205         when(osgiContainerManager.getRegisteredServices()).thenReturn(new ServiceReference[0]);
206         TransformContext ctx = new TransformContext(null, SystemExports.NONE, (PluginArtifact) mockPluginArtifact.proxy(), null, "foo", osgiContainerManager);
207         ctx.getExtraExports().add("my");
208         transformer.execute(ctx);
209 
210         assertEquals(ctx.getExtraExports().indexOf("my"), ctx.getExtraExports().lastIndexOf("my"));
211         // the generated bean should be tracked.
212         assertTrue(ctx.beanExists("foo"));
213 
214         mockPluginArtifact.verify();
215     }
216 
217     @Test
218     public void testImportManifestGenerationOnInterfaces() throws Exception {
219         final ComponentSpringStage stage = new ComponentSpringStage();
220 
221         final File pluginJar = new PluginJarBuilder()
222                 .addFormattedJava("my.MyFooChild",
223                         "package my;",
224                         "public class MyFooChild extends com.atlassian.plugin.osgi.factory.transform.dummypackage2.DummyClass2 {",
225                         "}")
226                 .addFormattedJava("my2.MyFooInterface",
227                         "package my2;",
228                         "public interface MyFooInterface {}")
229                 .addFormattedResource("atlassian-plugin.xml",
230                         "<atlassian-plugin name='plugin1' key='first' pluginsVersion='2'>",
231                         "    <plugin-info>",
232                         "        <version>1.0</version>",
233                         "    </plugin-info>",
234                         "    <component key='component1' class='my.MyFooChild' public='true'>",
235                         "       <interface>com.atlassian.plugin.osgi.factory.transform.dummypackage0.DummyInterface0</interface>",
236                         "       <interface>com.atlassian.plugin.osgi.factory.transform.dummypackage1.DummyInterface1</interface>",
237                         "       <interface>my2.MyFooInterface</interface>",
238                         "    </component>",
239                         "</atlassian-plugin>")
240                 .build();
241 
242         ServiceReference serviceReference = mock(ServiceReference.class);
243         when(serviceReference.getProperty(Constants.OBJECTCLASS)).thenReturn(new String[]{"my.Service"});
244 
245         OsgiContainerManager osgiContainerManager = mock(OsgiContainerManager.class);
246         when(osgiContainerManager.getRegisteredServices()).thenReturn(new ServiceReference[]{serviceReference});
247 
248         final TransformContext context = new TransformContext(null, SystemExports.NONE, new JarPluginArtifact(pluginJar), null, PluginAccessor.Descriptor.FILENAME, osgiContainerManager);
249         stage.execute(context);
250 
251         // don't import local interface.
252         assertFalse(context.getExtraImports().contains("my2.MyFooInterface"));
253 
254         // import only interfaces that don't exist in the plugin itself.
255         assertTrue(context.getExtraImports().contains("com.atlassian.plugin.osgi.factory.transform.dummypackage1"));
256         assertTrue(context.getExtraImports().contains("com.atlassian.plugin.osgi.factory.transform.dummypackage0"));
257     }
258 }