View Javadoc

1   package com.atlassian.plugin.osgi;
2   
3   import com.atlassian.plugin.DefaultModuleDescriptorFactory;
4   import com.atlassian.plugin.ModuleDescriptorFactory;
5   import com.atlassian.plugin.PluginAccessor;
6   import com.atlassian.plugin.event.PluginEventManager;
7   import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
8   import com.atlassian.plugin.factories.LegacyDynamicPluginFactory;
9   import com.atlassian.plugin.factories.PluginFactory;
10  import com.atlassian.plugin.hostcontainer.SimpleConstructorHostContainer;
11  import com.atlassian.plugin.loaders.BundledPluginLoader;
12  import com.atlassian.plugin.loaders.DirectoryPluginLoader;
13  import com.atlassian.plugin.loaders.PluginLoader;
14  import com.atlassian.plugin.manager.DefaultPluginManager;
15  import com.atlassian.plugin.manager.store.MemoryPluginPersistentStateStore;
16  import com.atlassian.plugin.module.ClassPrefixModuleFactory;
17  import com.atlassian.plugin.module.ModuleFactory;
18  import com.atlassian.plugin.module.PrefixDelegatingModuleFactory;
19  import com.atlassian.plugin.module.PrefixModuleFactory;
20  import com.atlassian.plugin.osgi.container.OsgiContainerManager;
21  import com.atlassian.plugin.osgi.container.OsgiPersistentCache;
22  import com.atlassian.plugin.osgi.container.PackageScannerConfiguration;
23  import com.atlassian.plugin.osgi.container.felix.FelixOsgiContainerManager;
24  import com.atlassian.plugin.osgi.container.impl.DefaultOsgiPersistentCache;
25  import com.atlassian.plugin.osgi.container.impl.DefaultPackageScannerConfiguration;
26  import com.atlassian.plugin.osgi.factory.OsgiBundleFactory;
27  import com.atlassian.plugin.osgi.factory.OsgiPluginFactory;
28  import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
29  import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
30  import com.atlassian.plugin.osgi.hostcomponents.InstanceBuilder;
31  import com.atlassian.plugin.osgi.module.BeanPrefixModuleFactory;
32  import com.atlassian.plugin.repositories.FilePluginInstaller;
33  import com.atlassian.plugin.test.PluginTestUtils;
34  
35  import com.google.common.collect.ImmutableSet;
36  import junit.framework.TestCase;
37  import org.apache.commons.io.FileUtils;
38  import org.apache.commons.io.IOUtils;
39  
40  import java.io.File;
41  import java.io.FileInputStream;
42  import java.io.FileOutputStream;
43  import java.io.IOException;
44  import java.io.InputStream;
45  import java.util.Arrays;
46  import java.util.HashMap;
47  import java.util.Map;
48  import java.util.zip.ZipEntry;
49  import java.util.zip.ZipOutputStream;
50  
51  /**
52   * Base for in-container unit tests
53   */
54  public abstract class PluginInContainerTestBase extends TestCase
55  {
56      protected FelixOsgiContainerManager osgiContainerManager;
57      protected File tmpDir;
58      protected File cacheDir;
59      protected File pluginsDir;
60      protected ModuleDescriptorFactory moduleDescriptorFactory;
61      protected DefaultPluginManager pluginManager;
62      protected PluginEventManager pluginEventManager;
63      protected ModuleFactory moduleFactory;
64      protected SimpleConstructorHostContainer hostContainer;
65  
66      @Override
67      public void setUp() throws Exception
68      {
69          tmpDir = PluginTestUtils.createTempDirectory(PluginInContainerTestBase.class);
70          cacheDir = new File(tmpDir, "cache");
71          cacheDir.mkdir();
72          pluginsDir = new File(tmpDir, "plugins");
73          pluginsDir.mkdir();
74          this.pluginEventManager = new DefaultPluginEventManager();
75          moduleFactory = new PrefixDelegatingModuleFactory(ImmutableSet.<PrefixModuleFactory>of(
76              new ClassPrefixModuleFactory(hostContainer),
77              new BeanPrefixModuleFactory()));
78          hostContainer = createHostContainer(new HashMap<Class<?>, Object>());
79      }
80  
81      protected SimpleConstructorHostContainer createHostContainer(Map<Class<?>, Object> originalContext)
82      {
83          Map<Class<?>, Object> context = new HashMap<Class<?>, Object>(originalContext);
84          context.put(ModuleFactory.class, moduleFactory);
85          return new SimpleConstructorHostContainer(context);
86      }
87  
88      @Override
89      public void tearDown() throws Exception
90      {
91          if (osgiContainerManager != null)
92          {
93              osgiContainerManager.stop();
94              osgiContainerManager.clearExportCache(); // prevent export cache from being reused across tests
95          }
96          FileUtils.deleteDirectory(tmpDir);
97          osgiContainerManager = null;
98          tmpDir = null;
99          pluginsDir = null;
100         moduleDescriptorFactory = null;
101         pluginManager = null;
102         pluginEventManager = null;
103         moduleFactory = null;
104         hostContainer = null;
105     }
106 
107     protected void initPluginManager() throws Exception
108     {
109         initPluginManager(null, new DefaultModuleDescriptorFactory(hostContainer));
110     }
111 
112     protected void initPluginManager(final HostComponentProvider hostComponentProvider) throws Exception
113     {
114         initPluginManager(hostComponentProvider, new DefaultModuleDescriptorFactory(hostContainer));
115     }
116 
117     protected void initPluginManager(final HostComponentProvider hostComponentProvider, final ModuleDescriptorFactory moduleDescriptorFactory, final String version)
118             throws Exception
119     {
120         final PackageScannerConfiguration scannerConfig = buildScannerConfiguration(version);
121         HostComponentProvider requiredWrappingProvider = getWrappingHostComponentProvider(hostComponentProvider);
122         OsgiPersistentCache cache = new DefaultOsgiPersistentCache(cacheDir);
123         osgiContainerManager = new FelixOsgiContainerManager(cache, scannerConfig, requiredWrappingProvider, pluginEventManager);
124 
125         final LegacyDynamicPluginFactory legacyFactory = new LegacyDynamicPluginFactory(PluginAccessor.Descriptor.FILENAME, tmpDir);
126         final OsgiPluginFactory osgiPluginDeployer = new OsgiPluginFactory(PluginAccessor.Descriptor.FILENAME, (String) null, cache, osgiContainerManager, pluginEventManager);
127         final OsgiBundleFactory osgiBundleFactory = new OsgiBundleFactory(osgiContainerManager, pluginEventManager);
128 
129         final DirectoryPluginLoader loader = new DirectoryPluginLoader(pluginsDir, Arrays.asList(legacyFactory, osgiPluginDeployer, osgiBundleFactory),
130                 new DefaultPluginEventManager());
131         initPluginManager(moduleDescriptorFactory, loader);
132     }
133 
134     protected void initPluginManager(final HostComponentProvider hostComponentProvider, final ModuleDescriptorFactory moduleDescriptorFactory)
135             throws Exception
136     {
137         initPluginManager(hostComponentProvider, moduleDescriptorFactory, (String) null);
138     }
139 
140     protected void initPluginManager(final ModuleDescriptorFactory moduleDescriptorFactory, PluginLoader loader)
141             throws Exception
142     {
143         this.moduleDescriptorFactory = moduleDescriptorFactory;
144         pluginManager = new DefaultPluginManager(new MemoryPluginPersistentStateStore(), Arrays.<PluginLoader>asList(loader), moduleDescriptorFactory,
145                 pluginEventManager);
146         pluginManager.setPluginInstaller(new FilePluginInstaller(pluginsDir));
147         pluginManager.init();
148     }
149 
150     protected void initBundlingPluginManager(final ModuleDescriptorFactory moduleDescriptorFactory, File... bundledPluginJars) throws Exception
151     {
152         this.moduleDescriptorFactory = moduleDescriptorFactory;
153         final PackageScannerConfiguration scannerConfig = buildScannerConfiguration("1.0");
154         HostComponentProvider requiredWrappingProvider = getWrappingHostComponentProvider(null);
155         OsgiPersistentCache cache = new DefaultOsgiPersistentCache(cacheDir);
156         osgiContainerManager = new FelixOsgiContainerManager(cache, scannerConfig, requiredWrappingProvider, pluginEventManager);
157 
158         final OsgiPluginFactory osgiPluginDeployer = new OsgiPluginFactory(PluginAccessor.Descriptor.FILENAME, (String) null, cache, osgiContainerManager, pluginEventManager);
159 
160         final DirectoryPluginLoader loader = new DirectoryPluginLoader(pluginsDir, Arrays.<PluginFactory>asList(osgiPluginDeployer),
161             new DefaultPluginEventManager());
162 
163         File zip = new File(bundledPluginJars[0].getParentFile(), "bundled-plugins.zip");
164         for (File bundledPluginJar : bundledPluginJars)
165         {
166             ZipOutputStream stream = null;
167             InputStream in = null;
168             try
169             {
170                 stream = new ZipOutputStream(new FileOutputStream(zip));
171                 in = new FileInputStream(bundledPluginJar);
172                 stream.putNextEntry(new ZipEntry(bundledPluginJar.getName()));
173                 IOUtils.copy(in, stream);
174                 stream.closeEntry();
175             }
176             catch (IOException ex)
177             {
178                 IOUtils.closeQuietly(in);
179                 IOUtils.closeQuietly(stream);
180             }
181         }
182         File bundledDir = new File(bundledPluginJars[0].getParentFile(), "bundled-plugins");
183         final BundledPluginLoader bundledLoader = new BundledPluginLoader(zip.toURL(), bundledDir, Arrays.<PluginFactory>asList(osgiPluginDeployer),
184             new DefaultPluginEventManager());
185 
186         pluginManager = new DefaultPluginManager(new MemoryPluginPersistentStateStore(), Arrays.<PluginLoader> asList(bundledLoader, loader), moduleDescriptorFactory,
187             pluginEventManager);
188         pluginManager.setPluginInstaller(new FilePluginInstaller(pluginsDir));
189         pluginManager.init();
190     }
191 
192     private HostComponentProvider getWrappingHostComponentProvider(final HostComponentProvider hostComponentProvider)
193     {
194         HostComponentProvider requiredWrappingProvider = new HostComponentProvider()
195         {
196             public void provide(final ComponentRegistrar registrar)
197             {
198 
199                 if (hostComponentProvider != null)
200                 {
201                     hostComponentProvider.provide(new ComponentRegistrar()
202                     {
203                         public InstanceBuilder register(Class<?>... mainInterfaces)
204                         {
205                             if (!Arrays.asList(mainInterfaces).contains(PluginEventManager.class))
206                             {
207                                 return registrar.register(mainInterfaces);
208                             }
209                             return null;
210                         }
211                     });
212                 }
213                 registrar.register(ModuleFactory.class).forInstance(moduleFactory);
214                 registrar.register(PluginEventManager.class).forInstance(pluginEventManager);
215                 registrar.register(PluginAccessor.class).forInstance(pluginManager);
216             }
217         };
218         return requiredWrappingProvider;
219     }
220 
221     private PackageScannerConfiguration buildScannerConfiguration(String version)
222     {
223         final PackageScannerConfiguration scannerConfig = new DefaultPackageScannerConfiguration(version);
224         scannerConfig.getPackageIncludes().add("com.atlassian.plugin*");
225         scannerConfig.getPackageIncludes().add("javax.servlet*");
226         scannerConfig.getPackageIncludes().add("com_cenqua_clover");
227         scannerConfig.getPackageExcludes().add("com.atlassian.plugin.osgi.bridge*");
228         scannerConfig.getPackageExcludes().add("com.atlassian.plugin.osgi.bridge.external");
229         scannerConfig.getPackageExcludes().add("com.atlassian.plugin.osgi.spring.external");
230         scannerConfig.getPackageVersions().put("org.apache.commons.logging", "1.1.1");
231         return scannerConfig;
232     }
233 }