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