1 package org.simantics.scl.osgi.internal;
3 import java.util.ArrayList;
4 import java.util.Collection;
6 import org.osgi.framework.BundleContext;
7 import org.osgi.util.tracker.ServiceTracker;
8 import org.simantics.scl.compiler.module.repository.UpdateListener;
9 import org.simantics.scl.compiler.source.ModuleSource;
10 import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
12 import gnu.trove.procedure.TObjectProcedure;
14 public class ServiceBasedModuleSourceRepository implements ModuleSourceRepository {
16 ServiceTracker<ModuleSourceRepository, ModuleSourceRepository> sourceRepositories;
18 public ServiceBasedModuleSourceRepository(BundleContext context) {
19 sourceRepositories = new ServiceTracker<ModuleSourceRepository, ModuleSourceRepository>(
20 context, ModuleSourceRepository.class, null);
21 sourceRepositories.open();
25 public ModuleSource getModuleSource(String moduleName,
26 UpdateListener listener) {
27 ModuleSource result = null;
28 ModuleSourceRepository resultRepository = null;
29 Object[] services = sourceRepositories.getServices();
31 for(Object sourceRepository_ : services) {
32 ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
33 ModuleSource source = sourceLoader.getModuleSource(moduleName, listener);
36 double resultPriority = result.getPriority();
37 double sourcePriority = source.getPriority();
38 if(resultPriority > sourcePriority)
40 if(resultPriority == sourcePriority)
41 throw new RuntimeException("Module " + moduleName + " has two sources " + result + " (from "+resultRepository+"), " +
42 source + " (from "+sourceLoader+") with the same priority.");
45 resultRepository = sourceLoader;
52 public String getDocumentation(String documentationName) {
53 // getServices is internally synchronized, so no need to synchronize here
54 Object[] services = sourceRepositories.getServices();
56 for(Object sourceRepository_ : services) {
57 ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
58 String documentation = sourceLoader.getDocumentation(documentationName);
59 if(documentation != null)
66 public void forAllModules(TObjectProcedure<String> procedure) {
67 // getServices is internally synchronized, so no need to synchronize here
68 Object[] services = sourceRepositories.getServices();
70 for(Object sourceRepository_ : services) {
71 ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
72 sourceLoader.forAllModules(procedure);
77 public Collection<String> getModuleNames() {
78 ArrayList<String> result = new ArrayList<>();
79 forAllModules((String name) -> {
87 public void forAllDocumentations(TObjectProcedure<String> procedure) {
88 Object[] services = sourceRepositories.getServices();
90 for(Object sourceRepository_ : services) {
91 ModuleSourceRepository sourceLoader = (ModuleSourceRepository)sourceRepository_;
92 sourceLoader.forAllDocumentations(procedure);
97 public Collection<String> getDocumentationNames() {
98 ArrayList<String> result = new ArrayList<>();
99 forAllDocumentations((String name) -> {
107 public void checkUpdates() {
108 for(Object service_ : sourceRepositories.getServices()) {
109 ModuleSourceRepository service = (ModuleSourceRepository)service_;
110 service.checkUpdates();