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