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.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 import com.atlassian.plugin.osgi.factory.transform.PluginTransformationException;
14 import com.atlassian.plugin.parsers.DescriptorParser;
15 import org.apache.commons.io.IOUtils;
16 import org.dom4j.Element;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 import java.io.File;
21 import java.io.InputStream;
22 import java.util.Set;
23 import java.util.function.Predicate;
24
25 import static com.google.common.base.Preconditions.checkNotNull;
26
27
28
29
30
31
32
33
34
35
36
37 public final class RemotablePluginFactory extends AbstractPluginFactory {
38
39 private static final Logger log = LoggerFactory.getLogger(RemotablePluginFactory.class);
40
41 private static final Predicate<Integer> IS_PLUGINS_3 = input -> input == Plugin.VERSION_3;
42
43 private final OsgiContainerManager osgi;
44 private final String pluginDescriptorFileName;
45 private final PluginEventManager pluginEventManager;
46
47 private final OsgiChainedModuleDescriptorFactoryCreator osgiChainedModuleDescriptorFactoryCreator;
48
49
50
51
52 public RemotablePluginFactory(String pluginDescriptorFileName, Set<Application> applications, final OsgiContainerManager osgi, PluginEventManager pluginEventManager) {
53 super(new OsgiPluginXmlDescriptorParserFactory(), applications);
54 this.pluginDescriptorFileName = checkNotNull(pluginDescriptorFileName, "Plugin descriptor is required");
55 this.osgi = checkNotNull(osgi, "The OSGi container is required");
56 this.pluginEventManager = checkNotNull(pluginEventManager, "The plugin event manager is required");
57 this.osgiChainedModuleDescriptorFactoryCreator = new OsgiChainedModuleDescriptorFactoryCreator(osgi::getServiceTracker);
58 }
59
60 @Override
61 protected InputStream getDescriptorInputStream(PluginArtifact pluginArtifact) {
62 return pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
63 }
64
65 @Override
66 protected Predicate<Integer> isValidPluginsVersion() {
67 return IS_PLUGINS_3;
68 }
69
70
71
72
73
74
75
76
77
78
79
80 public Plugin create(PluginArtifact pluginArtifact, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException {
81 checkNotNull(pluginArtifact, "The plugin deployment unit is required");
82 checkNotNull(moduleDescriptorFactory, "The module descriptor factory is required");
83
84 Plugin plugin;
85 InputStream pluginDescriptor = null;
86 try {
87 pluginDescriptor = pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
88 if (pluginDescriptor != null) {
89 final ModuleDescriptorFactory combinedFactory = getChainedModuleDescriptorFactory(moduleDescriptorFactory, pluginArtifact);
90 final DescriptorParser parser = descriptorParserFactory.getInstance(pluginDescriptor, applications);
91
92 final String pluginKey = parser.getKey();
93 final Plugin osgiPlugin = new OsgiPlugin(pluginKey, osgi, pluginArtifact, pluginArtifact, pluginEventManager);
94
95
96 plugin = parser.configurePlugin(combinedFactory, osgiPlugin);
97 } else {
98 throw new PluginParseException("Attempt to create Remotable plugin without a plugin descriptor!");
99 }
100 } catch (PluginTransformationException ex) {
101 return reportUnloadablePlugin(pluginArtifact.toFile(), ex);
102 } finally {
103 IOUtils.closeQuietly(pluginDescriptor);
104 }
105 return plugin;
106 }
107
108 @Override
109 public ModuleDescriptor<?> createModule(final Plugin plugin, final Element module, final ModuleDescriptorFactory moduleDescriptorFactory) {
110
111
112 return null;
113 }
114
115
116
117
118
119
120
121
122 private ModuleDescriptorFactory getChainedModuleDescriptorFactory(ModuleDescriptorFactory originalFactory, final PluginArtifact pluginArtifact) {
123 return osgiChainedModuleDescriptorFactoryCreator.create(pluginArtifact::doesResourceExist, originalFactory);
124 }
125
126 private Plugin reportUnloadablePlugin(File file, Exception e) {
127 log.error("Unable to load plugin: " + file, e);
128
129 UnloadablePlugin plugin = new UnloadablePlugin();
130 plugin.setErrorText("Unable to load plugin: " + e.getMessage());
131 return plugin;
132 }
133 }