]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptAnnotationModel.java
Support for SCL script database storage, editing and execution
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / scl / scriptEditor / SCLScriptAnnotationModel.java
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptAnnotationModel.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptAnnotationModel.java
new file mode 100644 (file)
index 0000000..fadb4f9
--- /dev/null
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.ui.scl.scriptEditor;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.simantics.Simantics;
+import org.simantics.db.procedure.Listener;
+import org.simantics.scl.compiler.commands.CommandSession;
+import org.simantics.scl.compiler.errors.CompilationError;
+import org.simantics.scl.compiler.errors.ErrorSeverity;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptAnnotationModel extends AnnotationModel {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLScriptAnnotationModel.class);
+
+    private final SCLScriptEditorInput input;
+    private final ModuleRepository repository;
+    private volatile boolean connected = false;
+
+    public SCLScriptAnnotationModel(SCLScriptEditorInput input, ModuleRepository repository) {
+        this.input = input;
+        this.repository = repository;
+    }
+
+    private Listener<String> sourceListener = new Listener<String>() {
+        @Override
+        public void execute(String result) {
+            if (connected && result != null)
+                updateAnnotations(result);
+        }
+        @Override
+        public void exception(Throwable t) {
+            LOGGER.error("Failed to read SCL script source from " + input.getScriptURI(), t);
+        }
+        @Override
+        public boolean isDisposed() {
+            return !connected;
+        }
+    };
+
+    private void listenToSource() {
+        Simantics.getSession().asyncRequest(new ReadSCLScriptDefinition(input.getScriptURI()), sourceListener);
+    }
+
+    private static final SCLReportingHandler NOP = new AbstractSCLReportingHandler() {
+        @Override
+        public void print(String text) {}
+    };
+
+    private void updateAnnotations(String sourceText) {
+        //LOGGER.debug("updateAnnotations:\n" + sourceText);
+        CompilationError[] errors = new CommandSession(repository, NOP).validate(sourceText);
+        setAnnotations(Arrays.asList(errors));
+    }
+
+    protected void setAnnotations(List<CompilationError> errors) {
+        synchronized (getLockObject()) {
+            removeAllAnnotations();
+            for (CompilationError error : errors) {
+                Annotation annotation = new Annotation(
+                        error.severity == ErrorSeverity.ERROR || error.severity == ErrorSeverity.IMPORT_ERROR ?
+                                "org.eclipse.ui.workbench.texteditor.error" :
+                                    "org.eclipse.ui.workbench.texteditor.warning",
+                                    true, error.description);
+                int begin = Locations.beginOf(error.location);
+                int end = Locations.endOf(error.location);
+                if (begin < 0 || end < begin) {
+                    begin = 0;
+                    end = 1;
+                }
+                addAnnotation(annotation, new Position(begin, end - begin));
+            }
+        }
+    }
+
+    @Override
+    public void connect(IDocument document) {
+        //LOGGER.debug("connect(" + document + ")");
+        super.connect(document);
+        connected = true;
+        listenToSource();
+    }
+
+    @Override
+    public void disconnect(IDocument document) {
+        //LOGGER.debug("disconnect(" + document + ")");
+        connected = false;
+        super.disconnect(document);
+    }
+
+}