1 package org.simantics.scl.ui.issues;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.concurrent.atomic.AtomicBoolean;
8 import org.eclipse.jface.viewers.IStructuredContentProvider;
9 import org.eclipse.jface.viewers.Viewer;
10 import org.eclipse.swt.widgets.Control;
11 import org.simantics.scl.compiler.errors.CompilationError;
12 import org.simantics.scl.compiler.errors.DoesNotExist;
13 import org.simantics.scl.compiler.errors.Failable;
14 import org.simantics.scl.compiler.errors.Failure;
15 import org.simantics.scl.compiler.module.Module;
16 import org.simantics.scl.compiler.module.repository.ModuleRepository;
17 import org.simantics.scl.compiler.module.repository.UpdateListener;
19 import gnu.trove.map.hash.THashMap;
20 import gnu.trove.procedure.TObjectObjectProcedure;
21 import gnu.trove.procedure.TObjectProcedure;
23 public class SCLIssuesContentProvider implements IStructuredContentProvider {
25 public static final int MAX_ISSUE_COUNT = 1000;
28 ModuleRepository repository;
29 boolean disposed = false;
30 AtomicBoolean refreshInProgress = new AtomicBoolean(false);
32 THashMap<String, CompilationError[]> currentFailures = new THashMap<String, CompilationError[]>();
33 THashMap<String, UpdateListener> updateListeners = new THashMap<String, UpdateListener>();
36 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
38 this.repository = (ModuleRepository)newInput;
43 private UpdateListener getUpdateListener(String moduleName) {
44 UpdateListener listener;
45 synchronized(updateListeners) {
46 listener = updateListeners.get(moduleName);
47 if(listener == null) {
48 listener = new UpdateListener() {
50 public void notifyAboutUpdate() {
52 listenModule(moduleName);
55 updateListeners.put(moduleName, listener);
61 private void listenModule(String moduleName) {
62 if(repository == null)
64 Failable<Module> result = repository.getModule(moduleName, getUpdateListener(moduleName));
65 synchronized(currentFailures) {
66 if(result instanceof Failure) {
67 Failure failure = (Failure)result;
68 currentFailures.put(moduleName, failure.errors);
70 else if(result == DoesNotExist.INSTANCE) {
71 if(currentFailures.remove(moduleName) == null)
75 CompilationError[] warnings = result.getResult().getWarnings();
76 if(warnings.length == 0) {
77 if(currentFailures.remove(moduleName) == null)
81 currentFailures.put(moduleName, warnings);
88 private void refresh() {
89 if(!refreshInProgress.compareAndSet(false, true))
93 Control control = viewer.getControl();
94 if(control.isDisposed() || disposed)
96 control.getDisplay().asyncExec(new Runnable() {
99 if(control.isDisposed() || disposed)
101 refreshInProgress.set(false);
107 private void listenIssues() {
110 if(repository == null)
112 repository.getSourceRepository().forAllModules(new TObjectProcedure<String>() {
114 public boolean execute(String moduleName) {
115 listenModule(moduleName);
124 public void dispose() {
127 this.disposed = true;
128 if(repository != null)
129 synchronized(updateListeners) {
130 updateListeners.forEachEntry(new TObjectObjectProcedure<String, UpdateListener>() {
132 public boolean execute(String moduleName, UpdateListener listener) {
133 listener.stopListening();
137 updateListeners.clear();
142 public Object[] getElements(Object inputElement) {
143 ArrayList<SCLIssuesTableEntry> result = new ArrayList<SCLIssuesTableEntry>();
144 synchronized(currentFailures) {
145 String[] moduleNames = currentFailures.keySet().toArray(new String[currentFailures.size()]);
146 Arrays.sort(moduleNames);
147 for(String moduleName : moduleNames) {
148 CompilationError[] errors = currentFailures.get(moduleName);
149 for(CompilationError error : errors)
150 result.add(new SCLIssuesTableEntry(moduleName, error));
151 if(result.size() >= MAX_ISSUE_COUNT)
155 Collections.sort(result);
156 return result.toArray();