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.Failable;
13 import org.simantics.scl.compiler.errors.Failure;
14 import org.simantics.scl.compiler.module.Module;
15 import org.simantics.scl.compiler.module.repository.ModuleRepository;
16 import org.simantics.scl.compiler.module.repository.UpdateListener;
18 import gnu.trove.map.hash.THashMap;
19 import gnu.trove.procedure.TObjectObjectProcedure;
20 import gnu.trove.procedure.TObjectProcedure;
22 public class SCLIssuesContentProvider implements IStructuredContentProvider {
24 public static final int MAX_ISSUE_COUNT = 1000;
27 ModuleRepository repository;
28 boolean disposed = false;
29 AtomicBoolean refreshInProgress = new AtomicBoolean(false);
31 THashMap<String, Failure> currentFailures = new THashMap<String, Failure>();
32 THashMap<String, UpdateListener> updateListeners = new THashMap<String, UpdateListener>();
35 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
37 this.repository = (ModuleRepository)newInput;
42 private UpdateListener getUpdateListener(String moduleName) {
43 UpdateListener listener;
44 synchronized(updateListeners) {
45 listener = updateListeners.get(moduleName);
46 if(listener == null) {
47 listener = new UpdateListener() {
49 public void notifyAboutUpdate() {
51 listenModule(moduleName);
54 updateListeners.put(moduleName, listener);
60 private void listenModule(String moduleName) {
61 if(repository == null)
63 Failable<Module> result = repository.getModule(moduleName, getUpdateListener(moduleName));
64 synchronized(currentFailures) {
65 if(result instanceof Failure) {
66 Failure failure = (Failure)result;
67 currentFailures.put(moduleName, failure);
70 if(currentFailures.remove(moduleName) == null)
76 private void refresh() {
77 if(!refreshInProgress.compareAndSet(false, true))
81 Control control = viewer.getControl();
82 if(control.isDisposed() || disposed)
84 control.getDisplay().asyncExec(new Runnable() {
87 if(control.isDisposed() || disposed)
89 refreshInProgress.set(false);
95 private void listenIssues() {
98 if(repository == null)
100 repository.getSourceRepository().forAllModules(new TObjectProcedure<String>() {
102 public boolean execute(String moduleName) {
103 listenModule(moduleName);
112 public void dispose() {
115 this.disposed = true;
116 if(repository != null)
117 synchronized(updateListeners) {
118 updateListeners.forEachEntry(new TObjectObjectProcedure<String, UpdateListener>() {
120 public boolean execute(String moduleName, UpdateListener listener) {
121 listener.stopListening();
125 updateListeners.clear();
130 public Object[] getElements(Object inputElement) {
131 ArrayList<SCLIssuesTableEntry> result = new ArrayList<SCLIssuesTableEntry>();
132 synchronized(currentFailures) {
133 String[] moduleNames = currentFailures.keySet().toArray(new String[currentFailures.size()]);
134 Arrays.sort(moduleNames);
135 for(String moduleName : moduleNames) {
136 Failure failure = currentFailures.get(moduleName);
137 for(CompilationError error : failure.errors)
138 result.add(new SCLIssuesTableEntry(moduleName, error));
139 if(result.size() >= MAX_ISSUE_COUNT)
143 Collections.sort(result);
144 return result.toArray();