1 package com.atlassian.plugin.osgi.factory;
2
3 import com.atlassian.plugin.JarPluginArtifact;
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.PluginFactory;
11 import com.atlassian.plugin.impl.UnloadablePlugin;
12 import com.atlassian.plugin.loaders.classloading.DeploymentUnit;
13 import com.atlassian.plugin.osgi.container.OsgiContainerException;
14 import com.atlassian.plugin.osgi.container.OsgiContainerManager;
15 import com.atlassian.plugin.osgi.util.OsgiHeaderUtil;
16 import com.atlassian.plugin.parsers.DescriptorParser;
17 import org.apache.commons.io.IOUtils;
18 import org.apache.commons.lang.Validate;
19 import org.osgi.framework.Bundle;
20 import org.osgi.framework.Constants;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.jar.Manifest;
28
29
30
31
32 public class OsgiBundleFactory implements PluginFactory
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 OsgiPluginXmlDescriptorParserFactory descriptorParserFactory;
39 private final String pluginDescriptorFileName;
40
41 public OsgiBundleFactory(OsgiContainerManager osgi, PluginEventManager pluginEventManager)
42 {
43 this(PluginAccessor.Descriptor.FILENAME, osgi, pluginEventManager);
44 }
45
46 public OsgiBundleFactory(String pluginDescriptorFileName, OsgiContainerManager osgi, PluginEventManager pluginEventManager)
47 {
48 this.pluginDescriptorFileName = pluginDescriptorFileName;
49 Validate.notNull(osgi, "The osgi container is required");
50 Validate.notNull(pluginEventManager, "The plugin event manager is required");
51 this.osgi = osgi;
52 this.pluginEventManager = pluginEventManager;
53 this.descriptorParserFactory = new OsgiPluginXmlDescriptorParserFactory();
54 }
55
56 public String canCreate(PluginArtifact pluginArtifact) throws PluginParseException {
57 Validate.notNull(pluginArtifact, "The plugin artifact is required");
58 String pluginKey = null;
59 InputStream manifestStream = null;
60 InputStream descriptorStream = null;
61
62 try
63 {
64 manifestStream = pluginArtifact.getResourceAsStream("META-INF/MANIFEST.MF");
65 if (manifestStream != null)
66 {
67 Manifest mf;
68 try {
69 mf = new Manifest(manifestStream);
70 } catch (IOException e) {
71 throw new PluginParseException("Unable to parse manifest", e);
72 }
73 String symName = mf.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
74 if (symName != null)
75 {
76 pluginKey = OsgiHeaderUtil.getPluginKey(mf);
77
78
79 descriptorStream = pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
80 if (descriptorStream != null)
81 {
82 final DescriptorParser descriptorParser = descriptorParserFactory.getInstance(descriptorStream);
83 if (descriptorParser.getPluginsVersion() == 1)
84 {
85
86 pluginKey = null;
87 }
88 }
89
90 }
91 }
92 return pluginKey;
93 }
94 finally
95 {
96 IOUtils.closeQuietly(manifestStream);
97 IOUtils.closeQuietly(descriptorStream);
98 }
99 }
100
101
102
103
104 public Plugin create(DeploymentUnit deploymentUnit, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
105 {
106 Validate.notNull(deploymentUnit, "The deployment unit is required");
107 return create(new JarPluginArtifact(deploymentUnit.getPath()), moduleDescriptorFactory);
108 }
109
110
111
112
113
114
115
116
117 public Plugin create(PluginArtifact pluginArtifact, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
118 {
119 Validate.notNull(pluginArtifact, "The plugin artifact is required");
120 Validate.notNull(moduleDescriptorFactory, "The module descriptor factory is required");
121
122 File file = pluginArtifact.toFile();
123 Bundle bundle;
124 try
125 {
126 bundle = osgi.installBundle(file);
127 } catch (OsgiContainerException ex)
128 {
129 return reportUnloadablePlugin(file, ex);
130 }
131 String key = OsgiHeaderUtil.getPluginKey(bundle);
132 return new OsgiBundlePlugin(bundle, key, pluginArtifact, pluginEventManager);
133 }
134
135 private Plugin reportUnloadablePlugin(File file, Exception e)
136 {
137 log.error("Unable to load plugin: "+file, e);
138
139 UnloadablePlugin plugin = new UnloadablePlugin();
140 plugin.setErrorText("Unable to load plugin: "+e.getMessage());
141 return plugin;
142 }
143 }