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