View Javadoc

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   * Plugin deployer that deploys OSGi bundles that don't contain XML descriptor files
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       * @deprecated Since 2.2.0, use {@link #create(PluginArtifact,ModuleDescriptorFactory)} instead
71       */
72      public Plugin create(DeploymentUnit deploymentUnit, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
73      {
74          return create(new JarPluginArtifact(deploymentUnit.getPath()), moduleDescriptorFactory);
75      }
76      /**
77       * Deploys the plugin artifact
78       * @param pluginArtifact the plugin artifact to deploy
79       * @param moduleDescriptorFactory The factory for plugin modules
80       * @return The instantiated and populated plugin
81       * @throws PluginParseException If the descriptor cannot be parsed
82       * @since 2.2.0
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 }