]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLIssuesContentProvider.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / issues / SCLIssuesContentProvider.java
1 package org.simantics.scl.ui.issues;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Arrays;\r
5 import java.util.Collections;\r
6 import java.util.concurrent.atomic.AtomicBoolean;\r
7 \r
8 import org.eclipse.jface.viewers.IStructuredContentProvider;\r
9 import org.eclipse.jface.viewers.Viewer;\r
10 import org.eclipse.swt.widgets.Control;\r
11 import org.simantics.scl.compiler.errors.CompilationError;\r
12 import org.simantics.scl.compiler.errors.Failable;\r
13 import org.simantics.scl.compiler.errors.Failure;\r
14 import org.simantics.scl.compiler.module.Module;\r
15 import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
16 import org.simantics.scl.compiler.module.repository.UpdateListener;\r
17 \r
18 import gnu.trove.map.hash.THashMap;\r
19 import gnu.trove.procedure.TObjectProcedure;\r
20 \r
21 public class SCLIssuesContentProvider implements IStructuredContentProvider {\r
22 \r
23     public static final int MAX_ISSUE_COUNT = 1000;\r
24     \r
25     Viewer viewer;\r
26     ModuleRepository repository;\r
27     boolean disposed = false;\r
28     AtomicBoolean refreshInProgress = new AtomicBoolean(false);\r
29     \r
30     THashMap<String, Failure> currentFailures = new THashMap<String, Failure>();\r
31     THashMap<String, UpdateListener> updateListeners = new THashMap<String, UpdateListener>(); \r
32     \r
33     @Override\r
34     public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
35         this.viewer = viewer;\r
36         this.repository = (ModuleRepository)newInput;\r
37         if(newInput != null)\r
38             listenIssues();\r
39     }\r
40     \r
41     private UpdateListener getUpdateListener(String moduleName) {\r
42         UpdateListener listener = updateListeners.get(moduleName);\r
43         if(listener == null) {\r
44             listener = new UpdateListener() {\r
45                 @Override\r
46                 public void notifyAboutUpdate() {\r
47                     if(!disposed)\r
48                         listenModule(moduleName);\r
49                 }\r
50             };\r
51             updateListeners.put(moduleName, listener);\r
52         }\r
53         return listener;\r
54     }\r
55     \r
56     private void listenModule(String moduleName) {\r
57         if(repository == null)\r
58             return;\r
59         Failable<Module> result = repository.getModule(moduleName, getUpdateListener(moduleName));\r
60         synchronized(currentFailures) {\r
61             if(result instanceof Failure) {\r
62                 Failure failure = (Failure)result;\r
63                 currentFailures.put(moduleName, failure);\r
64             }\r
65             else\r
66                 if(currentFailures.remove(moduleName) == null)\r
67                     return;\r
68         }\r
69         refresh();\r
70     }\r
71     \r
72     private void refresh() {\r
73         if(!refreshInProgress.compareAndSet(false, true))\r
74             return;\r
75         if(viewer == null)\r
76             return;\r
77         Control control = viewer.getControl();\r
78         if(control.isDisposed() || disposed)\r
79             return;\r
80         control.getDisplay().asyncExec(new Runnable() {\r
81             @Override\r
82             public void run() {\r
83                 if(control.isDisposed() || disposed)\r
84                     return;\r
85                 refreshInProgress.set(false);\r
86                 viewer.refresh();\r
87             }\r
88         });\r
89     }\r
90 \r
91     private void listenIssues() {\r
92         new Thread() {\r
93             public void run() {\r
94                 if(repository == null)\r
95                     return;\r
96                 repository.getSourceRepository().forAllModules(new TObjectProcedure<String>() {\r
97                     @Override\r
98                     public boolean execute(String moduleName) {\r
99                         listenModule(moduleName);\r
100                         return true;\r
101                     }\r
102                 });\r
103             }\r
104         }.start();\r
105     }\r
106 \r
107     @Override\r
108     public void dispose() {\r
109         this.disposed = true;\r
110     }\r
111 \r
112     @Override\r
113     public Object[] getElements(Object inputElement) {\r
114         ArrayList<SCLIssuesTableEntry> result = new ArrayList<SCLIssuesTableEntry>();\r
115         synchronized(currentFailures) {\r
116             String[] moduleNames = currentFailures.keySet().toArray(new String[currentFailures.size()]);\r
117             Arrays.sort(moduleNames);\r
118             for(String moduleName : moduleNames) {\r
119                 Failure failure = currentFailures.get(moduleName);\r
120                 for(CompilationError error : failure.errors)\r
121                     result.add(new SCLIssuesTableEntry(moduleName, error));\r
122                 if(result.size() >= MAX_ISSUE_COUNT)\r
123                     break;\r
124             }\r
125         }\r
126         Collections.sort(result);\r
127         return result.toArray();\r
128     }\r
129 \r
130 }\r