View Javadoc

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   * Plugin deployer that deploys OSGi bundles that don't contain XML descriptor files
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                      // It's not a bundle - it has no manifest, or the manifest doesn't contain a required key
84                      return null;
85                  }
86              }
87              else
88              {
89                  // It's an Atlassian Plugin, not a plain bundle
90                  return null;
91              }
92          }
93          finally
94          {
95              IOUtils.closeQuietly(descriptorStream);
96          }
97      }
98  
99      /**
100      * Create a plugin from the given artifact.
101      *
102      * @param pluginArtifact the plugin artifact containing the plugin.
103      * @param moduleDescriptorFactory The factory for plugin modules.
104      * @return The instantiated and populated plugin, or an {@link UnloadablePlugin} if the plugin cannot be loaded.
105      * @since 2.2.0
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 }