]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merge "Revert "Support enumerated property types in UC interface""
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 28 Aug 2019 17:04:21 +0000 (17:04 +0000)
committerGerrit Code Review <gerrit2@simantics>
Wed, 28 Aug 2019 17:04:21 +0000 (17:04 +0000)
70 files changed:
bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java
bundles/org.simantics.db.common/src/org/simantics/db/common/validation/L0Validations.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfo.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfoRequest.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java [new file with mode: 0644]
bundles/org.simantics.db.testing/META-INF/MANIFEST.MF
bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/SCLScriptTestBase.java
bundles/org.simantics.db.testing/src/org/simantics/db/testing/cases/FreshDatabaseTest.java
bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/AcornTestHandler.java
bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/TestBase.java
bundles/org.simantics.document.base.ontology/graph/Documentation.pgraph
bundles/org.simantics.document.server/scl/Document/All.scl
bundles/org.simantics.document.server/src/org/simantics/document/server/IEventCommand.java
bundles/org.simantics.document.server/src/org/simantics/document/server/bean/Command.java
bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetData.java
bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetManager.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocument.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocumentClient.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTViews.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/AbstractEventCommand.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PostEventCommand.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PropertyWidgetManager.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonSelectionListener.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonWidget.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/CommandEventWidget.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/Explorer.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ExplorerListener.java [new file with mode: 0644]
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/FillComposite.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/GridComposite.java
bundles/org.simantics.document.swt.ontology/graph/Components.pgraph
bundles/org.simantics.issues.common/META-INF/MANIFEST.MF
bundles/org.simantics.issues.common/adapters.xml
bundles/org.simantics.issues.common/src/org/simantics/issues/common/AllActiveIssues.java
bundles/org.simantics.issues.common/src/org/simantics/issues/common/AllVisibleIssues.java
bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/ConstraintIssueSource.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/Messages.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/ModelVisibleIssues.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/RunActiveValidations.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/messages.properties [new file with mode: 0644]
bundles/org.simantics.issues.ontology/graph/Issue.pgraph
bundles/org.simantics.issues.ontology/graph/Layer0Sources.pgraph [new file with mode: 0644]
bundles/org.simantics.issues.ui/build.properties
bundles/org.simantics.issues.ui/scl/Simantics/IssueUI.scl [new file with mode: 0644]
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/ConfigureIssueSources.java
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/RunActiveValidations.java
bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph
bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl
bundles/org.simantics.modeling/adapters.xml
bundles/org.simantics.modeling/scl/Simantics/Diagram.scl
bundles/org.simantics.modeling/scl/Simantics/Issue.scl
bundles/org.simantics.modeling/scl/Simantics/Ontologies.scl
bundles/org.simantics.modeling/scl/Simantics/Rename.scl
bundles/org.simantics.modeling/src/org/simantics/modeling/Rename.java
bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLCheckedStateRule.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLChildRule.java
bundles/org.simantics.modeling/src/org/simantics/modeling/svg/CreateSVGElement.java
bundles/org.simantics.platform.ui.ontology/META-INF/MANIFEST.MF
bundles/org.simantics.platform.ui.ontology/build.properties
bundles/org.simantics.platform.ui.ontology/graph/PlatformUI.pgraph
bundles/org.simantics.platform.ui.ontology/graph/ValidationView.pgraph [new file with mode: 0644]
bundles/org.simantics.platform.ui.ontology/scl/Simantics/PlatformUI.scl [moved from bundles/org.simantics.platform.ui.ontology/graph/scl/SCLMain.scl with 54% similarity]
bundles/org.simantics.scl.db/scl/Simantics/Variables.scl
bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java
bundles/org.simantics.scl.runtime/scl/Prelude.scl

index 2f52153a1192b45e2a6c33e42afd2da58a86e1a1..d27eeaa79244a5785070cbb0da57b6bebe52ecda 100644 (file)
@@ -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);
index 99ef91b7aa0040815b23a4dae559fa1ad3d7d6dd..1ff6e5fbcd6fecbb53a6dd17b6b2c6e86459c8ca 100644 (file)
@@ -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;
-               
+
        }
-       
+
 }
index e300384f1f686ac3c874d2a17e8046399f1ce0cf..6f310120bc6f5c5cc6eb9bbf0469199091a471ac 100644 (file)
@@ -164,6 +164,8 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
 
                        });
 
+                       result.add(new Entry(graph, resource));
+
                        graph.syncRequest(new ReadRequest() {
 
                                @Override
index f3753ce80bfc3949c84914c234c14f76520c29e4..4d208b4571d14faaac8772dc30e3e0df241d1ef9 100644 (file)
@@ -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<String> classifications;
        public final VariableBuilder builder;
        public final Resource literalRange;
@@ -30,9 +42,10 @@ public class PropertyInfo {
        public final Map<String,Pair<Resource, ChildReference>> subliteralPredicates;
        public final ValueAccessor valueAccessor;
        public final boolean hasEnumerationRange;
-       public PropertyInfo(Resource predicate, String name, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) {
+       public PropertyInfo(Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map<String,Pair<Resource, ChildReference>> 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<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) throws DatabaseException {
+       public static PropertyInfo make(ReadGraph graph, Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Map<String,Pair<Resource, ChildReference>> 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=")
index 2a181674c49a3cdf06f0317bcb382c5bbe002221..90e63e29f639c10cc7d4ec04caf053c0909116e6 100644 (file)
@@ -41,6 +41,8 @@ final public class PropertyInfoRequest extends ResourceRead<PropertyInfo> {
                String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);
                if(name != null) name = name.intern();
                
+               boolean isFunctional = graph.isInstanceOf(resource, L0.FunctionalRelation);
+               
                Set<String> 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<PropertyInfo> {
                                                }
                                        }
                                        
-                                       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.<String,Pair<Resource,ChildReference>>emptyMap(), accessor, hasEnumerationRange);
+               return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, Collections.<String,Pair<Resource,ChildReference>>emptyMap(), accessor, hasEnumerationRange);
                
        }
        
index 610c8c8bd42d8735868cf1f80e4603ae5e63b7d8..830f7a6bb74776ece6a99b35eb3b9b51999cc10a 100644 (file)
@@ -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<Resource> found = objectsForTypeNonFunctional(graph, type, relation, new HashSet<>());
+            return found.size() == 1 ? found.iterator().next() : null;
+        }
+    }
+
+    private static Set<Resource> objectsForTypeNonFunctional(ReadGraph graph, Resource type, Resource relation, Set<Resource> 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<String,Resource> 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 (file)
index 0000000..7f0c8a9
--- /dev/null
@@ -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;
+    }
+    
+}
index ed58556c7e570814bd4ce25e5473a6821f2c33bc..7927614cd37f9779292ee4ace98e5fd4ba7f00f0 100644 (file)
@@ -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.<String> emptySet(), null, null, null, null, null, null,
+                       false, false, Collections.<String> emptySet(), null, null, null, null, null, null,
                        Collections.<String, Pair<Resource, ChildReference>> 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 (file)
index 0000000..1c35049
--- /dev/null
@@ -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 (file)
index 0000000..8286abb
--- /dev/null
@@ -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;
+    }
+    
+}
index c80729ad86e094b385e0bbcc010c0e7192ef5c23..960ccf0095f1c8eb88811244a48594bf8e1588f7 100644 (file)
@@ -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,
index 26e916fc1bcdfa53ed8f0076155b33b3d7bf603e..1ea9e6a546d0e77a6469e4bef55d69478e2adeb3 100644 (file)
@@ -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<String, TestRunnable> testRunnables = new THashMap<String, TestRunnable>();
-    
+
     @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.<br><br>
