1 package com.atlassian.plugin.osgi.factory;
2
3 import com.atlassian.plugin.Application;
4 import com.atlassian.plugin.ModuleDescriptorFactory;
5 import com.atlassian.plugin.Plugin;
6 import com.atlassian.plugin.PluginAccessor;
7 import com.atlassian.plugin.PluginArtifact;
8 import com.atlassian.plugin.PluginParseException;
9 import com.atlassian.plugin.event.PluginEventManager;
10 import com.atlassian.plugin.factories.AbstractPluginFactory;
11 import com.atlassian.plugin.impl.UnloadablePlugin;
12 import com.atlassian.plugin.osgi.container.OsgiContainerManager;
13
14 import com.google.common.base.Predicate;
15 import com.google.common.collect.ImmutableSet;
16 import com.google.common.collect.Ranges;
17 import org.apache.commons.io.IOUtils;
18 import org.osgi.framework.Constants;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import java.io.InputStream;
23 import java.util.jar.Manifest;
24
25 import static com.atlassian.plugin.osgi.util.OsgiHeaderUtil.getManifest;
26 import static com.atlassian.plugin.osgi.util.OsgiHeaderUtil.getPluginKey;
27 import static com.google.common.base.Preconditions.checkNotNull;
28
29
30
31
32 public final class OsgiBundleFactory extends AbstractPluginFactory
33 {
34 private static final Logger log = LoggerFactory.getLogger(OsgiBundleFactory.class);
35
36 private final OsgiContainerManager osgi;
37 private final PluginEventManager pluginEventManager;
38 private final String pluginDescriptorFileName;
39
40 public OsgiBundleFactory(OsgiContainerManager osgi, PluginEventManager pluginEventManager)
41 {
42 this(PluginAccessor.Descriptor.FILENAME, osgi, pluginEventManager);
43 }
44
45 public OsgiBundleFactory(String pluginDescriptorFileName, OsgiContainerManager osgi, PluginEventManager pluginEventManager)
46 {
47 super(new OsgiPluginXmlDescriptorParserFactory(), ImmutableSet.<Application>of());
48 this.pluginDescriptorFileName = checkNotNull(pluginDescriptorFileName);
49 this.osgi = checkNotNull(osgi, "The osgi container is required");
50 this.pluginEventManager = checkNotNull(pluginEventManager, "The plugin event manager is required");
51 }
52
53 @Override
54 protected InputStream getDescriptorInputStream(PluginArtifact pluginArtifact)
55 {
56 return pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
57 }
58
59 @Override
60 protected Predicate<Integer> isValidPluginsVersion()
61 {
62 return Ranges.atLeast(Plugin.VERSION_2);
63 }
64
65 public String canCreate(final PluginArtifact pluginArtifact) throws PluginParseException
66 {
67 checkNotNull(pluginArtifact, "The plugin artifact is required");
68
69 InputStream descriptorStream = null;
70
71 try
72 {
73 descriptorStream = pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
74 if (null == descriptorStream)
75 {
76 final Manifest manifest = getManifest(pluginArtifact);
77 if ((null != manifest) && (null != manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME)))
78 {
79 return getPluginKey(manifest);
80 }
81 else
82 {
83
84 return null;
85 }
86 }
87 else
88 {
89
90 return null;
91 }
92 }
93 finally
94 {
95 IOUtils.closeQuietly(descriptorStream);
96 }
97 }
98
99
100
101
102
103
104
105
106
107 public Plugin create(final PluginArtifact pluginArtifact, final ModuleDescriptorFactory moduleDescriptorFactory)
108 {
109 checkNotNull(pluginArtifact, "The plugin artifact is required");
110 checkNotNull(moduleDescriptorFactory, "The module descriptor factory is required");
111
112 final String pluginKey = canCreate(pluginArtifact);
113 if (null == pluginKey)
114 {
115 log.warn("Unable to load plugin from '{}'", pluginArtifact);
116 return new UnloadablePlugin("PluginArtifact has no manifest or is not a bundle: '" + pluginArtifact + "'");
117 }
118 else
119 {
120 return new OsgiBundlePlugin(osgi, pluginKey, pluginArtifact);
121 }
122 }
123 }