X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.ui%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fui%2Fissues%2FSCLModuleIssueProvider.java;fp=bundles%2Forg.simantics.scl.ui%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fui%2Fissues%2FSCLModuleIssueProvider.java;h=20a89d41b7fda21248ff55c73e0d1f74fdc1ff2b;hp=0000000000000000000000000000000000000000;hb=a516cf32592cf470cfc3f6ff96ee8b5168bd7a43;hpb=7a7ad0a2319ce70a184e099adad8a69c23562bd9 diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLModuleIssueProvider.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLModuleIssueProvider.java new file mode 100644 index 000000000..20a89d41b --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLModuleIssueProvider.java @@ -0,0 +1,147 @@ +package org.simantics.scl.ui.issues; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +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 org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.osgi.issues.SCLIssueProviderFactory; +import org.simantics.scl.osgi.issues.SCLIssueProviderFactory.SCLIssueProvider; +import org.simantics.scl.osgi.issues.SCLIssuesTableEntry; +import org.simantics.scl.ui.editor2.OpenSCLDefinition; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; +import gnu.trove.procedure.TObjectProcedure; + +public class SCLModuleIssueProvider implements SCLIssueProvider { + + public static class SCLModuleIssueProviderFactory implements SCLIssueProviderFactory { + + @Override + public SCLIssueProvider getSCLIssueProvider() { + return new SCLModuleIssueProvider(); + } + + } + + ModuleRepository repository = SCLOsgi.MODULE_REPOSITORY; + + THashMap currentFailures = new THashMap<>(); + THashMap updateListeners = new THashMap<>(); + + private boolean disposed; + + SCLModuleIssueProvider() { + } + + private UpdateListener getUpdateListener(String moduleName, Runnable callback) { + UpdateListener listener; + synchronized(updateListeners) { + listener = updateListeners.get(moduleName); + if(listener == null) { + listener = new UpdateListener() { + @Override + public void notifyAboutUpdate() { + if(!disposed) + listenModule(moduleName, callback); + } + }; + updateListeners.put(moduleName, listener); + } + } + return listener; + } + + private void listenModule(String moduleName, Runnable callback) { + if(repository == null) + return; + Failable result = repository.getModule(moduleName, getUpdateListener(moduleName, callback)); + 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); + } + } + } + if (callback != null) + callback.run(); + } + + public void listenIssues(Runnable callback) { + new Thread() { + public void run() { + if(repository == null) + return; + repository.getSourceRepository().forAllModules(new TObjectProcedure() { + @Override + public boolean execute(String moduleName) { + listenModule(moduleName, callback); + return true; + } + }); + } + }.start(); + } + + @Override + public List getIssues() { + ArrayList result = new ArrayList<>(); + 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) { + @Override + public void openLocation() { + OpenSCLDefinition.openDefinition(moduleName, error.location); + } + }); + } + } + } + return result; + } + + @Override + public void dispose() { + if (disposed) + return; + disposed = true; + if(repository != null) { + synchronized(updateListeners) { + updateListeners.forEachEntry(new TObjectObjectProcedure() { + @Override + public boolean execute(String moduleName, UpdateListener listener) { + listener.stopListening(); + return true; + } + }); + updateListeners.clear(); + } + } + } + +}