View Javadoc
1   package com.atlassian.plugin.osgi.factory;
2   
3   import com.atlassian.plugin.Application;
4   import com.atlassian.plugin.ModuleDescriptor;
5   import com.atlassian.plugin.ModuleDescriptorFactory;
6   import com.atlassian.plugin.Plugin;
7   import com.atlassian.plugin.PluginArtifact;
8   import com.atlassian.plugin.PluginException;
9   import com.atlassian.plugin.PluginParseException;
10  import com.atlassian.plugin.factories.AbstractPluginFactory;
11  import com.atlassian.plugin.impl.UnloadablePlugin;
12  import com.atlassian.plugin.parsers.DescriptorParser;
13  import com.atlassian.plugin.parsers.XmlDescriptorParserFactory;
14  import com.google.common.base.Predicate;
15  import com.google.common.collect.ImmutableSet;
16  import org.apache.commons.io.IOUtils;
17  import org.dom4j.Element;
18  
19  import java.io.InputStream;
20  
21  import static com.google.common.base.Preconditions.checkNotNull;
22  
23  /**
24   * Creates unloadable plugins from static plugins.  Used to handle when a static plugin (version 1) is deployed
25   * to a directory that only accepts OSGi plugins.  This should be placed last in the chain of plugin factories and
26   * only if {@link com.atlassian.plugin.factories.LegacyDynamicPluginFactory} is not used.
27   *
28   * @since 2.2.3
29   */
30  public final class UnloadableStaticPluginFactory extends AbstractPluginFactory {
31      private final String pluginDescriptorFileName;
32  
33      public UnloadableStaticPluginFactory(String pluginDescriptorFileName) {
34          super(new XmlDescriptorParserFactory(), ImmutableSet.<Application>of());
35          this.pluginDescriptorFileName = pluginDescriptorFileName;
36      }
37  
38      @Override
39      protected InputStream getDescriptorInputStream(PluginArtifact pluginArtifact) {
40          return pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
41      }
42  
43      @Override
44      protected Predicate<Integer> isValidPluginsVersion() {
45          return new Predicate<Integer>() {
46              @Override
47              public boolean apply(final Integer input) {
48                  return input == Plugin.VERSION_1;
49              }
50          };
51      }
52  
53      /**
54       * Creates an unloadable plugin
55       *
56       * @param pluginArtifact          the plugin artifact to deploy
57       * @param moduleDescriptorFactory The factory for plugin modules
58       * @return The instantiated and populated plugin
59       * @throws PluginParseException If the descriptor cannot be parsed
60       */
61      public Plugin create(PluginArtifact pluginArtifact, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException {
62          checkNotNull(pluginArtifact, "The plugin deployment unit is required");
63          checkNotNull(moduleDescriptorFactory, "The module descriptor factory is required");
64  
65          UnloadablePlugin plugin = null;
66          InputStream pluginDescriptor = null;
67          try {
68              pluginDescriptor = pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
69              if (pluginDescriptor == null) {
70                  throw new PluginParseException("No descriptor found in classloader for : " + pluginArtifact);
71              }
72  
73              DescriptorParser parser = descriptorParserFactory.getInstance(pluginDescriptor, ImmutableSet.<Application>of());
74  
75              plugin = new UnloadablePlugin();
76              // This should be a valid plugin, it just got put in the wrong directory.
77              // We'll try to do a full configure because it looks more user-friendly.
78              try {
79                  parser.configurePlugin(moduleDescriptorFactory, plugin);
80              } catch (Exception ex) {
81                  // Error on full configure - we'll just set the key as this is an UnloadablePlugin anyway.
82                  plugin.setKey(parser.getKey());
83              }
84              plugin.setErrorText("Unable to load the static '" + pluginArtifact + "' plugin from the plugins directory.  Please " +
85                      "copy this file into WEB-INF/lib and restart.");
86          } finally {
87              IOUtils.closeQuietly(pluginDescriptor);
88          }
89          return plugin;
90      }
91  
92      @Override
93      public ModuleDescriptor<?> createModule(final Plugin plugin, final Element module, final ModuleDescriptorFactory moduleDescriptorFactory) {
94          if (plugin instanceof UnloadablePlugin) {
95              throw new PluginException("cannot create modules for an UnloadablePlugin");
96          }
97          return null;
98      }
99  }