index 963b2d9f5d23af902da80f54221f647c04d9a10e..53ddfb04fc0a1ceaa26c88586bfb684f5427c50a 100644 (file)
@@ -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
index 5f5da8f2e9d7ac1f746605259d59799d7969ac3a..e7e1722ac6f81aedf60022f60c13f153c7d07a9f 100644 (file)
@@ -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 {
index 1068fc2f50366ae19a72f8a3029534b86f2c7993..73e6ff8f13b47377064af2f7a2041aefe5da829b 100644 (file)
@@ -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 <marko.luukkainen@vtt.fi>
- *
  */
-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<String> 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)) {
index 4845558ea2b21bb1a72545af5b2957f347f22496..230dc878614d4fa96b5e71950683fa7d45878a39 100644 (file)
@@ -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 = <http://www.simantics.org/Layer0-1.1>
 STR = <http://www.simantics.org/Structural-1.2>
 SG = <http://www.simantics.org/Scenegraph-1.1>
@@ -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
index a90a24bcb62c30c55cad163eb3d242f869bec690..d676e2a3b2a296bacb86094ebec20bb6695ec510 100644 (file)
@@ -122,9 +122,9 @@ importJava "org.simantics.document.server.Functions" where
     readEventHandler :: Variable -> (Variable -> (String -> Maybe String) -> <ReadGraph> String) -> <ReadGraph> AbstractEventHandler
     eventHandler :: ((String -> Maybe String) -> String) -> <ReadGraph> AbstractEventHandler
 
-    readEventHandler2 :: (CommandContext -> <ReadGraph> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
-    writeEventHandler2 :: (CommandContext -> <WriteGraph> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
-    eventHandler2 :: (CommandContext -> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
+    readEventHandler2 :: (CommandContext -> <ReadGraph,Proc> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
+    writeEventHandler2 :: (CommandContext -> <WriteGraph,Proc> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
+    eventHandler2 :: (CommandContext -> <Proc> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
     
     responseHandler :: Variable -> String -> <ReadGraph> AbstractEventHandler
 
@@ -147,6 +147,9 @@ importJava "org.simantics.document.server.Functions" where
     compileDocumentSCLHandlerValueExpression :: Variable -> <ReadGraph> String
 
     primitiveProperties :: <Proc> DocumentProperties
+
+contextVariable :: Variable -> <ReadGraph> Variable
+contextVariable var = propertyValue (variableParent var) "input"
     
 propertyValueCached :: Serializable a => Typeable a => Variable -> String -> <ReadGraph> a
 propertyValueCached var prop = propertyValueCached_ var prop binding
index b971fef4c6b6ca8540d8cc257c7166db1d0c7f04..c10dafc2dc075ef1e4c5b340d396650878e93811 100644 (file)
@@ -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);
 
 }
index f47c0c5c38ff53eade8eaa9834d641aa4e0cba06..eabb2afdd3110f90db2504719e889ffde59dc890 100644 (file)
@@ -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;
index 1235d527c4fdac3e2b2dea298734780bd49e1124..2fb138fdea5c104368612166f6f6d0c538e2149a 100644 (file)
@@ -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;
     }
index 8474bfd15b1b14e3dcbda4f74c38fdc2d8955662..ab0b8cf87503437c38f16f2e9f19cd98dafcd7e0 100644 (file)
@@ -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<D extends Document, W> {
 
        public W createWidget(JSONObject object);
 
        public void updateProperties(D document, JSONObject object, W widget);
-       
+
        public void updateChildren(D document, JSONObject object, W widget, TreeMap<String, WidgetData> 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
index 41183050f2c969c4833994eddc4509a508afdaaa..1e97e22771ced6815a4b55cfadc1d8be1722196f 100644 (file)
@@ -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<String,String> 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<Pair<WidgetData, ICommand>> data, CommandContextMutable context, Object component);
        void layout();
-       
+
     void displayError(String error);
-       
+
 }
index 58c280595b0ac8fd31de57ca3d5cd6a45fdbaebd..e2a64ee1d445bc69c7025b3bfca4b71a9326e537 100644 (file)
@@ -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<JSONObject> objects) {
                assert thread.currentThreadAccess();
@@ -115,9 +133,9 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument {
 
        @Override
        protected void updateTree(HashSet<WidgetData> 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<Pair<WidgetData, ICommand>> data, CommandContextMutable context, Object component) {
+
+               // Build a linked list of commands
+
+               ArrayList<IEventCommand> commands = new ArrayList<>();
+               for(Pair<WidgetData, ICommand> 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<String, WidgetData> getWidgetData() {
         return widgetData;
     }
-    
+
     public void displayError(String error) {
         Logger.defaultLogError(error);
     }
-       
+
 }
index 468bf7bdaec4295d561e25b2f32e1212dcc06eef..3ea5da8a6d76ecfd3762a3133eb4d8e7c2d087b4 100644 (file)
@@ -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<Pair<WidgetData, ICommand>> getTriggeredCommands(Document document, Collection<ICommand> commands, String trigger) {
+               // Nulls should not get this far
+               assert(commands != null);
+               List<Pair<WidgetData, ICommand>> 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<WidgetData, ICommand>(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<String, Object> encoded = new HashMap<String, Object>();
-       
+
        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);
        }
-       
+
 }
index 3bd0364e7e7c19a27e7661b4bf299d9797a6c47a..57a2fbbe8312e0e3bb397b194d7f2248172e10b6 100644 (file)
@@ -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
index ff6d4fd13d5aa6d20e0894339c02bee95fc68569..24b6e6111c41774337c9aec5934decaf7c3da8d7 100644 (file)
@@ -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<String, String> 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<String, String> 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<String, String> 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
index 1c329706107d98a4eada3e872ebb116c340541da..f48111671e1ec47927ece48ee7cfda2b1c1643d2 100644 (file)
@@ -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<W> implements WidgetManager<SWTDocument, W> {
-       
+
        @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<ICommand> commands = JSONObjectUtils.getCommands(wd.object);
+
+               if(context == null) context = new CommandContextImpl();
+               context.putValue("event", event);
+
+               List<Pair<WidgetData, ICommand>> data = SWTViews.getTriggeredCommands(document, commands, "eventOut");
+
+               return document.handleCommands(data, context, wd.widget);
        }
 
-}
+}
\ No newline at end of file
index 303460deab8fc6b1474887e4bc73c0453a08d7e5..453d1d0a7261d1c80ba0688475490f25e65730cc 100644 (file)
@@ -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<WidgetData, String> data;
-    
-    public ButtonSelectionListener(LinkedHashMap<WidgetData, String> data) {
+
+    private WidgetData wd;
+    private List<Pair<WidgetData, ICommand>> data;
+
+    public ButtonSelectionListener(WidgetData wd, List<Pair<WidgetData, ICommand>> 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<IEventCommand> commands = new ArrayList<IEventCommand>();
-        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
index 384ef88cd8638f23e0f17dec7005cedc52b7ca49..88afe7b2ab802bcc235952bdaa6d42766f2cf68a 100644 (file)
@@ -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<Button> {
 
@@ -55,23 +71,14 @@ public class ButtonWidget extends LeafWidgetManager<Button> {
         public Collection<Object> updateCommandListeners(final SWTDocument document, final JSONObject object,
                 WidgetContainer<Button> container) {
             
-            List<Command> commands = object.getJSONField("commands");
+            WidgetData wd = document.getWidget(JSONObjectUtils.getId(object));
+            List<ICommand> commands = object.getJSONField("commands");
             HashSet<Object> listeners = new HashSet<Object>();
-            LinkedHashMap<WidgetData, String> data = new LinkedHashMap<WidgetData, String>();
-            if(commands != null) {
-                   for(Command c : commands) {
-                       if(c.getCommand() == null || c.getTargetId() == null || c.getTrigger() == null)
-                           continue;
-                       String trigger = c.getTrigger();
-                       if("click".equals(trigger)) {
-                           WidgetData wd = document.getWidgetData().get(c.getTargetId());
-                           if(wd != null)
-                               data.put(wd, c.getCommand());
-                       }
-                   }
-            }
-            data.put(document.getWidgetData().get(object.getId()), "onPress");
-            SelectionListener listener = new ButtonSelectionListener(data);
+            List<Pair<WidgetData, ICommand>> data = new ArrayList<>();
+            data.addAll(SWTViews.getTriggeredCommands(document, commands, "click"));
+            data.addAll(SWTViews.getTriggeredCommands(document, commands, "eventOut"));
+            data.add(new Pair<WidgetData, ICommand>(wd, new Command("onPress")));
+            SelectionListener listener = new ButtonSelectionListener(wd, data);
             Button button = container.getControl();
             if(!button.isDisposed()) {
                button.addSelectionListener(listener);
@@ -92,11 +99,12 @@ public class ButtonWidget extends LeafWidgetManager<Button> {
     }
 
     @Override
-    public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, String command) {
-        if("onPress".equals(command)) {
+    public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, ICommand command, CommandContext p) {
+        if("onPress".equals(command.getCommand())) {
+            CommandContextMutable context = new CommandContextImpl().merge(p);
             AbstractEventHandler onPress = object.getJSONField("onPress");
-            Map<String, String> data = Collections.emptyMap();
-            return new PostEventCommand(document, onPress, data);
+            if(onPress == null) return null;
+            return new PostEventCommand(document, onPress, context);
         }
         return null;
     }  
index 23311d93c18a00757af97dfea980ea379c513fcc..ca6c31ddffdf8e5a565bf3d71f49d41edb7a267f 100644 (file)
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * 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.HashMap;
 import java.util.List;
 import java.util.TreeMap;
 
@@ -10,6 +20,10 @@ import org.simantics.document.server.bean.DataDefinition;
 import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.server.client.WidgetManager;
 import org.simantics.document.server.handler.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.server.io.ICommand;
 import org.simantics.document.swt.core.SWTDocument;
 import org.simantics.document.swt.core.base.PostEventCommand;
 import org.simantics.document.swt.core.base.PropertyWidgetManager;
@@ -33,10 +47,12 @@ public class CommandEventWidget  extends PropertyWidgetManager<Object> {
     }
 
     @Override
-    public IEventCommand eventCommand(SWTDocument document, JSONObject object, Object component, String command) {
-        if("event".equals(command)) {
+    public IEventCommand eventCommand(SWTDocument document, JSONObject object, Object component, ICommand command, CommandContext p) {
+        if("event".equals(command.getCommand())) {
             List<DataDefinition> dataDefinitions = object.getJSONField("dataDefinitions");
-            HashMap<String, String> data = new HashMap<String, String>();
+            CommandContextMutable context = new CommandContextImpl();
+            context.merge(p);
+            context.merge(command.getConstants());
             for(DataDefinition dd : dataDefinitions) {
                 WidgetData wd = document.getWidgetData().get(dd.getElementId());
                 if(wd != null && wd.object != null) {
@@ -45,12 +61,12 @@ public class CommandEventWidget  extends PropertyWidgetManager<Object> {
                     if(manager != null) {
                         @SuppressWarnings("unchecked")
                         String result = manager.getProperty(document, wd.object, wd.widget, dd.getProperty());
-                        data.put(dd.getTarget(), result);
+                        context.putValue(dd.getTarget(), result);
                     }
                 }
             }
             AbstractEventHandler handler = object.getJSONField("SCLFunction");
-            return new PostEventCommand(document, handler, data);
+            return new PostEventCommand(document, handler, context);
         } else {
             return null;
         }
index deabd7573d3196eb9a0cd2a059f1c1bb20c64ae4..99f5cbd241272728f49de64a7290d7b333d245bb 100644 (file)
@@ -1,7 +1,22 @@
+/*******************************************************************************
+ * 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.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.jface.viewers.ISelection;
@@ -11,6 +26,7 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.ui.IWorkbenchSite;
 import org.simantics.Simantics;
 import org.simantics.browsing.ui.Column;
@@ -22,15 +38,28 @@ import org.simantics.browsing.ui.swt.widgets.ModelBrowser;
 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;
 import org.simantics.db.layer0.variable.VariableBean;
 import org.simantics.db.management.ISessionContext;
+import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
+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.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.document.swt.core.bean.ColumnBean;
 import org.simantics.document.swt.core.bean.ColumnsBean;
 import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.function.Function2;
 import org.simantics.ui.selection.WorkbenchSelectionUtils;
+import org.simantics.utils.datastructures.Pair;
 
 public class Explorer extends LeafWidgetManager<ModelBrowser> {
 
@@ -48,24 +77,24 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
                }
                return result;
        }
-       
+
        @Override
        protected ModelBrowser doCreateControl(SWTDocument document, Composite parent, JSONObject object) {
-               
+
                String browseContext = object.getJSONField("browseContext");
                if(browseContext == null) return null;
 
                String contextMenuId = object.getJSONField("contextMenuId");
-               
+
                Boolean displayFilter = object.getJSONField("displayFilter");
                Boolean displayHeader = object.getJSONField("displayHeader");
                Integer style = object.getJSONField("style");
                if(style == null) style = SWT.FULL_SELECTION;
-               
+
         Boolean vscroll = object.getJSONFieldDefault("VScroll", false);
         if(Boolean.TRUE.equals(vscroll))
             style |= SWT.V_SCROLL;
-        
+
         Boolean hscroll = object.getJSONFieldDefault("HScroll", false);
         if(Boolean.TRUE.equals(hscroll))
             style |= SWT.H_SCROLL;
@@ -73,12 +102,18 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
         Boolean noscroll = object.getJSONFieldDefault("NoScroll", false);
         if(Boolean.TRUE.equals(noscroll))
             style |= SWT.NO_SCROLL;
-               
+
+        Boolean check = object.getJSONFieldDefault("Check", false);
+        if(Boolean.TRUE.equals(check))
+            style |= SWT.CHECK;
+
                StatePersistor persistor = object.getJSONField("persistor");
                final Function1<Object, Boolean> selectionListener = object.getJSONField("selectionListener");
 
+               final Function2<Object, Boolean, Boolean> checkStateListener = object.getJSONField("checkStateListener");
+
                DragSourceListenerFactory dragSourceListenerFactory = object.getJSONField("dragSourceListenerFactory");
-               
+
                final IWorkbenchSite site = document.getSite();
                final ISelectionProvider selectionProvider = document.getSelectionProvider();
 
@@ -90,27 +125,27 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
 
                ColumnsBean columns = object.getBeanJSONFieldDefault("columns", ColumnsBean.BINDING, null);
                String editingColumn = object.getJSONFieldDefault("editingColumn", null);
-               
+
 //             Column[] COLUMNS = new Column[] {
 //                             new Column("HasDisplayProperty", "Parameter description", Align.LEFT, 80, "Input parameter name", true),
 //                             new Column("HasDisplayValue", "Value", Align.RIGHT, 65, "Value"),
 //                             new Column("HasDisplayUnit", "Unit", Align.RIGHT, 100, "Unit") 
 //             };
-               
+
 //             parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
-               
+
                final ModelBrowser control = new ModelBrowser(Collections.singleton(browseContext), args, site, parent, new WidgetSupportImpl(), style);
 
                Tree tree = control.getExplorerControl();
                tree.addListener(SWT.SetData, new Listener() {
-                       
+
                        @Override
                        public void handleEvent(Event event) {
                                SWTViews.notifyScrolledComposite(control);
                        }
-                       
+
                });
-               
+
                if(columns != null)
                        control.setColumns(getColumns(columns));
                if(editingColumn != null)
@@ -121,11 +156,11 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
                        control.setDragSourceListenerFactory(dragSourceListenerFactory);
                if(displayHeader != null)
                        tree.setHeaderVisible(displayHeader);
-               
+
                control.setStatePersistor(persistor);
 
                control.finish();
-               
+
                control.setInputSource(new InputSourceImpl<Object>() {
 
                        @Override
@@ -134,7 +169,7 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
                        }
 
                });
-               
+
                // TODO: fixme!
                Object i = object.getJSONField("explorerInput");
                if(i instanceof VariableBean) {
@@ -142,23 +177,34 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
                } else {
                        control.setInput(Simantics.getSessionContext(), i);
                }
-               
+
                control.addListenerToControl(SWT.Selection, new Listener() {
 
                        @Override
                        public void handleEvent(Event event) {
 
+                               switch (event.type) {
+                               case SWT.Selection:
+                                       if (event.detail == SWT.CHECK && event.item != null) {
+                                               TreeItem item = (TreeItem) event.item;
+                                               boolean checked = item.getChecked();
+                                               if(checkStateListener != null)
+                                                       selectionListener.apply(event);
+                                       }
+                                       break;
+                               }
+
                                if(selectionListener != null)
                                        selectionListener.apply(event);
-                               
+
                                ISelection selection = (ISelection)control.getExplorer().getWidgetSelection();
-                               
+
                                // TODO: refactor this!
 
                                if(selectionProvider != null) {
                                        selectionProvider.setSelection(selection);
                                }
-                               
+
 //                             if (site != null) {
 //                                     ISelectionProvider sp = site.getSelectionProvider();
 //                                     if (sp != null) {
@@ -168,12 +214,12 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
 
                        }
 
-               });     
+               });
 
                return control;
 
        }
-       
+
        @Override
        public String getProperty(SWTDocument document, JSONObject object, WidgetContainer<ModelBrowser> widget, String property) {
            if("selection".equals(property)) {
@@ -183,4 +229,46 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
            return null;
        }
 
+    public static class ExplorerCommandManager implements CommandManager<SWTDocument, WidgetContainer<ModelBrowser>> {
+
+        @Override
+        public Collection<Object> updateCommandListeners(final SWTDocument document, final JSONObject object,
+                WidgetContainer<ModelBrowser> container) {
+
+            WidgetData wd = document.getWidget(JSONObjectUtils.getId(object));
+            List<ICommand> commands = object.getJSONField("commands");
+            HashSet<Object> listeners = new HashSet<Object>();
+            List<Pair<WidgetData, ICommand>> data = new ArrayList<>();
+            data.addAll(SWTViews.getTriggeredCommands(document, commands, "eventOut"));
+            data.add(new Pair<WidgetData, ICommand>(wd, new Command("onCheck")));
+            Listener listener = new ExplorerListener(wd, data);
+            ModelBrowser browser = container.getControl();
+            if(!browser.isDisposed()) {
+                browser.addListenerToControl(SWT.Selection, listener);
+                listeners.add(listener);
+            }
+
+            return listeners;
+
+        }
+
+        @Override
+        public void removeListener(WidgetContainer<ModelBrowser> container, Object listener) {
+            if(container.getControl().isDisposed()) return;
+            if(listener instanceof ExplorerListener)
+                container.getControl().removeListenerFromControl(SWT.Selection, (Listener)listener);
+        }
+
+    }
+
+    @Override
+    public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, ICommand command, CommandContext p) {
+        if("onCheck".equals(command.getCommand())) {
+            CommandContextMutable context = new CommandContextImpl().merge(p);
+            AbstractEventHandler onCheck = object.getJSONField("onCheck");
+            return new PostEventCommand(document, onCheck, context);
+        }
+        return null;
+    }
+
 }
diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ExplorerListener.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ExplorerListener.java
new file mode 100644 (file)
index 0000000..0c63957
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.TreeItem;
+import org.simantics.browsing.ui.BuiltinKeys;
+import org.simantics.browsing.ui.NodeContext;
+import org.simantics.document.server.client.WidgetData;
+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.swt.core.SWTDocument;
+import org.simantics.document.swt.core.base.PropertyWidgetManager;
+import org.simantics.utils.datastructures.Pair;
+
+public class ExplorerListener implements Listener {
+
+    private WidgetData wd;
+    private List<Pair<WidgetData, ICommand>> data;
+
+    public ExplorerListener(WidgetData wd, List<Pair<WidgetData, ICommand>> data) {
+        this.wd = wd;
+        this.data = data;
+    }
+
+    @Override
+    public void handleEvent(Event event) {
+        switch (event.type) {
+        case SWT.Selection:
+            if (event.detail == SWT.CHECK && event.item != null) {
+                TreeItem item = (TreeItem) event.item;
+                NodeContext ctx = (NodeContext)item.getData();
+                Object value = ctx.getConstant(BuiltinKeys.INPUT);
+
+                boolean checked = item.getChecked();
+
+                CommandContextMutable context = new CommandContextImpl();
+                context.putValue("event", "onCheck");
+                context.putValue("checked", checked);
+                context.putValue("item", value);
+
+                if (!data.isEmpty()) {
+                    ((SWTDocument)wd.document).handleCommands(data, context, event.widget);
+                }
+
+                CommandContext ret = PropertyWidgetManager.sendEvent((SWTDocument)wd.document, wd, "onCheck", event.widget, context);
+            }
+            break;
+        }
+    }
+
+}
\ No newline at end of file
index 998be35727487003ea3ca1036557d0aa4b64a1f5..2a92068c77baf0eabf5aa2aecbe81a06941fbb48 100644 (file)
@@ -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.swt.core.widget;
 
 import java.util.TreeMap;
@@ -7,7 +18,6 @@ import org.eclipse.jface.layout.GridLayoutFactory;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
 import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.swt.core.SWTDocument;
@@ -29,23 +39,18 @@ public class FillComposite extends HasWidgetsWidgetManager<Composite> {
 //             result.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
                return result;
        }
-       
+
        @SuppressWarnings("unchecked")
        @Override
        public void updateChildren(SWTDocument document, JSONObject object, WidgetContainer widget, TreeMap<String, WidgetData> childMap) {
-               
+
                super.updateChildren(document, object, widget, childMap);
 
                WidgetData child = childMap.values().iterator().next();
                WidgetContainer container = (WidgetContainer)child.widget;
                if(container.getControl() == null) return;
                GridDataFactory.fillDefaults().grab(true, true).minSize(1, 1).applyTo((Control)container.getControl());
-               
-       }
-       
-       @Override
-       public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, String command) {
-           return null;
+
        }
-       
+
 }
index ce2538c03e9eefb82aa9645c523a7cd6ec36c14b..199fc0f488b2087a20c7e092b063ae2e4490547e 100644 (file)
@@ -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.swt.core.widget;
 
 import org.eclipse.jface.layout.GridLayoutFactory;
@@ -17,11 +28,11 @@ public class GridComposite extends HasWidgetsWidgetManager<Composite> {
 
        @Override
        protected Composite doCreateControl(SWTDocument document, Composite parent, JSONObject object) {
-               
+
                MarginsBean extendedMargins = object.getBeanJSONFieldDefault("extendedMargins", MarginsBean.BINDING, new MarginsBean(0, 0, 0, 0));
-               RGB.Integer background = object.getBeanJSONFieldDefault("background", RGB.Integer.BINDING, new RGB.Integer(255,0, 0));
+               RGB.Integer background = object.getBeanJSONFieldDefault("background", RGB.Integer.BINDING, new RGB.Integer(255, 255, 255));
                Integer numColumns = object.getJSONFieldDefault("numColumns", 1);
-               
+
                Composite result = new Composite(parent, SWT.NONE);
                GridLayoutFactory.fillDefaults().
                        numColumns(numColumns).
@@ -30,7 +41,7 @@ public class GridComposite extends HasWidgetsWidgetManager<Composite> {
                        applyTo(result);
                result.setBackground(document.getColor(background));
                return result;
-               
+
        }
-       
+
 }
index e577e6c5dadda5e00469d9acdf757ad6b10e2af8..b255c4f2b4bd53863bd6e6471e3e5014d33c3cea 100644 (file)
@@ -47,6 +47,8 @@ COMPONENTS.Component <T DOC.Components.PrimitiveComponent
     @SWT.defAttribute L0.Value "Boolean"
   >-- COMPONENTS.Component.NoScroll
     @SWT.defAttribute L0.Value "Boolean"
+  >-- COMPONENTS.Component.Check
+    @SWT.defAttribute L0.Value "Boolean"
   >-- COMPONENTS.Component.alignment
     @SWT.defAttribute L0.Value "String"
         
@@ -190,6 +192,8 @@ COMPONENTS.Explorer <T COMPONENTS.Component
     @SWT.defAttribute L0.Value "String"
   >-- COMPONENTS.Explorer.dragSourceListenerFactory
     @SWT.defAttribute L0.Value "DragSourceListenerFactory"
+  >-- COMPONENTS.Explorer.onCheck
+    @SWT.defAttribute L0.Value "AbstractEventHandler"
 
   @attribute COMPONENTS.Explorer.browseContext
     ""
index dce26de31ec484f5cbc21be57d0353aaf9b2b6a6..7fe964225269c0531b04e4426edb703abc548844 100644 (file)
@@ -12,7 +12,9 @@ Require-Bundle: org.simantics.issues;bundle-version="1.1.0",
  org.simantics.db.services;bundle-version="0.6.2",
  org.simantics;bundle-version="1.0.0",
  org.simantics.issues.ui.ontology;bundle-version="1.0.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.scl.db;bundle-version="0.1.3",
+ org.simantics.scl.runtime
 Export-Package: org.simantics.issues.common,
  org.simantics.issues.common.preferences
 Bundle-Vendor: VTT Technical Research Centre of Finland
index 5cf4730d26f0f167eadfb11ea7b37c488446b448..905c8d4bd1a53704a7eed50790d1651e9bac29f9 100644 (file)
                        class="org.simantics.issues.common.DependencyTrackerBatchIssueSource">
                        <this />
                </type>
+               <type
+                       uri="http://www.simantics.org/Issue-0.0/Sources/ConstraintIssueSource"
+                       class="org.simantics.issues.common.ConstraintIssueSource">
+                       <this />
+               </type>
        </target>
 
        <target interface="org.simantics.issues.common.IssueSource">
index 72728018561bcb598967ca78fe8b4abebda74c5d..006e779d47cb105311e11bf66906ca2c1c4de85a 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 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
@@ -8,11 +8,11 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 package org.simantics.issues.common;
 
-import gnu.trove.set.hash.THashSet;
-
+import java.util.List;
 import java.util.Set;
 
 import org.simantics.db.ReadGraph;
@@ -20,12 +20,13 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.adapter.Instances;
-import org.simantics.issues.ontology.IssueResource;
-import org.simantics.layer0.Layer0;
 import org.simantics.operation.Layer0X;
+import org.simantics.scl.db.SCLFunctions;
+import org.simantics.scl.runtime.tuple.Tuple0;
 import org.simantics.simulation.ontology.SimulationResource;
 
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Antti Villberg
  */
@@ -37,20 +38,23 @@ public class AllActiveIssues extends ResourceRead<Set<Resource>> {
 
     @Override
     public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
-        Layer0 L0 = Layer0.getInstance(graph);
+
         Layer0X L0X = Layer0X.getInstance(graph);
-        IssueResource ISSUE = IssueResource.getInstance(graph);
         SimulationResource SIMU = SimulationResource.getInstance(graph);
-        Set<Resource> result = new THashSet<Resource>();
-        Instances indexedIssues = graph.getPossibleAdapter(ISSUE.Issue, Instances.class);
+        Set<Resource> result = new THashSet<>();
+
         for (Resource model : graph.syncRequest(new ObjectsWithType(resource, L0X.Activates, SIMU.Model))) {
-            for (Resource issue : graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.Issue))) {
-                result.add(issue);
-            }
-            if (indexedIssues != null)
-                result.addAll(indexedIssues.find(graph, model));
+            result.addAll(graph.syncRequest(new AllModelIssues(model, false)));
         }
+
+        List<Resource> libraries = SCLFunctions.evaluateDB("Simantics/SharedOntologies", "getSharedOntologies", Tuple0.INSTANCE); 
+
+        for (Resource library : libraries) {
+            result.addAll(graph.syncRequest(new AllModelIssues(library, false)));
+        }
+
         return result;
+
     }
 
 }
index 35ad0235190e951072228153d14574771d356c5a..cc0006d9cfa98a4a8baa0c8084890523f800c4bc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 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
@@ -8,31 +8,26 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 package org.simantics.issues.common;
 
-import gnu.trove.map.hash.TObjectByteHashMap;
-import gnu.trove.set.hash.THashSet;
-
-import java.util.Collection;
-import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
-import org.simantics.Simantics;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.BinaryRead;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.adapter.Instances;
 import org.simantics.db.layer0.variable.Variable;
-import org.simantics.db.layer0.variable.Variables;
-import org.simantics.issues.common.preferences.IssuePrefs;
-import org.simantics.issues.ontology.IssueResource;
-import org.simantics.layer0.Layer0;
 import org.simantics.operation.Layer0X;
+import org.simantics.scl.db.SCLFunctions;
+import org.simantics.scl.runtime.tuple.Tuple0;
 import org.simantics.simulation.ontology.SimulationResource;
 
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Tuukka Lehtonen
  */
@@ -48,73 +43,22 @@ public class AllVisibleIssues extends BinaryRead<Resource, Boolean, Set<Variable
 
     @Override
     public Set<Variable> perform(ReadGraph graph) throws DatabaseException {
-        Layer0 L0 = Layer0.getInstance(graph);
+
         Layer0X L0X = Layer0X.getInstance(graph);
-        IssueResource ISSUE = IssueResource.getInstance(graph);
         SimulationResource SIMU = SimulationResource.getInstance(graph);
-
-        Resource project = Simantics.getProjectResource();
-        boolean showHidden = false;
-        boolean showNormal = true;
-        boolean showUser = true;
-        if (project != null) {
-            showHidden = IssuePrefs.showHiddenIssues(graph, project);
-            showNormal = IssuePrefs.showNormalIssues(graph, project);
-            showUser = IssuePrefs.showUserIssues(graph, project);
-        }
-
-        Instances issueIndex = graph.getPossibleAdapter(ISSUE.Issue, Instances.class);
-
-        // Cache for source activeness.
-        // 0 == not in cache, 1 == false, 2 == true
-        TObjectByteHashMap<Resource> sourceActivenessCache = new TObjectByteHashMap<Resource>();
-
-        Set<Variable> result = new THashSet<Variable>(1013);
+        Set<Variable> result = new THashSet<>();
 
         for (Resource model : graph.syncRequest(new ObjectsWithType(parameter, L0X.Activates, SIMU.Model))) {
-            Collection<Resource> modelIssues = graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.Issue));
-            Collection<Resource> indexedIssues = issueIndex != null ? issueIndex.find(graph, model) : Collections.<Resource>emptyList();
-            Collection<Resource> issues = !indexedIssues.isEmpty() ? new THashSet<Resource>(modelIssues.size() + indexedIssues.size()) : modelIssues;
-            if (!indexedIssues.isEmpty()) {
-                issues.addAll(modelIssues);
-                issues.addAll(indexedIssues);
-            }
-
-            for (Resource issue : issues) {
-                // Filter out unwanted material
-                boolean resolved = graph.hasStatement(issue, ISSUE.Resolved);
-                if (parameter2 && resolved)
-                    continue;
-                boolean hidden = graph.hasStatement(issue, ISSUE.Hidden);
-                boolean user = graph.hasStatement(issue, ISSUE.UserIssue);
-                boolean normal = !hidden && !user;
-                if (!showHidden && hidden)
-                    continue;
-                if (!showUser && user)
-                    continue;
-                if (!showNormal && normal)
-                    continue;
-
-                Resource source = graph.getPossibleObject(issue, ISSUE.IssueSource_Manages_Inverse);
-                if (source != null) {
-                    byte cache = sourceActivenessCache.get(source);
-                    boolean active = cache == 2 ? true : false;
-                    if (cache == 0) {
-                        active = Boolean.TRUE.equals(graph.getPossibleRelatedValue(source, ISSUE.IssueSource_active));
-                        sourceActivenessCache.put(source, active ? (byte) 2 : (byte) 1);
-                    }
-                    if (!active)
-                        continue;
-                }
+            result.addAll(graph.syncRequest(new ModelVisibleIssues(model, false)));
+        }
 
-                Variable var = Variables.getPossibleVariable(graph, issue);
-                if (var != null)
-                    result.add(var);
-            }
+        List<Resource> libraries = SCLFunctions.evaluateGraph("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); 
+        for (Resource library : libraries) {
+            result.addAll(graph.syncRequest(new ModelVisibleIssues(library, false)));
         }
 
-        // System.out.println("AllActiveIssues returned " + result.size());
         return result;
+
     }
 
 }
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java
new file mode 100644 (file)
index 0000000..0800560
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
+ *******************************************************************************/
+package org.simantics.issues.common;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.service.VirtualGraphSupport;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+
+import gnu.trove.set.hash.THashSet;
+
+public class BatchValidations {
+
+       private static final boolean PERF = false;
+
+       public static Map<Resource, Set<Issue>> validate(IProgressMonitor monitor, BatchIssueSource source, BatchIssueValidationContext context) throws DatabaseException {
+               Session session = Simantics.getSession();
+               return session.syncRequest(new ComposedValidation(monitor, source, context));
+       }
+
+       /**
+        * @param monitor
+        * @param source
+        * @param issues
+        * @return
+        * @throws DatabaseException
+        */
+       public static int store(final IProgressMonitor monitor,
+                       final Resource source, final Map<Resource, Set<Issue>> issues)
+                       throws DatabaseException {
+               return store(monitor, source, issues, Integer.MAX_VALUE);
+       }
+
+       /**
+        * @param monitor
+        * @param source
+        * @param issues
+        * @param maxIssuesToWrite
+        * @return number of issues written (added)
+        * @throws DatabaseException
+        */
+       public static int store(final IProgressMonitor monitor,
+                       final Resource source, final Map<Resource, Set<Issue>> issues,
+                       final int maxIssuesToWrite) throws DatabaseException {
+
+               if (issues.isEmpty() || maxIssuesToWrite <= 0)
+                       return 0;
+
+               Session session = Simantics.getSession();
+               VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);
+               VirtualGraph vg = support.getWorkspacePersistent(IssueConstants.ISSUE_VG);
+               final int[] writtenIssues = { 0 };
+
+               session.syncRequest(new WriteRequest(vg) {
+
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+
+                               for(Map.Entry<Resource, Set<Issue>> entry : issues.entrySet()) {
+
+                                       if (monitor.isCanceled())
+                                               return;
+
+                                       Resource context = entry.getKey();
+
+                                       Set<Issue> current = entry.getValue();
+                                       Set<Issue> existing = graph.sync(new BatchIssueDescriptions(source, context));
+
+                                       if(!existing.equals(current)) {
+
+                                               Set<Issue> added = new THashSet<Issue>(current);
+                                               Set<Issue> removed = new THashSet<Issue>(existing);
+                                               added.removeAll(existing);
+                                               removed.removeAll(current);
+
+                                               for(Issue add : added) {
+                                                       add.write(graph, source);
+                                                       // Stop if write limit is reached.
+                                                       if (++writtenIssues[0] >= maxIssuesToWrite)
+                                                               return;
+                                               }
+                                               for(Issue remove : removed) {
+                                                       Resource issue = graph.sync(new IssueByList(source, remove));
+                                                       if (issue == null)
+                                                               // FIXME: when can this happen and what should be done in this case?
+                                                               continue;
+                                                       graph.deny(issue, Layer0.getInstance(graph).PartOf);
+                                                       graph.deny(source, IssueResource.getInstance(graph).IssueSource_Manages, issue);
+                                                       RemoverUtil.remove(graph, issue);
+                                               }
+
+                                       }
+
+                               }
+
+                       }
+               });
+
+               return writtenIssues[0];
+
+       }
+
+       /**
+        * @param map
+        * @return
+        */
+       @SuppressWarnings("rawtypes")
+       private static int count(Map map) {
+               int result = 0;
+               for (Object obj : map.values()) {
+                       if (obj instanceof Set<?>) {
+                               Set<?> set = (Set<?>) obj;
+                               result += set.size();
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Checks if the specified <code>resourceToCheckForLinks</code> is linked to
+        * anything else besides itself and <code>excludeLinksTo</code>.
+        * 
+        * <p>
+        * This is used to if an issue context is still valid. We consider any issue
+        * context that is not attached to something else besides its issue context to
+        * be an invalid issue. Assertions and L0.InstanceOf do not count as external
+        * links.
+        * 
+        * @param graph database access handle
+        * @param resourceToCheckForLinks the resource to check for "external" links
+        * @param excludeLinksTo exclude links to this resource from evaluation
+        * @return <code>true</code> if there are links, <code>false</code> otherwise
+        * @throws DatabaseException 
+        */
+       public static boolean isLinkedToOtherThan(ReadGraph graph, Resource resourceToCheckForLinks,
+                       Resource excludeLinksTo)
+                                       throws DatabaseException
+       {
+               Layer0 L0 = Layer0.getInstance(graph);
+               for (Statement stm : graph.getStatements(resourceToCheckForLinks, L0.IsWeaklyRelatedTo)) {
+                       if (stm.isAsserted(resourceToCheckForLinks))
+                               continue;
+                       if (stm.getPredicate().equals(L0.InstanceOf))
+                               continue;
+                       Resource o = stm.getObject();
+                       if (o.equals(excludeLinksTo) || o.equals(resourceToCheckForLinks))
+                               continue;
+
+                       return true;
+               }
+               return false;
+       }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ConstraintIssueSource.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ConstraintIssueSource.java
new file mode 100644 (file)
index 0000000..0b02c0e
--- /dev/null
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * 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.issues.common;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.QueryMemoryWatcher;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest.DomainOnlyProcessor;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.db.service.QueryControl;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.db.SCLFunctions;
+import org.simantics.scl.runtime.function.Function1;
+
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * @author Antti Villberg
+ */
+public class ConstraintIssueSource implements BatchIssueSource {
+
+    private final Resource resource;
+
+    public ConstraintIssueSource(Resource resource) {
+        this.resource = resource;
+    }
+
+    @Override
+    public Map<Resource, Set<Issue>> run(IProgressMonitor monitor, ReadGraph graph, BatchIssueValidationContext context) throws DatabaseException {
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        Set<Issue> emptySet = Collections.emptySet();
+        CollectionSupport cs = graph.getService(CollectionSupport.class);
+        Map<Resource,Set<Issue>> result = cs.createMap(Set.class);
+        monitor.setTaskName("Constraint analysis");
+
+        DomainOnlyProcessor domain = context.domain;
+
+        int entityCount = domain.internals.size();
+
+        IssueResource ISSUE = IssueResource.getInstance(graph);
+        Resource type = graph.getSingleType(resource, ISSUE.IssueSource);
+        List<Function1<Resource, List<Issue>>> validators = new ArrayList<>();
+        for(Resource constraint : graph.getObjects(type, ISSUE.IssueSource_HasConstraint)) {
+            Function1<Resource, List<Issue>> validator = graph.getRelatedValue2(constraint, L0.Constraint_Validator, constraint);
+            //Resource function = graph.getSingleObject(constraint, L0.Constraint_Validator);
+            validators.add(validator);
+        }
+
+        QueryControl qc = graph.getService(QueryControl.class);
+        qc.flush(graph);
+
+        // Allow this process to make 50k queries
+        QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000, 0.5, 300);
+
+        SCLFunctions.runWithGraph(graph, () -> {
+
+            int totalExaminedCount = 0;
+            int examinedCount = 1000;
+
+            for(Resource r : domain.internals) {
+
+                Set<Issue> set = emptySet;
+                if (examinedCount >= 1000) {
+                    monitor.subTask(contextProgressMessage(totalExaminedCount, entityCount));
+                    examinedCount = 0;
+                    if(monitor.isCanceled()) return;
+                    memory.maintain();
+                }
+                for(Function1<Resource, List<Issue>> validator : validators) {
+                    try {
+                        @SuppressWarnings("unchecked")
+                        List<Issue> issues = validator.apply(r);//(List<Issue>)Functions.exec(graph, validator, graph, r);
+                        if (issues != null && !issues.isEmpty()) {
+                            if (set == emptySet)
+                                set = new THashSet<>();
+                            set.addAll(issues);
+                        }
+                    } catch (Throwable t) {
+                        Logger.defaultLogError(t);
+                    }
+                }
+                ++totalExaminedCount;
+                ++examinedCount;
+                if(!set.isEmpty())
+                    result.put(r, set);
+            }
+
+        });
+
+        return result;
+
+    }
+
+    private static String contextProgressMessage(int totalExaminedCount, int entityCount) {
+        StringBuilder sb = new StringBuilder(80)
+        .append("Validating resources").append(" ").append(100*totalExaminedCount / entityCount).append("% ready.");
+        return sb.toString();
+    }
+
+    @Override
+    public Resource getResource() {
+        return resource;
+    }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/Messages.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/Messages.java
new file mode 100644 (file)
index 0000000..f68cf62
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.issues.common;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+       private static final String BUNDLE_NAME = "org.simantics.issues.common.messages"; //$NON-NLS-1$
+       public static String RunActiveValidations_MonitorPreparingResourcesForValidation;
+       public static String RunActiveValidations_ValidateModel;
+       static {
+               // initialize resource bundle
+               NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+       }
+
+       private Messages() {
+       }
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ModelVisibleIssues.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ModelVisibleIssues.java
new file mode 100644 (file)
index 0000000..28d3417
--- /dev/null
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
+ *******************************************************************************/
+package org.simantics.issues.common;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.issues.common.preferences.IssuePrefs;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.simantics.simulation.ontology.SimulationResource;
+
+import gnu.trove.map.hash.TObjectByteHashMap;
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class ModelVisibleIssues extends BinaryRead<Resource, Boolean, Set<Variable>> {
+
+    public ModelVisibleIssues(Resource model) {
+        super(model, Boolean.FALSE);
+    }
+
+    public ModelVisibleIssues(Resource model, boolean onlyUnresolved) {
+        super(model, onlyUnresolved);
+    }
+
+    @Override
+    public Set<Variable> perform(ReadGraph graph) throws DatabaseException {
+
+        //System.err.println("ModelVisibleIssues for " + graph.getURI(parameter));
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        IssueResource ISSUE = IssueResource.getInstance(graph);
+
+        Resource project = Simantics.getProjectResource();
+        boolean showHidden = false;
+        boolean showNormal = true;
+        boolean showUser = true;
+        if (project != null) {
+            showHidden = IssuePrefs.showHiddenIssues(graph, project);
+            showNormal = IssuePrefs.showNormalIssues(graph, project);
+            showUser = IssuePrefs.showUserIssues(graph, project);
+        }
+
+        Instances issueIndex = graph.getPossibleAdapter(ISSUE.Issue, Instances.class);
+
+        // Cache for source activeness.
+        // 0 == not in cache, 1 == false, 2 == true
+        TObjectByteHashMap<Resource> sourceActivenessCache = new TObjectByteHashMap<Resource>();
+
+        Set<Variable> result = new THashSet<>(1013);
+
+        Collection<Resource> modelIssues = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, ISSUE.Issue));
+        Collection<Resource> indexedIssues = issueIndex != null ? issueIndex.find(graph, parameter) : Collections.<Resource>emptyList();
+        Collection<Resource> issues = !indexedIssues.isEmpty() ? new THashSet<Resource>(modelIssues.size() + indexedIssues.size()) : modelIssues;
+        if (!indexedIssues.isEmpty()) {
+            issues.addAll(modelIssues);
+            issues.addAll(indexedIssues);
+        }
+
+        for (Resource issue : issues) {
+            // Filter out unwanted material
+            boolean resolved = graph.hasStatement(issue, ISSUE.Resolved);
+            if (parameter2 && resolved)
+                continue;
+            boolean hidden = graph.hasStatement(issue, ISSUE.Hidden);
+            boolean user = graph.hasStatement(issue, ISSUE.UserIssue);
+            boolean normal = !hidden && !user;
+            if (!showHidden && hidden)
+                continue;
+            if (!showUser && user)
+                continue;
+            if (!showNormal && normal)
+                continue;
+
+            Resource source = graph.getPossibleObject(issue, ISSUE.IssueSource_Manages_Inverse);
+            if (source != null) {
+                byte cache = sourceActivenessCache.get(source);
+                boolean active = cache == 2 ? true : false;
+                if (cache == 0) {
+                    active = Boolean.TRUE.equals(graph.getPossibleRelatedValue(source, ISSUE.IssueSource_active));
+                    sourceActivenessCache.put(source, active ? (byte) 2 : (byte) 1);
+                }
+                if (!active)
+                    continue;
+            }
+
+            Variable var = Variables.getPossibleVariable(graph, issue);
+            if (var != null)
+                result.add(var);
+        }
+
+        // System.out.println("ModelVisibleIssues returned " + result.size());
+        return result;
+    }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/RunActiveValidations.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/RunActiveValidations.java
new file mode 100644 (file)
index 0000000..72a5f06
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
+ *******************************************************************************/
+package org.simantics.issues.common;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.request.Queries;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.utils.ListUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.PossibleActiveModel;
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
+import org.simantics.db.layer0.util.SessionGarbageCollection;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.issues.preferences.IssuePreferenceUtil;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class RunActiveValidations {
+
+    public static void run(IProgressMonitor monitor) throws DatabaseException {
+        Resource model = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+        if (model != null)
+            run(monitor, model);
+    }
+
+    public static void run(IProgressMonitor monitor, Resource model) throws DatabaseException {
+
+        final Session session = Simantics.getSession();
+
+        // 1. query for which composites to run the validation
+        final Collection<BatchIssueSource> validations = new ArrayList<>();
+        final BatchIssueValidationContext context = new BatchIssueValidationContext();
+
+        try {
+            toBatchIssueSources(session,
+                    session.syncRequest(new SelectedModelBatchIssueSources(model)),
+                    validations);
+
+            SubMonitor.convert(monitor, Messages.RunActiveValidations_MonitorPreparingResourcesForValidation, 100);
+            context.contexts = Collections.singletonList(model);
+            context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, model);
+
+            if (monitor.isCanceled())
+                throw new OperationCanceledException();
+
+        } finally {
+            monitor.done();
+        }
+
+        if (!validations.isEmpty() && !context.contexts.isEmpty())
+            run(monitor, validations, context);
+
+    }
+
+    static Collection<BatchIssueSource> toBatchIssueSources(RequestProcessor processor, Collection<Resource> sources, Collection<BatchIssueSource> result) throws DatabaseException {
+        for (Resource source : sources) {
+            BatchIssueSource bis = processor.syncRequest(Queries.adapt(source, BatchIssueSource.class, true));
+            if (bis != null)
+                result.add(bis);
+        }
+        return result;
+    }
+
+    public static void run(IProgressMonitor monitor, final Collection<BatchIssueSource> validations, final BatchIssueValidationContext context) throws DatabaseException {
+        SubMonitor progress = SubMonitor.convert(monitor, Messages.RunActiveValidations_ValidateModel, 100);
+        int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;
+        int writtenIssues = 0;
+        for (BatchIssueSource source : validations) {
+            Map<Resource, Set<Issue>> results = BatchValidations.validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), source, context);
+            if (progress.isCanceled())
+                throw new OperationCanceledException();
+
+            Collection<Resource> removed = Simantics.getSession().syncRequest(new ResourceRead<Collection<Resource>>(source.getResource()) {
+                @Override
+                public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
+                    IssueResource ISSUE = IssueResource.getInstance(graph);
+                    ArrayList<Resource> result = new ArrayList<>();
+                    for (Resource issue : graph.syncRequest(new ManagedIssues(resource))) {
+                        Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
+                        List<Resource> l = ListUtils.toList(graph, list);
+                        if (l.size() > 0) {
+                            Resource mainContext = l.get(0);
+                            if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
+                                result.add(mainContext);
+                        }
+                    }
+                    return result;
+                }
+            });
+
+            for (Resource r : removed) {
+                results.put(r, Collections.<Issue>emptySet());
+            }
+            if (progress.isCanceled())
+                throw new OperationCanceledException();
+
+            int wroteIssues = BatchValidations.store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), source.getResource(), results, Math.max(0, maxWrittenIssues - writtenIssues));
+            writtenIssues += wroteIssues;
+
+            // Try to keep resource consumption down.
+            SessionGarbageCollection.gc(null, Simantics.getSession(), true, null);
+
+        }
+
+    }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/messages.properties b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/messages.properties
new file mode 100644 (file)
index 0000000..99646ca
--- /dev/null
@@ -0,0 +1,2 @@
+RunActiveValidations_MonitorPreparingResourcesForValidation=Preparing resources for validation\r
+RunActiveValidations_ValidateModel=Validate Model\r
index a819028de94dc38b3a860edb753059b42235c0f9..e96923119907180732dee0438fac734897043d4e 100644 (file)
@@ -13,6 +13,7 @@ ISSUE.Functions : L0.Library
 ISSUE.IssueSourceType <T L0.Type
 
 ISSUE.IssueSource <T L0.Entity : ISSUE.IssueSourceType
+    @L0.tag L0.Abstract
     @L0.tag ISSUE.IssueSource.Selected
     >-- ISSUE.IssueSource.HasConstraint --> L0.Constraint <R L0.DependsOn
     >-- ISSUE.IssueSource.Manages --> ISSUE.Issue <R L0.IsRelatedTo
@@ -20,11 +21,13 @@ ISSUE.IssueSource <T L0.Entity : ISSUE.IssueSourceType
     >-- ISSUE.IssueSource.Selected --> ISSUE.IssueSource <R L0.IsRelatedTo
     >-- ISSUE.IssueSource.active ==> "Boolean" <R L0.HasProperty : L0.FunctionalRelation
     @L0.assert  ISSUE.IssueSource.active true
-        
+
 ISSUE.ContinuousIssueSource <T ISSUE.IssueSource
+    @L0.tag L0.Abstract
     >-- ISSUE.ContinuousIssueSource.lastUpdateRevision --> L0.Long <R L0.HasProperty : L0.FunctionalRelation
 
 ISSUE.DynamicIssueSource <T ISSUE.IssueSource
+    @L0.tag L0.Abstract
     L0.HasDescription "A dynamic issue source is a source that is browsed purely through the Variable interface to produce a single subtree to represent issues. The issues do not have to have a database resource representation backing them."
 
 ISSUE.Issue.ContextList <T L0.List
@@ -44,16 +47,16 @@ ISSUE.Issue <T L0.Entity
     >-- ISSUE.Issue.creationTime --> L0.String <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.hider ==> "Maybe (Boolean -> <WriteGraph> Boolean)" <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.hidden ==> "Boolean" <R L0.HasProperty : L0.FunctionalRelation
-    @L0.assert L0.HasDescription 
+    @L0.assert L0.HasDescription
       ISSUE.Functions.defaultDescription : L0.Function
         L0.HasValueType "String"
     @L0.assert ISSUE.Issue.severity
       ISSUE.Functions.standardIssueSeverity : L0.Function
         L0.HasValueType "String"
-    @L0.assert ISSUE.Issue.resource 
+    @L0.assert ISSUE.Issue.resource
       ISSUE.Functions.standardIssueResource : L0.Function
         L0.HasValueType "String"
-    @L0.assert ISSUE.Issue.path 
+    @L0.assert ISSUE.Issue.path
       ISSUE.Functions.standardIssuePath : L0.Function
         L0.HasValueType "String"
     @L0.assert ISSUE.Issue.contexts
@@ -86,7 +89,7 @@ ISSUE.Severity <T L0.Value
     @L0.tag L0.Enumeration
     @L0.assert L0.ConvertsToValueWith
         L0.Functions.resourceAsValue
-    
+
 ISSUE.Severity.Note : ISSUE.Severity
     L0.HasDescription "These issues are markers for documentation purposes"
 ISSUE.Severity.Info : ISSUE.Severity
@@ -101,6 +104,7 @@ ISSUE.Severity.Fatal : ISSUE.Severity
 ISSUE.Sources : L0.Library
 
 ISSUE.Sources.DependencyTracker <T ISSUE.ContinuousIssueSource
+  @L0.tag L0.Abstract
   >-- ISSUE.Sources.DependencyTracker.HasType --> L0.Entity <R L0.DependsOn  : L0.FunctionalRelation
   >-- ISSUE.Sources.DependencyTracker.HasSearchType --> L0.Entity <R L0.DependsOn
   >-- ISSUE.Sources.DependencyTracker.HasExtension --> L0.Function <R L0.DependsOn : L0.Function
@@ -108,9 +112,10 @@ ISSUE.Sources.DependencyTracker <T ISSUE.ContinuousIssueSource
   >-- ISSUE.Sources.DependencyTracker.HasConstraint --> L0.Constraint <R ISSUE.IssueSource.HasConstraint : L0.FunctionalRelation
   @L0.assert ISSUE.Sources.DependencyTracker.HasBaseFunction
     ISSUE.Functions.dependencyBaseRealizationFunction : L0.Function
-  
+
 ISSUE.Sources.ListeningDependencyTracker <T ISSUE.Sources.DependencyTracker
-  
+  @L0.tag L0.Abstract
+
 ISSUE.Sources.DependencyTracker.Issue <T ISSUE.Issue
   @L0.assert ISSUE.Issue.resource
     ISSUE.Functions.standardIssueResource
@@ -119,6 +124,9 @@ ISSUE.Sources.DependencyTracker.Issue <T ISSUE.Issue
 
 ISSUE.Sources.DependencyTracker.AnonymousIssue <T ISSUE.Sources.DependencyTracker.Issue
 
+ISSUE.Sources.ConstraintIssueSource <T ISSUE.IssueSource
+  @L0.tag L0.Abstract
+
 // IssueSource template
 ISSUE.constraint : L0.Template
     @template %type %constraint %source %validator %baseFunction
@@ -131,11 +139,11 @@ ISSUE.constraint : L0.Template
                 L0.HasObject %type
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasConstraint
-                L0.HasObject %constraint     
+                L0.HasObject %constraint
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasBaseFunction
-                L0.HasObject %baseFunction                          
-            
+                L0.HasObject %baseFunction
+
 
 ISSUE.listeningConstraint3 : L0.Template
     @template %type %constraint %source %validator
@@ -164,7 +172,7 @@ ISSUE.listeningConstraint : L0.Template
                 L0.HasObject %constraint
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasBaseFunction
-                L0.HasObject %baseFunction                
+                L0.HasObject %baseFunction
 
 // Issue template
 ISSUE.issue : L0.Template
@@ -198,5 +206,3 @@ ISSUE.assignConstraint : L0.Template
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasConstraint
                 L0.HasObject %constraint
-                
-                
\ No newline at end of file
diff --git a/bundles/org.simantics.issues.ontology/graph/Layer0Sources.pgraph b/bundles/org.simantics.issues.ontology/graph/Layer0Sources.pgraph
new file mode 100644 (file)
index 0000000..9b0cb10
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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 = <http://www.simantics.org/Layer0-1.1>
+ISSUE = <http://www.simantics.org/Issue-1.2>
+
+ISSUE.Sources.Relations <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Relations"
+    ISSUE.IssueSource.HasConstraint L0.Entity.RelationConstraint
+ISSUE.Sources.Properties <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Properties"
+    ISSUE.IssueSource.HasConstraint L0.Entity.PropertyConstraint
+ISSUE.Sources.Values <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Values"
+    ISSUE.IssueSource.HasConstraint L0.Entity.ValueConstraint
+ISSUE.Sources.URIs <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "URIs"
+    ISSUE.IssueSource.HasConstraint L0.Entity.URIConstraint
+ISSUE.Sources.Clusters <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Clusters"
+    ISSUE.IssueSource.HasConstraint L0.Entity.ClusterConstraint
index 4cab8fbcefb45e8bc1ae43b981675d25fcaab4bb..063f95b83d32bbb269e4cccdcc79c0fd0dc82a94 100644 (file)
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2007, 2011 Association for Decentralized Information Management
+# Copyright (c) 2007, 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
@@ -15,4 +15,5 @@ bin.includes = META-INF/,\
                .,\
                plugin.xml,\
                icons/,\
-               adapters.xml
+               adapters.xml,\
+               scl/
diff --git a/bundles/org.simantics.issues.ui/scl/Simantics/IssueUI.scl b/bundles/org.simantics.issues.ui/scl/Simantics/IssueUI.scl
new file mode 100644 (file)
index 0000000..7f0a5dd
--- /dev/null
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+import "Simantics/DB"
+
+importJava "org.simantics.issues.ui.handler.ConfigureIssueSources" where
+  @JavaName executeDefault
+  showIssueConfigurationDialog :: Resource -> <Proc> ()
\ No newline at end of file
index b168583e4e0fb1cb8bfb9cccfe412e14fb9f1887..720b9d10beeeacb12eead12496a7c308bf713a63 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management
+ * Copyright (c) 2007, 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 package org.simantics.issues.ui.handler;
 
@@ -40,12 +41,13 @@ import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.QueryIndexUtils;
 import org.simantics.db.layer0.request.PossibleActiveModel;
 import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.request.Write;
 import org.simantics.issues.common.IssueUtils;
 import org.simantics.issues.ontology.IssueResource;
 import org.simantics.layer0.Layer0;
-import org.simantics.modeling.ModelingUtils;
 import org.simantics.utils.ui.ErrorLogger;
 import org.simantics.utils.ui.dialogs.ListDialog;
 
@@ -67,176 +69,106 @@ public class ConfigureIssueSources extends AbstractHandler {
                        checked = value;
                }
        }
-       
-    @Override
-    public Object execute(ExecutionEvent event) throws ExecutionException {
 
-      try {
+       @Override
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               try {
+                       Resource indexRoot = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+                       executeDefault(indexRoot);
+               } catch (DatabaseException e) {
+                       throw new ExecutionException("Exception while showing validation configuration dialog", e);
+               }
+               return null;
+       }
 
-       final List<IssueSourceEntry> sources = Simantics.getSession().syncRequest(new UniqueRead<List<IssueSourceEntry>>() {
+       public static void executeDefault(Resource indexRoot) throws ExecutionException {
 
-                       @Override
-                       public List<IssueSourceEntry> perform(ReadGraph graph) throws DatabaseException {
-                               
-                               Resource activeModel = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
-                               if(activeModel == null) return Collections.emptyList();
-                               
-                               List<IssueSourceEntry> result = new ArrayList<IssueSourceEntry>();
-                               Layer0 L0 = Layer0.getInstance(graph);
-                               IssueResource ISSUE = IssueResource.getInstance(graph);
-                               for(Resource type : ModelingUtils.searchByType(graph, activeModel, ISSUE.IssueSourceType)) {
-                                       String name = NameUtils.getSafeLabel(graph, type);
-                                       boolean exists = graph.syncRequest(new PossibleObjectWithType(activeModel, L0.ConsistsOf, type)) != null;
-                                       boolean deprecated = graph.hasStatement(type, L0.Deprecated);
-                                       if(!exists && deprecated) continue;
-                                       result.add(new IssueSourceEntry(name, type, exists));
+               if (indexRoot == null)
+                       return;
+
+               try {
+                       final List<IssueSourceEntry> sources = Simantics.getSession().syncRequest(new UniqueRead<List<IssueSourceEntry>>() {
+
+                               @Override
+                               public List<IssueSourceEntry> perform(ReadGraph graph) throws DatabaseException {
+
+                                       if(indexRoot == null) return Collections.emptyList();
+
+                                       List<IssueSourceEntry> result = new ArrayList<IssueSourceEntry>();
+                                       Layer0 L0 = Layer0.getInstance(graph);
+                                       IssueResource ISSUE = IssueResource.getInstance(graph);
+                                       for(Resource type : QueryIndexUtils.searchByType(graph, indexRoot, ISSUE.IssueSourceType)) {
+                                               String name = NameUtils.getSafeLabel(graph, type);
+                                               boolean exists = graph.syncRequest(new PossibleObjectWithType(indexRoot, L0.ConsistsOf, type)) != null;
+                                               boolean deprecated = graph.hasStatement(type, L0.Deprecated);
+                                               boolean abstract_ = graph.hasStatement(type, L0.Abstract);
+                                               if(!exists && (deprecated || abstract_)) continue;
+                                               result.add(new IssueSourceEntry(name, type, exists));
+                                       }
+                                       return result;
                                }
-                               return result;
-                       }
-               
-       });
-       
-        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-         ListDialog<IssueSourceEntry> dialog = new ListDialog<IssueSourceEntry>(
-                 shell, sources,
-                 Messages.ConfigureIssueSources_SelectAvailableIssueSources,
-                 Messages.ConfigureIssueSources_SelectedSourcesAddRemoveMsg) {
-                
-                   protected CheckboxTableViewer createViewer(Composite composite) {
-                       CheckboxTableViewer viewer = CheckboxTableViewer.newCheckList(
-                               composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
-                       final Table table = (Table)viewer.getControl();
-                       viewer.setCheckStateProvider(new ICheckStateProvider() {
-                                               
+
+                       });
+
+                       Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                       ListDialog<IssueSourceEntry> dialog = new ListDialog<IssueSourceEntry>(
+                                       shell, sources,
+                                       Messages.ConfigureIssueSources_SelectAvailableIssueSources,
+                                       Messages.ConfigureIssueSources_SelectedSourcesAddRemoveMsg) {
+
+                               protected CheckboxTableViewer createViewer(Composite composite) {
+                                       CheckboxTableViewer viewer = CheckboxTableViewer.newCheckList(
+                                                       composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+                                       viewer.setCheckStateProvider(new ICheckStateProvider() {
                                                @Override
-                                               public boolean isGrayed(Object arg0) {
+                                               public boolean isGrayed(Object o) {
                                                        return false;
                                                }
-                                               
                                                @Override
-                                               public boolean isChecked(Object arg0) {
-                                                       IssueSourceEntry entry = (IssueSourceEntry)arg0;
+                                               public boolean isChecked(Object o) {
+                                                       IssueSourceEntry entry = (IssueSourceEntry)o;
                                                        return entry.isChecked();
                                                }
-                                               
                                        });
-                       viewer.addCheckStateListener(new ICheckStateListener() {
-                                               
-                                               @Override
-                                               public void checkStateChanged(CheckStateChangedEvent arg0) {
-                                                       IssueSourceEntry entry = (IssueSourceEntry)arg0.getElement();
-                                                       entry.setChecked(arg0.getChecked());
-                                               }
+                                       viewer.addCheckStateListener(e -> {
+                                               IssueSourceEntry entry = (IssueSourceEntry)e.getElement();
+                                               entry.setChecked(e.getChecked());
                                        });
-                       table.addSelectionListener(new SelectionListener () {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       table.deselectAll();
-                               }
-                               @Override
-                               public void widgetDefaultSelected(SelectionEvent e) {}
-                       });
-                       return viewer;
-                   }
-
-         };
-         int result = dialog.open();
-         if (result != Dialog.OK)
-             return null;
-       
-       Simantics.getSession().syncRequest(new WriteRequest() {
-
-                       @Override
-                       public void perform(WriteGraph graph) throws DatabaseException {
-                               
-                               Resource activeModel = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
-                               if(activeModel == null) return;
-                               
+                                       viewer.getTable().addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
+                                               viewer.getTable().deselectAll();
+                                       }));
+                                       return viewer;
+                               }
+
+                       };
+                       int result = dialog.open();
+                       if (result != Dialog.OK)
+                               return;
+
+                       Simantics.getSession().syncRequest((Write) graph -> {
+
                                Layer0 L0 = Layer0.getInstance(graph);
 
                                for(IssueSourceEntry entry : sources) {
 
-                                       Resource existing = graph.syncRequest(new PossibleObjectWithType(activeModel, L0.ConsistsOf, entry.getResource())); 
-                                       
+                                       Resource existing = graph.syncRequest(new PossibleObjectWithType(indexRoot, L0.ConsistsOf, entry.getResource()));
+
                                        if(existing == null && entry.isChecked()) {
                                                String name = NameUtils.getSafeLabel(graph, entry.getResource());
-                                               IssueUtils.addIssueSource(graph, activeModel, entry.getResource(), name);
+                                               IssueUtils.addIssueSource(graph, indexRoot, entry.getResource(), name);
                                        }
-                                       
+
                                        if(existing != null && !entry.isChecked()) {
                                                RemoverUtil.remove(graph, existing);
                                        }
-                                       
+
                                }
-                               
-                       }
-               
-       });
-         
-//        try {
-//            PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
-//                @Override
-//                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-//                    try {
-//                        purgeResolvedIssues(monitor);
-//                    } catch (DatabaseException e) {
-//                        throw new InvocationTargetException(e);
-//                    } finally {
-//                        monitor.done();
-//                    }
-//                }
-//            });
-//        } catch (InvocationTargetException e) {
-//            ErrorLogger.defaultLogError(e);
-        } catch (DatabaseException e) {
-            ErrorLogger.defaultLogError(e);
-        }
-        return null;
-    }
-
-//    private void purgeResolvedIssues(IProgressMonitor monitor) throws DatabaseException {
-//        Session session = Simantics.getSession();
-//        final Resource project = Simantics.getProjectResource();
-//        if (project == null)
-//            return;
-//
-//        final SubMonitor mon = SubMonitor.convert(monitor, "Purging resolved issues...", 100);
-//
-//        session.syncRequest(new DelayedWriteRequest() {
-//            @Override
-//            public void perform(WriteGraph graph) throws DatabaseException {
-//                graph.markUndoPoint();
-//                IssueResource ISSUE = IssueResource.getInstance(graph);
-//                Set<Resource> toBeRemoved = new HashSet<Resource>();
-//                Map<Resource, Boolean> sourceIsContinuous = new THashMap<Resource, Boolean>(); 
-//                for (Resource activeIssue : graph.syncRequest(new AllActiveIssues(project))) {
-//                    if (graph.hasStatement(activeIssue, ISSUE.Resolved)) {
-//                        Resource managedBy = graph.getPossibleObject(activeIssue, ISSUE.IssueSource_Manages_Inverse);
-//                        if (managedBy != null) {
-//                            Boolean isContinuous = sourceIsContinuous.get(managedBy);
-//                            if (isContinuous == null) {
-//                                isContinuous = graph.isInstanceOf(managedBy, ISSUE.ContinuousIssueSource);
-//                                sourceIsContinuous.put(managedBy, isContinuous);
-//                            }
-//                            if (isContinuous)
-//                                continue;
-//                        }
-//                        toBeRemoved.add(activeIssue);
-//                    }
-//                }
-//
-//                mon.setTaskName("Purging " + toBeRemoved.size() + " resolved batch issues...");
-//                mon.setWorkRemaining(toBeRemoved.size());
-//                StringBuilder sb = new StringBuilder();
-//                sb.append("Purged " + toBeRemoved.size() + " resolved batch issue(s)");
-//                for (Resource remove : toBeRemoved) {
-//                    //sb.append(NameUtils.getSafeLabel(graph, remove) + " ");
-//                    RemoverUtil.remove(graph, remove);
-//                    mon.worked(1);
-//                }
-//                Layer0Utils.addCommentMetadata(graph, sb.toString());
-//            }
-//        });
-//    }
+
+                       });
+               } catch (DatabaseException e) {
+                       ErrorLogger.defaultLogError(e);
+               }
+
+       }
 
 }
index 0ab0ef98cb75b824978d0ca3743ecd2cad225f7e..efdba04d0ee07fecb12bbb814628989ef6ec434e 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management
+ * Copyright (c) 2007, 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 package org.simantics.issues.ui.handler;
 
@@ -57,12 +58,25 @@ public class RunActiveValidations extends AbstractHandler {
 
     @Override
     public Object execute(ExecutionEvent event) throws ExecutionException {
-        Runnable postValidation = null;
-        run(postValidation);
+        try {
+            run();
+        } catch (DatabaseException e) {
+            throw new ExecutionException("Error while running active validations", e);
+        }
         return null;
     }
 
-    public void run(Runnable postValidation) {
+    public static void run() throws DatabaseException {
+        Resource model = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+        if(model != null)
+            run(null);
+    }
+
+    public static void run(Resource model) {
+        run(model, null);
+    }
+
+    public static void run(Resource model, Runnable postValidation) {
 
         final Session session = Simantics.getSession();
 
@@ -77,8 +91,6 @@ public class RunActiveValidations extends AbstractHandler {
                     @Override
                     public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                         try {
-                            Resource model = session.sync(new PossibleActiveModel(Simantics.getProjectResource()));
-                            if(model == null) return;
 
                             toBatchIssueSources(session,
                                     session.syncRequest(new SelectedModelBatchIssueSources(model)),
@@ -151,7 +163,7 @@ public class RunActiveValidations extends AbstractHandler {
                                             Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
                                             List<Resource> l = ListUtils.toList(graph, list);
                                             if (l.size() > 0) {
-                                                Resource mainContext = l.get(0); 
+                                                Resource mainContext = l.get(0);
                                                 if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
                                                     result.add(mainContext);
                                             }
@@ -174,7 +186,7 @@ public class RunActiveValidations extends AbstractHandler {
 
                             }
                         } catch (OperationCanceledException e) {
-                               throw e;
+                            throw e;
                         } catch (Exception e) {
                             throw new InvocationTargetException(e);
                         } finally {
index 47931cc4f1172e7eb0bc631471114d8fd648209b..98b7aa98120c69217aba16c8a9cf709a98bccbf0 100644 (file)
@@ -32,6 +32,9 @@ MOD.SCLLabelForegroundColorRule <T VP.VisualsRule
 MOD.SCLLabelBackgroundColorRule <T VP.VisualsRule
   >-- MOD.SCLLabelBackgroundColorRule.getColor ==> "Resource -> Maybe (Double, Double, Double) -> String -> Integer -> <ReadGraph> Maybe (Double, Double, Double)]" <R L0.HasProperty : L0.FunctionalRelation
 
+MOD.SCLCheckedStateRule <T VP.VisualsRule
+  >-- MOD.SCLCheckedStateRule.getState ==> "BrowseNodeRule CheckedState" <R L0.HasProperty : L0.FunctionalRelation
+
 MOD.SCLAction <T ACT.Action
   --> MOD.SCLAction.action ==> "Resource -> <Proc> ()" <R L0.HasProperty : L0.FunctionalRelation 
 
@@ -412,6 +415,13 @@ MOD.sclLabelBackgroundColorRule : L0.Template
             L0.SCLValue.expression %expression
             L0.HasValueType "Resource -> Maybe (Double, Double, Double) -> String -> Integer -> <ReadGraph> Maybe (Double, Double, Double)"
 
+MOD.sclCheckedStateRule : L0.Template
+    @template %action %expression
+        %action : MOD.SCLCheckedStateRule
+          MOD.SCLCheckedStateRule.getState _ : MOD.SCLValue
+            L0.SCLValue.expression %expression
+            L0.HasValueType "Browsable a => a -> <ReadGraph> CheckedState"
+
 MOD.sclAction : L0.Template
     @template %action %expression
         %action : MOD.SCLAction
index 590ddd21ce8f658d40b133dd6cb0fddd3be8607d..d051042d5f4258b6c92acbace7b52eeec2a9114b 100644 (file)
@@ -111,6 +111,9 @@ importJava "org.simantics.browsing.ui.content.LabelDecorator" where
 
 importJava "org.simantics.browsing.ui.CheckedState" where
     data CheckedState
+    CHECKED :: CheckedState
+    GRAYED :: CheckedState
+    NOT_CHECKED :: CheckedState
 
 importJava "org.simantics.browsing.ui.content.Labeler$Modifier" where
     data Modifier
@@ -138,3 +141,6 @@ instanceOfTest :: Variable -> <ReadGraph> (Resource -> <ReadGraph> Boolean)
 instanceOfTest self = do
   typeResource = singleObject (represents $ parent self) MOD.InstanceOfTest.HasType
   (\r -> isInstanceOf r typeResource) 
+
+type BrowseNodeRule a = VariableOrResource -> <ReadGraph,Proc> a  
+  
\ No newline at end of file
index 7693586d8029b79dcb5ccc80d838e3821644e791..063a661c94bbd6bab2285b7df0826562438ae6b8 100644 (file)
         </type>
     </target>
 
+    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">
+        <type uri="http://www.simantics.org/Modeling-0.0/SCLCheckedStateRule"
+            class="org.simantics.modeling.adapters.SCLCheckedStateRule">
+            <graph />
+            <this />
+        </type>
+    </target>
+
     <target interface="org.simantics.browsing.ui.model.tests.Test">
         <type uri="http://www.simantics.org/Modeling-0.0/SCLTest"
             class="org.simantics.modeling.adapters.SCLTest">
index 14a558bec05c0b549ddd5600e4c3ebec224e6cab..451bda827d64c910d20f328689d72406bc46136a 100644 (file)
@@ -512,10 +512,7 @@ setElements (DiagramInfo diagram configuration componentMap) joinMap elementSpec
         Just connection
     createNode connection (Terminal elementName terminal) = do
         element = newOrMappedElement elementName
-        if terminal == DIA.Flag.ConnectionPoint then
-            createConnector connection element terminal DIA.HasPlainConnector
-        else        
-            createConnector connection element terminal DIA.HasPlainConnector
+        createConnector connection element terminal DIA.HasPlainConnector
     createNode connection (RouteLine isHorizontal position) = do
         newEntity [
             hasName (freshElementName ()),
@@ -552,7 +549,7 @@ setElements (DiagramInfo diagram configuration componentMap) joinMap elementSpec
         claim a DIA.AreConnected b
     // Returns (connectionRelation :: Maybe Resource, connector attachment relation :: Resource)  
     resolveAttachmentRelation element terminal defaultAttachmentRelation =
-        if terminal == DIA.Flag.ConnectionPoint then
+        if isSubrelationOf terminal DIA.Flag.ConnectionPoint then
             (Nothing, flagTypeToAttachmentRelation element)
         else
             match possibleObject terminal MOD.DiagramConnectionRelationToConnectionRelation with
index e09297750d680e90d2bc55081e285d6d3f12fa45..ee7e51e0be85b398c2d2f96cb3cd3c6b01e7f95a 100644 (file)
@@ -1,20 +1,21 @@
 include "Simantics/Entity" hiding (nameOf)
 import "Simantics/Model"
+import "UI/Progress"
 import "http://www.simantics.org/Issue-1.2" as ISSUE
 
 type Issue = Resource
 type Severity = Resource
-    
+
 issuesOf :: Model -> <ReadGraph> [Issue]
 issuesOf model = recurse ISSUE.Issue model
   where
     recurse t r = do
-        cs = children r 
+        cs = children r
         issues = filter isIssue cs
         issueGrp = filter (not . isIssue) cs
         issues + concatMap (recurse t) issueGrp
     isIssue r = isInstanceOf r ISSUE.Issue
-    
+
 importJava "org.simantics.issues.common.IssueUtils" where
     @JavaName newUserIssueForModel
     newUserIssueForModel :: Model -> String -> Severity -> [Resource] -> <WriteGraph> Issue
@@ -25,4 +26,20 @@ userIssueAdvanced model label severity contexts = do
 
 importJava "org.simantics.issues.common.IssueUtils" where
     @JavaName newUserIssueForModel
-    userIssue :: () -> <WriteGraph> Issue
\ No newline at end of file
+    userIssue :: () -> <WriteGraph> Issue
+
+importJava "org.simantics.db" where
+    @JavaName Issue
+    data IssueI
+
+importJava "org.simantics.db.layer0.validation.ValidationUtils" where
+  @JavaName validateConstraintsForDomain
+  validateDomain :: Resource -> <ReadGraph> [IssueI]
+
+importJava "org.simantics.modeling.utils.BatchValidations" where
+  @JavaName runAll
+  runAllBatchValidations :: ProgressMonitor -> Resource -> Resource -> <Proc> ()
+
+importJava "org.simantics.issues.common.RunActiveValidations" where
+  @JavaName run
+  runActiveValidations :: ProgressMonitor -> Resource -> <Proc> ()
\ No newline at end of file
index 30a482ffc6d068cfcbc45bdd93dba4490a081c52..6a1ed98425149af507f17e6ab3360df7e40d35b1 100644 (file)
@@ -1,6 +1,7 @@
 include "Simantics/DB"
 
 include "http://www.simantics.org/Layer0-1.1" as L0
+include "http://www.simantics.org/Layer0X-1.1" as L0X
 include "http://www.simantics.org/Structural-1.2" as STR
 include "http://www.simantics.org/Diagram-2.2" as DIA
 include "http://www.simantics.org/Modeling-1.2" as MOD
@@ -10,4 +11,5 @@ include "http://www.simantics.org/Spreadsheet-1.2" as SHEET
 include "http://www.simantics.org/Image2-1.2" as IMAGE
 include "http://www.simantics.org/Document-1.2" as DOCUMENT
 include "http://www.simantics.org/Event-1.2" as EVENT
-include "http://www.simantics.org/Project-1.2" as PROJECT
\ No newline at end of file
+include "http://www.simantics.org/Project-1.2" as PROJECT
+include "http://www.simantics.org/Issue-1.2" as ISSUE
index cb048e037ff672cb87841f22bd53adab9316866f..e7667ed877a59ab1bb841341a44f3c1039e110ab 100644 (file)
@@ -11,7 +11,7 @@ importJava "org.simantics.modeling.Rename" where
     Example:
     
         > renameNode resource "NewName"
-        "Succesfully renamed oldName to NewName"
+        "Successfully renamed oldName to NewName"
         
     or error if failed
     """
@@ -26,7 +26,7 @@ Renames the given `entity` with the given `newName` and returns
 Example:
 
     > renameMBNode entity "NewName"
-    "Succesfully renamed oldName to NewName"
+    "Successfully renamed oldName to NewName"
     
 or error if failed
 """
index 5d8543d213131cab85739580703ef6bad121a411..0c5007ba5167a868bb469062f26e2a91781c120b 100644 (file)
@@ -29,7 +29,7 @@ public class Rename {
        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
        graph.addMetadata(cm.add("Renamed node " + nodeName + ", resource  " + node +  ", to " + newName));
        
-               return "Succesfully renamed "+ nodeName + " to " + newName;
+               return "Successfully renamed "+ nodeName + " to " + newName;
     }
     
 }
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLCheckedStateRule.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLCheckedStateRule.java
new file mode 100644 (file)
index 0000000..0c7da8d
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * 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.modeling.adapters;
+
+import org.simantics.browsing.ui.CheckedState;
+import org.simantics.browsing.ui.model.check.CheckedStateRule;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.VariableOrResource;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLCheckedStateRule implements CheckedStateRule {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLCheckedStateRule.class);
+
+    private Resource rule;
+
+    public SCLCheckedStateRule(ReadGraph graph, Resource rule) {
+        this.rule = rule;
+    }
+
+    @Override
+    public boolean isCompatible(Class<?> contentType) {
+        return contentType.equals(Resource.class) || contentType.equals(Variable.class);
+    }
+
+    @Override
+    public CheckedState getCheckedState(ReadGraph graph, Object content) throws DatabaseException {
+
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+
+        Variable ruleVariable = Variables.getVariable(graph, rule);
+
+        Function1<Object,CheckedState> getLabels = ruleVariable.getPossiblePropertyValue(graph, MOD.SCLCheckedStateRule_getState);
+        if(getLabels == null) {
+            LOGGER.warn("Didn't find value for subject={}, predicate={}.", rule, ModelingResources.URIs.SCLCheckedStateRule_getState);
+            return CheckedState.NOT_CHECKED;
+        }
+
+        SCLContext sclContext = SCLContext.getCurrent();
+        Object oldGraph = sclContext.get("graph");
+        try {
+            sclContext.put("graph", graph);
+            return getLabels.apply(VariableOrResource.make(content));
+        } catch (Throwable t) {
+            LOGGER.error("Calculating checked state failed.", t);
+            throw new DatabaseException(t);
+        } finally {
+            sclContext.put("graph", oldGraph);
+        }
+
+    }
+
+}
index a04b9315f544d698913c655ce084e485ec05224a..1ea88caf4377bb7cb66b31e8b55b8eeafec32ac9 100644 (file)
@@ -41,7 +41,7 @@ public class SCLChildRule implements ChildRule {
         
         Variable ruleVariable = Variables.getVariable(graph, rule);
 
-        Function1<Resource,List<Resource>> getChildren = ruleVariable.getPossiblePropertyValue(graph, MOD.SCLChildRule_getChildren);
+        Function1<Object,List<Resource>> getChildren = ruleVariable.getPossiblePropertyValue(graph, MOD.SCLChildRule_getChildren);
         if(getChildren == null) return Collections.emptyList();
 
         SCLContext sclContext = SCLContext.getCurrent();
index 1f302a64db4c2b7262339366bdb438123e7b3d11..92dbe16a65e9b383c7a923d572d3f9bd6d26d92d 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.modeling.svg;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 import org.simantics.databoard.Bindings;
 import org.simantics.db.Resource;
@@ -35,7 +36,7 @@ public class CreateSVGElement {
             g.claimValue(transform, new double[] {1.0, 0.0, 0.0, 1.0, mposX, mposY}, Bindings.DOUBLE_ARRAY);
             element = GraphUtils.create(g,
                     L0.InstanceOf, DIA.SVGElement,
-                    G2D.HasSVGDocument, new String(data),
+                    G2D.HasSVGDocument, new String(data, StandardCharsets.UTF_8),
                     DIA.HasTransform, transform);
             AddElement.claimFreshElementName(g, diagram, element);
         } else if ("png".equals(suffix)) {
index 3aaaed2f668aa308727dc4947ef2993d0854ee27..1e8ad54e13d4b8396d0f37626eb7b488322c0428 100644 (file)
@@ -18,7 +18,8 @@ Require-Bundle: org.simantics.layer0,
  org.simantics.modeling.template2d.ontology;bundle-version="1.0.0",
  org.simantics.spreadsheet.ontology;bundle-version="1.2.0",
  org.simantics.selectionview.ui.ontology;bundle-version="1.1.0",
- org.simantics.diagram.ontology;bundle-version="2.2.0"
+ org.simantics.diagram.ontology;bundle-version="2.2.0",
+ org.simantics.issues.ontology;bundle-version="1.2.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.simantics.platform.ui
 Automatic-Module-Name: org.simantics.platform.ui.ontology
index cda1dacf966eb0b731d8df17785754decdbc2b0d..0a96411a7e286c5cfcbdf337444a7d29929746a3 100644 (file)
@@ -2,5 +2,6 @@ source.. = src/
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
-               graph.tg
+               graph.tg,\
+               scl/
 src.includes = graph/
index 11b07f80eba5ab9520a20a9582a9f3d0d47fb0af..78f9204cf4b1070b838c1ca1f19941d6b6fb0e29 100644 (file)
@@ -1,3 +1,15 @@
+/*******************************************************************************
+ * 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - reorganization
+ *******************************************************************************/
 L0 = <http://www.simantics.org/Layer0-1.1>
 PROJECT = <http://www.simantics.org/Project-1.2>
 MOD = <http://www.simantics.org/Modeling-1.2>
@@ -17,8 +29,7 @@ PlatformUI = <http://www.simantics.org/PlatformUI-1.0> : L0.Ontology
     L0.IsLinkedTo MOD
     
 PlatformUI.SCLMain : L0.SCLModule
-    L0.SCLModule.definition _ : L0.String
-      @L0.loadString "scl/SCLMain.scl"
+    L0.SCLModule.definition """ include "Simantics/PlatformUI" """
     
 PlatformUI.NameLabelMode <T L0.String
     @L0.tag L0.Enumeration
diff --git a/bundles/org.simantics.platform.ui.ontology/graph/ValidationView.pgraph b/bundles/org.simantics.platform.ui.ontology/graph/ValidationView.pgraph
new file mode 100644 (file)
index 0000000..31aeb3c
--- /dev/null
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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 = <http://www.simantics.org/Layer0-1.1>
+DOC = <http://www.simantics.org/Documentation-1.2>
+SWT = <http://www.simantics.org/SWT-1.0>
+STR = <http://www.simantics.org/Structural-1.2>
+SEL = <http://www.simantics.org/SelectionView-1.2>
+COMPONENTS = <http://www.simantics.org/SWT-1.0/Components>
+VIEWS = <http://www.simantics.org/PlatformUI-1.0/Views>
+VP = <http://www.simantics.org/Viewpoint-1.2>
+MOD = <http://www.simantics.org/Modeling-1.2>
+PROJECT = <http://www.simantics.org/Project-1.2>
+ISSUE = <http://www.simantics.org/Issue-1.2>
+
+VIEWS.ValidationContribution : SWT.TypedVariableTabContribution
+    SEL.AbstractVariableTabContribution.HasPriority 1
+    SEL.AbstractTypedVariableTabContribution.HasType L0.IndexRoot
+    SWT.TypedVariableTabContribution.HasView VIEWS.Validations
+    L0.HasLabel "Validation"
+
+VIEW = VIEWS.Validations : DOC.Document
+VIEW.Root : DOC.Components.Root
+  @DOC.child1_
+    VIEW.Panel
+      @SWT.scrolledComposite
+      @DOC.child2_ VIEW.Explorer
+      @DOC.child1_
+        VIEW.Panel2
+          @SWT.gridComposite 2
+          @DOC.child1_
+            VIEW.Cell1
+              @SWT.gridCell _ false false 1
+                VIEW.ConfigureButton
+                  @SWT.button "Configure"
+                  @VIEWS.sclEvent COMPONENTS.Button.onPress "configureButtonClick self"
+          @DOC.child2_
+            VIEW.Cell2
+              @SWT.gridCell _ false false 1
+                VIEW.ValidateButton
+                  @SWT.button "Validate"
+                  @VIEWS.sclEvent COMPONENTS.Button.onPress "validateButtonClick self"
+
+VIEW.Columns = { columns = [
+          {key = "single", label = "Issue sources", tooltip = "Issue sources", width = 80, weight = 1, alignment = "LEFT", grab = true}
+          ]} : SWT.Literals.Columns
+
+VIEW.Explorer
+  COMPONENTS.Component.Check true
+  @SWT.explorer true true
+    "http://www.simantics.org/PlatformUI-1.0/Views/Validations/BrowseContext"
+    "#ValidationSelection"
+    VIEW.Columns
+  @VIEWS.sclEvent COMPONENTS.Explorer.onCheck "issueSourceExplorerCheck self"
+
+MBC = MOD.ModelingBrowseContext
+
+VIEWS.Validations.BrowseContext : VP.BrowseContext
+    VP.BrowseContext.Includes PROJECT.ProjectBrowseContext
+    VP.BrowseContext.HasVisualsContribution PROJECT.Contributions.StandardNameLabelRule
+    VP.BrowseContext.HasChildContribution VIEWS.Validations.BrowseContext.Children : VP.ChildContribution
+        VP.ChildContribution.HasParentNodeType MBC.Variable
+        VP.ChildContribution.HasChildNodeType ISSUE.IssueSource
+        VP.ChildContribution.HasRule VIEWS.Validations.BrowseContext.Children.Rule : MOD.SCLChildRule
+            @MOD.scl MOD.SCLChildRule.getChildren "usedIssueSources" "Resource -> <ReadGraph> [Resource]"
+    VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution
+        VP.VisualsContribution.HasNodeType ISSUE.IssueSource
+        VP.VisualsContribution.HasPriority 1.0
+        VP.VisualsContribution.HasRule VIEWS.Validations.BrowseContext.Checked
+          @MOD.sclCheckedStateRule "checkedStateRule"
similarity index 54%
rename from bundles/org.simantics.platform.ui.ontology/graph/scl/SCLMain.scl
rename to bundles/org.simantics.platform.ui.ontology/scl/Simantics/PlatformUI.scl
index 44c53d80e4cfa35e9320f51ae3b93227eac94dbe..07309cb7b2876ea7a233439edea2e57d00e5c0d9 100644 (file)
@@ -1,5 +1,19 @@
+/*******************************************************************************
+ * 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - reorganization
+ *******************************************************************************/
 include "Simantics/All"
 include "SWT/All"
+import "UI/Progress"
+import "Simantics/IssueUI"
 
 useSelectedHandler :: Variable -> (String -> Maybe String) -> <WriteGraph> String
 useSelectedHandler input parameters = do
@@ -84,4 +98,48 @@ standardPropertiesElementTransformation var = do
           Nothing -> var
           Just component -> resourceVariable component
       else var
-  
\ No newline at end of file
+
+configureButtonClickHandler :: Resource -> CommandContext -> <Proc> Maybe CommandResult
+configureButtonClickHandler indexRoot context = do
+    showIssueConfigurationDialog indexRoot 
+    Nothing
+      
+configureButtonClick :: Variable -> <ReadGraph,Proc> AbstractEventHandler
+configureButtonClick self = do
+  indexRoot = represents $ contextVariable self
+  eventHandler2 $ configureButtonClickHandler indexRoot
+
+validateButtonClickHandler :: Resource -> CommandContext -> <Proc> Maybe CommandResult
+validateButtonClickHandler indexRoot context = do
+    runActiveValidations (createNullProgressMonitor ()) indexRoot
+    Nothing
+
+validateButtonClick :: Variable -> <ReadGraph,Proc> AbstractEventHandler
+validateButtonClick self = do
+  indexRoot = represents $ contextVariable self
+  eventHandler2 $ validateButtonClickHandler indexRoot
+
+issueSourceExplorerCheckHandler :: Resource -> CommandContext -> <Proc> Maybe CommandResult
+issueSourceExplorerCheckHandler indexRoot context = match possibleValue context "item" with
+  Nothing -> Nothing
+  Just issueSource -> match possibleValue context "checked" with
+    Nothing -> Nothing
+    Just value -> if value then do
+        syncWrite $ \_ -> claim issueSource ISSUE.IssueSource.Selected (parent issueSource)
+        Nothing
+      else do
+        syncWrite $ \_ -> denyByPredicate issueSource ISSUE.IssueSource.Selected
+        Nothing  
+
+issueSourceExplorerCheck :: Variable -> <ReadGraph,Proc> AbstractEventHandler
+issueSourceExplorerCheck self = do
+  indexRoot = represents $ contextVariable self
+  eventHandler2 $ issueSourceExplorerCheckHandler indexRoot
+
+usedIssueSources :: Resource -> <ReadGraph> [Resource]
+usedIssueSources indexRoot = do
+   objectsWithType indexRoot L0.ConsistsOf ISSUE.IssueSource
+
+checkedStateRule :: BrowseNodeRule CheckedState
+checkedStateRule (ResourceX r) = if existsStatement3 r ISSUE.IssueSource.Selected (parent r) then CHECKED else NOT_CHECKED
+      
\ No newline at end of file
index 436e0a17357f32072ec80c2cea18f8f97d3bb734..47bf1a944cb92cdf824cce774e4fc6b385791f17 100644 (file)
@@ -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
+ *******************************************************************************/
 include "Simantics/Model"
 include "Simantics/DB"
 import "Simantics/DB" as DB
@@ -437,4 +448,15 @@ importJava "org.simantics.db.layer0.variable.RVI" where
 instantiateUnder :: Resource -> Resource -> <WriteGraph> Resource
 instantiateUnder container typeToInstantiate = do
     fn = (resourceVariable typeToInstantiate)#methods#instantiateUnder :: Resource -> Resource -> <WriteGraph> Resource  
-    fn container typeToInstantiate
\ No newline at end of file
+    fn container typeToInstantiate
+
+@JavaType "org.simantics.db.layer0.variable.VariableOrResource"
+data VariableOrResource =
+    @JavaType "org.simantics.db.layer0.variable.ResourceX"
+    @FieldNames [value]
+    ResourceX Resource
+  | @JavaType "org.simantics.db.layer0.variable.VariableX"
+    @FieldNames [value]
+    VariableX Variable
+    
+    
\ No newline at end of file
index e20dfc471ad9ea28831463f00bc9bfc220d8704a..d8f83e05f5b2f231bc5dcd14bf27bf93ff85ffdc 100644 (file)
@@ -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.scl.db;
 
 import java.io.IOException;
@@ -152,6 +163,18 @@ public class SCLFunctions {
         }
     }
 
+    public static void runWithGraph(Object graph, Runnable r) {
+        final SCLContext context = SCLContext.getCurrent();
+        SCLContext.push(context);
+        Object oldGraph = context.put(GRAPH, graph);
+        try {
+            r.run();
+        } finally {
+            context.put(GRAPH, oldGraph);
+            SCLContext.pop();
+        }
+    }
+
     private static Object[] NO_ARGS = new Object[] { Tuple0.INSTANCE };
 
     public static <T> void asyncRead(final Function f) throws DatabaseException {    
index f983251093272d2168cb9eacc05db4542660afa0..86d13fb6628e77401b7a7fd0be2866834216ffca 100644 (file)
@@ -75,7 +75,7 @@ infixl 6  (+), (-)
 infixl 5  (\\), (<<), (<+)
 infix  4  (!=), (<), (<=), (>=), (>)
 infixr 3  (&&), (&<&)
-infixr 2  (||), orElse, morelse
+infixr 2  (||), orElse, orElseM, morelse
 infixr 1  (>>=), (>>), (:=), (>=>)
 infixr 1  ($)
 infixl 1  catch