View Javadoc

1   package com.atlassian.plugin.loaders;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Iterator;
6   import java.util.List;
7   
8   import junit.framework.TestCase;
9   
10  import com.atlassian.plugin.DefaultModuleDescriptorFactory;
11  import com.atlassian.plugin.ModuleDescriptor;
12  import com.atlassian.plugin.Plugin;
13  import com.atlassian.plugin.PluginParseException;
14  import com.atlassian.plugin.StateAware;
15  import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
16  import com.atlassian.plugin.elements.ResourceLocation;
17  import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
18  import com.atlassian.plugin.impl.UnloadablePlugin;
19  import com.atlassian.plugin.mock.MockAnimalModuleDescriptor;
20  import com.atlassian.plugin.mock.MockBear;
21  import com.atlassian.plugin.mock.MockGold;
22  import com.atlassian.plugin.mock.MockMineral;
23  import com.atlassian.plugin.mock.MockMineralModuleDescriptor;
24  import com.atlassian.plugin.mock.MockVegetableModuleDescriptor;
25  import com.atlassian.plugin.util.ClassLoaderUtils;
26  import com.google.common.collect.Iterables;
27  
28  public class TestSinglePluginLoader extends TestCase
29  {
30      public void testSinglePluginLoader() throws Exception
31      {
32          final SinglePluginLoader loader = new SinglePluginLoader("test-system-plugin.xml");
33          final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
34          moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
35          moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
36          final Collection plugins = loader.loadAllPlugins(moduleDescriptorFactory);
37  
38          assertEquals(1, plugins.size());
39  
40          // test the plugin information
41          final Plugin plugin = (Plugin) plugins.iterator().next();
42          assertTrue(plugin.isSystemPlugin());
43      }
44  
45      public void testRejectOsgiPlugin() throws Exception
46      {
47          final SinglePluginLoader loader = new SinglePluginLoader("test-osgi-plugin.xml");
48          final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
49          final Collection<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
50  
51          assertEquals(1, plugins.size());
52  
53          // test the plugin information
54          final Plugin plugin = plugins.iterator().next();
55          assertTrue(plugin instanceof UnloadablePlugin);
56          assertEquals("test.atlassian.plugin", plugin.getKey());
57      }
58  
59      public void testAtlassianPlugin() throws Exception
60      {
61          final SinglePluginLoader loader = new SinglePluginLoader("test-atlassian-plugin.xml");
62          final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
63          moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
64          moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
65          moduleDescriptorFactory.addModuleDescriptor("vegetable", MockVegetableModuleDescriptor.class);
66          final Collection plugins = loader.loadAllPlugins(moduleDescriptorFactory);
67  
68          assertEquals(1, plugins.size());
69  
70          // test the plugin information
71          final Plugin plugin = (Plugin) plugins.iterator().next();
72          enableModules(plugin);
73          assertEquals("Test Plugin", plugin.getName());
74          assertEquals("test.atlassian.plugin", plugin.getKey());
75          assertNotNull(plugin.getPluginInformation());
76          assertEquals("1.0", plugin.getPluginInformation().getVersion());
77          assertEquals("test.atlassian.plugin.i18n", plugin.getI18nNameKey());
78          assertEquals("test.atlassian.plugin.desc.i18n", plugin.getPluginInformation().getDescriptionKey());
79          assertEquals("This plugin descriptor is just used for test purposes!", plugin.getPluginInformation().getDescription());
80          assertEquals("Atlassian Software Systems Pty Ltd", plugin.getPluginInformation().getVendorName());
81          assertEquals("http://www.atlassian.com", plugin.getPluginInformation().getVendorUrl());
82          assertEquals(3f, plugin.getPluginInformation().getMinVersion(), 0);
83          assertEquals(3.1f, plugin.getPluginInformation().getMaxVersion(), 0);
84          assertEquals(4, plugin.getModuleDescriptors().size());
85  
86          final ModuleDescriptor bearDescriptor = plugin.getModuleDescriptor("bear");
87          assertEquals("test.atlassian.plugin:bear", bearDescriptor.getCompleteKey());
88          assertEquals("bear", bearDescriptor.getKey());
89          assertEquals("Bear Animal", bearDescriptor.getName());
90          assertEquals(MockBear.class, bearDescriptor.getModuleClass());
91          assertEquals("A plugin module to describe a bear", bearDescriptor.getDescription());
92          assertTrue(bearDescriptor.isEnabledByDefault());
93          assertEquals("test.atlassian.module.bear.name", bearDescriptor.getI18nNameKey());
94          assertEquals("test.atlassian.module.bear.description", bearDescriptor.getDescriptionKey());
95  
96          final Iterable resources = bearDescriptor.getResourceDescriptors();
97          assertEquals(3, Iterables.size(resources));
98  
99          assertEquals("20", bearDescriptor.getParams().get("height"));
100         assertEquals("brown", bearDescriptor.getParams().get("colour"));
101 
102         final List goldDescriptors = plugin.getModuleDescriptorsByModuleClass(MockGold.class);
103         assertEquals(1, goldDescriptors.size());
104         final ModuleDescriptor goldDescriptor = (ModuleDescriptor) goldDescriptors.get(0);
105         assertEquals("test.atlassian.plugin:gold", goldDescriptor.getCompleteKey());
106         assertEquals(new MockGold(20), goldDescriptor.getModule());
107         assertEquals(goldDescriptors, plugin.getModuleDescriptorsByModuleClass(MockMineral.class));
108 
109         assertEquals(1, Iterables.size(plugin.getResourceDescriptors()));
110         final ResourceLocation pluginResource = plugin.getResourceLocation("download", "icon.gif");
111         assertEquals("/icon.gif", pluginResource.getLocation());
112     }
113 
114     public void testDisabledPlugin() throws PluginParseException
115     {
116         final SinglePluginLoader loader = new SinglePluginLoader("test-disabled-plugin.xml");
117         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
118         moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
119         final Collection plugins = loader.loadAllPlugins(moduleDescriptorFactory);
120         assertEquals(1, plugins.size());
121         final Plugin plugin = (Plugin) plugins.iterator().next();
122         assertFalse(plugin.isEnabledByDefault());
123 
124         assertEquals(1, plugin.getModuleDescriptors().size());
125         final ModuleDescriptor module = plugin.getModuleDescriptor("gold");
126         assertFalse(module.isEnabledByDefault());
127     }
128 
129     public void testPluginByUrl() throws PluginParseException
130     {
131         final SinglePluginLoader loader = new SinglePluginLoader(ClassLoaderUtils.getResource("test-disabled-plugin.xml", SinglePluginLoader.class));
132         // URL created should be reentrant and create a different stream each
133         // time
134         assertNotSame(loader.getSource(), loader.getSource());
135         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
136         moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
137         moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
138         final Collection<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
139         assertEquals(1, plugins.size());
140         assertFalse((plugins.iterator().next()).isEnabledByDefault());
141     }
142 
143     /**
144      * @deprecated testing deprecated behaviour
145      */
146     @Deprecated
147     public void testPluginByInputStream() throws PluginParseException
148     {
149         final SinglePluginLoader loader = new SinglePluginLoader(ClassLoaderUtils.getResourceAsStream("test-disabled-plugin.xml", SinglePluginLoader.class));
150         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
151         moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
152         moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
153         final Collection<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
154         assertEquals(1, plugins.size());
155         assertFalse((plugins.iterator().next()).isEnabledByDefault());
156     }
157 
158     /**
159      * @deprecated testing deprecated behaviour
160      */
161     @Deprecated
162     public void testPluginByInputStreamNotReentrant() throws PluginParseException
163     {
164         final SinglePluginLoader loader = new SinglePluginLoader(ClassLoaderUtils.getResourceAsStream("test-disabled-plugin.xml", SinglePluginLoader.class));
165         loader.getSource();
166         try
167         {
168             loader.getSource();
169             fail("IllegalStateException expected");
170         }
171         catch (final IllegalStateException expected)
172         {}
173     }
174 
175     public void testPluginsInOrder() throws PluginParseException
176     {
177         final SinglePluginLoader loader = new SinglePluginLoader(ClassLoaderUtils.getResource("test-ordered-pluginmodules.xml", SinglePluginLoader.class));
178         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
179         moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
180         final Collection plugins = loader.loadAllPlugins(moduleDescriptorFactory);
181         final Plugin plugin = (Plugin) plugins.iterator().next();
182         final Collection modules = plugin.getModuleDescriptors();
183         assertEquals(3, modules.size());
184         final Iterator iterator = modules.iterator();
185         assertEquals("yogi1", ((MockAnimalModuleDescriptor) iterator.next()).getKey());
186         assertEquals("yogi2", ((MockAnimalModuleDescriptor) iterator.next()).getKey());
187         assertEquals("yogi3", ((MockAnimalModuleDescriptor) iterator.next()).getKey());
188     }
189 
190     public void testUnknownPluginModule() throws PluginParseException
191     {
192         final SinglePluginLoader loader = new SinglePluginLoader("test-bad-plugin.xml");
193         final Collection plugins = loader.loadAllPlugins(new DefaultModuleDescriptorFactory(new DefaultHostContainer()));
194         final List pluginsList = new ArrayList(plugins);
195 
196         assertEquals(1, pluginsList.size());
197 
198         final Plugin plugin = (Plugin) plugins.iterator().next();
199         final List moduleList = new ArrayList(plugin.getModuleDescriptors());
200 
201         // The module that had the problem should be an
202         // UnrecognisedModuleDescriptor
203         assertEquals(UnrecognisedModuleDescriptor.class, moduleList.get(0).getClass());
204     }
205 
206     // PLUG-5
207     public void testPluginWithOnlyPermittedModules() throws PluginParseException
208     {
209         final SinglePluginLoader loader = new SinglePluginLoader("test-atlassian-plugin.xml");
210 
211         // Define the module descriptor factory
212         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
213         moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
214         moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
215 
216         // Exclude mineral
217         final List permittedList = new ArrayList();
218         permittedList.add("animal");
219         moduleDescriptorFactory.setPermittedModuleKeys(permittedList);
220 
221         final Collection plugins = loader.loadAllPlugins(moduleDescriptorFactory);
222 
223         // 1 plugin returned
224         assertEquals(1, plugins.size());
225 
226         final Plugin plugin = (Plugin) plugins.iterator().next();
227 
228         // Only one descriptor, animal
229         assertEquals(1, plugin.getModuleDescriptors().size());
230         assertNotNull(plugin.getModuleDescriptor("bear"));
231         assertNull(plugin.getModuleDescriptor("gold"));
232     }
233 
234     // PLUG-5
235     public void testPluginWithOnlyPermittedModulesAndMissingModuleDescriptor() throws PluginParseException
236     {
237         final SinglePluginLoader loader = new SinglePluginLoader("test-atlassian-plugin.xml");
238 
239         // Define the module descriptor factory
240         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
241         moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
242 
243         // Exclude mineral
244         final List permittedList = new ArrayList();
245         permittedList.add("animal");
246         moduleDescriptorFactory.setPermittedModuleKeys(permittedList);
247 
248         final Collection plugins = loader.loadAllPlugins(moduleDescriptorFactory);
249 
250         // 1 plugin returned
251         assertEquals(1, plugins.size());
252 
253         final Plugin plugin = (Plugin) plugins.iterator().next();
254 
255         // Only one descriptor, animal
256         assertEquals(1, plugin.getModuleDescriptors().size());
257         assertNotNull(plugin.getModuleDescriptor("bear"));
258         assertNull(plugin.getModuleDescriptor("gold"));
259     }
260 
261     public void testBadPluginKey() throws PluginParseException
262     {
263         final SinglePluginLoader loader = new SinglePluginLoader("test-bad-plugin-key-plugin.xml");
264         final Collection<Plugin> plugins = loader.loadAllPlugins(null);
265         assertEquals(1, plugins.size());
266         final Plugin plugin = plugins.iterator().next();
267         assertTrue(plugin instanceof UnloadablePlugin);
268         assertEquals("test-bad-plugin-key-plugin.xml", plugin.getKey());
269         assertTrue(((UnloadablePlugin) plugin).getErrorText().endsWith("Plugin keys cannot contain ':'. Key is 'test:bad'"));
270     }
271 
272     public void testNonUniqueKeysWithinAPlugin() throws PluginParseException
273     {
274         final SinglePluginLoader loader = new SinglePluginLoader("test-bad-non-unique-keys-plugin.xml");
275         final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
276         moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
277         moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
278 
279         final List<Plugin> plugins = new ArrayList<Plugin>(loader.loadAllPlugins(moduleDescriptorFactory));
280         assertEquals(1, plugins.size());
281         final Plugin plugin = plugins.get(0);
282         assertTrue(plugin instanceof UnloadablePlugin);
283         assertTrue(((UnloadablePlugin) plugin).getErrorText().endsWith("Found duplicate key 'bear' within plugin 'test.bad.plugin'"));
284     }
285 
286     public void testBadResource()
287     {
288         final List<Plugin> plugins = new ArrayList<Plugin>(new SinglePluginLoader("foo").loadAllPlugins(null));
289         assertEquals(1, plugins.size());
290         assertTrue(plugins.get(0) instanceof UnloadablePlugin);
291         assertEquals("foo", plugins.get(0).getKey());
292     }
293 
294     public void enableModules(final Plugin plugin)
295     {
296         for (final ModuleDescriptor descriptor : plugin.getModuleDescriptors())
297         {
298             if (descriptor instanceof StateAware)
299             {
300                 ((StateAware) descriptor).enabled();
301             }
302         }
303     }
304 }