1 package com.atlassian.plugin.osgi.factory;
2
3 import com.atlassian.plugin.DefaultModuleDescriptorFactory;
4 import com.atlassian.plugin.ModuleDescriptor;
5 import com.atlassian.plugin.ModuleDescriptorFactory;
6 import com.atlassian.plugin.descriptors.ChainModuleDescriptorFactory;
7 import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
8 import com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory;
9 import com.atlassian.plugin.osgi.factory.descriptor.ComponentImportModuleDescriptor;
10 import com.atlassian.plugin.osgi.factory.descriptor.ComponentModuleDescriptor;
11 import com.atlassian.plugin.osgi.factory.descriptor.ModuleTypeModuleDescriptor;
12 import org.osgi.util.tracker.ServiceTracker;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.List;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public class OsgiChainedModuleDescriptorFactoryCreator
34 {
35 private final ServiceTrackerFactory serviceTrackerFactory;
36 private final ModuleDescriptorFactory transformedDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer())
37 {{
38 addModuleDescriptor("component", ComponentModuleDescriptor.class);
39 addModuleDescriptor("component-import", ComponentImportModuleDescriptor.class);
40 addModuleDescriptor("module-type", ModuleTypeModuleDescriptor.class);
41 }};
42
43 private volatile ServiceTracker moduleDescriptorFactoryTracker;
44
45 public static interface ServiceTrackerFactory
46 {
47
48 ServiceTracker create(String className);
49 }
50
51 public static interface ResourceLocator
52 {
53 boolean doesResourceExist(String name);
54 }
55
56 public OsgiChainedModuleDescriptorFactoryCreator(ServiceTrackerFactory serviceTrackerFactory)
57 {
58 this.serviceTrackerFactory = serviceTrackerFactory;
59 }
60
61 public ModuleDescriptorFactory create(ResourceLocator resourceLocator, ModuleDescriptorFactory originalModuleDescriptorFactory)
62 {
63
64 synchronized (this)
65 {
66 if (moduleDescriptorFactoryTracker == null)
67 {
68 moduleDescriptorFactoryTracker = serviceTrackerFactory.create(ModuleDescriptorFactory.class.getName());
69 }
70 }
71
72 List<ModuleDescriptorFactory> factories = new ArrayList<ModuleDescriptorFactory>();
73
74 factories.add(transformedDescriptorFactory);
75 factories.add(originalModuleDescriptorFactory);
76 Object[] serviceObjs = moduleDescriptorFactoryTracker.getServices();
77
78 Collection<ModuleDescriptorFactory> wrappedListable = new ArrayList<ModuleDescriptorFactory>();
79
80
81 if (serviceObjs != null)
82 {
83 for (Object fac : serviceObjs)
84 {
85 ModuleDescriptorFactory dynFactory = (ModuleDescriptorFactory) fac;
86
87
88
89 if (!(dynFactory instanceof ListableModuleDescriptorFactory))
90 {
91 factories.add((ModuleDescriptorFactory) fac);
92 }
93 else
94 {
95 for (Class<? extends ModuleDescriptor> descriptor : ((ListableModuleDescriptorFactory)dynFactory).getModuleDescriptorClasses())
96 {
97
98 if (!resourceLocator.doesResourceExist(descriptor.getName().replace('.','/') + ".class"))
99 {
100 wrappedListable.add(new UnavailableModuleDescriptorRequiringRestartFallbackFactory((ModuleDescriptorFactory) fac));
101 break;
102 }
103 }
104 }
105 }
106 }
107
108 factories.add(new ChainModuleDescriptorFactory(wrappedListable));
109
110
111 factories.add(new UnrecognisedModuleDescriptorFallbackFactory());
112
113 return new ChainModuleDescriptorFactory(factories);
114 }
115 }