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
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.List;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public class OsgiChainedModuleDescriptorFactoryCreator {
32 private final ServiceTrackerFactory serviceTrackerFactory;
33 private final ModuleDescriptorFactory transformedDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer()) {{
34 addModuleDescriptor("component", ComponentModuleDescriptor.class);
35 addModuleDescriptor("component-import", ComponentImportModuleDescriptor.class);
36 addModuleDescriptor("module-type", ModuleTypeModuleDescriptor.class);
37 }};
38
39 private volatile ServiceTracker moduleDescriptorFactoryTracker;
40
41 public interface ServiceTrackerFactory {
42
43 ServiceTracker create(String className);
44 }
45
46 public interface ResourceLocator {
47 boolean doesResourceExist(String name);
48 }
49
50 public OsgiChainedModuleDescriptorFactoryCreator(ServiceTrackerFactory serviceTrackerFactory) {
51 this.serviceTrackerFactory = serviceTrackerFactory;
52 }
53
54 public ModuleDescriptorFactory create(ResourceLocator resourceLocator, ModuleDescriptorFactory originalModuleDescriptorFactory) {
55
56 synchronized (this) {
57 if (moduleDescriptorFactoryTracker == null) {
58 moduleDescriptorFactoryTracker = serviceTrackerFactory.create(ModuleDescriptorFactory.class.getName());
59 }
60 }
61
62 List<ModuleDescriptorFactory> factories = new ArrayList<>();
63
64 factories.add(transformedDescriptorFactory);
65 factories.add(originalModuleDescriptorFactory);
66 Object[] serviceObjs = moduleDescriptorFactoryTracker.getServices();
67
68 Collection<ModuleDescriptorFactory> wrappedListable = new ArrayList<>();
69
70
71 if (serviceObjs != null) {
72 for (Object fac : serviceObjs) {
73 ModuleDescriptorFactory dynFactory = (ModuleDescriptorFactory) fac;
74
75
76
77 if (!(dynFactory instanceof ListableModuleDescriptorFactory)) {
78 factories.add((ModuleDescriptorFactory) fac);
79 } else {
80 for (Class<? extends ModuleDescriptor> descriptor : ((ListableModuleDescriptorFactory) dynFactory).getModuleDescriptorClasses()) {
81
82 if (!resourceLocator.doesResourceExist(descriptor.getName().replace('.', '/') + ".class")) {
83 wrappedListable.add(new UnavailableModuleDescriptorRequiringRestartFallbackFactory((ModuleDescriptorFactory) fac));
84 break;
85 }
86 }
87 }
88 }
89 }
90
91 factories.add(new ChainModuleDescriptorFactory(wrappedListable));
92
93
94 factories.add(new UnrecognisedModuleDescriptorFallbackFactory());
95
96 return new ChainModuleDescriptorFactory(factories);
97 }
98 }