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 private static final Logger log = LoggerFactory.getLogger(OsgiChainedModuleDescriptorFactoryCreator.class);
43
44 private volatile ServiceTracker moduleDescriptorFactoryTracker;
45
46 public static interface ServiceTrackerFactory
47 {
48
49 ServiceTracker create(String className);
50 }
51
52 public static interface ResourceLocator
53 {
54 boolean doesResourceExist(String name);
55 }
56
57 public OsgiChainedModuleDescriptorFactoryCreator(ServiceTrackerFactory serviceTrackerFactory)
58 {
59 this.serviceTrackerFactory = serviceTrackerFactory;
60 }
61
62 public ModuleDescriptorFactory create(ResourceLocator resourceLocator, ModuleDescriptorFactory originalModuleDescriptorFactory)
63 {
64
65 synchronized (this)
66 {
67 if (moduleDescriptorFactoryTracker == null)
68 {
69 moduleDescriptorFactoryTracker = serviceTrackerFactory.create(ModuleDescriptorFactory.class.getName());
70 }
71 }
72
73 List<ModuleDescriptorFactory> factories = new ArrayList<ModuleDescriptorFactory>();
74
75 factories.add(transformedDescriptorFactory);
76 factories.add(originalModuleDescriptorFactory);
77 Object[] serviceObjs = moduleDescriptorFactoryTracker.getServices();
78
79 Collection<ModuleDescriptorFactory> wrappedListable = new ArrayList<ModuleDescriptorFactory>();
80
81
82 if (serviceObjs != null)
83 {
84 for (Object fac : serviceObjs)
85 {
86 ModuleDescriptorFactory dynFactory = (ModuleDescriptorFactory) fac;
87
88
89
90 if (!(dynFactory instanceof ListableModuleDescriptorFactory))
91 {
92 factories.add((ModuleDescriptorFactory) fac);
93 }
94 else
95 {
96 for (Class<ModuleDescriptor<?>> descriptor : ((ListableModuleDescriptorFactory)dynFactory).getModuleDescriptorClasses())
97 {
98
99 if (!resourceLocator.doesResourceExist(descriptor.getName().replace('.','/') + ".class"))
100 {
101 wrappedListable.add(new UnavailableModuleDescriptorRequiringRestartFallbackFactory((ModuleDescriptorFactory) fac));
102 break;
103 }
104 }
105 }
106 }
107 }
108
109 factories.add(new ChainModuleDescriptorFactory(wrappedListable));
110
111
112 factories.add(new UnrecognisedModuleDescriptorFallbackFactory());
113
114 return new ChainModuleDescriptorFactory(factories);
115 }
116 }