1 package org.simantics.scl.osgi.internal;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Enumeration;
8 import org.osgi.framework.Bundle;
9 import org.osgi.framework.BundleContext;
10 import org.osgi.framework.BundleEvent;
11 import org.osgi.service.component.ComponentContext;
12 import org.osgi.service.component.annotations.Activate;
13 import org.osgi.service.component.annotations.Component;
14 import org.osgi.service.component.annotations.Deactivate;
15 import org.osgi.util.tracker.BundleTracker;
16 import org.simantics.scl.compiler.module.repository.UpdateListener;
17 import org.simantics.scl.compiler.source.ModuleSource;
18 import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
20 import gnu.trove.map.hash.THashMap;
21 import gnu.trove.procedure.TObjectObjectProcedure;
22 import gnu.trove.set.hash.THashSet;
25 public class BundleModuleSourceRepository implements ModuleSourceRepository {
28 THashMap<String, BundleModuleSource> modules = new THashMap<String, BundleModuleSource>();
29 THashMap<Bundle, ArrayList<String>> modulesPerBundle = new THashMap<Bundle, ArrayList<String>>();
30 THashMap<String, BundleDocumentationSource> documentations = new THashMap<String, BundleDocumentationSource>();
31 THashMap<Bundle, ArrayList<String>> documentationsPerBundle = new THashMap<Bundle, ArrayList<String>>();
33 class Tracker extends BundleTracker<Bundle> {
34 public Tracker(BundleContext context) {
35 super(context, 0xffffffff, null);
39 public Bundle addingBundle(Bundle bundle, BundleEvent event) {
40 synchronized(BundleModuleSourceRepository.this) {
41 Enumeration<URL> moduleEntries = bundle.findEntries("scl", "*.scl", true);
42 if(moduleEntries != null) {
43 ArrayList<String> modulesInThisBundle = new ArrayList<String>();
44 while(moduleEntries.hasMoreElements()) {
45 URL url = moduleEntries.nextElement();
46 String path = url.getPath();
47 String moduleName = path.substring(5, path.length()-4);
48 modules.put(moduleName, new BundleModuleSource(moduleName, bundle, url));
49 modulesInThisBundle.add(moduleName);
51 modulesPerBundle.put(bundle, modulesInThisBundle);
54 modulesPerBundle.put(bundle, new ArrayList<String>(0));
56 Enumeration<URL> documentationEntries = bundle.findEntries("scl", "*.md", true);
57 if(documentationEntries != null) {
58 ArrayList<String> documentationsInThisBundle = new ArrayList<String>();
59 while(documentationEntries.hasMoreElements()) {
60 URL url = documentationEntries.nextElement();
61 String path = url.getPath();
62 String documentationName = path.substring(5, path.length()-3);
63 documentations.put(documentationName, new BundleDocumentationSource(documentationName, bundle, url));
64 documentationsInThisBundle.add(documentationName);
66 documentationsPerBundle.put(bundle, documentationsInThisBundle);
69 documentationsPerBundle.put(bundle, new ArrayList<String>(0));
76 public void removedBundle(Bundle bundle, BundleEvent event,
78 synchronized(BundleModuleSourceRepository.this) {
79 ArrayList<String> moduleList = modulesPerBundle.get(bundle);
80 if(moduleList != null)
81 for(String moduleName : moduleList)
82 modules.remove(moduleName);
83 ArrayList<String> documentationsList = documentationsPerBundle.get(bundle);
84 if(documentationsList != null)
85 for(String documentation : documentationsList)
86 documentations.remove(documentation);
92 public void activate(ComponentContext context) {
93 tracker = new Tracker(context.getBundleContext());
98 public void deactivate(ComponentContext context) {
103 synchronized public ModuleSource getModuleSource(String moduleName,
104 UpdateListener listener) {
105 return modules.get(moduleName);
109 public synchronized Collection<String> getModuleNames() {
110 return new ArrayList<String>(modules.keySet());
114 public synchronized Collection<String> getDocumentationNames() {
115 return new ArrayList<String>(documentations.keySet());
119 synchronized public String getDocumentation(String documentationName) {
120 BundleDocumentationSource source = documentations.get(documentationName);
124 return source.getText();
128 public void checkUpdates() {
130 modulesPerBundle.forEachEntry(new TObjectObjectProcedure<Bundle, ArrayList<String>>() {
132 public boolean execute(Bundle bundle, ArrayList<String> oldModules) {
133 Enumeration<URL> moduleEntries = bundle.findEntries("scl", "*.scl", true);
134 if(moduleEntries != null) {
135 THashSet<String> oldModuleSet = new THashSet<String>(oldModules);
136 ArrayList<String> modulesInThisBundle = new ArrayList<String>();
137 while(moduleEntries.hasMoreElements()) {
138 URL url = moduleEntries.nextElement();
139 String path = url.getPath();
140 String moduleName = path.substring(5, path.length()-4);
141 if(!oldModuleSet.remove(moduleName))
142 modules.put(moduleName, new BundleModuleSource(moduleName, bundle, url));
143 modulesInThisBundle.add(moduleName);
145 for(String oldModule : oldModuleSet)
146 modules.remove(oldModule);
147 modulesPerBundle.put(bundle, modulesInThisBundle);
150 for(String oldModule : oldModules)
151 modules.remove(oldModule);
152 modulesPerBundle.put(bundle, new ArrayList<String>(0));
157 documentationsPerBundle.forEachEntry(new TObjectObjectProcedure<Bundle, ArrayList<String>>() {
159 public boolean execute(Bundle bundle, ArrayList<String> oldDocumentations) {
160 Enumeration<URL> documentationEntries = bundle.findEntries("scl", "*.md", true);
161 if(documentationEntries != null) {
162 THashSet<String> oldDocSet = new THashSet<String>(oldDocumentations);
163 ArrayList<String> documentationsInThisBundle = new ArrayList<String>();
164 while(documentationEntries.hasMoreElements()) {
165 URL url = documentationEntries.nextElement();
166 String path = url.getPath();
167 String documentationName = path.substring(5, path.length()-3);
168 if(!oldDocSet.remove(documentationName))
169 documentations.put(documentationName, new BundleDocumentationSource(documentationName, bundle, url));
170 documentationsInThisBundle.add(documentationName);
172 for(String oldDocumentation : oldDocSet)
173 documentations.remove(oldDocumentation);
174 documentationsPerBundle.put(bundle, documentationsInThisBundle);
177 for(String oldDocumentation : oldDocumentations)
178 documentations.remove(oldDocumentation);
179 documentationsPerBundle.put(bundle, new ArrayList<String>(0));
185 for(BundleModuleSource source : modules.values())
186 source.checkUpdates();
190 public void clear() {
191 for (BundleModuleSource source : modules.values()) {