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