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
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();
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 }