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