]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLModuleIssueProvider.java
SCL expressions to SCL Issues view
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / issues / SCLModuleIssueProvider.java
1 package org.simantics.scl.ui.issues;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.List;
6
7 import org.simantics.scl.compiler.errors.CompilationError;
8 import org.simantics.scl.compiler.errors.DoesNotExist;
9 import org.simantics.scl.compiler.errors.Failable;
10 import org.simantics.scl.compiler.errors.Failure;
11 import org.simantics.scl.compiler.module.Module;
12 import org.simantics.scl.compiler.module.repository.ModuleRepository;
13 import org.simantics.scl.compiler.module.repository.UpdateListener;
14 import org.simantics.scl.osgi.SCLOsgi;
15 import org.simantics.scl.osgi.issues.SCLIssueProviderFactory;
16 import org.simantics.scl.osgi.issues.SCLIssueProviderFactory.SCLIssueProvider;
17 import org.simantics.scl.osgi.issues.SCLIssuesTableEntry;
18 import org.simantics.scl.ui.editor2.OpenSCLDefinition;
19
20 import gnu.trove.map.hash.THashMap;
21 import gnu.trove.procedure.TObjectObjectProcedure;
22 import gnu.trove.procedure.TObjectProcedure;
23
24 public class SCLModuleIssueProvider implements SCLIssueProvider {
25
26     public static class SCLModuleIssueProviderFactory implements SCLIssueProviderFactory {
27
28         @Override
29         public SCLIssueProvider getSCLIssueProvider() {
30             return new SCLModuleIssueProvider();
31         }
32         
33     }
34     
35     ModuleRepository repository = SCLOsgi.MODULE_REPOSITORY;
36
37     THashMap<String, CompilationError[]> currentFailures = new THashMap<>();
38     THashMap<String, UpdateListener> updateListeners = new THashMap<>();
39
40     private boolean disposed;
41     
42     SCLModuleIssueProvider() {
43     }
44
45     private UpdateListener getUpdateListener(String moduleName, Runnable callback) {
46         UpdateListener listener;
47         synchronized(updateListeners) {
48             listener = updateListeners.get(moduleName);
49             if(listener == null) {
50                 listener = new UpdateListener() {
51                     @Override
52                     public void notifyAboutUpdate() {
53                         if(!disposed)
54                             listenModule(moduleName, callback);
55                     }
56                 };
57                 updateListeners.put(moduleName, listener);
58             }
59         }
60         return listener;
61     }
62
63     private void listenModule(String moduleName, Runnable callback) {
64         if(repository == null)
65             return;
66         Failable<Module> result = repository.getModule(moduleName, getUpdateListener(moduleName, callback));
67         synchronized(currentFailures) {
68             if(result instanceof Failure) {
69                 Failure failure = (Failure)result;
70                 currentFailures.put(moduleName, failure.errors);
71             }
72             else if(result == DoesNotExist.INSTANCE) {
73                 if(currentFailures.remove(moduleName) == null)
74                     return;
75             }
76             else {
77                 CompilationError[] warnings = result.getResult().getWarnings();
78                 if(warnings.length == 0) {
79                     if(currentFailures.remove(moduleName) == null)
80                         return;
81                 }
82                 else {
83                     currentFailures.put(moduleName, warnings);
84                 }
85             }
86         }
87         if (callback != null)
88             callback.run();
89     }
90
91     public void listenIssues(Runnable callback) {
92         new Thread() {
93             public void run() {
94                 if(repository == null)
95                     return;
96                 repository.getSourceRepository().forAllModules(new TObjectProcedure<String>() {
97                     @Override
98                     public boolean execute(String moduleName) {
99                         listenModule(moduleName, callback);
100                         return true;
101                     }
102                 });
103             }
104         }.start();
105     }
106
107     @Override
108     public List<SCLIssuesTableEntry> getIssues() {
109         ArrayList<SCLIssuesTableEntry> result = new ArrayList<>();
110         synchronized(currentFailures) {
111             String[] moduleNames = currentFailures.keySet().toArray(new String[currentFailures.size()]);
112             Arrays.sort(moduleNames);
113             for(String moduleName : moduleNames) {
114                 CompilationError[] errors = currentFailures.get(moduleName);
115                 for(CompilationError error : errors) {
116                     result.add(new SCLIssuesTableEntry(moduleName, error) {
117                         @Override
118                         public void openLocation() {
119                             OpenSCLDefinition.openDefinition(moduleName, error.location);
120                         }
121                     });
122                 }
123             }
124         }
125         return result;
126     }
127
128     @Override
129     public void dispose() {
130         if (disposed)
131             return;
132         disposed = true;
133         if(repository != null) {
134             synchronized(updateListeners) {
135                 updateListeners.forEachEntry(new TObjectObjectProcedure<String, UpdateListener>() {
136                     @Override
137                     public boolean execute(String moduleName, UpdateListener listener) {
138                         listener.stopListening();
139                         return true;
140                     }
141                 });
142                 updateListeners.clear();
143             }
144         }
145     }
146
147 }