]> gerrit.simantics Code Review - simantics/platform.git/blob
fadb4f909f9c679aeb52f11247e45e1a21cf3c06
[simantics/platform.git] /
1 /*******************************************************************************
2  * Copyright (c) 2017 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     Semantum Oy - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.ui.scl.scriptEditor;
13
14 import java.util.Arrays;
15 import java.util.List;
16
17 import org.eclipse.jface.text.IDocument;
18 import org.eclipse.jface.text.Position;
19 import org.eclipse.jface.text.source.Annotation;
20 import org.eclipse.jface.text.source.AnnotationModel;
21 import org.simantics.Simantics;
22 import org.simantics.db.procedure.Listener;
23 import org.simantics.scl.compiler.commands.CommandSession;
24 import org.simantics.scl.compiler.errors.CompilationError;
25 import org.simantics.scl.compiler.errors.ErrorSeverity;
26 import org.simantics.scl.compiler.errors.Locations;
27 import org.simantics.scl.compiler.module.repository.ModuleRepository;
28 import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
29 import org.simantics.scl.runtime.reporting.SCLReportingHandler;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * @author Tuukka Lehtonen
35  * @since 1.31.0
36  */
37 public class SCLScriptAnnotationModel extends AnnotationModel {
38
39     private static final Logger LOGGER = LoggerFactory.getLogger(SCLScriptAnnotationModel.class);
40
41     private final SCLScriptEditorInput input;
42     private final ModuleRepository repository;
43     private volatile boolean connected = false;
44
45     public SCLScriptAnnotationModel(SCLScriptEditorInput input, ModuleRepository repository) {
46         this.input = input;
47         this.repository = repository;
48     }
49
50     private Listener<String> sourceListener = new Listener<String>() {
51         @Override
52         public void execute(String result) {
53             if (connected && result != null)
54                 updateAnnotations(result);
55         }
56         @Override
57         public void exception(Throwable t) {
58             LOGGER.error("Failed to read SCL script source from " + input.getScriptURI(), t);
59         }
60         @Override
61         public boolean isDisposed() {
62             return !connected;
63         }
64     };
65
66     private void listenToSource() {
67         Simantics.getSession().asyncRequest(new ReadSCLScriptDefinition(input.getScriptURI()), sourceListener);
68     }
69
70     private static final SCLReportingHandler NOP = new AbstractSCLReportingHandler() {
71         @Override
72         public void print(String text) {}
73     };
74
75     private void updateAnnotations(String sourceText) {
76         //LOGGER.debug("updateAnnotations:\n" + sourceText);
77         CompilationError[] errors = new CommandSession(repository, NOP).validate(sourceText);
78         setAnnotations(Arrays.asList(errors));
79     }
80
81     protected void setAnnotations(List<CompilationError> errors) {
82         synchronized (getLockObject()) {
83             removeAllAnnotations();
84             for (CompilationError error : errors) {
85                 Annotation annotation = new Annotation(
86                         error.severity == ErrorSeverity.ERROR || error.severity == ErrorSeverity.IMPORT_ERROR ?
87                                 "org.eclipse.ui.workbench.texteditor.error" :
88                                     "org.eclipse.ui.workbench.texteditor.warning",
89                                     true, error.description);
90                 int begin = Locations.beginOf(error.location);
91                 int end = Locations.endOf(error.location);
92                 if (begin < 0 || end < begin) {
93                     begin = 0;
94                     end = 1;
95                 }
96                 addAnnotation(annotation, new Position(begin, end - begin));
97             }
98         }
99     }
100
101     @Override
102     public void connect(IDocument document) {
103         //LOGGER.debug("connect(" + document + ")");
104         super.connect(document);
105         connected = true;
106         listenToSource();
107     }
108
109     @Override
110     public void disconnect(IDocument document) {
111         //LOGGER.debug("disconnect(" + document + ")");
112         connected = false;
113         super.disconnect(document);
114     }
115
116 }