1 package com.atlassian.plugin.osgi.factory;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4 import com.atlassian.plugin.PluginState;
5 import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
6 import com.atlassian.plugin.event.PluginEventManager;
7 import com.atlassian.plugin.event.events.PluginModuleAvailableEvent;
8 import com.atlassian.plugin.event.events.PluginModuleUnavailableEvent;
9 import com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory;
10 import org.dom4j.Element;
11 import org.osgi.framework.Bundle;
12 import org.osgi.framework.ServiceReference;
13 import org.osgi.util.tracker.ServiceTrackerCustomizer;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import static com.google.common.base.Preconditions.checkNotNull;
21
22
23
24
25
26
27
28
29 class UnrecognizedModuleDescriptorServiceTrackerCustomizer implements ServiceTrackerCustomizer
30 {
31 private static final Logger log = LoggerFactory.getLogger(UnrecognizedModuleDescriptorServiceTrackerCustomizer.class);
32
33 private final Bundle bundle;
34 private final OsgiPlugin plugin;
35 private final PluginEventManager pluginEventManager;
36
37 public UnrecognizedModuleDescriptorServiceTrackerCustomizer(OsgiPlugin plugin, PluginEventManager pluginEventManager)
38 {
39 this.plugin = checkNotNull(plugin);
40 this.bundle = checkNotNull(plugin.getBundle());
41 this.pluginEventManager = checkNotNull(pluginEventManager);
42 }
43
44
45
46
47
48 public Object addingService(final ServiceReference serviceReference)
49 {
50 final ListableModuleDescriptorFactory factory = (ListableModuleDescriptorFactory) bundle.getBundleContext().getService(serviceReference);
51
52
53
54 if (canFactoryResolveUnrecognizedDescriptor(factory) || isFactoryInUse(factory))
55 {
56 return factory;
57 }
58 else
59 {
60
61
62 bundle.getBundleContext().ungetService(serviceReference);
63 return null;
64 }
65 }
66
67
68
69
70
71
72
73 private boolean canFactoryResolveUnrecognizedDescriptor(ListableModuleDescriptorFactory factory)
74 {
75 boolean usedFactory = false;
76 for (final UnrecognisedModuleDescriptor unrecognised : getModuleDescriptorsByDescriptorClass(UnrecognisedModuleDescriptor.class))
77 {
78 final Element source = plugin.getModuleElements().get(unrecognised.getKey());
79 if ((source != null) && factory.hasModuleDescriptor(source.getName()))
80 {
81 usedFactory = true;
82 try
83 {
84 final ModuleDescriptor<?> descriptor = factory.getModuleDescriptor(source.getName());
85 descriptor.init(unrecognised.getPlugin(), source);
86 plugin.addModuleDescriptor(descriptor);
87 if (log.isInfoEnabled())
88 {
89 log.info("Turned unrecognized plugin module " + descriptor.getCompleteKey() + " into module " + descriptor);
90 }
91 pluginEventManager.broadcast(new PluginModuleAvailableEvent(descriptor));
92 }
93 catch (final Exception e)
94 {
95 log.error("Unable to transform " + unrecognised.getCompleteKey() + " into actual plugin module using factory " + factory, e);
96 unrecognised.setErrorText(e.getMessage());
97 }
98 }
99 }
100 return usedFactory;
101 }
102
103
104
105
106
107
108 private boolean isFactoryInUse(ListableModuleDescriptorFactory factory)
109 {
110 for (ModuleDescriptor<?> descriptor : plugin.getModuleDescriptors())
111 {
112 for (Class<? extends ModuleDescriptor> descriptorClass : factory.getModuleDescriptorClasses())
113 {
114 if (descriptorClass == descriptor.getClass())
115 {
116 return true;
117 }
118 }
119 }
120 return false;
121 }
122
123 public void modifiedService(final ServiceReference serviceReference, final Object o)
124 {
125
126 }
127
128
129
130
131
132 public void removedService(final ServiceReference serviceReference, final Object o)
133 {
134 final ListableModuleDescriptorFactory factory = (ListableModuleDescriptorFactory) o;
135 for (final Class<? extends ModuleDescriptor> moduleDescriptorClass : factory.getModuleDescriptorClasses())
136 {
137 for (final ModuleDescriptor<?> descriptor : getModuleDescriptorsByDescriptorClass(moduleDescriptorClass))
138 {
139 if (plugin.getPluginState() == PluginState.ENABLED)
140 {
141 pluginEventManager.broadcast(new PluginModuleUnavailableEvent(descriptor));
142 }
143 final UnrecognisedModuleDescriptor unrecognisedModuleDescriptor = new UnrecognisedModuleDescriptor();
144 final Element source = plugin.getModuleElements().get(descriptor.getKey());
145 if (source != null )
146 {
147 unrecognisedModuleDescriptor.init(plugin, source);
148 unrecognisedModuleDescriptor.setErrorText(UnrecognisedModuleDescriptorFallbackFactory.DESCRIPTOR_TEXT);
149 plugin.addModuleDescriptor(unrecognisedModuleDescriptor);
150
151 if (plugin.getPluginState() == PluginState.ENABLED)
152 {
153 pluginEventManager.broadcast(new PluginModuleAvailableEvent(unrecognisedModuleDescriptor));
154 if (log.isInfoEnabled())
155 {
156 log.info("Removed plugin module " + unrecognisedModuleDescriptor.getCompleteKey() + " as its factory was uninstalled");
157 }
158 }
159 }
160 }
161 }
162 }
163
164
165
166
167
168
169
170 <T extends ModuleDescriptor<?>> List<T> getModuleDescriptorsByDescriptorClass(final Class<T> descriptor)
171 {
172 final List<T> result = new ArrayList<T>();
173
174 for (final ModuleDescriptor<?> moduleDescriptor : plugin.getModuleDescriptors())
175 {
176 if (descriptor.isAssignableFrom(moduleDescriptor.getClass()))
177 {
178 result.add(descriptor.cast(moduleDescriptor));
179 }
180 }
181 return result;
182 }
183 }