PageRenderTime 58ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/refapp-core/src/main/java/com/atlassian/plugin/refimpl/ContainerManager.java

https://github.com/mrdon/REFAPP
Java | 335 lines | 278 code | 46 blank | 11 comment | 9 complexity | 1c979b0d29586a3a7889e60a44ae0a6b MD5 | raw file
  1. package com.atlassian.plugin.refimpl;
  2. import com.atlassian.event.api.EventPublisher;
  3. import com.atlassian.event.config.EventThreadPoolConfiguration;
  4. import com.atlassian.event.config.ListenerHandlersConfiguration;
  5. import com.atlassian.event.internal.AsynchronousAbleEventDispatcher;
  6. import com.atlassian.event.internal.EventExecutorFactoryImpl;
  7. import com.atlassian.event.internal.EventPublisherImpl;
  8. import com.atlassian.event.internal.EventThreadPoolConfigurationImpl;
  9. import com.atlassian.event.internal.ListenerHandlerConfigurationImpl;
  10. import com.atlassian.event.spi.EventDispatcher;
  11. import com.atlassian.event.spi.EventExecutorFactory;
  12. import com.atlassian.plugin.DefaultModuleDescriptorFactory;
  13. import com.atlassian.plugin.ModuleDescriptorFactory;
  14. import com.atlassian.plugin.PluginAccessor;
  15. import com.atlassian.plugin.PluginController;
  16. import com.atlassian.plugin.PluginParseException;
  17. import com.atlassian.plugin.event.PluginEventManager;
  18. import com.atlassian.plugin.hostcontainer.HostContainer;
  19. import com.atlassian.plugin.hostcontainer.SimpleConstructorHostContainer;
  20. import com.atlassian.plugin.main.AtlassianPlugins;
  21. import com.atlassian.plugin.main.PluginsConfiguration;
  22. import com.atlassian.plugin.main.PluginsConfigurationBuilder;
  23. import com.atlassian.plugin.metadata.DefaultPluginMetadataManager;
  24. import com.atlassian.plugin.metadata.PluginMetadataManager;
  25. import com.atlassian.plugin.module.ClassPrefixModuleFactory;
  26. import com.atlassian.plugin.module.PrefixDelegatingModuleFactory;
  27. import com.atlassian.plugin.module.ModuleFactory;
  28. import com.atlassian.plugin.module.PrefixModuleFactory;
  29. import com.atlassian.plugin.osgi.container.OsgiContainerManager;
  30. import com.atlassian.plugin.osgi.container.impl.DefaultPackageScannerConfiguration;
  31. import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
  32. import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
  33. import com.atlassian.plugin.osgi.module.BeanPrefixModuleFactory;
  34. import com.atlassian.plugin.refimpl.servlet.SimpleContentTypeResolver;
  35. import com.atlassian.plugin.refimpl.servlet.SimpleServletContextFactory;
  36. import com.atlassian.plugin.refimpl.webresource.SimpleWebResourceIntegration;
  37. import com.atlassian.plugin.servlet.DefaultServletModuleManager;
  38. import com.atlassian.plugin.servlet.DownloadStrategy;
  39. import com.atlassian.plugin.servlet.PluginResourceDownload;
  40. import com.atlassian.plugin.servlet.ServletModuleManager;
  41. import com.atlassian.plugin.servlet.descriptors.ServletContextListenerModuleDescriptor;
  42. import com.atlassian.plugin.servlet.descriptors.ServletContextParamModuleDescriptor;
  43. import com.atlassian.plugin.servlet.descriptors.ServletFilterModuleDescriptor;
  44. import com.atlassian.plugin.servlet.descriptors.ServletModuleDescriptor;
  45. import com.atlassian.plugin.util.Assertions;
  46. import com.atlassian.plugin.webresource.DefaultResourceBatchingConfiguration;
  47. import com.atlassian.plugin.webresource.PluginResourceLocator;
  48. import com.atlassian.plugin.webresource.PluginResourceLocatorImpl;
  49. import com.atlassian.plugin.webresource.WebResourceIntegration;
  50. import com.atlassian.plugin.webresource.WebResourceManager;
  51. import com.atlassian.plugin.webresource.WebResourceManagerImpl;
  52. import com.atlassian.plugin.webresource.WebResourceModuleDescriptor;
  53. import com.atlassian.plugin.webresource.WebResourceUrlProvider;
  54. import com.atlassian.plugin.webresource.WebResourceUrlProviderImpl;
  55. import com.atlassian.plugin.webresource.transformer.WebResourceTransformerModuleDescriptor;
  56. import com.google.common.collect.ImmutableSet;
  57. import org.apache.commons.io.IOUtils;
  58. import org.apache.commons.lang.StringUtils;
  59. import javax.servlet.ServletContext;
  60. import java.io.File;
  61. import java.io.IOException;
  62. import java.io.InputStream;
  63. import java.util.*;
  64. /**
  65. * A simple class that behaves like Spring's ContainerManager class.
  66. */
  67. public class ContainerManager
  68. {
  69. /**
  70. * the name of the bundled plugins zip file to use.
  71. */
  72. private static final String BUNDLED_PLUGINS_ZIP = "/atlassian-bundled-plugins.zip";
  73. /**
  74. * System property key for overriding package export versions.
  75. */
  76. private static final String PACKAGE_VERSION_EXPORT_OVERRIDES = "refapp.packageExport.overrides";
  77. private final ServletModuleManager servletModuleManager;
  78. private final SimpleWebResourceIntegration webResourceIntegration;
  79. private final WebResourceManager webResourceManager;
  80. private final OsgiContainerManager osgiContainerManager;
  81. private final WebResourceUrlProvider webResourceUrlProvider;
  82. private final PluginAccessor pluginAccessor;
  83. private final HostComponentProvider hostComponentProvider;
  84. private final DefaultModuleDescriptorFactory moduleDescriptorFactory;
  85. private final Map<Class<?>, Object> publicContainer;
  86. private final AtlassianPlugins plugins;
  87. private final HostContainer hostContainer;
  88. private static ContainerManager instance;
  89. private final List<DownloadStrategy> downloadStrategies;
  90. public ContainerManager(final ServletContext servletContext)
  91. {
  92. instance = this;
  93. webResourceIntegration = new SimpleWebResourceIntegration(servletContext);
  94. webResourceUrlProvider = new WebResourceUrlProviderImpl(webResourceIntegration);
  95. // Delegating host container since the real one requires the created object map, which won't be available until later
  96. final HostContainer delegatingHostContainer = new HostContainer()
  97. {
  98. public <T> T create(final Class<T> moduleClass) throws IllegalArgumentException
  99. {
  100. return hostContainer.create(moduleClass);
  101. }
  102. };
  103. moduleDescriptorFactory = new DefaultModuleDescriptorFactory(delegatingHostContainer);
  104. moduleDescriptorFactory.addModuleDescriptor("servlet", ServletModuleDescriptor.class);
  105. moduleDescriptorFactory.addModuleDescriptor("servlet-filter", ServletFilterModuleDescriptor.class);
  106. moduleDescriptorFactory.addModuleDescriptor("servlet-context-param", ServletContextParamModuleDescriptor.class);
  107. moduleDescriptorFactory.addModuleDescriptor("servlet-context-listener", ServletContextListenerModuleDescriptor.class);
  108. moduleDescriptorFactory.addModuleDescriptor("web-resource", WebResourceModuleDescriptor.class);
  109. moduleDescriptorFactory.addModuleDescriptor("web-resource-transformer", WebResourceTransformerModuleDescriptor.class);
  110. final DefaultPackageScannerConfiguration scannerConfig = new DefaultPackageScannerConfiguration(determineVersion());
  111. scannerConfig.setServletContext(servletContext);
  112. final List<String> packageIncludes = new ArrayList<String>(scannerConfig.getPackageIncludes());
  113. packageIncludes.add("org.bouncycastle*");
  114. packageIncludes.add("org.dom4j*");
  115. packageIncludes.add("javax.servlet*");
  116. packageIncludes.add("com.google.common.*");
  117. packageIncludes.add("com.atlassian.sal*");
  118. packageIncludes.add("com.opensymphony.module.sitemesh*");
  119. scannerConfig.setPackageIncludes(packageIncludes);
  120. scannerConfig.setPackageVersions(new HashMap<String,String>() {{
  121. put("javax.servlet", "2.5");
  122. put("javax.servlet.http", "2.5");
  123. put("com.google.common.*", SystemExportVersionUtils.getGoogleGuavaVersion());
  124. }});
  125. final String packageVersionExportString = System.getProperty(PACKAGE_VERSION_EXPORT_OVERRIDES);
  126. if (packageVersionExportString != null)
  127. {
  128. scannerConfig.getPackageVersions().putAll(ConfigParser.parseMap(packageVersionExportString));
  129. }
  130. hostComponentProvider = new SimpleHostComponentProvider();
  131. File osgiCache = findAndCreateDirectory(servletContext, "osgi.cache", "WEB-INF/osgi-cache");
  132. File bundledPluginDir = findAndCreateDirectory(servletContext, "bundledplugins.cache", "WEB-INF/bundled-plugins");
  133. final PluginsConfiguration config = new PluginsConfigurationBuilder()
  134. .useLegacyDynamicPluginDeployer(true)
  135. .bundledPluginUrl(this.getClass().getResource(BUNDLED_PLUGINS_ZIP))
  136. .bundledPluginCacheDirectory(bundledPluginDir)
  137. .pluginDirectory(makeSureDirectoryExists(servletContext, "/WEB-INF/plugins"))
  138. .moduleDescriptorFactory(moduleDescriptorFactory)
  139. .packageScannerConfiguration(scannerConfig)
  140. .hostComponentProvider(hostComponentProvider)
  141. .osgiPersistentCache(osgiCache)
  142. .pluginStateStore(new DefaultPluginPersistentStateStore(osgiCache))
  143. .applicationKey("refapp")
  144. .build();
  145. PrefixDelegatingModuleFactory moduleFactory = new PrefixDelegatingModuleFactory(ImmutableSet.<PrefixModuleFactory>of(new BeanPrefixModuleFactory()));
  146. plugins = new AtlassianPlugins(config);
  147. final PluginEventManager pluginEventManager = plugins.getPluginEventManager();
  148. osgiContainerManager = plugins.getOsgiContainerManager();
  149. servletModuleManager = new DefaultServletModuleManager(servletContext, pluginEventManager);
  150. pluginAccessor = plugins.getPluginAccessor();
  151. final PluginResourceLocator pluginResourceLocator = new PluginResourceLocatorImpl(webResourceIntegration, new SimpleServletContextFactory(servletContext), webResourceUrlProvider);
  152. final PluginResourceDownload pluginDownloadStrategy = new PluginResourceDownload(pluginResourceLocator, new SimpleContentTypeResolver(), "UTF-8");
  153. webResourceManager = new WebResourceManagerImpl(pluginResourceLocator, webResourceIntegration, webResourceUrlProvider, new DefaultResourceBatchingConfiguration());
  154. publicContainer = new HashMap<Class<?>, Object>();
  155. publicContainer.put(PluginController.class, plugins.getPluginController());
  156. // TODO: should re-use event publisher from plugin event manager
  157. publicContainer.put(EventPublisher.class, createEventPublisher());
  158. publicContainer.put(ServletModuleManager.class, servletModuleManager);
  159. publicContainer.put(WebResourceManager.class, webResourceManager);
  160. publicContainer.put(Map.class, publicContainer);
  161. publicContainer.put(ModuleFactory.class, moduleFactory);
  162. publicContainer.put(PluginMetadataManager.class, new DefaultPluginMetadataManager());
  163. hostContainer = new SimpleConstructorHostContainer(publicContainer);
  164. moduleFactory.addPrefixModuleFactory(new ClassPrefixModuleFactory(hostContainer));
  165. try
  166. {
  167. plugins.start();
  168. }
  169. catch (final PluginParseException e)
  170. {
  171. throw new RuntimeException(e);
  172. }
  173. downloadStrategies = new ArrayList<DownloadStrategy>();
  174. downloadStrategies.add(pluginDownloadStrategy);
  175. }
  176. private File findAndCreateDirectory(ServletContext servletContext, String sysPropName, String defaultPath)
  177. {
  178. File dir;
  179. if (System.getProperty(sysPropName) != null)
  180. {
  181. dir = makeSureDirectoryExists(System.getProperty(sysPropName));
  182. }
  183. else
  184. {
  185. dir = makeSureDirectoryExists(servletContext, defaultPath);
  186. }
  187. return dir;
  188. }
  189. private EventPublisher createEventPublisher()
  190. {
  191. EventThreadPoolConfiguration threadPoolConfiguration = new EventThreadPoolConfigurationImpl();
  192. EventExecutorFactory factory = new EventExecutorFactoryImpl(threadPoolConfiguration);
  193. EventDispatcher dispatcher = new AsynchronousAbleEventDispatcher(factory);
  194. ListenerHandlersConfiguration listenerHandlersConfiguration = new ListenerHandlerConfigurationImpl();
  195. EventPublisher publisher = new EventPublisherImpl(dispatcher, listenerHandlersConfiguration);
  196. return publisher;
  197. }
  198. private String determineVersion()
  199. {
  200. InputStream in = null;
  201. final Properties props = new Properties();
  202. try
  203. {
  204. in = getClass().getClassLoader().getResourceAsStream("META-INF/maven/com.atlassian.plugins/atlassian-plugins-core/pom.properties");
  205. if (in != null)
  206. {
  207. props.load(in);
  208. return props.getProperty("version");
  209. }
  210. } catch (final IOException e) {
  211. e.printStackTrace();
  212. return null;
  213. }
  214. finally
  215. {
  216. IOUtils.closeQuietly(in);
  217. }
  218. return null;
  219. }
  220. private File makeSureDirectoryExists(final ServletContext servletContext, final String relativePath)
  221. {
  222. return makeSureDirectoryExists(servletContext.getRealPath(relativePath));
  223. }
  224. private File makeSureDirectoryExists(final String path)
  225. {
  226. final File dir = new File(path);
  227. if (!dir.exists() && !dir.mkdirs())
  228. {
  229. throw new RuntimeException("Could not create directory <" + dir + ">");
  230. }
  231. return dir;
  232. }
  233. public static synchronized void setInstance(final ContainerManager mgr)
  234. {
  235. instance = mgr;
  236. }
  237. public static synchronized ContainerManager getInstance()
  238. {
  239. return instance;
  240. }
  241. public ServletModuleManager getServletModuleManager()
  242. {
  243. return servletModuleManager;
  244. }
  245. public OsgiContainerManager getOsgiContainerManager()
  246. {
  247. return osgiContainerManager;
  248. }
  249. public PluginAccessor getPluginAccessor()
  250. {
  251. return pluginAccessor;
  252. }
  253. public HostComponentProvider getHostComponentProvider()
  254. {
  255. return hostComponentProvider;
  256. }
  257. public ModuleDescriptorFactory getModuleDescriptorFactory()
  258. {
  259. return moduleDescriptorFactory;
  260. }
  261. public List<DownloadStrategy> getDownloadStrategies()
  262. {
  263. return downloadStrategies;
  264. }
  265. public WebResourceManager getWebResourceManager()
  266. {
  267. return webResourceManager;
  268. }
  269. public WebResourceIntegration getWebResourceIntegration()
  270. {
  271. return webResourceIntegration;
  272. }
  273. void shutdown()
  274. {
  275. plugins.stop();
  276. }
  277. private class SimpleHostComponentProvider implements HostComponentProvider
  278. {
  279. public void provide(final ComponentRegistrar componentRegistrar)
  280. {
  281. Assertions.notNull("publicContainer", publicContainer);
  282. for (final Map.Entry<Class<?>, Object> entry : publicContainer.entrySet())
  283. {
  284. final String name = StringUtils.uncapitalize(entry.getKey().getSimpleName());
  285. componentRegistrar.register(entry.getKey()).forInstance(entry.getValue()).withName(name);
  286. }
  287. }
  288. }
  289. }