View Javadoc

1   /*
2    * Created by IntelliJ IDEA.
3    * User: Mike
4    * Date: Jul 29, 2004
5    * Time: 4:28:18 PM
6    */
7   package com.atlassian.plugin.descriptors;
8   
9   import java.util.List;
10  
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.elements.ResourceDescriptor;
16  import com.atlassian.plugin.impl.StaticPlugin;
17  import com.atlassian.plugin.mock.MockAnimal;
18  import com.atlassian.plugin.mock.MockAnimalModuleDescriptor;
19  import com.atlassian.plugin.mock.MockMineral;
20  import com.atlassian.plugin.module.ModuleFactory;
21  import com.atlassian.plugin.util.ClassLoaderUtils;
22  
23  import org.dom4j.DocumentException;
24  import org.dom4j.DocumentHelper;
25  import org.dom4j.Element;
26  
27  import junit.framework.TestCase;
28  
29  import static org.mockito.Mockito.mock;
30  import static org.mockito.Mockito.never;
31  import static org.mockito.Mockito.spy;
32  import static org.mockito.Mockito.verify;
33  
34  public class TestAbstractModuleDescriptor extends TestCase
35  {
36      public void testAssertModuleClassImplements() throws DocumentException, PluginParseException
37      {
38          ModuleDescriptor descriptor = new AbstractModuleDescriptor(ModuleFactory.LEGACY_MODULE_FACTORY) {
39              public void init(Plugin plugin, Element element) throws PluginParseException
40              {
41                  super.init(plugin, element);
42                  enabled();
43                  assertModuleClassImplements(MockMineral.class);
44              }
45  
46              public Object getModule()
47              {
48                  return null;
49              }
50          };
51  
52          try
53          {
54              descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockBear\" />").getRootElement());
55              ((StateAware)descriptor).enabled();
56              fail("Should have blown up.");
57          }
58          catch (PluginParseException e)
59          {
60              assertEquals("Given module class: com.atlassian.plugin.mock.MockBear does not implement com.atlassian.plugin.mock.MockMineral", e.getMessage());
61          }
62  
63          // now succeed
64          descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockGold\" />").getRootElement());
65      }
66  
67      public void testLoadClassFromNewModuleFactory()
68      {
69          ModuleFactory moduleFactory = mock(ModuleFactory.class);
70          AbstractModuleDescriptor moduleDescriptor = new StringModuleDescriptor(moduleFactory, "foo");
71          Plugin plugin = mock(Plugin.class);
72          moduleDescriptor.loadClass(plugin, "foo");
73          assertEquals(String.class, moduleDescriptor.getModuleClass());
74      }
75  
76      public void testLoadClassFromNewModuleFactoryWithExtendsNumberType()
77      {
78          ModuleFactory moduleFactory = mock(ModuleFactory.class);
79          AbstractModuleDescriptor moduleDescriptor = new ExtendsNumberModuleDescriptor(moduleFactory, "foo");
80          Plugin plugin = mock(Plugin.class);
81  
82          try
83          {
84              moduleDescriptor.loadClass(plugin, "foo");
85              fail("Should have complained about extends type");
86          }
87          catch (IllegalStateException ex)
88          {
89              // success
90          }
91      }
92  
93      public void testLoadClassFromNewModuleFactoryWithExtendsNothingType()
94      {
95          ModuleFactory moduleFactory = mock(ModuleFactory.class);
96          AbstractModuleDescriptor moduleDescriptor = new ExtendsNothingModuleDescriptor(moduleFactory, "foo");
97          Plugin plugin = mock(Plugin.class);
98  
99          try
100         {
101             moduleDescriptor.loadClass(plugin, "foo");
102             fail("Should have complained about extends type");
103         }
104         catch (IllegalStateException ex)
105         {
106             // success
107         }
108     }
109 
110     public void testGetModuleReturnClass()
111     {
112         AbstractModuleDescriptor desc = new MockAnimalModuleDescriptor();
113         assertEquals(MockAnimal.class, desc.getModuleReturnClass());
114     }
115 
116     public void testGetModuleReturnClassWithExtendsNumber()
117     {
118         ModuleFactory moduleFactory = mock(ModuleFactory.class);
119         AbstractModuleDescriptor moduleDescriptor = new ExtendsNothingModuleDescriptor(moduleFactory, "foo");
120         assertEquals(Object.class, moduleDescriptor.getModuleReturnClass());
121     }
122 
123     public void testLoadClassFromNewModuleFactoryButUnknownType()
124     {
125         ModuleFactory moduleFactory = mock(ModuleFactory.class);
126         AbstractModuleDescriptor moduleDescriptor = new AbstractModuleDescriptor(moduleFactory)
127         {
128             public AbstractModuleDescriptor init()
129             {
130                 moduleClassName = "foo";
131                 return this;
132             }
133 
134             @Override
135             public Object getModule()
136             {
137                 return null;
138             }
139         }.init();
140         try
141         {
142             Plugin plugin = mock(Plugin.class);
143             moduleDescriptor.loadClass(plugin, "foo");
144             fail("Should have complained about unknown type");
145         }
146         catch (IllegalStateException ex)
147         {
148             // success
149         }
150     }
151 
152     public void testSingletonness() throws DocumentException, PluginParseException
153     {
154         ModuleDescriptor descriptor = makeSingletonDescriptor();
155 
156         // try a default descriptor with no singleton="" element. Should _be_ a singleton
157         descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockBear\" />").getRootElement());
158         ((StateAware)descriptor).enabled();
159         Object module = descriptor.getModule();
160         assertTrue(module == descriptor.getModule());
161 
162         // now try a default descriptor with singleton="true" element. Should still be a singleton
163         descriptor = makeSingletonDescriptor();
164         descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockBear\" singleton=\"true\" />").getRootElement());
165         ((StateAware)descriptor).enabled();
166         module = descriptor.getModule();
167         assertTrue(module == descriptor.getModule());
168 
169         // now try reiniting as a non-singleton
170         descriptor = makeSingletonDescriptor();
171         descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockBear\" singleton=\"false\" />").getRootElement());
172         ((StateAware)descriptor).enabled();
173         module = descriptor.getModule();
174         assertTrue(module != descriptor.getModule());
175     }
176 
177     public void testGetResourceDescriptor() throws DocumentException, PluginParseException
178     {
179         ModuleDescriptor descriptor = makeSingletonDescriptor();
180         descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockBear\">" +
181                 "<resource type='velocity' name='view' location='foo' />" +
182                 "</animal>").getRootElement());
183 
184         assertNull(descriptor.getResourceLocation("foo", "bar"));
185         assertNull(descriptor.getResourceLocation("velocity", "bar"));
186         assertNull(descriptor.getResourceLocation("foo", "view"));
187         assertEquals(new ResourceDescriptor(DocumentHelper.parseText("<resource type='velocity' name='view' location='foo' />").getRootElement()).getResourceLocationForName("view").getLocation(), descriptor.getResourceLocation("velocity", "view").getLocation());
188     }
189 
190     public void testGetResourceDescriptorByType() throws DocumentException, PluginParseException
191     {
192         ModuleDescriptor descriptor = makeSingletonDescriptor();
193         descriptor.init(new StaticPlugin(), DocumentHelper.parseText("<animal key=\"key\" name=\"bear\" class=\"com.atlassian.plugin.mock.MockBear\">" +
194                 "<resource type='velocity' name='view' location='foo' />" +
195                 "<resource type='velocity' name='input-params' location='bar' />" +
196                 "</animal>").getRootElement());
197 
198         final List resourceDescriptors = descriptor.getResourceDescriptors("velocity");
199         assertNotNull(resourceDescriptors);
200         assertEquals(2, resourceDescriptors.size());
201 
202         ResourceDescriptor resourceDescriptor = (ResourceDescriptor) resourceDescriptors.get(0);
203         assertEquals(new ResourceDescriptor(DocumentHelper.parseText("<resource type='velocity' name='view' location='foo' />").getRootElement()), resourceDescriptor);
204 
205         resourceDescriptor = (ResourceDescriptor) resourceDescriptors.get(1);
206         assertEquals(new ResourceDescriptor(DocumentHelper.parseText("<resource type='velocity' name='input-params' location='bar' />").getRootElement()), resourceDescriptor);
207     }
208 
209     public void testDestroy()
210     {
211         AbstractModuleDescriptor descriptor = spy(new StringModuleDescriptor(ModuleFactory.LEGACY_MODULE_FACTORY, null));
212         Plugin plugin = mock(Plugin.class);
213         descriptor.setPlugin(plugin);
214         // enable the module descriptor first; otherwise, disabled() won't be called from destroy()
215         descriptor.enabled();
216 
217         descriptor.destroy(plugin);
218 
219         verify(descriptor).disabled();
220         assertSame(plugin, descriptor.getPlugin());
221     }
222 
223     public void testDestroyWhenDisabled()
224     {
225         AbstractModuleDescriptor descriptor = spy(new StringModuleDescriptor(ModuleFactory.LEGACY_MODULE_FACTORY, null));
226         Plugin plugin = mock(Plugin.class);
227         descriptor.setPlugin(plugin);
228 
229         descriptor.destroy(plugin);
230 
231         // it's never enabled, so disabled() won't be called
232         verify(descriptor, never()).disabled();
233         assertSame(plugin, descriptor.getPlugin());
234     }
235 
236     private ModuleDescriptor makeSingletonDescriptor()
237     {
238         ModuleDescriptor descriptor = new AbstractModuleDescriptor(ModuleFactory.LEGACY_MODULE_FACTORY) {
239             Object module;
240 
241             public void init(Plugin plugin, Element element) throws PluginParseException
242             {
243                 super.init(plugin, element);
244             }
245 
246             public Object getModule()
247             {
248                 try
249                 {
250                     if (!isSingleton())
251                     {
252                         return ClassLoaderUtils.loadClass(getModuleClass().getName(), TestAbstractModuleDescriptor.class).newInstance();
253                     }
254                     else
255                     {
256                         if (module == null)
257                         {
258                             module = ClassLoaderUtils.loadClass(getModuleClass().getName(), TestAbstractModuleDescriptor.class).newInstance();
259                         }
260 
261                         return module;
262                     }
263                 }
264                 catch (Exception e)
265                 {
266                     throw new RuntimeException("What happened Dave?");
267                 }
268             }
269         };
270         return descriptor;
271     }
272 
273     private static class StringModuleDescriptor extends AbstractModuleDescriptor<String>
274     {
275         public StringModuleDescriptor(ModuleFactory moduleFactory, String className)
276         {
277             super(moduleFactory);
278             moduleClassName = className;
279         }
280 
281         @Override
282         public String getModule()
283         {
284             return null;
285         }
286 
287     }
288 
289     private static class ExtendsNumberModuleDescriptor<T extends Number> extends AbstractModuleDescriptor<T>
290     {
291         public ExtendsNumberModuleDescriptor(ModuleFactory moduleFactory, String className)
292         {
293             super(moduleFactory);
294             moduleClassName = className;
295         }
296 
297         @Override
298         public T getModule()
299         {
300             return null;
301         }
302     }
303 
304     private static class ExtendsNothingModuleDescriptor<T> extends AbstractModuleDescriptor<T>
305     {
306         public ExtendsNothingModuleDescriptor(ModuleFactory moduleFactory, String className)
307         {
308             super(moduleFactory);
309             moduleClassName = className;
310         }
311 
312         @Override
313         public T getModule()
314         {
315             return null;
316         }
317     }
318 }