1 package com.atlassian.plugin.main;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.LinkedList;
6 import java.util.List;
7 import java.util.Set;
8 import java.util.concurrent.atomic.AtomicReference;
9
10 import com.atlassian.event.api.EventPublisher;
11 import com.atlassian.plugin.Application;
12 import com.atlassian.plugin.PluginAccessor;
13 import com.atlassian.plugin.PluginController;
14 import com.atlassian.plugin.PluginParseException;
15 import com.atlassian.plugin.SplitStartupPluginSystemLifecycle;
16 import com.atlassian.plugin.event.PluginEventListener;
17 import com.atlassian.plugin.event.PluginEventManager;
18 import com.atlassian.plugin.event.events.PluginFrameworkShutdownEvent;
19 import com.atlassian.plugin.event.events.PluginFrameworkStartedEvent;
20 import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
21 import com.atlassian.plugin.factories.LegacyDynamicPluginFactory;
22 import com.atlassian.plugin.factories.PluginFactory;
23 import com.atlassian.plugin.loaders.BundledPluginLoader;
24 import com.atlassian.plugin.loaders.ClassPathPluginLoader;
25 import com.atlassian.plugin.loaders.DirectoryPluginLoader;
26 import com.atlassian.plugin.loaders.PluginLoader;
27 import com.atlassian.plugin.manager.DefaultPluginManager;
28 import com.atlassian.plugin.osgi.container.OsgiContainerManager;
29 import com.atlassian.plugin.osgi.container.felix.FelixOsgiContainerManager;
30 import com.atlassian.plugin.osgi.factory.OsgiBundleFactory;
31 import com.atlassian.plugin.osgi.factory.OsgiPluginFactory;
32 import com.atlassian.plugin.osgi.factory.RemotablePluginFactory;
33 import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
34 import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
35 import com.atlassian.plugin.repositories.FilePluginInstaller;
36
37 import com.google.common.collect.ImmutableSet;
38 import com.google.common.collect.Sets;
39
40
41
42
43 public class AtlassianPlugins
44 {
45 private OsgiContainerManager osgiContainerManager;
46 private DefaultPluginEventManager pluginEventManager;
47 private DefaultPluginManager pluginManager;
48 private HotDeployer hotDeployer;
49 private EventPublisher eventPublisher;
50
51
52
53
54 public static final String TEMP_DIRECTORY_SUFFIX = ".tmp";
55
56
57
58
59
60
61
62
63 public AtlassianPlugins(final PluginsConfiguration config)
64 {
65 pluginEventManager = new DefaultPluginEventManager();
66 eventPublisher = pluginEventManager.getEventPublisher();
67
68 final AtomicReference<PluginAccessor> pluginManagerRef = new AtomicReference<PluginAccessor>();
69 osgiContainerManager = new FelixOsgiContainerManager(
70 config.getOsgiPersistentCache(),
71 config.getPackageScannerConfiguration(),
72 new CriticalHostComponentProvider(config.getHostComponentProvider(), pluginEventManager, pluginManagerRef),
73 pluginEventManager);
74
75 final Set<Application> applications = config.getApplication() != null ?
76 Sets.newHashSet(config.getApplication()) : ImmutableSet.<Application>of();
77
78
79 final OsgiPluginFactory osgiPluginDeployer = new OsgiPluginFactory(
80 config.getPluginDescriptorFilename(),
81 applications,
82 config.getOsgiPersistentCache(),
83 osgiContainerManager,
84 pluginEventManager);
85
86 final OsgiBundleFactory osgiBundleDeployer = new OsgiBundleFactory(osgiContainerManager, pluginEventManager);
87
88 final RemotablePluginFactory remotablePluginFactory = new RemotablePluginFactory(
89 config.getPluginDescriptorFilename(),
90 applications,
91 osgiContainerManager,
92 pluginEventManager);
93
94 final List<PluginFactory> pluginDeployers = new LinkedList<PluginFactory>(Arrays.asList(osgiPluginDeployer, osgiBundleDeployer, remotablePluginFactory));
95 if (config.isUseLegacyDynamicPluginDeployer())
96 {
97 pluginDeployers.add(new LegacyDynamicPluginFactory(config.getPluginDescriptorFilename()));
98 }
99
100 final List<PluginLoader> pluginLoaders = new ArrayList<PluginLoader>();
101
102
103 pluginLoaders.add(new ClassPathPluginLoader());
104
105
106 if (config.getBundledPluginUrl() != null)
107 {
108 pluginLoaders.add(new BundledPluginLoader(config.getBundledPluginUrl(), config.getBundledPluginCacheDirectory(), pluginDeployers, pluginEventManager));
109 }
110
111
112 pluginLoaders.add(new DirectoryPluginLoader(config.getPluginDirectory(), pluginDeployers, pluginEventManager));
113
114 pluginManager = new DefaultPluginManager(
115 config.getPluginStateStore(),
116 pluginLoaders,
117 config.getModuleDescriptorFactory(),
118 pluginEventManager);
119 pluginManagerRef.set(pluginManager);
120
121 pluginManager.setPluginInstaller(new FilePluginInstaller(config.getPluginDirectory()));
122
123 if (config.getHotDeployPollingPeriod() > 0)
124 {
125 hotDeployer = new HotDeployer(pluginManager, config.getHotDeployPollingPeriod());
126 }
127 }
128
129 public void afterPropertiesSet()
130 {
131 pluginEventManager.register(this);
132 }
133
134 public void destroy()
135 {
136 pluginEventManager.unregister(this);
137 }
138
139
140
141
142
143
144
145 @Deprecated
146 public void start() throws PluginParseException
147 {
148 afterPropertiesSet();
149 getPluginSystemLifecycle().init();
150 }
151
152
153
154
155
156
157 @Deprecated
158 public void stop()
159 {
160 getPluginSystemLifecycle().shutdown();
161 destroy();
162 }
163
164
165
166
167 public OsgiContainerManager getOsgiContainerManager()
168 {
169 return osgiContainerManager;
170 }
171
172
173
174
175 public PluginEventManager getPluginEventManager()
176 {
177 return pluginEventManager;
178 }
179
180
181
182
183 public EventPublisher getEventPublisher()
184 {
185 return eventPublisher;
186 }
187
188
189
190
191 public PluginController getPluginController()
192 {
193 return pluginManager;
194 }
195
196
197
198
199 public PluginAccessor getPluginAccessor()
200 {
201 return pluginManager;
202 }
203
204
205
206
207 public SplitStartupPluginSystemLifecycle getPluginSystemLifecycle()
208 {
209 return pluginManager;
210 }
211
212
213 @PluginEventListener
214 public void onPluginFrameworkStartedEvent(final PluginFrameworkStartedEvent event)
215 {
216 if (hotDeployer != null && !hotDeployer.isRunning())
217 {
218 hotDeployer.start();
219 }
220 }
221
222 @PluginEventListener
223 public void onPluginFrameworkShutdownEvent(final PluginFrameworkShutdownEvent event)
224 {
225 if (hotDeployer != null && hotDeployer.isRunning())
226 {
227 hotDeployer.stop();
228 }
229 }
230
231 private static class CriticalHostComponentProvider implements HostComponentProvider
232 {
233 private final HostComponentProvider delegate;
234 private final PluginEventManager pluginEventManager;
235 private final AtomicReference<PluginAccessor> pluginManagerRef;
236
237 public CriticalHostComponentProvider(
238 final HostComponentProvider delegate,
239 final PluginEventManager pluginEventManager,
240 final AtomicReference<PluginAccessor> pluginManagerRef)
241 {
242 this.delegate = delegate;
243 this.pluginEventManager = pluginEventManager;
244 this.pluginManagerRef = pluginManagerRef;
245 }
246
247 public void provide(final ComponentRegistrar registrar)
248 {
249 registrar.register(PluginEventManager.class).forInstance(pluginEventManager);
250 registrar.register(PluginAccessor.class).forInstance(pluginManagerRef.get());
251 delegate.provide(registrar);
252 }
253 }
254 }