1 package com.atlassian.plugin.osgi.factory;
2
3 import org.osgi.util.tracker.ServiceTrackerCustomizer;
4 import org.osgi.framework.ServiceReference;
5 import org.osgi.framework.Bundle;
6 import org.dom4j.Element;
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.apache.commons.lang.Validate;
10 import com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory;
11 import com.atlassian.plugin.descriptors.UnrecognisedModuleDescriptor;
12 import com.atlassian.plugin.ModuleDescriptor;
13
14 import java.util.List;
15 import java.util.ArrayList;
16
17
18
19
20
21
22
23
24 class UnrecognizedModuleDescriptorServiceTrackerCustomizer implements ServiceTrackerCustomizer
25 {
26 private static final Log log = LogFactory.getLog(UnrecognizedModuleDescriptorServiceTrackerCustomizer.class);
27
28 private final Bundle bundle;
29 private final OsgiPlugin plugin;
30
31 public UnrecognizedModuleDescriptorServiceTrackerCustomizer(OsgiPlugin plugin)
32 {
33 Validate.notNull(plugin);
34 this.bundle = plugin.getBundle();
35 Validate.notNull(bundle);
36 this.plugin = plugin;
37 }
38
39
40
41
42 public Object addingService(final ServiceReference serviceReference)
43 {
44 final ListableModuleDescriptorFactory factory = (ListableModuleDescriptorFactory) bundle.getBundleContext().getService(serviceReference);
45 boolean usedFactory = false;
46 for (final UnrecognisedModuleDescriptor unrecognised : getModuleDescriptorsByDescriptorClass(UnrecognisedModuleDescriptor.class))
47 {
48 final Element source = plugin.getModuleElements().get(unrecognised.getKey());
49 if ((source != null) && factory.hasModuleDescriptor(source.getName()))
50 {
51 usedFactory = true;
52 try
53 {
54 final ModuleDescriptor<?> descriptor = factory.getModuleDescriptor(source.getName());
55 descriptor.init(unrecognised.getPlugin(), source);
56 plugin.addModuleDescriptor(descriptor);
57 if (log.isInfoEnabled())
58 {
59 log.info("Turned plugin module " + descriptor.getCompleteKey() + " into module " + descriptor);
60 }
61 }
62 catch (final Exception e)
63 {
64 log.error("Unable to transform " + unrecognised.getCompleteKey() + " into actual plugin module using factory " + factory, e);
65 unrecognised.setErrorText(e.getMessage());
66 }
67 }
68 }
69 if (usedFactory)
70 {
71 return factory;
72 }
73 else
74 {
75
76
77 bundle.getBundleContext().ungetService(serviceReference);
78 return null;
79 }
80 }
81
82
83
84
85 public void modifiedService(final ServiceReference serviceReference, final Object o)
86 {
87 removedService(serviceReference, o);
88 addingService(serviceReference);
89 }
90
91
92
93
94
95 public void removedService(final ServiceReference serviceReference, final Object o)
96 {
97 final ListableModuleDescriptorFactory factory = (ListableModuleDescriptorFactory) o;
98 for (final Class<ModuleDescriptor<?>> moduleDescriptorClass : factory.getModuleDescriptorClasses())
99 {
100 for (final ModuleDescriptor<?> descriptor : getModuleDescriptorsByDescriptorClass(moduleDescriptorClass))
101 {
102 final UnrecognisedModuleDescriptor unrecognisedModuleDescriptor = new UnrecognisedModuleDescriptor();
103 final Element source = plugin.getModuleElements().get(descriptor.getKey());
104 if (source != null)
105 {
106 unrecognisedModuleDescriptor.init(plugin, source);
107 unrecognisedModuleDescriptor.setErrorText(UnrecognisedModuleDescriptorFallbackFactory.DESCRIPTOR_TEXT);
108 plugin.addModuleDescriptor(unrecognisedModuleDescriptor);
109 if (log.isInfoEnabled())
110 {
111 log.info("Removed plugin module " + unrecognisedModuleDescriptor.getCompleteKey() + " as its factory was uninstalled");
112 }
113 }
114 }
115 }
116 }
117
118
119
120
121
122
123
124 <T extends ModuleDescriptor<?>> List<T> getModuleDescriptorsByDescriptorClass(final Class<T> descriptor)
125 {
126 final List<T> result = new ArrayList<T>();
127
128 for (final ModuleDescriptor<?> moduleDescriptor : plugin.getModuleDescriptors())
129 {
130 if (moduleDescriptor.getClass()
131 .isAssignableFrom(descriptor))
132 {
133 result.add(descriptor.cast(moduleDescriptor));
134 }
135 }
136 return result;
137 }
138 }