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 Iterable plugins = loader.loadAllPlugins(moduleDescriptorFactory);
37
38 assertEquals(1, Iterables.size(plugins));
39
40
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 Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
50
51 assertEquals(1, Iterables.size(plugins));
52
53
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 Iterable plugins = loader.loadAllPlugins(moduleDescriptorFactory);
67
68 assertEquals(1, Iterables.size(plugins));
69
70
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 Iterable plugins = loader.loadAllPlugins(moduleDescriptorFactory);
120 assertEquals(1, Iterables.size(plugins));
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
133
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 Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
139 assertEquals(1, Iterables.size(plugins));
140 assertFalse((plugins.iterator().next()).isEnabledByDefault());
141 }
142
143
144
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 Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
154 assertEquals(1, Iterables.size(plugins));
155 assertFalse((plugins.iterator().next()).isEnabledByDefault());
156 }
157
158
159
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 Iterable 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 Iterable plugins = loader.loadAllPlugins(new DefaultModuleDescriptorFactory(new DefaultHostContainer()));
194
195 assertEquals(1, Iterables.size(plugins));
196
197 final Plugin plugin = (Plugin) plugins.iterator().next();
198 final List moduleList = new ArrayList(plugin.getModuleDescriptors());
199
200
201
202 assertEquals(UnrecognisedModuleDescriptor.class, moduleList.get(0).getClass());
203 }
204
205
206 public void testPluginWithOnlyPermittedModules() throws PluginParseException
207 {
208 final SinglePluginLoader loader = new SinglePluginLoader("test-atlassian-plugin.xml");
209
210
211 final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
212 moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
213 moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
214
215
216 final List permittedList = new ArrayList();
217 permittedList.add("animal");
218 moduleDescriptorFactory.setPermittedModuleKeys(permittedList);
219
220 final Iterable plugins = loader.loadAllPlugins(moduleDescriptorFactory);
221
222
223 assertEquals(1, Iterables.size(plugins));
224
225 final Plugin plugin = (Plugin) plugins.iterator().next();
226
227
228 assertEquals(1, plugin.getModuleDescriptors().size());
229 assertNotNull(plugin.getModuleDescriptor("bear"));
230 assertNull(plugin.getModuleDescriptor("gold"));
231 }
232
233
234 public void testPluginWithOnlyPermittedModulesAndMissingModuleDescriptor() throws PluginParseException
235 {
236 final SinglePluginLoader loader = new SinglePluginLoader("test-atlassian-plugin.xml");
237
238
239 final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
240 moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
241
242
243 final List permittedList = new ArrayList();
244 permittedList.add("animal");
245 moduleDescriptorFactory.setPermittedModuleKeys(permittedList);
246
247 final Iterable plugins = loader.loadAllPlugins(moduleDescriptorFactory);
248
249
250 assertEquals(1, Iterables.size(plugins));
251
252 final Plugin plugin = (Plugin) plugins.iterator().next();
253
254
255 assertEquals(1, plugin.getModuleDescriptors().size());
256 assertNotNull(plugin.getModuleDescriptor("bear"));
257 assertNull(plugin.getModuleDescriptor("gold"));
258 }
259
260 public void testBadPluginKey() throws PluginParseException
261 {
262 final SinglePluginLoader loader = new SinglePluginLoader("test-bad-plugin-key-plugin.xml");
263 final Iterable<Plugin> plugins = loader.loadAllPlugins(null);
264 assertEquals(1, Iterables.size(plugins));
265 final Plugin plugin = plugins.iterator().next();
266 assertTrue(plugin instanceof UnloadablePlugin);
267 assertEquals("test-bad-plugin-key-plugin.xml", plugin.getKey());
268 assertTrue(((UnloadablePlugin) plugin).getErrorText().endsWith("Plugin keys cannot contain ':'. Key is 'test:bad'"));
269 }
270
271 public void testNonUniqueKeysWithinAPlugin() throws PluginParseException
272 {
273 final SinglePluginLoader loader = new SinglePluginLoader("test-bad-non-unique-keys-plugin.xml");
274 final DefaultModuleDescriptorFactory moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
275 moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
276 moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
277
278 final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
279 assertEquals(1, Iterables.size(plugins));
280 final Plugin plugin = Iterables.get(plugins, 0);
281 assertTrue(plugin instanceof UnloadablePlugin);
282 assertTrue(((UnloadablePlugin) plugin).getErrorText().endsWith("Found duplicate key 'bear' within plugin 'test.bad.plugin'"));
283 }
284
285 public void testBadResource()
286 {
287 final Iterable<Plugin> plugins = new SinglePluginLoader("foo").loadAllPlugins(null);
288 assertEquals(1, Iterables.size(plugins));
289 assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
290 assertEquals("foo", Iterables.get(plugins, 0).getKey());
291 }
292
293 public void enableModules(final Plugin plugin)
294 {
295 for (final ModuleDescriptor descriptor : plugin.getModuleDescriptors())
296 {
297 if (descriptor instanceof StateAware)
298 {
299 ((StateAware) descriptor).enabled();
300 }
301 }
302 }
303 }