1 package org.simantics.scl.osgi.internal;
4 import java.util.ArrayList;
5 import java.util.Enumeration;
7 import org.osgi.framework.Bundle;
8 import org.osgi.framework.BundleContext;
9 import org.osgi.framework.BundleEvent;
10 import org.osgi.service.component.ComponentContext;
11 import org.osgi.service.component.annotations.Activate;
12 import org.osgi.service.component.annotations.Component;
13 import org.osgi.service.component.annotations.Deactivate;
14 import org.osgi.util.tracker.BundleTracker;
15 import org.simantics.scl.compiler.module.repository.UpdateListener;
16 import org.simantics.scl.compiler.source.ModuleSource;
17 import org.simantics.scl.compiler.source.repository.AbstractModuleSourceRepository;
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.procedure.TObjectProcedure;
23 import gnu.trove.set.hash.THashSet;
26 public class BundleModuleSourceRepository extends AbstractModuleSourceRepository implements ModuleSourceRepository {
29 THashMap<String, BundleModuleSource> modules = new THashMap<String, BundleModuleSource>();
30 THashMap<Bundle, ArrayList<String>> modulesPerBundle = new THashMap<Bundle, ArrayList<String>>();
31 THashMap<String, BundleDocumentationSource> documentations = new THashMap<String, BundleDocumentationSource>();
32 THashMap<Bundle, ArrayList<String>> documentationsPerBundle = new THashMap<Bundle, ArrayList<String>>();
34 class Tracker extends BundleTracker<Bundle> {
35 public Tracker(BundleContext context) {
36 super(context, 0xffffffff, null);
40 public Bundle addingBundle(Bundle bundle, BundleEvent event) {
41 synchronized(BundleModuleSourceRepository.this) {
42 Enumeration<URL> moduleEntries = bundle.findEntries("scl", "*.scl", true);
43 if(moduleEntries != null) {
44 ArrayList<String> modulesInThisBundle = new ArrayList<String>();
45 while(moduleEntries.hasMoreElements()) {
46 URL url = moduleEntries.nextElement();
47 String path = url.getPath();
48 String moduleName = path.substring(5, path.length()-4);
49 modules.put(moduleName, new BundleModuleSource(moduleName, bundle, url));
50 modulesInThisBundle.add(moduleName);
52 modulesPerBundle.put(bundle, modulesInThisBundle);
55 modulesPerBundle.put(bundle, new ArrayList<String>(0));
57 Enumeration<URL> documentationEntries = bundle.findEntries("scl", "*.md", true);
58 if(documentationEntries != null) {
59 ArrayList<String> documentationsInThisBundle = new ArrayList<String>();
60 while(documentationEntries.hasMoreElements()) {
61 URL url = documentationEntries.nextElement();
62 String path = url.getPath();
63 String documentationName = path.substring(5, path.length()-3);
64 documentations.put(documentationName, new BundleDocumentationSource(documentationName, bundle, url));
65 documentationsInThisBundle.add(documentationName);
67 documentationsPerBundle.put(bundle, documentationsInThisBundle);
70 documentationsPerBundle.put(bundle, new ArrayList<String>(0));
77 public void removedBundle(Bundle bundle, BundleEvent event,
79 synchronized(BundleModuleSourceRepository.this) {
80 ArrayList<String> moduleList = modulesPerBundle.get(bundle);
81 if(moduleList != null)
82 for(String moduleName : moduleList)
83 modules.remove(moduleName);
84 ArrayList<String> documentationsList = documentationsPerBundle.get(bundle);
85 if(documentationsList != null)
86 for(String documentation : documentationsList)
87 documentations.remove(documentation);
93 public void activate(ComponentContext context) {
94 tracker = new Tracker(context.getBundleContext());
99 public void deactivate(ComponentContext context) {
104 synchronized public ModuleSource getModuleSource(String moduleName,
105 UpdateListener listener) {
106 return modules.get(moduleName);
110 synchronized public void forAllModules(TObjectProcedure<String> procedure) {
111 modules.forEachKey(procedure);
115 synchronized public String getDocumentation(String documentationName) {
116 BundleDocumentationSource source = documentations.get(documentationName);
120 return source.getText();
124 synchronized public void forAllDocumentations(TObjectProcedure<String> procedure) {
125 documentations.forEachKey(procedure);
129 public void checkUpdates() {
131 modulesPerBundle.forEachEntry(new TObjectObjectProcedure<Bundle, ArrayList<String>>() {
133 public boolean execute(Bundle bundle, ArrayList<String> oldModules) {
134 Enumeration<URL> moduleEntries = bundle.findEntries("scl", "*.scl", true);
135 if(moduleEntries != null) {
136 THashSet<String> oldModuleSet = new THashSet<String>(oldModules);
137 ArrayList<String> modulesInThisBundle = new ArrayList<String>();
138 while(moduleEntries.hasMoreElements()) {
139 URL url = moduleEntries.nextElement();
140 String path = url.getPath();
141 String moduleName = path.substring(5, path.length()-4);
142 if(!oldModuleSet.remove(moduleName))
143 modules.put(moduleName, new BundleModuleSource(moduleName, bundle, url));
144 modulesInThisBundle.add(moduleName);
146 for(String oldModule : oldModuleSet)
147 modules.remove(oldModule);
148 modulesPerBundle.put(bundle, modulesInThisBundle);
151 for(String oldModule : oldModules)
152 modules.remove(oldModule);
153 modulesPerBundle.put(bundle, new ArrayList<String>(0));
158 documentationsPerBundle.forEachEntry(new TObjectObjectProcedure<Bundle, ArrayList<String>>() {
160 public boolean execute(Bundle bundle, ArrayList<String> oldDocumentations) {
161 Enumeration<URL> documentationEntries = bundle.findEntries("scl", "*.md", true);
162 if(documentationEntries != null) {
163 THashSet<String> oldDocSet = new THashSet<String>(oldDocumentations);
164 ArrayList<String> documentationsInThisBundle = new ArrayList<String>();
165 while(documentationEntries.hasMoreElements()) {
166 URL url = documentationEntries.nextElement();
167 String path = url.getPath();
168 String documentationName = path.substring(5, path.length()-3);
169 if(!oldDocSet.remove(documentationName))
170 documentations.put(documentationName, new BundleDocumentationSource(documentationName, bundle, url));
171 documentationsInThisBundle.add(documentationName);
173 for(String oldDocumentation : oldDocSet)
174 documentations.remove(oldDocumentation);
175 documentationsPerBundle.put(bundle, documentationsInThisBundle);
178 for(String oldDocumentation : oldDocumentations)
179 documentations.remove(oldDocumentation);
180 documentationsPerBundle.put(bundle, new ArrayList<String>(0));
186 for(BundleModuleSource source : modules.values())
187 source.checkUpdates();
191 public void clear() {
192 for (BundleModuleSource source : modules.values()) {