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.PluginArtifact;
7 import com.atlassian.plugin.PluginParseException;
8 import com.atlassian.plugin.event.PluginEventManager;
9 import com.atlassian.plugin.factories.AbstractPluginFactory;
10 import com.atlassian.plugin.impl.UnloadablePlugin;
11 import com.atlassian.plugin.osgi.container.OsgiContainerManager;
12 import com.atlassian.plugin.osgi.factory.transform.PluginTransformationException;
13 import com.atlassian.plugin.parsers.DescriptorParser;
14 import com.google.common.base.Predicate;
15 import com.google.common.collect.Ranges;
16 import org.apache.commons.io.IOUtils;
17 import org.osgi.util.tracker.ServiceTracker;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 import java.io.File;
22 import java.io.InputStream;
23 import java.util.Set;
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 final OsgiContainerManager osgi;
42 private final String pluginDescriptorFileName;
43 private final PluginEventManager pluginEventManager;
44
45 private final OsgiChainedModuleDescriptorFactoryCreator osgiChainedModuleDescriptorFactoryCreator;
46
47
48
49
50 public RemotablePluginFactory(String pluginDescriptorFileName, Set<Application> applications, final OsgiContainerManager osgi, PluginEventManager pluginEventManager)
51 {
52 super(new OsgiPluginXmlDescriptorParserFactory(), applications);
53 this.pluginDescriptorFileName = checkNotNull(pluginDescriptorFileName, "Plugin descriptor is required");
54 this.osgi = checkNotNull(osgi, "The OSGi container is required");
55 this.pluginEventManager = checkNotNull(pluginEventManager, "The plugin event manager is required");
56 this.osgiChainedModuleDescriptorFactoryCreator = new OsgiChainedModuleDescriptorFactoryCreator(new OsgiChainedModuleDescriptorFactoryCreator.ServiceTrackerFactory()
57 {
58 public ServiceTracker create(String className)
59 {
60 return osgi.getServiceTracker(className);
61 }
62 });
63 }
64
65 @Override
66 protected InputStream getDescriptorInputStream(PluginArtifact pluginArtifact)
67 {
68 return pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
69 }
70
71 @Override
72 protected Predicate<Integer> isValidPluginsVersion()
73 {
74 return Ranges.singleton(Plugin.VERSION_3);
75 }
76
77
78
79
80
81
82
83
84
85
86
87 public Plugin create(PluginArtifact pluginArtifact, ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
88 {
89 checkNotNull(pluginArtifact, "The plugin deployment unit is required");
90 checkNotNull(moduleDescriptorFactory, "The module descriptor factory is required");
91
92 Plugin plugin = null;
93 InputStream pluginDescriptor = null;
94 try
95 {
96 pluginDescriptor = pluginArtifact.getResourceAsStream(pluginDescriptorFileName);
97 if (pluginDescriptor != null)
98 {
99 final ModuleDescriptorFactory combinedFactory = getChainedModuleDescriptorFactory(moduleDescriptorFactory, pluginArtifact);
100 final DescriptorParser parser = descriptorParserFactory.getInstance(pluginDescriptor, applications);
101
102 final String pluginKey = parser.getKey();
103 final Plugin osgiPlugin = new OsgiPlugin(pluginKey, osgi, pluginArtifact, pluginArtifact, pluginEventManager);
104
105
106 plugin = parser.configurePlugin(combinedFactory, osgiPlugin);
107 }
108 else
109 {
110 throw new PluginParseException("Attempt to create Remotable plugin without a plugin descriptor!");
111 }
112 }
113 catch (PluginTransformationException ex)
114 {
115 return reportUnloadablePlugin(pluginArtifact.toFile(), ex);
116 }
117 finally
118 {
119 IOUtils.closeQuietly(pluginDescriptor);
120 }
121 return plugin;
122 }
123
124
125
126
127
128
129
130
131 private ModuleDescriptorFactory getChainedModuleDescriptorFactory(ModuleDescriptorFactory originalFactory, final PluginArtifact pluginArtifact)
132 {
133 return osgiChainedModuleDescriptorFactoryCreator.create(new OsgiChainedModuleDescriptorFactoryCreator.ResourceLocator()
134 {
135 public boolean doesResourceExist(String name)
136 {
137 return pluginArtifact.doesResourceExist(name);
138 }
139 }, originalFactory);
140 }
141
142 private Plugin reportUnloadablePlugin(File file, Exception e)
143 {
144 log.error("Unable to load plugin: " + file, e);
145
146 UnloadablePlugin plugin = new UnloadablePlugin();
147 plugin.setErrorText("Unable to load plugin: " + e.getMessage());
148 return plugin;
149 }
150 }