]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / source / repository / MapModuleSourceRepository.java
1 package org.simantics.scl.compiler.source.repository;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5
6 import org.simantics.scl.compiler.module.Module;
7 import org.simantics.scl.compiler.module.repository.UpdateListener;
8 import org.simantics.scl.compiler.module.repository.UpdateListener.Observable;
9 import org.simantics.scl.compiler.source.ModuleSource;
10 import org.simantics.scl.compiler.source.PrecompiledModuleSource;
11
12 import gnu.trove.map.hash.THashMap;
13 import gnu.trove.procedure.TObjectProcedure;
14
15 /**
16  * An implementation of {@link ModuleSourceRepository} as a finite map.
17  * This implementation does not support listening module changes,
18  * so it should not be modified after it has been taken into use.
19  * 
20  * @author Hannu Niemistö
21  */
22 public class MapModuleSourceRepository implements ModuleSourceRepository {
23     THashMap<String, ModuleSource> modules = new THashMap<String, ModuleSource>();
24     THashMap<String, String> documentations = new THashMap<String, String>();
25     
26     THashMap<String, ArrayList<UpdateListener>> listeners = new THashMap<String, ArrayList<UpdateListener>>(); 
27     
28     public MapModuleSourceRepository() {
29     }
30     
31     public MapModuleSourceRepository(ModuleSource ... descriptors) {
32         for(ModuleSource descriptor : descriptors)
33             addModuleDescriptor(descriptor);
34     }
35     
36     public MapModuleSourceRepository(Module ... modules) {
37         for(Module module : modules)
38             addModule(module);
39     }
40     
41     public void addModuleDescriptor(ModuleSource descriptor) {
42         modules.put(descriptor.getModuleName(), descriptor);
43         synchronized (listeners) {
44             ArrayList<UpdateListener> list = listeners.get(descriptor.getModuleName());
45             if(list != null)
46                 for(UpdateListener listener : list.toArray(new UpdateListener[list.size()]))
47                     listener.notifyAboutUpdate();
48         }
49     }
50     
51     public void addModule(Module module) {
52         addModuleDescriptor(new PrecompiledModuleSource(module));
53     }
54     
55     public void addDocumentation(String documentationName, String documentation) {
56         documentations.put(documentationName, documentation);
57     }
58
59     @Override
60     public ModuleSource getModuleSource(String moduleName,
61             UpdateListener listener) {
62         if(listener != null) {
63             synchronized(listeners) {
64                 ArrayList<UpdateListener> list = listeners.get(moduleName);
65                 if(list == null) {
66                     list = new ArrayList<UpdateListener>(2);
67                     listeners.put(moduleName, list);
68                 }
69                 list.add(listener);
70             }
71             listener.addObservable(new Observable() {
72                 @Override
73                 public void removeListener(UpdateListener listener) {
74                     synchronized(listeners) {
75                         ArrayList<UpdateListener> list = listeners.get(moduleName);
76                         if(list != null) {
77                             list.remove(listener);
78                             if(list.isEmpty())
79                                 listeners.remove(moduleName);
80                         }
81                     }
82                 }
83             });
84         }
85         return modules.get(moduleName);
86     }
87
88     @Override
89     public Collection<String> getModuleNames() {
90         return modules.keySet();
91     }
92     
93     @Override
94     public void forAllModules(TObjectProcedure<String> procedure) {
95         modules.forEachKey(procedure);
96     }
97
98     @Override
99     public String getDocumentation(String documentationName) {
100         return documentations.get(documentationName);
101     }
102     
103     @Override
104     public Collection<String> getDocumentationNames() {
105         return documentations.keySet();
106     }
107 }