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