From: Tuukka Lehtonen Date: Wed, 28 Aug 2019 17:04:21 +0000 (+0000) Subject: Merge "Revert "Support enumerated property types in UC interface"" X-Git-Tag: v1.43.0~136^2~87 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=e5c9ce2de1b970b17c3ffc1151d7c49743df6183;hp=1b2114e1f1cbae2f85ae396ef37a3199aaf67a3c Merge "Revert "Support enumerated property types in UC interface"" --- diff --git a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java index 2f52153a1..d27eeaa79 100644 --- a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java +++ b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java @@ -427,6 +427,10 @@ public class GraphExplorerComposite extends Composite implements Widget, IAdapta ((Control)explorer.getControl()).addListener(eventType, listener); } + public void removeListenerFromControl(int eventType, Listener listener) { + ((Control)explorer.getControl()).removeListener(eventType, listener); + } + public void finish() { created = true; createControls(site); diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/validation/L0Validations.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/validation/L0Validations.java index 99ef91b7a..1ff6e5fbc 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/validation/L0Validations.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/validation/L0Validations.java @@ -12,7 +12,7 @@ import org.simantics.scl.compiler.types.Type; public class L0Validations { public static String checkValueType(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException { - + if (subject == null) return null; if (predicate == null) @@ -25,9 +25,34 @@ public class L0Validations { String valueTypeText = graph.getPossibleRelatedValue(predicate, L0.RequiresValueType, Bindings.STRING); if(valueTypeText != null) { Type valueType = CommonDBUtils.getSCLType(graph, subject, valueTypeText); + if(valueType == null) { + Resource range = graph.getPossibleObject(predicate, L0.HasRange); + if(range != null) { + return null; + } else { + StringBuilder sb = new StringBuilder() + .append("The value type ") + .append(valueType) + .append(" of predicate ") + .append(NameUtils.getSafeName(graph, predicate, true)) + .append(" cannot be resolved.") + .append(NameUtils.getSafeName(graph, object, true)) + .append("."); + return sb.toString(); + } + } String valueTypeText2 = graph.getPossibleRelatedValue(object, L0.HasValueType, Bindings.STRING); if(valueTypeText2 != null) { Type valueType2 = CommonDBUtils.getSCLType(graph, subject, valueTypeText2); + if(valueType2 == null) { + StringBuilder sb = new StringBuilder() + .append("The value type ") + .append(valueType2) + .append(" of object ") + .append(NameUtils.getSafeName(graph, object, true)) + .append(" cannot be resolved."); + return sb.toString(); + } if(!valueType.equals(valueType2)) { StringBuilder sb = new StringBuilder() .append("The value type ") @@ -44,9 +69,9 @@ public class L0Validations { } } } - + return null; - + } - + } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java index e300384f1..6f310120b 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java @@ -164,6 +164,8 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic }); + result.add(new Entry(graph, resource)); + graph.syncRequest(new ReadRequest() { @Override diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfo.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfo.java index f3753ce80..4d208b457 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfo.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfo.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2019 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.db.layer0.request; import java.util.Collection; @@ -20,6 +31,7 @@ public class PropertyInfo { public final Resource predicate; public final String name; public final boolean isHasProperty; + public final boolean isFunctional; public final Set classifications; public final VariableBuilder builder; public final Resource literalRange; @@ -30,9 +42,10 @@ public class PropertyInfo { public final Map> subliteralPredicates; public final ValueAccessor valueAccessor; public final boolean hasEnumerationRange; - public PropertyInfo(Resource predicate, String name, boolean isHasProperty, Set classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) { + public PropertyInfo(Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) { this.predicate = predicate; this.name = name; + this.isFunctional = isFunctional; this.isHasProperty = isHasProperty; this.classifications = classifications; this.builder = builder; @@ -45,7 +58,7 @@ public class PropertyInfo { this.valueAccessor = valueAccessor; this.hasEnumerationRange = hasEnumerationRange; } - public static PropertyInfo make(ReadGraph graph, Resource predicate, String name, boolean isHasProperty, Set classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Map> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) throws DatabaseException { + public static PropertyInfo make(ReadGraph graph, Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Map> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); if(literalRange != null) { @@ -58,7 +71,7 @@ public class PropertyInfo { Binding defaultBinding = requiredDatatype != null ? Bindings.getBinding(requiredDatatype) : null; - return new PropertyInfo(predicate, name, isHasProperty, classifications, builder, literalRange, requiredDatatype, definedUnit, requiredValueType, defaultBinding, subliteralPredicates, valueAccessor, hasEnumerationRange); + return new PropertyInfo(predicate, name, isFunctional, isHasProperty, classifications, builder, literalRange, requiredDatatype, definedUnit, requiredValueType, defaultBinding, subliteralPredicates, valueAccessor, hasEnumerationRange); } public boolean hasClassification(String classification) { @@ -75,6 +88,8 @@ public class PropertyInfo { .append(requiredValueType) .append(", predicate=") .append(predicate) + .append(", isFunctional=") + .append(isFunctional) .append(", isHasProperty=") .append(isHasProperty) .append(", hasEnumerationRange=") diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfoRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfoRequest.java index 2a181674c..90e63e29f 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfoRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfoRequest.java @@ -41,6 +41,8 @@ final public class PropertyInfoRequest extends ResourceRead { String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING); if(name != null) name = name.intern(); + boolean isFunctional = graph.isInstanceOf(resource, L0.FunctionalRelation); + Set classifications = graph.sync(new ClassificationsRequest(graph.getPrincipalTypes(resource))); VariableBuilder variableBuilder = graph.getPossibleAdapter(resource, VariableBuilder.class); @@ -88,13 +90,13 @@ final public class PropertyInfoRequest extends ResourceRead { } } - return PropertyInfo.make(graph, resource, name, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, map, accessor, hasEnumerationRange); + return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, map, accessor, hasEnumerationRange); } } } - return PropertyInfo.make(graph, resource, name, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, Collections.>emptyMap(), accessor, hasEnumerationRange); + return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, Collections.>emptyMap(), accessor, hasEnumerationRange); } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java index 610c8c8bd..830f7a6bb 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java @@ -71,7 +71,6 @@ import org.simantics.db.common.primitiverequest.PossibleRelatedValue; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.request.DelayedWriteRequest; import org.simantics.db.common.request.ObjectsWithType; -import org.simantics.db.common.request.PossibleChild; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.utils.CommonDBUtils; @@ -116,9 +115,7 @@ import org.simantics.graph.representation.PrettyPrintTG; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; import org.simantics.operation.Layer0X; -import org.simantics.scl.compiler.environment.Environments; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; -import org.simantics.scl.compiler.top.SCLExpressionCompilationException; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.runtime.function.Function; @@ -1382,6 +1379,41 @@ public class Layer0Utils { return result; } + public static Resource possibleObjectForType(ReadGraph graph, Resource type, Resource relation) throws DatabaseException { + PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(relation)); + return possibleObjectForType(graph, type, relation, pi.isFunctional); + } + + public static Resource possibleObjectForType(ReadGraph graph, Resource type, Resource relation, boolean functional) throws DatabaseException { + if(functional) { + Layer0 L0 = Layer0.getInstance(graph); + Resource result = graph.getPossibleObject(type, relation); + if(result != null) + return result; + for(Resource su : graph.getObjects(L0.Inherits, type)) { + Resource r = possibleObjectForType(graph, su, relation, functional); + if(r != null) { + if(result != null) + return null; + result = r; + } + } + return result; + } else { + Set found = objectsForTypeNonFunctional(graph, type, relation, new HashSet<>()); + return found.size() == 1 ? found.iterator().next() : null; + } + } + + private static Set objectsForTypeNonFunctional(ReadGraph graph, Resource type, Resource relation, Set found) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + found.addAll(graph.getObjects(type, relation)); + for(Resource su : graph.getObjects(L0.Inherits, type)) { + objectsForTypeNonFunctional(graph, su, relation, found); + } + return found; + } + public static Resource getPossiblePredicateByNameFromType(ReadGraph graph, Resource type, String name) throws DatabaseException { Map domain = getDomainOf(graph, type); return domain.get(name); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java new file mode 100644 index 000000000..7f0c8a948 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2019 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.db.layer0.variable; + +import org.simantics.db.Resource; + +public class ResourceX implements VariableOrResource { + + public final Resource value; + + public ResourceX(Resource value) { + this.value = value; + } + + @Override + public String toString() { + return "ResourceX " + value; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) + return true; + if(obj == null || obj.getClass() != getClass()) + return false; + ResourceX other = (ResourceX)obj; + return value == null ? other.value == null : value.equals(other.value); + } + + @Override + public int hashCode() { + return 31 * (value == null ? 0 : value.hashCode()) + 13532; + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java index ed58556c7..7927614cd 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java @@ -38,7 +38,7 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { private static final Logger LOGGER = LoggerFactory.getLogger(StandardGraphPropertyVariable.class); protected static final PropertyInfo NO_PROPERTY = new PropertyInfo(null, null, - false, Collections. emptySet(), null, null, null, null, null, null, + false, false, Collections. emptySet(), null, null, null, null, null, null, Collections.> emptyMap(), null, false); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java new file mode 100644 index 000000000..1c35049a9 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2019 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.db.layer0.variable; + +import org.simantics.db.Resource; + +/** + * An interface to match the VariableOrResource SCL data type + * which represents either a Resource or a Variable. Allows + * defining SCL classes with either of the two as a input. + * + * @author Antti Villberg + * @since 1.40.0 + */ +public interface VariableOrResource { + + public static VariableOrResource make(Resource value) { + return new ResourceX(value); + } + + public static VariableOrResource make(Variable value) { + return new VariableX(value); + } + + public static VariableOrResource make(Object value) { + if(value instanceof Resource) + return make((Resource)value); + if(value instanceof Variable) + return make((Variable)value); + throw new IllegalArgumentException("VariableOrResource acccepts only Variable or Resource, got " + value + " with class " + value.getClass().getName()); + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java new file mode 100644 index 000000000..8286abb62 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2019 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.db.layer0.variable; + +public class VariableX implements VariableOrResource { + + public final Variable value; + + public VariableX(Variable value) { + this.value = value; + } + + @Override + public String toString() { + return "VariableX " + value; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) + return true; + if(obj == null || obj.getClass() != getClass()) + return false; + VariableX other = (VariableX)obj; + return value == null ? other.value == null : value.equals(other.value); + } + + @Override + public int hashCode() { + return 31 * (value == null ? 0 : value.hashCode()) + 13532; + } + +} diff --git a/bundles/org.simantics.db.testing/META-INF/MANIFEST.MF b/bundles/org.simantics.db.testing/META-INF/MANIFEST.MF index c80729ad8..960ccf009 100644 --- a/bundles/org.simantics.db.testing/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.db.testing/META-INF/MANIFEST.MF @@ -8,17 +8,18 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.simantics.db.layer0;bundle-version="1.1.0", org.simantics.graph.db;bundle-version="1.1.5";visibility:=reexport, org.simantics.project;bundle-version="1.0.1";visibility:=reexport, - org.apache.log4j;bundle-version="1.2.15", org.simantics.db.procore;bundle-version="1.1.1", org.simantics.db.services;bundle-version="1.1.0", org.eclipse.core.runtime;bundle-version="3.6.0", org.simantics.workbench;bundle-version="1.1.0", org.simantics.db.management;bundle-version="1.1.0", + org.simantics.db.indexing;bundle-version="1.1.0", org.simantics;bundle-version="1.0.0";visibility:=reexport, org.simantics.scl.osgi;bundle-version="1.0.4", org.junit;bundle-version="4.12.0", org.simantics.db.server, - org.apache.commons.math3 + org.apache.commons.math3, + org.slf4j.api;bundle-version="1.7.25" Export-Package: org.simantics.db.testing.annotation, org.simantics.db.testing.base, org.simantics.db.testing.cases, diff --git a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java index 26e916fc1..1ea9e6a54 100644 --- a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java +++ b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java @@ -19,21 +19,24 @@ import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.osgi.internal.Activator; import org.simantics.scl.osgi.internal.ServiceBasedModuleSourceRepository; import org.simantics.scl.osgi.internal.ServiceBasedTestRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import gnu.trove.map.hash.THashMap; /** * Utilizies {@link TestRepository} for collecting SCL tests from bundles * - * @author Jani - * + * @author Jani Simomaa */ public class SCLScriptTestBase extends FreshDatabaseTest { + private static final Logger LOGGER = LoggerFactory.getLogger(SCLScriptTestBase.class); + private Map testRunnables = new THashMap(); - + @Rule public TestName testName = new TestName(); - + /** * Constructor that initially searches for all SCL test scripts and stores * them into a Map for later access @@ -47,14 +50,14 @@ public class SCLScriptTestBase extends FreshDatabaseTest { testRunnables.put(runnable.getName(), runnable); } } - + /** * Simplest method for running a SCL test */ protected void test() { test(-1); } - + /** * Executes a test case with given timeout as seconds. When time runs out one * can assume a deadlock has happened. The process is killed after the timeout @@ -65,7 +68,7 @@ public class SCLScriptTestBase extends FreshDatabaseTest { protected void test(int timeout) { testImpl(timeout); } - + /** * Executes a test case with given timeout as seconds * @@ -75,25 +78,26 @@ public class SCLScriptTestBase extends FreshDatabaseTest { SCLOsgi.SOURCE_REPOSITORY = new ServiceBasedModuleSourceRepository(Activator.getContext()); SCLOsgi.MODULE_REPOSITORY = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY); SCLOsgi.TEST_REPOSITORY = new ServiceBasedTestRepository(Activator.getContext()); - + String testName = resolveTestName(); TestRunnable runnable = testRunnables.get(testName); - + if (timeout > -1) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { + LOGGER.info("Watchdog will kill this test process because it has been executing for over {} seconds", timeout); //$NON-NLS-1$ String processName = ManagementFactory.getRuntimeMXBean().getName(); - System.out.println("PID: " + processName); + LOGGER.info("Test Process Name: {}", processName); //$NON-NLS-1$ String PID = processName.split("@")[0]; String command = "taskkill /F /PID " + PID; - System.out.println("Command: " + command); + LOGGER.info("Running command to kill test process: {}", command); //$NON-NLS-1$ try { Runtime.getRuntime().exec(command); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Failed to kill process that ran over its execution time limit of {} seconds", timeout, e); } } @@ -101,7 +105,7 @@ public class SCLScriptTestBase extends FreshDatabaseTest { try { runnable.run(); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error("Failed to run test {} runnable {}", testName, runnable, e); } finally { timer.cancel(); } @@ -109,11 +113,11 @@ public class SCLScriptTestBase extends FreshDatabaseTest { try { runnable.run(); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error("Failed to run test {} runnable {}", testName, runnable, e); } } } - + /** * Resolves the full test name based on the names of classes that extends this * SCLScriptTestBase class.

diff --git a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/cases/FreshDatabaseTest.java b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/cases/FreshDatabaseTest.java index 963b2d9f5..53ddfb04f 100644 --- a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/cases/FreshDatabaseTest.java +++ b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/cases/FreshDatabaseTest.java @@ -30,15 +30,11 @@ public class FreshDatabaseTest extends TestBase { @Before public void setUp() throws Exception { - TestBase.printStart(this); TestSettings testSettings = TestSettings.getInstanceUnsafe(); configure(testSettings); -// state = AcornTests.newSimanticsWorkspace(testSettings, null); state = Tests.newSimanticsWorkspace(testSettings, null); - super.setUp(); - } @After diff --git a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/AcornTestHandler.java b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/AcornTestHandler.java index 5f5da8f2e..e7e1722ac 100644 --- a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/AcornTestHandler.java +++ b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/AcornTestHandler.java @@ -1,6 +1,7 @@ package org.simantics.db.testing.common; import java.io.File; +import java.io.IOException; import java.util.Properties; import org.eclipse.core.runtime.Platform; @@ -10,6 +11,7 @@ import org.simantics.db.Manager; import org.simantics.db.ServerI; import org.simantics.db.Session; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.indexing.DatabaseIndexing; /** * ProCore specific test handler. @@ -33,15 +35,27 @@ public class AcornTestHandler { void initNew() throws DatabaseException { Management m = getManagement(); - if (m.exist()) + if (m.exist()) { m.delete(); + } + deleteIndexes(); m.create(); } void initIfNeccessary() throws DatabaseException { Management m = getManagement(); - if (!m.exist()) + if (!m.exist()) { m.create(); + deleteIndexes(); + } + } + + private void deleteIndexes() throws DatabaseException { + try { + DatabaseIndexing.deleteAllIndexes(); + } catch (IOException e) { + throw new DatabaseException("Failed to delete all existing indexes", e); + } } public Session getSession() throws DatabaseException { diff --git a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/TestBase.java b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/TestBase.java index 1068fc2f5..73e6ff8f1 100644 --- a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/TestBase.java +++ b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/TestBase.java @@ -27,7 +27,6 @@ import org.simantics.db.Session; import org.simantics.db.WriteGraph; import org.simantics.db.WriteOnlyGraph; import org.simantics.db.common.request.WriteOnlyRequest; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ServiceNotFoundException; import org.simantics.db.management.SessionContext; @@ -38,14 +37,17 @@ import org.simantics.db.service.LifecycleSupport; import org.simantics.db.testing.impl.Configuration; import org.simantics.layer0.Layer0; import org.simantics.utils.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Base class for Simantics Test Cases. Assumes that ProCore is already running. + * Base class for Simantics Test Cases. + * Assumes that the Simantics database is already running. * * @author Marko Luukkainen - * */ -abstract public class TestBase /*extends TestCase*/ { +public abstract class TestBase { + private static final Logger LOGGER = LoggerFactory.getLogger(TestBase.class); public static final boolean DEBUG = Configuration.get().debug; public static final String ROOT_LIBRARY_URI = "http:/"; private NoExitSecurityManager noExitSecurityManager; @@ -56,7 +58,7 @@ abstract public class TestBase /*extends TestCase*/ { static boolean printStart = true; public static final ArrayList initialWorkspaceFiles = FileUtils.createFileFilter(Platform.getLocation().toFile(), null); public static void printStart(Object t) { - if(printStart) System.out.println("Test is " + t.getClass().getName() /*+ "." + t.getName()*/); + if(printStart) LOGGER.info("Test is {}", t.getClass().getName()); } protected static void setPrintStart(boolean value) { printStart = value; @@ -270,9 +272,9 @@ abstract public class TestBase /*extends TestCase*/ { try { session.getService(LifecycleSupport.class).close(0, true); } catch (ServiceNotFoundException e) { - Logger.defaultLogError(e); + LOGGER.error("Failed to find LifecycleSupport service", e); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("Failed to close database", e); } } // if (!Thread.currentThread().equals(thread)) { diff --git a/bundles/org.simantics.document.base.ontology/graph/Documentation.pgraph b/bundles/org.simantics.document.base.ontology/graph/Documentation.pgraph index 4845558ea..230dc8786 100644 --- a/bundles/org.simantics.document.base.ontology/graph/Documentation.pgraph +++ b/bundles/org.simantics.document.base.ontology/graph/Documentation.pgraph @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2019 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 + *******************************************************************************/ L0 = STR = SG = @@ -100,6 +111,65 @@ Documentation.child10 : L0.Template Documentation.Relations.parent %connection %connection : STR.Connection +Documentation.child1_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part1.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child2_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part2.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child3_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part3.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child4_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part4.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child5_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part5.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child6_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part6.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child7_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part7.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child8_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part8.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child9_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part9.Inverse %parent + Documentation.Relations.parent.Inverse %child + +Documentation.child10_ : L0.Template + @template %parent %child + _ : STR.Connection + Documentation.Relations.part10.Inverse %parent + Documentation.Relations.parent.Inverse %child Documentation.singleData : L0.Template @template %commandEvent %defVar %dataSource %eventSource %eventRelation %sourceName %targetName %DataSourceConn %DataTargetConn %EventConn diff --git a/bundles/org.simantics.document.server/scl/Document/All.scl b/bundles/org.simantics.document.server/scl/Document/All.scl index a90a24bcb..d676e2a3b 100644 --- a/bundles/org.simantics.document.server/scl/Document/All.scl +++ b/bundles/org.simantics.document.server/scl/Document/All.scl @@ -122,9 +122,9 @@ importJava "org.simantics.document.server.Functions" where readEventHandler :: Variable -> (Variable -> (String -> Maybe String) -> String) -> AbstractEventHandler eventHandler :: ((String -> Maybe String) -> String) -> AbstractEventHandler - readEventHandler2 :: (CommandContext -> Maybe CommandResult) -> AbstractEventHandler - writeEventHandler2 :: (CommandContext -> Maybe CommandResult) -> AbstractEventHandler - eventHandler2 :: (CommandContext -> Maybe CommandResult) -> AbstractEventHandler + readEventHandler2 :: (CommandContext -> Maybe CommandResult) -> AbstractEventHandler + writeEventHandler2 :: (CommandContext -> Maybe CommandResult) -> AbstractEventHandler + eventHandler2 :: (CommandContext -> Maybe CommandResult) -> AbstractEventHandler responseHandler :: Variable -> String -> AbstractEventHandler @@ -147,6 +147,9 @@ importJava "org.simantics.document.server.Functions" where compileDocumentSCLHandlerValueExpression :: Variable -> String primitiveProperties :: DocumentProperties + +contextVariable :: Variable -> Variable +contextVariable var = propertyValue (variableParent var) "input" propertyValueCached :: Serializable a => Typeable a => Variable -> String -> a propertyValueCached var prop = propertyValueCached_ var prop binding diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/IEventCommand.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/IEventCommand.java index b971fef4c..c10dafc2d 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/IEventCommand.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/IEventCommand.java @@ -1,11 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.server; +import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.CommandContextMutable; + public interface IEventCommand { public void setNext(IEventCommand command); public IEventCommand getNext(); - public void handleCommand(); - public void commandSuccess(); + public CommandContext handleCommand(CommandContextMutable context); + public CommandContext commandSuccess(CommandContextMutable context); public void commandError(String errorMessage); } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/bean/Command.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/bean/Command.java index f47c0c5c3..eabb2afdd 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/bean/Command.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/bean/Command.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.server.bean; import org.simantics.document.server.io.CommandContext; @@ -12,6 +23,10 @@ public class Command implements ICommand { public Command() {} + public Command(String command) { + this.command = command; + } + public Command(String targetId, String trigger, String command, CommandContext constants) { this.targetId = targetId; this.trigger = trigger; diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetData.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetData.java index 1235d527c..2fb138fde 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetData.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetData.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.server.client; import java.util.HashSet; @@ -5,6 +16,8 @@ import java.util.TreeMap; import org.simantics.document.server.IEventCommand; import org.simantics.document.server.JSONObject; +import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.ICommand; public class WidgetData { @@ -67,12 +80,12 @@ public class WidgetData { } @SuppressWarnings({ "unchecked", "rawtypes" }) - public IEventCommand eventCommand(String command) { + public IEventCommand eventCommand(ICommand command, CommandContext c) { if(object == null) return null; WidgetManager manager = document.getManager(object); if(manager != null) - return manager.eventCommand(document, object, widget, command); + return manager.eventCommand(document, object, widget, command, c); else return null; } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetManager.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetManager.java index 8474bfd15..ab0b8cf87 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetManager.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetManager.java @@ -1,20 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.server.client; import java.util.TreeMap; import org.simantics.document.server.IEventCommand; import org.simantics.document.server.JSONObject; +import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.ICommand; public interface WidgetManager { public W createWidget(JSONObject object); public void updateProperties(D document, JSONObject object, W widget); - + public void updateChildren(D document, JSONObject object, W widget, TreeMap childMap); - - public IEventCommand eventCommand(D document, JSONObject object, W widget, String command); - + + public IEventCommand eventCommand(D document, JSONObject object, W widget, ICommand command, CommandContext context); + public String getProperty(D document, JSONObject object, W widget, String property); - + } \ No newline at end of file diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocument.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocument.java index 41183050f..1e97e2277 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocument.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocument.java @@ -1,6 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core; import java.util.Collections; +import java.util.List; import java.util.Map; import org.eclipse.jface.viewers.ISelectionProvider; @@ -8,20 +20,25 @@ import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.ui.IWorkbenchSite; import org.simantics.document.server.client.Document; -import org.simantics.document.server.handler.AbstractEventHandler; +import org.simantics.document.server.client.WidgetData; +import org.simantics.document.server.io.AbstractEventHandler; import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.CommandContextMutable; +import org.simantics.document.server.io.ICommand; +import org.simantics.utils.datastructures.Pair; public interface SWTDocument extends Document { public static final Map NO_PARAMETERS = Collections.emptyMap(); - + IWorkbenchSite getSite(); ISelectionProvider getSelectionProvider(); Color getColor(org.simantics.datatypes.literal.RGB.Integer bean); Font getFont(org.simantics.datatypes.literal.Font bean); - void post(AbstractEventHandler handler, CommandContext parameters); + void post(AbstractEventHandler handler, CommandContextMutable context); + CommandContext handleCommands(List> data, CommandContextMutable context, Object component); void layout(); - + void displayError(String error); - + } diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocumentClient.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocumentClient.java index 58c280595..e2a64ee1d 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocumentClient.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocumentClient.java @@ -1,8 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import org.eclipse.jface.layout.GridDataFactory; @@ -15,16 +28,20 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.IWorkbenchSite; import org.simantics.db.common.utils.Logger; +import org.simantics.document.server.IEventCommand; import org.simantics.document.server.JSONObject; import org.simantics.document.server.client.DocumentClient; import org.simantics.document.server.client.WidgetData; import org.simantics.document.server.client.WidgetMapping; -import org.simantics.document.server.handler.AbstractEventHandler; +import org.simantics.document.server.io.AbstractEventHandler; import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.CommandContextMutable; +import org.simantics.document.server.io.ICommand; import org.simantics.document.swt.core.base.WidgetContainer; import org.simantics.document.swt.core.widget.FillComposite; import org.simantics.ui.colors.Colors; import org.simantics.ui.fonts.Fonts; +import org.simantics.utils.datastructures.Pair; import org.simantics.utils.threads.IThreadWorkQueue; import org.simantics.utils.threads.SWTThread; @@ -41,9 +58,9 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument { private boolean requireLayout=false; public SWTDocumentClient(WidgetMapping mapping, ISelectionProvider selectionProvider, IWorkbenchSite site, Composite container) { - + super(mapping, SWTViews.getCommandMapping()); - + this.container = container; this.site = site; this.selectionProvider = selectionProvider; @@ -55,19 +72,19 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument { FillComposite mgr = new FillComposite(); WidgetContainer wc = mgr.createWidget(rootObject); wc.createControl(this, container, rootObject); - + GridDataFactory.fillDefaults().grab(true, true).minSize(1, 1).applyTo((Control)wc.getControl()); GridLayoutFactory.fillDefaults().applyTo((Composite)wc.getControl()); - + widgetData.put("root", new WidgetData(this, wc, rootObject)); - + } - + @Override public IThreadWorkQueue thread() { return thread; } - + @Override public Color getColor(org.simantics.datatypes.literal.RGB.Integer descriptor) { Color color = colors.get(descriptor); @@ -77,7 +94,7 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument { } return color; } - + @Override public Font getFont(org.simantics.datatypes.literal.Font descriptor) { Font font = fonts.get(descriptor); @@ -87,22 +104,23 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument { } return font; } - + @Override public ISelectionProvider getSelectionProvider() { return selectionProvider; } - + @Override public IWorkbenchSite getSite() { return site; } - + @Override - public void post(final AbstractEventHandler handler, CommandContext parameters) { + public void post(AbstractEventHandler handler, CommandContextMutable parameters) { handler.handle(parameters); } + @Override protected void updateDocument(Collection objects) { assert thread.currentThreadAccess(); @@ -115,9 +133,9 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument { @Override protected void updateTree(HashSet updates) { - + if(updates.isEmpty()) return; - + for(WidgetData data : updates) { WidgetContainer container = (WidgetContainer)data.widget; Control ctrl = container.getControl(); @@ -130,29 +148,59 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument { } } } - + super.updateTree(updates); - + for(WidgetData data : widgetData.values()) { WidgetContainer container = (WidgetContainer)data.widget; if(container != null) container.getOrCreateControl(this, data.object); } - + + } + + @Override + public CommandContext handleCommands(List> data, CommandContextMutable context, Object component) { + + // Build a linked list of commands + + ArrayList commands = new ArrayList<>(); + for(Pair pair : data) { + WidgetData d = pair.first; + + ICommand c = pair.second; + IEventCommand p = d.eventCommand(c, null); +// if(component != null && p != null) +// p.setTrigger(component); + if(p != null) { + if(!commands.isEmpty()) + commands.get(commands.size()-1).setNext(p); + commands.add(p); + } + } + + // Execute the first command, the linked list handles the rest of them + if(!commands.isEmpty()) { + try { + commands.get(0).handleCommand(context); + } finally { + } + } + return context; } - + @Override public void layout() { requireLayout = true; } - + @Override public HashMap getWidgetData() { return widgetData; } - + public void displayError(String error) { Logger.defaultLogError(error); } - + } diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTViews.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTViews.java index 468bf7bda..3ea5da8a6 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTViews.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTViews.java @@ -1,6 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.swt.widgets.Composite; @@ -8,8 +22,11 @@ import org.eclipse.swt.widgets.Control; import org.simantics.document.server.JSONObject; import org.simantics.document.server.client.CommandMapping; import org.simantics.document.server.client.CommandMappingImpl; +import org.simantics.document.server.client.Document; +import org.simantics.document.server.client.WidgetData; import org.simantics.document.server.client.WidgetMapping; import org.simantics.document.server.client.WidgetMappingImpl; +import org.simantics.document.server.io.ICommand; import org.simantics.document.swt.core.base.ScrolledCompositeContent; import org.simantics.document.swt.core.widget.BrowserWidget; import org.simantics.document.swt.core.widget.ButtonWidget; @@ -23,13 +40,14 @@ import org.simantics.document.swt.core.widget.LabelWidget; import org.simantics.document.swt.core.widget.SCLTextEditor; import org.simantics.document.swt.core.widget.ScrolledCompositeWidget; import org.simantics.document.swt.core.widget.TrackedTextWidget; +import org.simantics.utils.datastructures.Pair; public class SWTViews { private static WidgetMappingImpl mapping = null; - + public static WidgetMapping getMapping() { - + if(mapping == null) { mapping = new WidgetMappingImpl(); mapping.register("Root", new FillComposite()); @@ -45,25 +63,40 @@ public class SWTViews { mapping.register("Browser", new BrowserWidget()); mapping.register("SCLTextEditor", new SCLTextEditor()); } - + return mapping; - + + } + + private static CommandMappingImpl commandMapping = null; + + public static CommandMapping getCommandMapping() { + + if(commandMapping == null) { + commandMapping = new CommandMappingImpl(); + commandMapping.register("Button", new ButtonWidget.ButtonCommandManager()); + commandMapping.register("Explorer", new Explorer.ExplorerCommandManager()); + } + + return commandMapping; + + } + + public static List> getTriggeredCommands(Document document, Collection commands, String trigger) { + // Nulls should not get this far + assert(commands != null); + List> data = new ArrayList<>(); + for(ICommand c : commands) { + if(c.getCommand() == null || c.getTargetId() == null || c.getTrigger() == null) + continue; + if(trigger.equals(c.getTrigger())) { + WidgetData wd = document.getWidgetData().get(c.getTargetId()); + if(wd != null) + data.add(new Pair(wd, c)); + } + } + return data; } - - private static CommandMappingImpl commandMapping = null; - - public static CommandMapping getCommandMapping() { - - if(commandMapping == null) { - - commandMapping = new CommandMappingImpl(); - commandMapping.register("Button", new ButtonWidget.ButtonCommandManager()); - - } - - return commandMapping; - - } public static void notifyScrolledComposite(Control c) { if(c instanceof ScrolledCompositeContent) { @@ -75,17 +108,17 @@ public class SWTViews { if(parent == null) return; notifyScrolledComposite(parent); } - + public static Map encoded = new HashMap(); - + public static String encode(JSONObject object, String property, Object data) { String key = object.getId() + "#" + property; encoded.put(key, data); return key; } - + public static Object decode(String key) { return encoded.get(key); } - + } diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/AbstractEventCommand.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/AbstractEventCommand.java index 3bd0364e7..57a2fbbe8 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/AbstractEventCommand.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/AbstractEventCommand.java @@ -1,6 +1,8 @@ package org.simantics.document.swt.core.base; import org.simantics.document.server.IEventCommand; +import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.CommandContextMutable; import org.simantics.document.swt.core.SWTDocument; public abstract class AbstractEventCommand implements IEventCommand { @@ -23,9 +25,10 @@ public abstract class AbstractEventCommand implements IEventCommand { } @Override - public void commandSuccess() { + public CommandContext commandSuccess(CommandContextMutable context) { if(next != null) - next.handleCommand(); + return next.handleCommand(context); + return context; } @Override diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PostEventCommand.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PostEventCommand.java index ff6d4fd13..24b6e6111 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PostEventCommand.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PostEventCommand.java @@ -1,40 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core.base; -import java.util.Map; - -import org.simantics.document.server.handler.AbstractEventHandler; +import org.simantics.document.server.io.AbstractEventHandler; import org.simantics.document.server.io.CommandContext; import org.simantics.document.server.io.CommandContextImpl; +import org.simantics.document.server.io.CommandContextMutable; import org.simantics.document.swt.core.SWTDocument; public class PostEventCommand extends AbstractEventCommand { private AbstractEventHandler handler; - private CommandContextImpl parameters; + private CommandContextMutable context; - public PostEventCommand(SWTDocument document, AbstractEventHandler handler, Map parameters) { - this(document, handler, parameters, null); + public PostEventCommand(SWTDocument document, AbstractEventHandler handler, CommandContextMutable context) { + this(document, handler, context, null); } - public PostEventCommand(SWTDocument document, AbstractEventHandler handler, Map parameters, PostEventCommand next) { + public PostEventCommand(SWTDocument document, AbstractEventHandler handler, CommandContextMutable context, PostEventCommand next) { super(document); + assert(handler != null); this.handler = handler; - this.parameters = new CommandContextImpl(); - for(Map.Entry entry : parameters.entrySet()) { - this.parameters.putString(entry.getKey(), entry.getValue()); - } + this.context = context; this.next = next; } @Override - public void handleCommand() { - document.post(handler, parameters); + public CommandContext handleCommand(CommandContextMutable context) { + CommandContextMutable mergedContext = new CommandContextImpl().merge(context) + .merge(this.context); + document.post(handler, mergedContext); + return context; } @Override - public void commandSuccess() { + public CommandContext commandSuccess(CommandContextMutable context) { if(next != null) - next.handleCommand(); + return next.handleCommand(context); + return context; } @Override diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PropertyWidgetManager.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PropertyWidgetManager.java index 1c3297061..f48111671 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PropertyWidgetManager.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PropertyWidgetManager.java @@ -1,20 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core.base; +import java.util.Collection; +import java.util.List; + import org.simantics.document.server.IEventCommand; import org.simantics.document.server.JSONObject; +import org.simantics.document.server.client.WidgetData; import org.simantics.document.server.client.WidgetManager; +import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.CommandContextImpl; +import org.simantics.document.server.io.CommandContextMutable; +import org.simantics.document.server.io.ICommand; +import org.simantics.document.server.io.JSONObjectUtils; import org.simantics.document.swt.core.SWTDocument; +import org.simantics.document.swt.core.SWTViews; +import org.simantics.utils.datastructures.Pair; public abstract class PropertyWidgetManager implements WidgetManager { - + @Override public String getProperty(SWTDocument document, JSONObject object, W widget, String property) { return null; } - + @Override - public IEventCommand eventCommand(SWTDocument document, JSONObject object, W widget, String command) { - return null; + public IEventCommand eventCommand(SWTDocument document, JSONObject object, W widget, ICommand command, CommandContext context) { + return null; + } + + public static CommandContext sendEvent(SWTDocument document, WidgetData wd, String event, Object target, CommandContextMutable context) { + Collection commands = JSONObjectUtils.getCommands(wd.object); + + if(context == null) context = new CommandContextImpl(); + context.putValue("event", event); + + List> data = SWTViews.getTriggeredCommands(document, commands, "eventOut"); + + return document.handleCommands(data, context, wd.widget); } -} +} \ No newline at end of file diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonSelectionListener.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonSelectionListener.java index 303460dea..453d1d0a7 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonSelectionListener.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonSelectionListener.java @@ -1,19 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core.widget; -import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.util.List; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; -import org.simantics.document.server.IEventCommand; import org.simantics.document.server.client.WidgetData; +import org.simantics.document.server.io.CommandContextImpl; +import org.simantics.document.server.io.CommandContextMutable; +import org.simantics.document.server.io.ICommand; import org.simantics.document.swt.core.SWTDocument; +import org.simantics.document.swt.core.base.PropertyWidgetManager; +import org.simantics.utils.datastructures.Pair; public class ButtonSelectionListener implements SelectionListener { - - private LinkedHashMap data; - - public ButtonSelectionListener(LinkedHashMap data) { + + private WidgetData wd; + private List> data; + + public ButtonSelectionListener(WidgetData wd, List> data) { + this.wd = wd; this.data = data; } @@ -24,27 +40,16 @@ public class ButtonSelectionListener implements SelectionListener { @Override public void widgetDefaultSelected(SelectionEvent e) { - SWTDocument document = null; - // Build a linked list of commands - ArrayList commands = new ArrayList(); - for(WidgetData d : data.keySet()) { - document = (SWTDocument)d.document; // assume that all widgets are from the same document - IEventCommand p = d.eventCommand(data.get(d)); - if(p != null) { - if(!commands.isEmpty()) - commands.get(commands.size()-1).setNext(p); - commands.add(p); - } + + CommandContextMutable context = new CommandContextImpl(); + context.putValue("event", "onPress"); + + if(!data.isEmpty()) { + ((SWTDocument)wd.document).handleCommands(data, context, e.widget); } - // empty errors -// if(document != null) -// document.displayError(""); + PropertyWidgetManager.sendEvent((SWTDocument)wd.document, wd, "onPress", e.widget, context); - // Execute the first command, the linked list handles the rest of them - if(!commands.isEmpty()) - commands.get(0).handleCommand(); - } - + } \ No newline at end of file diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonWidget.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonWidget.java index 384ef88cd..88afe7b2a 100644 --- a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonWidget.java +++ b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonWidget.java @@ -1,11 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 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.document.swt.core.widget; +import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionListener; @@ -17,11 +26,18 @@ import org.simantics.document.server.bean.Command; import org.simantics.document.server.client.CommandManager; import org.simantics.document.server.client.WidgetData; import org.simantics.document.server.handler.AbstractEventHandler; -import org.simantics.document.server.handler.EventHandler; +import org.simantics.document.server.io.CommandContext; +import org.simantics.document.server.io.CommandContextImpl; +import org.simantics.document.server.io.CommandContextMutable; +import org.simantics.document.server.io.ICommand; +import org.simantics.document.server.io.JSONObjectUtils; import org.simantics.document.swt.core.SWTDocument; +import org.simantics.document.swt.core.SWTViews; import org.simantics.document.swt.core.base.LeafWidgetManager; import org.simantics.document.swt.core.base.PostEventCommand; import org.simantics.document.swt.core.base.WidgetContainer; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.SWTUtils; public class ButtonWidget extends LeafWidgetManager