package org.simantics.scl.compiler.source.repository; import java.util.ArrayList; import java.util.Collection; import org.simantics.scl.compiler.module.Module; import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.module.repository.UpdateListener.Observable; import org.simantics.scl.compiler.source.ModuleSource; import org.simantics.scl.compiler.source.PrecompiledModuleSource; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectProcedure; /** * An implementation of {@link ModuleSourceRepository} as a finite map. * This implementation does not support listening module changes, * so it should not be modified after it has been taken into use. * * @author Hannu Niemistö */ public class MapModuleSourceRepository implements ModuleSourceRepository { THashMap modules = new THashMap(); THashMap documentations = new THashMap(); THashMap> listeners = new THashMap>(); public MapModuleSourceRepository() { } public MapModuleSourceRepository(ModuleSource ... descriptors) { for(ModuleSource descriptor : descriptors) addModuleDescriptor(descriptor); } public MapModuleSourceRepository(Module ... modules) { for(Module module : modules) addModule(module); } public void addModuleDescriptor(ModuleSource descriptor) { modules.put(descriptor.getModuleName(), descriptor); synchronized (listeners) { ArrayList list = listeners.get(descriptor.getModuleName()); if(list != null) for(UpdateListener listener : list.toArray(new UpdateListener[list.size()])) listener.notifyAboutUpdate(); } } public void addModule(Module module) { addModuleDescriptor(new PrecompiledModuleSource(module)); } public void addDocumentation(String documentationName, String documentation) { documentations.put(documentationName, documentation); } @Override public ModuleSource getModuleSource(String moduleName, UpdateListener listener) { if(listener != null) { synchronized(listeners) { ArrayList list = listeners.get(moduleName); if(list == null) { list = new ArrayList(2); listeners.put(moduleName, list); } list.add(listener); } listener.addObservable(new Observable() { @Override public void removeListener(UpdateListener listener) { synchronized(listeners) { ArrayList list = listeners.get(moduleName); if(list != null) { list.remove(listener); if(list.isEmpty()) listeners.remove(moduleName); } } } }); } return modules.get(moduleName); } @Override public Collection getModuleNames() { return modules.keySet(); } @Override public void forAllModules(TObjectProcedure procedure) { modules.forEachKey(procedure); } @Override public String getDocumentation(String documentationName) { return documentations.get(documentationName); } @Override public Collection getDocumentationNames() { return documentations.keySet(); } }