>-- 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 ""
// _ : VP.BrowseContext
L0.SCLModule : MOD.TypeWithChangeInformation
+L0.SCLScript : MOD.TypeWithChangeInformation
L0.Library : MOD.TypeWithChangeInformation
SIMU.Model : MOD.TypeWithChangeInformation
MOD.Subscription : 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
@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
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
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
@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
<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">
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">
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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
--- /dev/null
+/*******************************************************************************
+ * 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
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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");
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+ };
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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());
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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
--- /dev/null
+/*******************************************************************************
+ * 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
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
importJava "org.simantics.modeling.ModelingUtils" where
createSCLModuleDefault :: Resource -> <WriteGraph> ()
+ createSCLScriptDefault :: Resource -> <WriteGraph> ()
createPGraphDefault :: Resource -> <WriteGraph> ()
createSCLModule :: Resource -> String -> <WriteGraph> ()
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);
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">
public CommandSession getSession() {
return session;
}
+
+ public SCLReportingHandler getHandler() {
+ return handler;
+ }
+
public void interruptCurrentCommands() {
synchronized(currentJobs) {
for(Job job : currentJobs)
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;
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);
+ }
+
}