1 package com.atlassian.plugin.loaders;
2
3 import com.atlassian.plugin.AutowireCapablePlugin;
4 import com.atlassian.plugin.DefaultPluginArtifactFactory;
5 import com.atlassian.plugin.Plugin;
6 import com.atlassian.plugin.PluginArtifact;
7 import com.atlassian.plugin.PluginArtifactBackedPlugin;
8 import com.atlassian.plugin.PluginException;
9 import com.atlassian.plugin.event.PluginEventManager;
10 import com.atlassian.plugin.factories.PluginFactory;
11 import com.atlassian.plugin.impl.AbstractDelegatingPlugin;
12 import com.atlassian.plugin.loaders.classloading.DeploymentUnit;
13 import com.atlassian.plugin.loaders.classloading.EmptyScanner;
14 import com.atlassian.plugin.loaders.classloading.ForwardingScanner;
15 import com.atlassian.plugin.loaders.classloading.Scanner;
16 import com.atlassian.plugin.module.ContainerAccessor;
17 import com.atlassian.plugin.module.ContainerManagedPlugin;
18 import org.apache.commons.io.FileUtils;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import static com.atlassian.plugin.PluginArtifact.AllowsReference.ReferenceMode.PERMIT_REFERENCE;
29 import static com.google.common.base.Preconditions.checkArgument;
30 import static com.google.common.base.Preconditions.checkNotNull;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class BundledPluginLoader extends ScanningPluginLoader
47 {
48 private static final Logger log = LoggerFactory.getLogger(BundledPluginLoader.class);
49
50
51 public static String getListSuffix()
52 {
53 return ".list";
54 }
55
56 private BundledPluginLoader(
57 final Scanner scanner,
58 final List<PluginFactory> pluginFactories,
59 final PluginEventManager eventManager)
60 {
61 super(new NonRemovingScanner(scanner), pluginFactories, new DefaultPluginArtifactFactory(PERMIT_REFERENCE),
62 eventManager);
63 }
64
65
66
67
68
69
70
71
72
73
74 public BundledPluginLoader(
75 final File source,
76 final List<PluginFactory> pluginFactories,
77 final PluginEventManager eventManager)
78 {
79 this(buildSourceScanner(source), pluginFactories, eventManager);
80 }
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 public BundledPluginLoader(
98 final URL zipUrl,
99 final File pluginPath,
100 final List<PluginFactory> pluginFactories,
101 final PluginEventManager eventManager)
102 {
103 this(buildZipScanner(zipUrl, pluginPath), pluginFactories, eventManager);
104 }
105
106 @Override
107 protected Plugin postProcess(final Plugin plugin)
108 {
109 if (plugin instanceof ContainerManagedPlugin)
110 {
111 return new BundledPluginContainerManagedPluginDelegate((ContainerManagedPlugin) plugin);
112 }
113 else if (plugin instanceof PluginArtifactBackedPlugin)
114 {
115 return new BundledPluginArtifactBackedPluginDelegate((PluginArtifactBackedPlugin)plugin);
116 }
117 return new BundledPluginDelegate(plugin);
118 }
119
120 private static Scanner buildScannerCommon(final File file)
121 {
122 if (file.isDirectory())
123 {
124
125 return new DirectoryScanner(file);
126 }
127 else if (file.isFile() && file.getName().endsWith(getListSuffix()))
128 {
129
130 final List<File> files = readListFile(file);
131 return new FileListScanner(files);
132 }
133 else
134 {
135
136 return null;
137 }
138 }
139
140 private static Scanner buildSourceScanner(final File source)
141 {
142 checkNotNull(source, "Source must not be null");
143 final Scanner scanner = buildScannerCommon(source);
144 if (null == scanner)
145 {
146 log.error("Cannot build a scanner for source '{}'", source);
147
148
149 return new EmptyScanner();
150 }
151 else
152 {
153 return scanner;
154 }
155 }
156
157 private static Scanner buildZipScanner(final URL url, final File pluginPath)
158 {
159
160 checkArgument(null != url, "Bundled plugins url cannot be null");
161
162
163 Scanner scanner = null;
164
165
166
167 final File file = FileUtils.toFile(url);
168 if (null != file)
169 {
170 scanner = buildScannerCommon(file);
171 }
172
173 if (null == scanner)
174 {
175
176 com.atlassian.plugin.util.FileUtils.conditionallyExtractZipFile(url, pluginPath);
177 scanner = new DirectoryScanner(pluginPath);
178 }
179
180 return scanner;
181 }
182
183 private static List<File> readListFile(final File file)
184 {
185 try
186 {
187 final List<String> fnames = (List<String>) FileUtils.readLines(file);
188 final List<File> files = new ArrayList<File>();
189 for (final String fname : fnames)
190 {
191 files.add(new File(fname));
192 }
193 return files;
194 }
195 catch (IOException e)
196 {
197 throw new IllegalStateException("Unable to read list from " + file, e);
198 }
199 }
200
201
202
203
204
205
206
207 private static class NonRemovingScanner extends ForwardingScanner
208 {
209 NonRemovingScanner(final Scanner scanner)
210 {
211 super(scanner);
212 }
213
214 @Override
215 public void remove(final DeploymentUnit unit) throws PluginException
216 {
217
218 }
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232
233 private static class BundledPluginDelegate extends AbstractDelegatingPlugin
234 {
235
236 public BundledPluginDelegate(final Plugin delegate)
237 {
238 super(delegate);
239 }
240
241 @Override
242 public boolean isBundledPlugin()
243 {
244 return true;
245 }
246
247
248 }
249
250
251
252
253
254 private static class BundledPluginArtifactBackedPluginDelegate extends BundledPluginDelegate implements PluginArtifactBackedPlugin
255 {
256 private final PluginArtifactBackedPlugin delegate;
257
258 private BundledPluginArtifactBackedPluginDelegate(final PluginArtifactBackedPlugin delegate)
259 {
260 super(delegate);
261 this.delegate = delegate;
262 }
263
264 public PluginArtifact getPluginArtifact()
265 {
266 return delegate.getPluginArtifact();
267 }
268 }
269
270 private static class BundledPluginContainerManagedPluginDelegate extends BundledPluginArtifactBackedPluginDelegate implements ContainerManagedPlugin,
271 AutowireCapablePlugin
272 {
273 private final ContainerManagedPlugin delegate;
274
275 private BundledPluginContainerManagedPluginDelegate(final ContainerManagedPlugin delegate)
276 {
277 super(delegate);
278 this.delegate = delegate;
279 }
280
281 @Override
282 public ContainerAccessor getContainerAccessor()
283 {
284 return delegate.getContainerAccessor();
285 }
286
287 @Override
288 public <T> T autowire(final Class<T> clazz)
289 {
290 if (delegate instanceof AutowireCapablePlugin)
291 {
292 return ((AutowireCapablePlugin)delegate).autowire(clazz);
293 }
294 else
295 {
296 return delegate.getContainerAccessor().createBean(clazz);
297 }
298 }
299
300 @Override
301 public <T> T autowire(final Class<T> clazz, final AutowireStrategy autowireStrategy)
302 {
303 if (delegate instanceof AutowireCapablePlugin)
304 {
305 return ((AutowireCapablePlugin)delegate).autowire(clazz, autowireStrategy);
306 }
307 else
308 {
309 return delegate.getContainerAccessor().createBean(clazz);
310 }
311 }
312
313 @Override
314 public void autowire(final Object instance)
315 {
316 if (delegate instanceof AutowireCapablePlugin)
317 {
318 ((AutowireCapablePlugin)delegate).autowire(instance);
319 }
320 else
321 {
322 delegate.getContainerAccessor().injectBean(instance);
323 }
324 }
325
326 @Override
327 public void autowire(final Object instance, final AutowireStrategy autowireStrategy)
328 {
329 if (delegate instanceof AutowireCapablePlugin)
330 {
331 ((AutowireCapablePlugin)delegate).autowire(instance, autowireStrategy);
332 }
333 else
334 {
335 delegate.getContainerAccessor().injectBean(instance);
336 }
337 }
338 }
339 }