1 package com.atlassian.plugin.main;
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.hostcontainer.DefaultHostContainer;
8 import com.atlassian.plugin.manager.PluginPersistentStateStore;
9 import com.atlassian.plugin.manager.store.MemoryPluginPersistentStateStore;
10 import com.atlassian.plugin.osgi.container.OsgiPersistentCache;
11 import com.atlassian.plugin.osgi.container.PackageScannerConfiguration;
12 import com.atlassian.plugin.osgi.container.impl.DefaultOsgiPersistentCache;
13 import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
14 import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
15 import com.atlassian.plugin.schema.impl.DefaultDescribedModuleDescriptorFactory;
16
17 import static com.atlassian.plugin.util.Assertions.isTrue;
18 import static com.atlassian.plugin.util.Assertions.notNull;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.net.URL;
23 import java.util.concurrent.TimeUnit;
24
25
26
27
28
29
30
31
32 public class PluginsConfigurationBuilder
33 {
34
35
36
37
38 public static PluginsConfigurationBuilder pluginsConfiguration()
39 {
40 return new PluginsConfigurationBuilder();
41 }
42
43 private PackageScannerConfiguration packageScannerConfiguration;
44 private HostComponentProvider hostComponentProvider;
45 private File osgiPersistentCache;
46 private File pluginDirectory;
47 private URL bundledPluginUrl;
48 private File bundledPluginCacheDirectory;
49 private String pluginDescriptorFilename;
50 private ModuleDescriptorFactory moduleDescriptorFactory;
51 private PluginPersistentStateStore pluginStateStore;
52 private long hotDeployPollingPeriod;
53 private boolean useLegacyDynamicPluginDeployer = false;
54 private Application application;
55
56
57
58
59
60
61 public PluginsConfigurationBuilder packageScannerConfiguration(final PackageScannerConfiguration packageScannerConfiguration)
62 {
63 this.packageScannerConfiguration = notNull("packageScannerConfiguration", packageScannerConfiguration);
64 return this;
65 }
66
67
68
69
70
71
72
73 public PluginsConfigurationBuilder hostComponentProvider(final HostComponentProvider hostComponentProvider)
74 {
75 this.hostComponentProvider = notNull("hostComponentProvider", hostComponentProvider);
76 return this;
77 }
78
79
80
81
82
83
84
85 public PluginsConfigurationBuilder osgiPersistentCache(final File osgiPersistentCache)
86 {
87 this.osgiPersistentCache = osgiPersistentCache;
88 return this;
89 }
90
91
92
93
94
95
96 public PluginsConfigurationBuilder pluginDirectory(final File pluginDirectory)
97 {
98 this.pluginDirectory = pluginDirectory;
99 return this;
100 }
101
102
103
104
105
106
107
108 public PluginsConfigurationBuilder bundledPluginUrl(final URL bundledPluginUrl)
109 {
110 this.bundledPluginUrl = bundledPluginUrl;
111 return this;
112 }
113
114
115
116
117
118
119
120 public PluginsConfigurationBuilder bundledPluginCacheDirectory(final File bundledPluginCacheDirectory)
121 {
122 this.bundledPluginCacheDirectory = bundledPluginCacheDirectory;
123 return this;
124 }
125
126
127
128
129
130
131 public PluginsConfigurationBuilder pluginDescriptorFilename(final String pluginDescriptorFilename)
132 {
133 this.pluginDescriptorFilename = pluginDescriptorFilename;
134 return this;
135 }
136
137
138
139
140
141
142
143
144 public PluginsConfigurationBuilder moduleDescriptorFactory(final ModuleDescriptorFactory moduleDescriptorFactory)
145 {
146 this.moduleDescriptorFactory = moduleDescriptorFactory;
147 return this;
148 }
149
150
151
152
153
154
155
156 public PluginsConfigurationBuilder pluginStateStore(final PluginPersistentStateStore pluginStateStore)
157 {
158 this.pluginStateStore = pluginStateStore;
159 return this;
160 }
161
162
163
164
165
166
167
168 public PluginsConfigurationBuilder hotDeployPollingFrequency(final long hotDeployPollingFrequency, final TimeUnit timeUnit)
169 {
170 hotDeployPollingPeriod = timeUnit.toMillis(hotDeployPollingFrequency);
171 return this;
172 }
173
174
175
176
177
178
179 public PluginsConfigurationBuilder useLegacyDynamicPluginDeployer(final boolean useLegacyDynamicPluginDeployer)
180 {
181 this.useLegacyDynamicPluginDeployer = useLegacyDynamicPluginDeployer;
182 return this;
183 }
184
185
186
187
188
189
190 public PluginsConfigurationBuilder application(final Application application)
191 {
192 this.application = application;
193 return this;
194 }
195
196
197
198
199
200
201 public PluginsConfiguration build()
202 {
203 notNull("Plugin directory must be defined", pluginDirectory);
204 isTrue("Plugin directory must exist", pluginDirectory.exists());
205
206 if (packageScannerConfiguration == null)
207 {
208 packageScannerConfiguration = new PackageScannerConfigurationBuilder().build();
209 }
210 if (pluginDescriptorFilename == null)
211 {
212 pluginDescriptorFilename = PluginAccessor.Descriptor.FILENAME;
213 }
214
215 if (hostComponentProvider == null)
216 {
217 hostComponentProvider = new HostComponentProvider()
218 {
219 public void provide(final ComponentRegistrar registrar)
220 {
221 }
222 };
223 }
224
225 if (pluginStateStore == null)
226 {
227 pluginStateStore = new MemoryPluginPersistentStateStore();
228 }
229
230 if (moduleDescriptorFactory == null)
231 {
232 moduleDescriptorFactory = new DefaultDescribedModuleDescriptorFactory(new DefaultHostContainer());
233 }
234
235 if (osgiPersistentCache == null)
236 {
237 osgiPersistentCache = createTempDir("atlassian-plugins-osgi-cache");
238 }
239
240 if (bundledPluginUrl != null && bundledPluginCacheDirectory == null)
241 {
242 throw new IllegalArgumentException("Bundled plugin cache directory MUST be defined when bundled plugin URL is defined");
243 }
244
245 return new InternalPluginsConfiguration(this);
246 }
247
248 private File createTempDir(final String prefix)
249 {
250 try
251 {
252 final File directory = File.createTempFile(prefix, AtlassianPlugins.TEMP_DIRECTORY_SUFFIX);
253 directory.delete();
254 directory.mkdir();
255 return directory;
256 }
257 catch (final IOException e)
258 {
259 throw new IllegalStateException("Was not able to create temp file with prefix <" + prefix + ">", e);
260 }
261 }
262
263 private static class InternalPluginsConfiguration implements PluginsConfiguration
264 {
265 private final PackageScannerConfiguration packageScannerConfiguration;
266 private final HostComponentProvider hostComponentProvider;
267 private final OsgiPersistentCache osgiPersistentCache;
268 private final File pluginDirectory;
269 private final URL bundledPluginUrl;
270 private final File bundledPluginCacheDirectory;
271 private final String pluginDescriptorFilename;
272 private final ModuleDescriptorFactory moduleDescriptorFactory;
273 private final PluginPersistentStateStore pluginStateStore;
274 private final long hotDeployPollingPeriod;
275 private final boolean useLegacyDynamicPluginDeployer;
276 private final Application application;
277
278 InternalPluginsConfiguration(final PluginsConfigurationBuilder builder)
279 {
280 packageScannerConfiguration = builder.packageScannerConfiguration;
281 hostComponentProvider = builder.hostComponentProvider;
282 osgiPersistentCache = new DefaultOsgiPersistentCache(builder.osgiPersistentCache, builder.packageScannerConfiguration.getCurrentHostVersion());
283 pluginDirectory = builder.pluginDirectory;
284 bundledPluginUrl = builder.bundledPluginUrl;
285 bundledPluginCacheDirectory = builder.bundledPluginCacheDirectory;
286 pluginDescriptorFilename = builder.pluginDescriptorFilename;
287 moduleDescriptorFactory = builder.moduleDescriptorFactory;
288 pluginStateStore = builder.pluginStateStore;
289 hotDeployPollingPeriod = builder.hotDeployPollingPeriod;
290 useLegacyDynamicPluginDeployer = builder.useLegacyDynamicPluginDeployer;
291 application = builder.application;
292 }
293
294 public PackageScannerConfiguration getPackageScannerConfiguration()
295 {
296 return packageScannerConfiguration;
297 }
298
299 public HostComponentProvider getHostComponentProvider()
300 {
301 return hostComponentProvider;
302 }
303
304 public String getPluginDescriptorFilename()
305 {
306 return pluginDescriptorFilename;
307 }
308
309 public File getPluginDirectory()
310 {
311 return pluginDirectory;
312 }
313
314 public URL getBundledPluginUrl()
315 {
316 return bundledPluginUrl;
317 }
318
319 public File getBundledPluginCacheDirectory()
320 {
321 return bundledPluginCacheDirectory;
322 }
323
324 public ModuleDescriptorFactory getModuleDescriptorFactory()
325 {
326 return moduleDescriptorFactory;
327 }
328
329 public PluginPersistentStateStore getPluginStateStore()
330 {
331 return pluginStateStore;
332 }
333
334 public long getHotDeployPollingPeriod()
335 {
336 return hotDeployPollingPeriod;
337 }
338
339 public boolean isUseLegacyDynamicPluginDeployer()
340 {
341 return useLegacyDynamicPluginDeployer;
342 }
343
344 public Application getApplication()
345 {
346 return application;
347 }
348
349 public OsgiPersistentCache getOsgiPersistentCache()
350 {
351 return osgiPersistentCache;
352 }
353 }
354 }