]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Support for SCL script database storage, editing and execution 91/891/3
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 25 Aug 2017 21:38:28 +0000 (00:38 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Sun, 27 Aug 2017 13:28:16 +0000 (16:28 +0300)
* Ontology for defining an SCL script in the database (L0.SCLScript)
* A text editor for L0.SCLScripts:
** Basic syntax highlighting (same as in SCL Module editor)
** Script validation
** Easy script execution directly from the editor (CTRL+R)
* View scripts in model browser under L0.Library instances
* Script execution from Model Browser context menu

refs #7450

Change-Id: I57016492589b6a9b693d926a56a3d0fe7b317023

23 files changed:
bundles/org.simantics.layer0/graph/Layer0SCL.pgraph
bundles/org.simantics.modeling.ontology/graph/Modeling.pgraph
bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph
bundles/org.simantics.modeling.ui/adapters.xml
bundles/org.simantics.modeling.ui/plugin.xml
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/SCLScripts.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/ReadSCLScriptDefinition.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/ReadSCLScriptSource.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/RunSCLScriptActionFactory.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/RunSCLScriptHandler.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptAnnotationModel.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditor.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorAdapter.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorDocumentProvider.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorInput.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorInputFactory.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptSource.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/WriteSCLScriptDefinition.java [new file with mode: 0644]
bundles/org.simantics.modeling/scl/Simantics/SCL.scl
bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java
bundles/org.simantics.scl.ui/plugin.xml
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLConsole.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLConsoleView.java

index 526139c0db35f983d4d9a968c6004ba08e556a83..783f4f401f271affbd497959b5ec60e2806ee6bd 100644 (file)
@@ -57,6 +57,10 @@ L0.SCLModule <T L0.Entity
     >-- L0.SCLModule.definition --> L0.String <R L0.HasProperty : L0.TotalFunction
     @L0.assert L0.SCLModule.definition ""
 
+L0.SCLScript <T L0.Entity
+    >-- L0.SCLScript.definition --> L0.String <R L0.HasProperty : L0.TotalFunction
+    @L0.assert L0.SCLScript.definition ""
+
 L0.Ontology
     >-- L0.Ontology.defaultLocalName --> L0.String <R L0.HasProperty : L0.TotalFunction
     @L0.assert L0.Ontology.defaultLocalName ""
index f337ab602de2fa93677000393c2903eaa3e66260..2d3c38d65e1d98a8db9d2ed7ee82b08ec6e6bf40 100644 (file)
@@ -426,6 +426,7 @@ L0X.HasGeneratedNamePrefix : SEL.GenericParameterType
 //      _ : VP.BrowseContext
 
 L0.SCLModule : MOD.TypeWithChangeInformation
+L0.SCLScript : MOD.TypeWithChangeInformation
 L0.Library : MOD.TypeWithChangeInformation
 SIMU.Model : MOD.TypeWithChangeInformation
 MOD.Subscription : MOD.TypeWithChangeInformation
@@ -440,6 +441,7 @@ L0.Relation : MOD.TypeWithChangeInformation
 STR.ComponentType <T MOD.TypeWithChangeInformation
 
 L0.SCLModule : L0.TypeWithIdentifier
+L0.SCLScript : L0.TypeWithIdentifier
 L0.Type  : L0.TypeWithIdentifier
 L0.Relation : L0.TypeWithIdentifier
 L0.Library : L0.TypeWithIdentifier
index 86171a31a445049705b104c7bfa9b89eb5e42d4c..d392fa2cbaf7322be3a7a21684a547fe87803bd5 100644 (file)
@@ -182,6 +182,8 @@ MBC
 
     @VP.namedRelationChildRule           MOD.Contributions.SCLModules L0.Entity   L0.ConsistsOf L0.SCLModule
     
+    @VP.namedRelationChildRule           MOD.Contributions.SCLScripts L0.Entity   L0.ConsistsOf L0.SCLScript
+    
     @VP.namedRelationChildRule           MOD.Contributions.SCLQueries L0.Library   L0.ConsistsOf MOD.SCLQuery
     
     @VP.namedRelationChildRule           MOD.Contributions.PGraphs L0.Ontology   L0.ConsistsOf L0.PGraph
@@ -342,6 +344,7 @@ MBC
         VP.VisualsContribution.HasCondition MBC.IsUserDefinedComponentTest
     @VP.namedConstantImageRule           MOD.Contributions.ImageImage            IMAGE.Image                          SILK.image
     @VP.namedConstantImageRule           MOD.Contributions.ModuleImage           L0.SCLModule                         SILK.box
+    @VP.namedConstantImageRule           MOD.Contributions.ScriptImage           L0.SCLScript                         SILK.script_go
     @VP.namedConstantImageRule           MOD.Contributions.PGraphImage           L0.PGraph                            SILK.box
     @VP.namedConstantImageRule           MOD.Contributions.QueryImage            MOD.SCLQuery                         SILK.script
     @VP.namedConstantImageRule           MOD.Contributions.CodeImage             STR.ProceduralComponentTypeCode      SILK.book_open
@@ -497,6 +500,20 @@ MAC
             STR.ComponentType
         VP.ActionContribution.HasAction ACTIONS.NewSCLModule
         VP.ActionContribution.IsVisibleIf TESTS.IsContainerNotPublished
+    VP.BrowseContext.HasActionContribution MOD.Contributions.NewSCLScript : VP.ActionContribution
+        L0.HasLabel "SCL Script"
+        VP.ActionContribution.HasImage SILK.script_go
+        VP.ActionContribution.HasCategory VP.NewActionCategory
+        VP.ActionContribution.HasNodeType
+            L0.Library
+        VP.ActionContribution.HasAction ACTIONS.NewSCLScript
+        VP.ActionContribution.IsVisibleIf TESTS.IsContainerNotPublished
+    VP.BrowseContext.HasActionContribution _ : VP.ActionContribution
+        L0.HasLabel "Run SCL Script"
+        VP.ActionContribution.HasImage SILK.script_start
+        VP.ActionContribution.HasCategory VP.EditActionCategory
+        VP.ActionContribution.HasNodeType L0.SCLScript
+        VP.ActionContribution.HasAction ACTIONS.RunSCLScript
     VP.BrowseContext.HasActionContribution MOD.Contributions.NewPGraph : VP.ActionContribution
         L0.HasLabel "Ontology Definition File"
         VP.ActionContribution.HasImage SILK.page_white_text
@@ -658,6 +675,9 @@ ACTIONS.CreateNewVersion
   @MOD.sclAction "newVersionAction"
 ACTIONS.NewSCLModule
   @MOD.sclAction "createSCLModuleAction"
+ACTIONS.NewSCLScript
+  @MOD.sclAction "createSCLScriptAction"
+ACTIONS.RunSCLScript : ACT.Action
 ACTIONS.NewPGraph
   @MOD.sclAction "createPGraphAction"
 ACTIONS.NewSCLQuery : ACT.Action
index 495e4e40631b91b140fef805b4d57c578bff3308..fdb55072aac219cec9a6deebf273f0aa172bb43f 100644 (file)
                <resource
                        uri="http://www.simantics.org/Modeling-0.0/ModelingActionContext/Actions/ImportImages"
                        class="org.simantics.image.ui.ImportImagesActionFactory" />
+               <resource
+                       uri="http://www.simantics.org/Modeling-0.0/ModelingActionContext/Actions/RunSCLScript"
+                       class="org.simantics.modeling.ui.scl.scriptEditor.RunSCLScriptActionFactory" />
        </target>
 
        <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">
index 7a29cd7864f0f8a1c4f0b00861ea2a25715acfb3..41bf9eccc5170e1ee55b1653c4c7dab4e1d2ea30 100644 (file)
             class="org.simantics.modeling.ui.componentTypeEditor.ComponentTypeScriptEditor"
             id="org.simantics.modeling.ui.componentTypeScriptEditor">
       </editor>
+      <editor
+            class="org.simantics.modeling.ui.scl.scriptEditor.SCLScriptEditor"
+            default="false"
+            icon="platform:/plugin/com.famfamfam.silk/icons/script_go.png"
+            id="org.simantics.modeling.ui.scl.scriptEditor"
+            name="SCL Script Editor">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.ui.elementFactories">
+      <factory
+            class="org.simantics.modeling.ui.scl.scriptEditor.SCLScriptEditorInputFactory"
+            id="org.simantics.modeling.ui.scl.scriptEditor.inputFactory">
+      </factory>
    </extension>
    <extension
          point="org.eclipse.core.expressions.definitions">
             </equals>
          </with>
       </definition>
+      <definition
+            id="org.simantics.modeling.ui.inSCLScriptEditor">
+         <with
+               variable="activePartId">
+            <equals
+                  value="org.simantics.modeling.ui.scl.scriptEditor">
+            </equals>
+         </with>
+      </definition>
    </extension>
    <extension
          point="org.eclipse.ui.commands">
             categoryId="org.simantics.modeling.ui.category"
             id="org.simantics.modeling.typical.sync.toggleRealtime">
       </command>
+      <command
+            name="Run SCL Script"
+            categoryId="org.simantics.modeling.ui.category"
+            id="org.simantics.modeling.ui.scl.scriptEditor.run">
+      </command>
    </extension>
    <extension
          point="org.eclipse.core.expressions.definitions">
             commandId="org.simantics.modeling.typical.sync.toggleRealtime"
             class="org.simantics.modeling.ui.typicals.ToggleTypicalRealtimeSync">
       </handler>
+      <handler
+            commandId="org.simantics.modeling.ui.scl.scriptEditor.run"
+            class="org.simantics.modeling.ui.scl.scriptEditor.RunSCLScriptHandler">
+         <enabledWhen>
+            <reference
+                  definitionId="org.simantics.modeling.ui.inSCLScriptEditor">
+            </reference>
+         </enabledWhen>
+      </handler>
    </extension>
    <extension
          point="org.eclipse.ui.bindings">
             schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
             sequence="F1">
       </key>
+      <key
+            commandId="org.simantics.modeling.ui.scl.scriptEditor.run"
+            contextId="org.simantics.modeling.ui.scl.scriptEditor.context"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="Ctrl+R">
+      </key>
    </extension>
    <extension
          point="org.eclipse.ui.menus">
                id="org.simantics.modeling.ui.elementtoolbar">
          </toolbar>
       </menuContribution>-->
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.simantics.modeling.ui.scl.scriptEditor.EditorContext?after=additions">
+         <command
+               commandId="org.simantics.modeling.ui.scl.scriptEditor.run"
+               label="Run Script"
+               icon="platform:/plugin/com.famfamfam.silk/companion/script_start.png"
+               style="push"
+               tooltip="Run the Current Contents of This SCL Script">
+         </command>
+      </menuContribution>
    </extension>
    <extension
          point="org.eclipse.ui.contexts">
             id="org.simantics.ui.undoContext"
             parentId="org.eclipse.ui.contexts.window">
       </context>
+      <context
+            name="In SCL Script Editor"
+            id="org.simantics.modeling.ui.scl.scriptEditor.context"
+            parentId="org.eclipse.ui.contexts.window">
+      </context>
    </extension>
    <extension
          point="org.simantics.ui.perspectiveContextBinding">
             id="org.simantics.modeling.ui.sclModuleEditor2"
             priority="10">
       </adapterClass>
+      <adapterClass
+            class="org.simantics.modeling.ui.scl.scriptEditor.SCLScriptEditorAdapter"
+            id="org.simantics.modeling.ui.scl.scriptEditor.adapter"
+            priority="20">
+      </adapterClass>
    </extension>
    <extension
          point="org.eclipse.core.runtime.preferences">
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/SCLScripts.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/SCLScripts.java
new file mode 100644 (file)
index 0000000..350a819
--- /dev/null
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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;
+
+import java.io.StringReader;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.scl.compiler.commands.CommandSession;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScripts {
+
+       private static final Logger LOGGER = LoggerFactory.getLogger(SCLScripts.class);
+
+       private static final String SCL_CONSOLE_ID = "org.simantics.scl.ui.console";
+
+       /**
+        * @param processor database handle
+        * @param script the script to validate
+        * @return <code>null</code> if ok to run script, otherwise a problem description
+        * @throws DatabaseException
+        */
+       public static String canRunScript(RequestProcessor processor, final Resource script) throws DatabaseException {
+               return null;
+       }
+
+       public static void runScriptWithProgress(String scriptName, String scriptText, CommandSession session, SCLReportingHandler handler) {
+               Job job = new Job("Run SCL Script") {
+                       @Override
+                       protected IStatus run(IProgressMonitor monitor) {
+                               runScriptWithProgress(monitor, scriptName, scriptText, session, handler);
+                               return Status.OK_STATUS;
+                       }
+               };
+               job.setUser(true);
+               job.schedule();
+       }
+
+       public static void runScriptWithProgress(IProgressMonitor monitor, String scriptName, String scriptText, CommandSession session, SCLReportingHandler handler) {
+               monitor.beginTask(scriptName, IProgressMonitor.UNKNOWN);
+               try {
+                       session.execute(new StringReader(scriptText), handler);
+               } finally {
+                       monitor.done();
+               }
+       }
+
+       public static Pair<CommandSession, SCLReportingHandler> getOrCreateConsoleCommandSession() {
+               return getSCLConsoleCommandSession(true);
+       }
+
+       public static Pair<CommandSession, SCLReportingHandler> getSCLConsoleCommandSession(boolean createIfNecessary) {
+               IWorkbenchPart part;
+               try {
+                       part = createIfNecessary
+                                       ? WorkbenchUtils.showView(SCL_CONSOLE_ID, IWorkbenchPage.VIEW_VISIBLE)
+                                       : WorkbenchUtils.findView(SCL_CONSOLE_ID);
+                       if (part != null)
+                               return Pair.make(part.getAdapter(CommandSession.class), part.getAdapter(SCLReportingHandler.class));
+               } catch (PartInitException e) {
+                       LOGGER.error("Failed to open SCL Console view. Using new CommandSession, reporting to stdout via Logger.", e);
+               }
+               SCLReportingHandler handler = SCLReportingHandler.DEFAULT_WITHOUT_ECHO;
+               return Pair.make(new CommandSession(SCLOsgi.MODULE_REPOSITORY, handler), SCLReportingHandler.DEFAULT);
+       }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/ReadSCLScriptDefinition.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/ReadSCLScriptDefinition.java
new file mode 100644 (file)
index 0000000..8e8ce6e
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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 org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.strings.StringUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class ReadSCLScriptDefinition extends UnaryRead<String, String> {
+
+    public ReadSCLScriptDefinition(String scriptURI) {
+        super(scriptURI);
+    }
+
+    @Override
+    public String perform(ReadGraph graph) throws DatabaseException {
+        Resource scriptResource = graph.getPossibleResource(parameter);
+        if (scriptResource == null)
+            return null;
+        Layer0 L0 = Layer0.getInstance(graph);
+        if (!graph.isInstanceOf(scriptResource, L0.SCLScript))
+            return null;
+        return StringUtils.safeString( graph.getPossibleRelatedValue(scriptResource, L0.SCLScript_definition, Bindings.STRING) );
+    }
+
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/ReadSCLScriptSource.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/ReadSCLScriptSource.java
new file mode 100644 (file)
index 0000000..b475c91
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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 org.simantics.db.ReadGraph;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+class ReadSCLScriptSource extends UnaryRead<String, SCLScriptSource> {
+
+    public ReadSCLScriptSource(String scriptURI) {
+        super(scriptURI);
+    }
+
+    @Override
+    public SCLScriptSource perform(ReadGraph graph) throws DatabaseException {
+        return new SCLScriptSource(
+                parameter,
+                graph.syncRequest(new ReadSCLScriptDefinition(parameter)));
+    }
+
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/RunSCLScriptActionFactory.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/RunSCLScriptActionFactory.java
new file mode 100644 (file)
index 0000000..6171e21
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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 org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.ui.IWorkbenchPart;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.primitiverequest.RelatedValue;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ui.Activator;
+import org.simantics.modeling.ui.scl.SCLScripts;
+import org.simantics.scl.compiler.commands.CommandSession;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class RunSCLScriptActionFactory implements ActionFactory {
+
+       @Override
+       public Runnable create(Object target) {
+               if(!(target instanceof Resource))
+                       return null;
+               return () -> runScript((Resource) target);
+       }
+
+       public static void runScript(Resource resource) {
+               try {
+                       Session s = Simantics.getSession();
+                       Layer0 L0 = Layer0.getInstance(s);
+                       String error = SCLScripts.canRunScript(s, resource);
+                       IWorkbenchPart part = WorkbenchUtils.getActiveWorkbenchPart();
+                       IStatusLineManager status = part != null ? WorkbenchUtils.getStatusLine(part) : null;
+                       if (error == null) {
+                               String scriptName = s.syncRequest(new RelatedValue<String>(resource, L0.HasName, Bindings.STRING));
+                               String text = s.syncRequest(new RelatedValue<String>(resource, L0.SCLScript_definition, Bindings.STRING));
+                               Pair<CommandSession, SCLReportingHandler> p = SCLScripts.getOrCreateConsoleCommandSession();
+                               SCLScripts.runScriptWithProgress(scriptName, text, p.first, p.second);
+                               status.setErrorMessage(null);
+                       } else {
+                               if (status != null)
+                                       status.setErrorMessage(error);
+                       }
+               } catch (DatabaseException e) {
+                       Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to run SCL script.", e));
+                       return;
+               }
+       }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/RunSCLScriptHandler.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/RunSCLScriptHandler.java
new file mode 100644 (file)
index 0000000..5ba4872
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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 org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.simantics.Simantics;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.common.primitiverequest.PossibleResource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.modeling.ui.Activator;
+import org.simantics.modeling.ui.scl.SCLScripts;
+import org.simantics.scl.compiler.commands.CommandSession;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class RunSCLScriptHandler extends AbstractHandler {
+
+       @Override
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               IEditorPart editor = HandlerUtil.getActiveEditorChecked(event);
+               IStatusLineManager status = WorkbenchUtils.getStatusLine(editor);
+               try {
+                       final Resource script = getInputResource(Simantics.getSession(), editor);
+                       if (script == null)
+                               return null;
+                       String error = SCLScripts.canRunScript(Simantics.getSession(), script);
+                       if (error == null) {
+                               String textSnapshot = getDocumentText(editor);
+                               if (textSnapshot != null) {
+                                       Pair<CommandSession, SCLReportingHandler> p = SCLScripts.getOrCreateConsoleCommandSession();
+                                       SCLScripts.runScriptWithProgress(editor.getTitle(), textSnapshot, p.first, p.second);
+                                       status.setErrorMessage(null);
+                               }
+                       } else {
+                               status.setErrorMessage(error);
+                       }
+               } catch (DatabaseException ex) {
+                       Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to run SCL script.", ex));
+               }
+               return null;
+       }
+
+       private static Resource getInputResource(RequestProcessor processor, IEditorPart editor) throws DatabaseException {
+               IEditorInput input = editor.getEditorInput();
+               return (input instanceof SCLScriptEditorInput)
+                               ? processor.syncRequest(new PossibleResource(((SCLScriptEditorInput) input).getScriptURI()))
+                               : null;
+       }
+
+       private static String getDocumentText(IEditorPart editor) {
+               if (!(editor instanceof ITextEditor))
+                       return null;
+               IDocument document = ((ITextEditor) editor).getDocumentProvider().getDocument(editor.getEditorInput());
+               return document == null ? null : document.get();
+       }
+
+}
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);
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditor.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditor.java
new file mode 100644 (file)
index 0000000..253b697
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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 org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.contexts.IContextService;
+import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew;
+import org.simantics.scl.ui.editor2.SCLModuleEditor2;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptEditor extends SCLModuleEditor2 {
+
+    public SCLScriptEditor() {
+        super();
+        setDocumentProvider(new SCLScriptEditorDocumentProvider((SCLSourceViewerConfigurationNew) getSourceViewerConfiguration()));
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        super.createPartControl(parent);
+        getSite().getService(IContextService.class).activateContext("org.simantics.modeling.ui.scl.scriptEditor.context");
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorAdapter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorAdapter.java
new file mode 100644 (file)
index 0000000..ceb0e58
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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 org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter;
+import org.simantics.ui.workbench.editor.EditorAdapter;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptEditorAdapter extends AbstractResourceEditorAdapter implements EditorAdapter {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLScriptEditorAdapter.class);
+    
+    public SCLScriptEditorAdapter() {
+        super("SCL Script Editor", null, 20);
+    }
+
+    private Resource toResource(Object input) {
+        if (input instanceof IStructuredSelection)
+            input = ((IStructuredSelection)input).getFirstElement();
+        if (!(input instanceof Resource)) {
+            if(input instanceof IAdaptable) {
+                input = ((IAdaptable)input).getAdapter(Resource.class);
+                if (input == null)
+                    return null;
+            }
+            else
+                return null;
+        }
+        return (Resource) input;
+    }
+
+    @Override
+    public boolean canHandle(ReadGraph g, Object input) throws DatabaseException {
+        Resource resource = toResource(input);
+        return g.isInstanceOf(resource, Layer0.getInstance(g).SCLScript);
+    }
+
+    protected void openEditor(Resource input) throws Exception {
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        if (page == null)
+            return;
+        Simantics.getSession().asyncRequest(new ReadRequest() {
+            @Override
+            public void run(ReadGraph graph) throws DatabaseException {
+                String uri = graph.getURI(input);
+                PlatformUI.getWorkbench().getDisplay().asyncExec(openEditor(uri));
+            }
+        });
+    }
+
+    private static Runnable openEditor(String uri) {
+        return () -> {
+            try {
+                WorkbenchUtils.openEditor("org.simantics.modeling.ui.scl.scriptEditor", new SCLScriptEditorInput(uri));
+            } catch (PartInitException e) {
+                LOGGER.error("Could not initialize part", e);
+            }
+        };
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorDocumentProvider.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorDocumentProvider.java
new file mode 100644 (file)
index 0000000..c58e72d
--- /dev/null
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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 org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.AbstractDocumentProvider;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew;
+import org.simantics.scl.ui.editor2.SCLPartitionScanner;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptEditorDocumentProvider extends AbstractDocumentProvider {
+
+    private SCLSourceViewerConfigurationNew sourceViewer;
+    protected AnnotationModel annotationModel = new AnnotationModel();
+
+    private Object currentElement;
+    private SCLScriptSource currentSource;
+
+    public SCLScriptEditorDocumentProvider(SCLSourceViewerConfigurationNew sourceViewer) {
+        this.sourceViewer = sourceViewer;
+    }
+
+    private void updateScriptSource(Object input) {
+        if (currentElement != null && currentElement.equals(input))
+            return;
+        currentElement = input;
+        if (!(currentElement instanceof SCLScriptEditorInput))
+            return;
+
+        SCLScriptSource source = ((SCLScriptEditorInput) currentElement).getAdapter(SCLScriptSource.class);
+        if (source != null)
+            currentSource = source;
+    }
+
+    @Override
+    protected IDocument createDocument(Object element) throws CoreException {
+        updateScriptSource(element);
+        if (currentSource == null)
+            throw new CoreException(
+                    new Status(Status.ERROR, "org.simantics.scl.ui", "Source for the SCL module could not be found."));
+        Document document = new Document(currentSource.getSourceText());
+        IDocumentPartitioner partitioner = new FastPartitioner(new SCLPartitionScanner(), SCLPartitionScanner.PARTITION_TYPES);
+        partitioner.connect(document);
+        document.setDocumentPartitioner(partitioner);
+        sourceViewer.updateCompletionAssistModuleName(currentSource.getScriptURI());
+        return document;
+    }
+
+    @Override
+    public void changed(Object element) {
+        updateScriptSource(element);
+    }
+
+    @Override
+    public void aboutToChange(Object element) {
+        super.aboutToChange(element);
+    }
+
+    @Override
+    public boolean isModifiable(Object element) {
+        if (currentSource == null)
+            return false;
+        return currentSource.isUpdateable();
+    }
+
+    @Override
+    public boolean isReadOnly(Object element) {
+        return !isModifiable(element);
+    }
+
+    @Override
+    protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
+        SCLScriptEditorInput input = (SCLScriptEditorInput) element;
+        return new SCLScriptAnnotationModel(input, SCLOsgi.MODULE_REPOSITORY);
+    }
+
+    @Override
+    protected void doSaveDocument(IProgressMonitor monitor, Object element,
+            IDocument document, boolean overwrite) throws CoreException
+    {
+        if (currentSource != null)
+            currentSource.update(document.get());
+    }
+
+    @Override
+    protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
+        return null;
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorInput.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorInput.java
new file mode 100644 (file)
index 0000000..90a87cb
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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 org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+import org.simantics.Simantics;
+import org.simantics.db.exception.DatabaseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptEditorInput implements IEditorInput, IPersistableElement {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLScriptEditorInput.class);
+
+    private final String scriptURI;
+
+    public SCLScriptEditorInput(String scriptURI) {
+        this.scriptURI = scriptURI;
+    }
+
+    public String getScriptURI() {
+        return scriptURI;
+    }
+
+    @Override
+    public boolean exists() {
+        // Not worth it testing this from the database.
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T getAdapter(Class<T> adapter) {
+        if (adapter.equals(SCLScriptSource.class)) {
+            try {
+                return (T) Simantics.getSession().syncRequest(new ReadSCLScriptSource(scriptURI));
+            } catch (DatabaseException e) {
+                LOGGER.error("Failed to read SCL script source", e);
+            }
+        }
+        if (adapter.equals(IPersistableElement.class))
+            return (T) this;
+        return null;
+    }
+
+    @Override
+    public String getFactoryId() {
+        return "org.simantics.modeling.ui.scl.scriptEditor.inputFactory";
+    }
+
+    @Override
+    public String getName() {
+        int p = scriptURI.lastIndexOf('/');
+        if(p >= 0)
+            return scriptURI.substring(p+1);
+        else
+            return scriptURI;
+    }
+
+    @Override
+    public String getToolTipText() {
+        return scriptURI;
+    }
+
+    @Override
+    public ImageDescriptor getImageDescriptor() {
+        return null;
+    }
+
+    @Override
+    public IPersistableElement getPersistable() {
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((scriptURI == null) ? 0 : scriptURI.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null || getClass() != obj.getClass())
+            return false;
+        SCLScriptEditorInput other = (SCLScriptEditorInput) obj;
+        return scriptURI.equals(other.scriptURI);
+    }
+
+    @Override
+    public void saveState(IMemento memento) {
+        memento.putTextData(scriptURI);
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorInputFactory.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptEditorInputFactory.java
new file mode 100644 (file)
index 0000000..9087ac7
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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 org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IMemento;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptEditorInputFactory implements IElementFactory {
+
+    @Override
+    public IAdaptable createElement(IMemento memento) {
+        return new SCLScriptEditorInput(memento.getTextData());
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptSource.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/SCLScriptSource.java
new file mode 100644 (file)
index 0000000..87c74b7
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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 org.simantics.Simantics;
+import org.simantics.db.exception.DatabaseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+class SCLScriptSource {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLScriptSource.class);
+
+    private String scriptURI;
+    private String scriptText;
+
+    public SCLScriptSource(String scriptURI, String scriptText) {
+        this.scriptURI = scriptURI;
+        this.scriptText = scriptText;
+    }
+
+    public void update(String newSourceText) {
+        try {
+            Simantics.getSession().syncRequest(new WriteSCLScriptDefinition(scriptURI, newSourceText));
+        } catch (DatabaseException e) {
+            LOGGER.error("Failed to write SCL script source from " + scriptURI, e);
+        }
+    }
+
+    public boolean isUpdateable() {
+        return true;
+    }
+
+    public String getSourceText() {
+        return scriptText;
+    }
+
+    public String getScriptURI() {
+        return scriptURI;
+    }
+
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/WriteSCLScriptDefinition.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/scriptEditor/WriteSCLScriptDefinition.java
new file mode 100644 (file)
index 0000000..67a79df
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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 org.simantics.databoard.Bindings;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class WriteSCLScriptDefinition extends WriteRequest {
+
+    private final String scriptURI;
+    private final String definition;
+
+    public WriteSCLScriptDefinition(String scriptURI, String sourceText) {
+        this.scriptURI = scriptURI;
+        this.definition = sourceText;
+    }
+
+    @Override
+    public void perform(WriteGraph graph) throws DatabaseException {
+        Resource moduleResource = graph.getPossibleResource(scriptURI);
+        if (moduleResource == null)
+            return;
+        Layer0 L0 = Layer0.getInstance(graph);
+        if (!graph.isInstanceOf(moduleResource, L0.SCLScript))
+            return;
+        graph.claimLiteral(moduleResource, L0.SCLScript_definition, definition, Bindings.STRING);
+    }
+
+}
\ No newline at end of file
index 32db0f4bc6545cca456aaa697aa49477aafe1ac3..72c733a59f5999dd9c38db1be0d52bfe3474cd81 100644 (file)
@@ -12,14 +12,13 @@ importJava "org.simantics.scl.ui.editor.TextAndErrors" where
     createTextAndErrors :: String -> [CompilationError] -> TextAndErrors
 
 createSCLModuleAction :: Resource -> <Proc> ()
-createSCLModuleAction res = do
-  syncWrite (\() -> createSCLModuleDefault res)
-  ()
+createSCLModuleAction res = ignore $ syncWrite (\() -> createSCLModuleDefault res)
+
+createSCLScriptAction :: Resource -> <Proc> ()
+createSCLScriptAction res = ignore $ syncWrite (\() -> createSCLScriptDefault res)
 
 createPGraphAction :: Resource -> <Proc> ()
-createPGraphAction res = do
-  syncWrite (\() -> createPGraphDefault res)
-  ()
+createPGraphAction res = ignore $ syncWrite (\() -> createPGraphDefault res)
 
 createSCLValueIndependent :: Resource -> String -> <WriteGraph> Resource
 createSCLValueIndependent valueType expression = do
@@ -41,6 +40,7 @@ setExpression self expression = do
 
 importJava "org.simantics.modeling.ModelingUtils" where
     createSCLModuleDefault :: Resource -> <WriteGraph> ()
+    createSCLScriptDefault :: Resource -> <WriteGraph> ()
     createPGraphDefault :: Resource -> <WriteGraph> ()
     createSCLModule :: Resource -> String -> <WriteGraph> ()
 
index b4e63a6cc5c4188544baeb3eaf7abafcf6f3d6a7..81505e0bc89863a8594cc6dc31e8fc874d6229ab 100644 (file)
@@ -1728,6 +1728,21 @@ public class ModelingUtils {
        Layer0Utils.addCommentMetadata(graph, "Created SCL Module " + name + " " + sclModule.toString());
     }
 
+    public static void createSCLScriptDefault(WriteGraph graph, Resource target) throws DatabaseException {
+        String name = NameUtils.findFreshEscapedName(graph, "SCLScript", target);
+        createSCLScript(graph, target, name);
+    }
+
+    public static void createSCLScript(WriteGraph graph, Resource target, String name) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        Resource sclModule = GraphUtils.create2(graph, L0.SCLScript,
+                L0.HasName, name,
+                L0.PartOf, target,
+                L0.SCLScript_definition, "");
+        Layer0Utils.addCommentMetadata(graph, "Created SCL Script " + name + " " + sclModule.toString());
+    }
+
     public static void createPGraphDefault(WriteGraph graph, Resource target) throws DatabaseException {
        String name = NameUtils.findFreshEscapedName(graph, "Ontology Definition File", target);
        createPGraph(graph, target, name);
index dd1539c4627e7df2e0601c5480af4731db60e886..ad9e3baf02c1cc2fbaa7019dfff9fe7dfcd2d063 100644 (file)
             id="org.simantics.scl.ui.editor2"
             name="SCL Module Editor">
       </editor>
+      <editor
+            class="org.simantics.scl.ui.script.SCLScriptEditor"
+            contributorClass="org.eclipse.ui.texteditor.BasicTextEditorActionContributor"
+            default="true"
+            extensions="scls"
+            filenames="*.scls"
+            id="org.simantics.scl.ui.script.editor"
+            name="SCL Script Editor">
+      </editor>
    </extension>
    <extension
          point="org.eclipse.core.filebuffers.documentSetup">
index 5eacaa093211d68d7d5d29ea8b36aa027c7b0668..16a946fbebb86922ee99bd9ad481b5e547d37fd1 100644 (file)
@@ -173,6 +173,11 @@ public class SCLConsole extends AbstractCommandConsole {
     public CommandSession getSession() {
         return session;
     }
+
+    public SCLReportingHandler getHandler() {
+        return handler;
+    }
+
     public void interruptCurrentCommands() {
         synchronized(currentJobs) {
             for(Job job : currentJobs)
index a7eb4332333cc0cba1a4325c36e69b829c7a7a75..63b89a0b5a9c2ae274302f09a671c8f036e02e97 100644 (file)
@@ -30,11 +30,13 @@ import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.ui.part.ViewPart;
 import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.simantics.scl.compiler.commands.CommandSession;
 import org.simantics.scl.compiler.commands.CommandSessionImportEntry;
 import org.simantics.scl.compiler.commands.SCLConsoleListener;
 import org.simantics.scl.compiler.module.repository.UpdateListener;
 import org.simantics.scl.compiler.testing.TestRunnable;
 import org.simantics.scl.osgi.internal.TestUtils;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
 import org.simantics.scl.ui.Activator;
 import org.simantics.scl.ui.imports.internal.ManageImportsDialog;
 import org.simantics.scl.ui.tests.SCLTestsDialog;
@@ -335,4 +337,14 @@ public class SCLConsoleView extends ViewPart {
         console.dispose();
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T getAdapter(Class<T> adapter) {
+        if (adapter == CommandSession.class)
+            return (T) console.getSession();
+        if (adapter == SCLReportingHandler.class)
+            return (T) console.getHandler();
+        return super.getAdapter(adapter);
+    }
+
 }