1 package com.atlassian.plugin.osgi.factory;
2
3 import com.atlassian.plugin.*;
4 import com.atlassian.plugin.event.PluginEventManager;
5 import com.atlassian.plugin.impl.UnloadablePlugin;
6 import com.atlassian.plugin.factories.PluginFactory;
7 import com.atlassian.plugin.loaders.classloading.DeploymentUnit;
8 import com.atlassian.plugin.osgi.container.OsgiContainerException;
9 import com.atlassian.plugin.osgi.container.OsgiContainerManager;
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12 import org.apache.commons.lang.Validate;
13 import org.apache.commons.io.IOUtils;
14 import org.osgi.framework.Constants;
15 import org.osgi.framework.Bundle;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.jar.Manifest;
21
22
23
24
25 public class OsgiBundleFactory implements PluginFactory
26 {
27 private static final Log log = LogFactory.getLog(OsgiBundleFactory.class);
28
29 private final OsgiContainerManager osgi;
30 private final PluginEventManager pluginEventManager;
31
32 public OsgiBundleFactory(OsgiContainerManager osgi, PluginEventManager pluginEventManager)
33 {
34 Validate.notNull(osgi, "The osgi container is required");
35 this.osgi = osgi;
36 this.pluginEventManager = pluginEventManager;
37 }
38
39 public String canCreate(PluginArtifact pluginArtifact) throws PluginParseException {
40 Validate.notNull(pluginArtifact, "The plugin artifact is required");
41 String pluginKey = null;
42 InputStream manifestStream = pluginArtifact.getResourceAsStream("META-INF/MANIFEST.MF");
43
44 try
45 {
46 if (manifestStream != null)
47 {
48 Manifest mf;
49 try {
50 mf = new Manifest(manifestStream);
51 } catch (IOException e) {
52 throw new PluginParseException("Unable to parse manifest", e);
53 }
54 String symName = mf.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
55 if (symName != null)
56 {
57 pluginKey = getPluginKey(mf.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME),
58 mf.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
59 }
60 }
61 return pluginKey;
62 }
63 finally
64 {
65 IOUtils.closeQuietly(manifestStream);
66 }
67 }
68
69
70
71
72 public Plugin create(DeploymentUnit deploymentUnit, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
73 {
74 return create(new JarPluginArtifact(deploymentUnit.getPath()), moduleDescriptorFactory);
75 }
76
77
78
79
80
81
82
83
84 public Plugin create(PluginArtifact pluginArtifact, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
85 {
86 Validate.notNull(pluginArtifact, "The plugin artifact is required");
87 Validate.notNull(moduleDescriptorFactory, "The module descriptor factory is required");
88
89 File file = pluginArtifact.toFile();
90 Bundle bundle;
91 try
92 {
93 bundle = osgi.installBundle(file);
94 } catch (OsgiContainerException ex)
95 {
96 return reportUnloadablePlugin(file, ex);
97 }
98 String key = getPluginKey(bundle.getSymbolicName(), (String) bundle.getHeaders().get(Constants.BUNDLE_VERSION));
99 return new OsgiBundlePlugin(bundle, key, pluginEventManager);
100 }
101
102 private Plugin reportUnloadablePlugin(File file, Exception e)
103 {
104 log.error("Unable to load plugin: "+file, e);
105
106 UnloadablePlugin plugin = new UnloadablePlugin();
107 plugin.setErrorText("Unable to load plugin: "+e.getMessage());
108 return plugin;
109 }
110
111 private String getPluginKey(String symbolicName, String version)
112 {
113 return symbolicName + "-" + version;
114 }
115 }