-package org.simantics.scl.ui.issues;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.concurrent.atomic.AtomicBoolean;\r
-\r
-import org.eclipse.jface.viewers.IStructuredContentProvider;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.simantics.scl.compiler.errors.CompilationError;\r
-import org.simantics.scl.compiler.errors.Failable;\r
-import org.simantics.scl.compiler.errors.Failure;\r
-import org.simantics.scl.compiler.module.Module;\r
-import org.simantics.scl.compiler.module.repository.ModuleRepository;\r
-import org.simantics.scl.compiler.module.repository.UpdateListener;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectProcedure;\r
-\r
-public class SCLIssuesContentProvider implements IStructuredContentProvider {\r
-\r
- public static final int MAX_ISSUE_COUNT = 1000;\r
- \r
- Viewer viewer;\r
- ModuleRepository repository;\r
- boolean disposed = false;\r
- AtomicBoolean refreshInProgress = new AtomicBoolean(false);\r
- \r
- THashMap<String, Failure> currentFailures = new THashMap<String, Failure>();\r
- THashMap<String, UpdateListener> updateListeners = new THashMap<String, UpdateListener>(); \r
- \r
- @Override\r
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
- this.viewer = viewer;\r
- this.repository = (ModuleRepository)newInput;\r
- if(newInput != null)\r
- listenIssues();\r
- }\r
- \r
- private UpdateListener getUpdateListener(String moduleName) {\r
- UpdateListener listener = updateListeners.get(moduleName);\r
- if(listener == null) {\r
- listener = new UpdateListener() {\r
- @Override\r
- public void notifyAboutUpdate() {\r
- if(!disposed)\r
- listenModule(moduleName);\r
- }\r
- };\r
- updateListeners.put(moduleName, listener);\r
- }\r
- return listener;\r
- }\r
- \r
- private void listenModule(String moduleName) {\r
- if(repository == null)\r
- return;\r
- Failable<Module> result = repository.getModule(moduleName, getUpdateListener(moduleName));\r
- synchronized(currentFailures) {\r
- if(result instanceof Failure) {\r
- Failure failure = (Failure)result;\r
- currentFailures.put(moduleName, failure);\r
- }\r
- else\r
- if(currentFailures.remove(moduleName) == null)\r
- return;\r
- }\r
- refresh();\r
- }\r
- \r
- private void refresh() {\r
- if(!refreshInProgress.compareAndSet(false, true))\r
- return;\r
- if(viewer == null)\r
- return;\r
- Control control = viewer.getControl();\r
- if(control.isDisposed() || disposed)\r
- return;\r
- control.getDisplay().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- if(control.isDisposed() || disposed)\r
- return;\r
- refreshInProgress.set(false);\r
- viewer.refresh();\r
- }\r
- });\r
- }\r
-\r
- private void listenIssues() {\r
- new Thread() {\r
- public void run() {\r
- if(repository == null)\r
- return;\r
- repository.getSourceRepository().forAllModules(new TObjectProcedure<String>() {\r
- @Override\r
- public boolean execute(String moduleName) {\r
- listenModule(moduleName);\r
- return true;\r
- }\r
- });\r
- }\r
- }.start();\r
- }\r
-\r
- @Override\r
- public void dispose() {\r
- this.disposed = true;\r
- }\r
-\r
- @Override\r
- public Object[] getElements(Object inputElement) {\r
- ArrayList<SCLIssuesTableEntry> result = new ArrayList<SCLIssuesTableEntry>();\r
- synchronized(currentFailures) {\r
- String[] moduleNames = currentFailures.keySet().toArray(new String[currentFailures.size()]);\r
- Arrays.sort(moduleNames);\r
- for(String moduleName : moduleNames) {\r
- Failure failure = currentFailures.get(moduleName);\r
- for(CompilationError error : failure.errors)\r
- result.add(new SCLIssuesTableEntry(moduleName, error));\r
- if(result.size() >= MAX_ISSUE_COUNT)\r
- break;\r
- }\r
- }\r
- Collections.sort(result);\r
- return result.toArray();\r
- }\r
-\r
-}\r
+package org.simantics.scl.ui.issues;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Control;
+import org.simantics.scl.compiler.errors.CompilationError;
+import org.simantics.scl.compiler.errors.DoesNotExist;
+import org.simantics.scl.compiler.errors.Failable;
+import org.simantics.scl.compiler.errors.Failure;
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+import gnu.trove.procedure.TObjectProcedure;
+
+public class SCLIssuesContentProvider implements IStructuredContentProvider {
+
+ public static final int MAX_ISSUE_COUNT = 1000;
+
+ Viewer viewer;
+ ModuleRepository repository;
+ boolean disposed = false;
+ AtomicBoolean refreshInProgress = new AtomicBoolean(false);
+
+ THashMap<String, CompilationError[]> currentFailures = new THashMap<String, CompilationError[]>();
+ THashMap<String, UpdateListener> updateListeners = new THashMap<String, UpdateListener>();
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ this.viewer = viewer;
+ this.repository = (ModuleRepository)newInput;
+ if(newInput != null)
+ listenIssues();
+ }
+
+ private UpdateListener getUpdateListener(String moduleName) {
+ UpdateListener listener;
+ synchronized(updateListeners) {
+ listener = updateListeners.get(moduleName);
+ if(listener == null) {
+ listener = new UpdateListener() {
+ @Override
+ public void notifyAboutUpdate() {
+ if(!disposed)
+ listenModule(moduleName);
+ }
+ };
+ updateListeners.put(moduleName, listener);
+ }
+ }
+ return listener;
+ }
+
+ private void listenModule(String moduleName) {
+ if(repository == null)
+ return;
+ Failable<Module> result = repository.getModule(moduleName, getUpdateListener(moduleName));
+ synchronized(currentFailures) {
+ if(result instanceof Failure) {
+ Failure failure = (Failure)result;
+ currentFailures.put(moduleName, failure.errors);
+ }
+ else if(result == DoesNotExist.INSTANCE) {
+ if(currentFailures.remove(moduleName) == null)
+ return;
+ }
+ else {
+ CompilationError[] warnings = result.getResult().getWarnings();
+ if(warnings.length == 0) {
+ if(currentFailures.remove(moduleName) == null)
+ return;
+ }
+ else {
+ currentFailures.put(moduleName, warnings);
+ }
+ }
+ }
+ refresh();
+ }
+
+ private void refresh() {
+ if(!refreshInProgress.compareAndSet(false, true))
+ return;
+ if(viewer == null)
+ return;
+ Control control = viewer.getControl();
+ if(control.isDisposed() || disposed)
+ return;
+ control.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ if(control.isDisposed() || disposed)
+ return;
+ refreshInProgress.set(false);
+ viewer.refresh();
+ }
+ });
+ }
+
+ private void listenIssues() {
+ new Thread() {
+ public void run() {
+ if(repository == null)
+ return;
+ repository.getSourceRepository().forAllModules(new TObjectProcedure<String>() {
+ @Override
+ public boolean execute(String moduleName) {
+ listenModule(moduleName);
+ return true;
+ }
+ });
+ }
+ }.start();
+ }
+
+ @Override
+ public void dispose() {
+ if(this.disposed)
+ return;
+ this.disposed = true;
+ if(repository != null)
+ synchronized(updateListeners) {
+ updateListeners.forEachEntry(new TObjectObjectProcedure<String, UpdateListener>() {
+ @Override
+ public boolean execute(String moduleName, UpdateListener listener) {
+ listener.stopListening();
+ return true;
+ }
+ });
+ updateListeners.clear();
+ }
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ ArrayList<SCLIssuesTableEntry> result = new ArrayList<SCLIssuesTableEntry>();
+ synchronized(currentFailures) {
+ String[] moduleNames = currentFailures.keySet().toArray(new String[currentFailures.size()]);
+ Arrays.sort(moduleNames);
+ for(String moduleName : moduleNames) {
+ CompilationError[] errors = currentFailures.get(moduleName);
+ for(CompilationError error : errors)
+ result.add(new SCLIssuesTableEntry(moduleName, error));
+ if(result.size() >= MAX_ISSUE_COUNT)
+ break;
+ }
+ }
+ Collections.sort(result);
+ return result.toArray();
+ }
+
+}