]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Support enumerated property types in UC interface 94/3094/4
authorJussi Koskela <jussi.koskela@semantum.fi>
Tue, 13 Aug 2019 05:55:06 +0000 (08:55 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 21 Aug 2019 20:27:14 +0000 (20:27 +0000)
Other improvements:
-Support labels in enumeration values
-Sort enum values in edit combo alphanumerically (was hash order)

Bugs fixed:
-Instantiated values for IC properties were not converted properly on
type edit if the UC was defined in linked index root

gitlab #339

Change-Id: I7d73a7465adb0ff13b3245ac332a37bff9095810

bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/EnumerationVariableModifier3.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/GetEnumerationValue.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewer.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java
bundles/org.simantics.modeling/src/org/simantics/modeling/userComponent/ComponentTypeCommands.java
bundles/org.simantics.selectionview/src/org/simantics/selectionview/function/All.java

index 32bd28c17f789f1658a271a5e064807c4932f833..3bd3e7b91217ef5233388158c88f86e8bb24abdc 100644 (file)
@@ -13,10 +13,12 @@ package org.simantics.browsing.ui.graph.impl;
 
 import java.util.List;
 
+import org.simantics.browsing.ui.common.modifiers.EnumerationValue;
 import org.simantics.browsing.ui.content.Labeler.EnumerationModifier;
 import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.VirtualGraph;
 import org.simantics.db.WriteGraph;
@@ -53,6 +55,10 @@ public class EnumerationVariableModifier3 implements EnumerationModifier {
            return processor.syncRequest(new Read<String>() {
                 @Override
                 public String perform(ReadGraph graph) throws DatabaseException {
+                    EnumerationValue<Resource> ev = graph.syncRequest(new GetEnumerationValue(variable.getParent(graph).getRepresents(graph)));
+                    if(ev != null) {
+                           return ev.getEnumeratedValue().getName();
+                    }
           //           System.err.println(variable.getURI(graph));
                        return variable.getValue(graph);//variable.getPossiblePropertyValue(graph, Variables.LABEL);
                 }
index c246e7bd9091f5142014ccc37acf53d8250e0372..9e8adfebea1fa65805c66078c0794e14a49ffec1 100644 (file)
@@ -41,6 +41,14 @@ public class GetEnumerationValue extends ResourceRead<EnumerationValue<Resource>
     public EnumerationValue<Resource> perform(ReadGraph graph) throws DatabaseException {
         return enumerate(graph, resource);
     }
+    
+    public static String getEnumerationValueName(ReadGraph graph, Resource resource) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        String label = graph.getPossibleRelatedValue(resource, L0.HasLabel, Bindings.STRING);
+        if(label != null)
+            return label;
+        return safeName(graph, resource);
+    }
 
     public static EnumerationValue<Resource> enumerate(ReadGraph graph, Resource resource) throws DatabaseException {
         Layer0 l0 = Layer0.getInstance(graph);
@@ -61,7 +69,7 @@ public class GetEnumerationValue extends ResourceRead<EnumerationValue<Resource>
                     Collection<Resource> values = graph.getObjects(type, l0.ConsistsOf);
                     List<EnumeratedValue<Resource>> result = new ArrayList<EnumeratedValue<Resource>>(values.size());
                     for (Resource value : values) {
-                        result.add(new EnumeratedValue<Resource>(safeName(graph, value), value));
+                        result.add(new EnumeratedValue<Resource>(getEnumerationValueName(graph, value), value));
                     }
                     Enumeration<Resource> enumeration = new Enumeration<Resource>(result);
                     return new EnumerationValue<Resource>(enumeration, enumeration.find(resource));
index 75c60d24cd28d27190c382fba285def14f1f46a6..ef63fabe09dc52db6ce5cad752b352c09247d3c6 100644 (file)
@@ -34,6 +34,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.simantics.Simantics;
+import org.simantics.browsing.ui.graph.impl.GetEnumerationValue;
 import org.simantics.databoard.Bindings;
 import org.simantics.databoard.binding.Binding;
 import org.simantics.databoard.binding.error.BindingException;
@@ -42,6 +43,7 @@ import org.simantics.databoard.type.NumberType;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.IsEnumeratedValue;
 import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
@@ -198,10 +200,12 @@ public class ComponentTypeViewer {
                         
                         for(Resource assertion : graph.getAssertedObjects(data.componentType, relation)) {
                             try {
-                                expression = graph.getPossibleRelatedValue(assertion, L0.SCLValue_expression, Bindings.STRING);
+                               expression = graph.getPossibleRelatedValue(assertion, L0.SCLValue_expression, Bindings.STRING);
                                 if(expression != null) {
                                        defaultValue = "=" + expression; //$NON-NLS-1$
-                                } else {
+                                } else if (graph.sync(new IsEnumeratedValue(assertion))) {
+                                   defaultValue = GetEnumerationValue.getEnumerationValueName(graph, assertion);
+                               } else {
                                        Datatype dt = getPossibleDatatype(graph, assertion);
                                        if (dt == null)
                                            continue;
index ea10d6d8d4e44d700cf6cc789b97ca49ed9e6e6c..820d45f2e1ecf9365a65aa3895771b68519ee8ee 100644 (file)
@@ -1,8 +1,11 @@
 package org.simantics.modeling.ui.componentTypeEditor;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
@@ -33,18 +36,24 @@ import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.forms.widgets.Form;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
 import org.simantics.databoard.type.NumberType;
 import org.simantics.databoard.units.internal.library.UnitLibrary;
 import org.simantics.databoard.util.Limit;
 import org.simantics.databoard.util.Range;
 import org.simantics.databoard.util.RangeException;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
+import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.IndexRoot;
+import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.function.DbConsumer;
+import org.simantics.db.layer0.QueryIndexUtils;
 import org.simantics.layer0.Layer0;
 import org.simantics.modeling.userComponent.ComponentTypeCommands;
 import org.simantics.scl.runtime.function.Function2;
@@ -216,6 +225,26 @@ public class ComponentTypeViewerData {
         editor.setEditor(text, selectedItem, column);
     }
 
+    private static class TypeDefinitionMapRequest extends ResourceRead<Map<String,Resource>> {
+        public TypeDefinitionMapRequest(Resource resource) {
+            super(resource);
+        }
+
+        @Override
+        public Map<String,Resource> perform(ReadGraph graph) throws DatabaseException {
+            Layer0 L0 = Layer0.getInstance(graph);
+            Map<String,Resource> result = new HashMap<>();
+            for(Resource valueType : QueryIndexUtils.searchByType(graph, resource, L0.ValueType)) {
+                Collection<Statement> stms = graph.getAssertedStatements(valueType, L0.HasValueType);
+                if(stms.size() == 1) {
+                    String sclValueType = graph.getValue(stms.iterator().next().getObject(), Bindings.STRING);
+                    result.put(sclValueType, valueType);
+                }
+            }
+            return result;
+        }
+    }
+
     public void editType(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column, String range, final boolean convertDefaultValue) {
         int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;
         final Combo combo = new Combo(table, SWT.NONE | extraStyle);
@@ -246,12 +275,18 @@ public class ComponentTypeViewerData {
                 if (propertyInfo.immutable)
                     return;
 
+                
                 Simantics.getSession().async(new WriteRequest() {
                     @Override
                     public void perform(WriteGraph graph)
                             throws DatabaseException {
                         graph.markUndoPoint();
-                        ComponentTypeCommands.editType(graph, componentType, propertyInfo.resource, convertDefaultValue, newValue);
+
+                        Resource root = graph.syncRequest(new IndexRoot(componentType));
+                        Map<String,Resource> typeDefinitionMap = graph.syncRequest(new TypeDefinitionMapRequest(root));
+                        Resource possibleGraphType = typeDefinitionMap.get(newValue);
+
+                        ComponentTypeCommands.editType(graph, componentType, propertyInfo.resource, convertDefaultValue, newValue, possibleGraphType);
                         if (range != null) ComponentTypeCommands.setRange(graph, componentType, propertyInfo.resource, range);
                     }
                 });
index 74ae599e3797f6a06d9c07f2c9ed6bc7d4789843..c92d80c848cec727999d467fefa167ee792fd3a5 100644 (file)
@@ -11,6 +11,7 @@
  *******************************************************************************/
 package org.simantics.modeling.userComponent;
 
+import java.util.Collections;
 import java.util.Map;
 
 import org.simantics.databoard.Bindings;
@@ -27,11 +28,13 @@ import org.simantics.db.Resource;
 import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.CommentMetadata;
+import org.simantics.db.common.request.EnumerationMap;
+import org.simantics.db.common.request.IsEnumeratedValue;
 import org.simantics.db.common.request.UnaryRead;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ServiceException;
-import org.simantics.db.layer0.request.ModelInstances;
+import org.simantics.db.layer0.QueryIndexUtils;
 import org.simantics.db.layer0.util.Layer0Utils;
 import org.simantics.layer0.Layer0;
 import org.simantics.modeling.ModelingResources;
@@ -42,6 +45,7 @@ import org.simantics.scl.runtime.tuple.Tuple3;
 import org.simantics.selectionview.SelectionViewResources;
 import org.simantics.structural.stubs.StructuralResource2;
 import org.simantics.structural2.utils.StructuralUtils;
+import org.simantics.utils.strings.AlphanumComparator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -199,6 +203,11 @@ public class ComponentTypeCommands {
 
     public static void setRequiredType(WriteGraph g, Resource componentType, Resource property,
             String requiredType) throws DatabaseException {
+        setRequiredType(g, componentType, property, requiredType, null);
+    }
+
+    public static void setRequiredType(WriteGraph g, Resource componentType, Resource property,
+            String requiredType, Resource possibleType) throws DatabaseException {
         Layer0 L0 = Layer0.getInstance(g);
         g.claimLiteral(property, L0.RequiresValueType, requiredType);
 
@@ -211,17 +220,34 @@ public class ComponentTypeCommands {
             }
         }
 
+        // We assert the range of the property only if we are given a dedicated graph value type
+        if(g.hasStatement(property, L0.HasRange))
+            g.deny(property, L0.HasRange);
+        
+        if(possibleType != null) {
+            // We have a dedicated graph type for this SCL value type
+            if(g.hasStatement(possibleType, L0.Enumeration)) {
+                // This value type is an enumeration - let's constrain the range of this predicate to match the enumeration type only
+                g.claim(property, L0.HasRange, possibleType);
+            }
+        }
+
         CommentMetadata cm = g.getMetadata(CommentMetadata.class);
         g.addMetadata(cm.add("Set required type "+ requiredType + " for component/annotation " + property));
     }
     
     public static void editType(WriteGraph graph, Resource componentType, Resource property, boolean convertDefaultValue, String newValue) throws DatabaseException {
-        ComponentTypeCommands.setRequiredType(graph, componentType, property, newValue);
+        editType(graph, componentType, property, convertDefaultValue, newValue, null);
+    }
+
+    public static void editType(WriteGraph graph, Resource componentType, Resource property, boolean convertDefaultValue, String newValue, Resource possibleType) throws DatabaseException {
+        ComponentTypeCommands.setRequiredType(graph, componentType, property, newValue, possibleType);
         if (convertDefaultValue) {
-            ComponentTypeCommands.convertDefaultValue(graph, componentType, property, newValue);
-            Map<String, Resource> instances = graph.sync(new ModelInstances(componentType, componentType));
-            for(Resource instance : instances.values()) {
-                ComponentTypeCommands.convertInstantiatedValue(graph, instance, property, newValue);
+            ComponentTypeCommands.convertDefaultValue(graph, componentType, property, newValue, possibleType);
+            for (Resource indexRoot : Layer0Utils.listIndexRoots(graph)) {
+                for(Resource instance : QueryIndexUtils.searchByTypeShallow(graph, indexRoot, componentType)) {
+                    ComponentTypeCommands.convertInstantiatedValue(graph, instance, property, newValue, componentType);
+                }
             }
         }
     }
@@ -270,11 +296,29 @@ public class ComponentTypeCommands {
                     " in " + NameUtils.getSafeName(g, type) + ".");
             return;
         }
+
+       Layer0 L0 = Layer0.getInstance(g);
+       Resource range = g.getPossibleObject(relation, L0.HasRange);
+       if (range != null) {
+            if(g.hasStatement(range, L0.Enumeration)) {
+                   Map<String,Resource> values = g.syncRequest(new EnumerationMap(range));
+                   Resource value = values.get(valueText);
+                   if (value != null) {
+                       for(Resource assertion : g.getObjects(type, L0.Asserts)) {
+                           Resource p = g.getSingleObject(assertion, L0.HasPredicate);
+                           if (p.equals(relation)) {
+                               g.deny(assertion, L0.HasObject, object);
+                               g.claim(assertion, L0.HasObject, value);
+                           }
+                       }
+                   }
+                   return;
+            }
+        }
         
         if(valueText.length() > 0 && valueText.charAt(0) == '=') {
                
-               String expression = valueText.substring(1);
-               Layer0 L0 = Layer0.getInstance(g);
+            String expression = valueText.substring(1);
                ModelingResources MOD = ModelingResources.getInstance(g);
                if(!g.isInstanceOf(object, MOD.SCLValue)) {
                        Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);
@@ -288,7 +332,6 @@ public class ComponentTypeCommands {
             
         } else {
                
-               Layer0 L0 = Layer0.getInstance(g);
                ModelingResources MOD = ModelingResources.getInstance(g);
                if(g.isInstanceOf(object, MOD.SCLValue)) {
                        Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);
@@ -421,6 +464,22 @@ public class ComponentTypeCommands {
 
     public static void convertDefaultValue(WriteGraph g,
             Resource type, Resource relation, String newSCLType) throws DatabaseException {
+        convertDefaultValue(g, type, relation, newSCLType, null);
+    }
+
+    private static Resource findAssertionWithPO(ReadGraph graph, Resource possibleType, Resource predicate, Resource object) throws DatabaseException {
+           Layer0 L0 = Layer0.getInstance(graph);
+        for(Resource assertion : graph.getObjects(possibleType, L0.Asserts)) {
+            Resource p = graph.getSingleObject(assertion, L0.HasPredicate);
+            Resource o = graph.getSingleObject(assertion, L0.HasObject);
+            if(predicate.equals(p) && object.equals(o))
+                return assertion;
+        }
+        return null;
+    }
+    
+    public static void convertDefaultValue(WriteGraph g,
+            Resource type, Resource relation, String newSCLType, Resource possibleType) throws DatabaseException {
         Resource object = getAssertedObject(g, type, relation);
         if(object == null) {
             LOGGER.warn("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + 
@@ -428,27 +487,60 @@ public class ComponentTypeCommands {
             return;
         }
 
+        Layer0 L0 = Layer0.getInstance(g);
+        if(possibleType != null) {
+            if(g.hasStatement(possibleType, L0.Enumeration)) {
+                if(!g.isInstanceOf(object, possibleType)) {
+                    Map<String, Resource> enumMap = g.syncRequest(new EnumerationMap(possibleType));
+                    String firstKey = Collections.min(enumMap.keySet(), AlphanumComparator.COMPARATOR);
+                    Resource defaultValue = enumMap.get(firstKey);
+                    
+                    if (defaultValue != null) {
+                        Resource assertion = findAssertionWithPO(g, type, relation, object);
+                        if(assertion != null) {
+                            g.deny(assertion, L0.HasObject);
+                            g.claim(assertion, L0.HasObject, defaultValue);
+                            return;
+                        } else {
+                            Layer0Utils.assert_(g, type, relation, defaultValue);
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+
         Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);
         if (tuple == null)
             return;
 
-        Layer0 L0 = Layer0.getInstance(g);
         g.claimLiteral(object, L0.HasDataType, L0.DataType, tuple.get(0), Bindings.getBindingUnchecked(Datatype.class));
         g.claimLiteral(object, L0.HasValueType, g.<String>getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING), Bindings.STRING);
         g.claimValue(object, tuple.get(1), (Binding)tuple.get(2));
 
     }
 
-    public static void convertInstantiatedValue(WriteGraph g, Resource instance, Resource relation, String newSCLType)
+    public static void convertInstantiatedValue(WriteGraph g, Resource instance, Resource relation, String newSCLType) throws DatabaseException {
+       convertInstantiatedValue(g, instance, relation, newSCLType, null);
+    }
+    
+    public static void convertInstantiatedValue(WriteGraph g, Resource instance, Resource relation, String newSCLType, Resource possibleType)
             throws DatabaseException {
 
         Statement stm = g.getPossibleStatement(instance, relation);
         if(stm != null && !stm.isAsserted(instance)) {
 
-            Resource object = stm.getObject();
+            Layer0 L0 = Layer0.getInstance(g);
+               Resource object = stm.getObject();
+
+               if(g.sync(new IsEnumeratedValue(object))) {
+                       if(!g.isInstanceOf(object, possibleType)) {
+                               g.deny(instance, relation);
+                       }
+                       return;
+               }
 
             // We can only convert literals
-            Layer0 L0 = Layer0.getInstance(g);
             if(!g.isInstanceOf(object, L0.Literal)) return;
 
             Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);
index 79541b06134deb344a5f6f71c4dda854edcfc145..233a1e5a11608fd20088deeb0a82f9c6d31d422d 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.selectionview.function;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Map;
 import java.util.function.Consumer;
 
@@ -12,7 +13,9 @@ import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.FontDialog;
 import org.simantics.Simantics;
 import org.simantics.browsing.ui.NodeContext;
+import org.simantics.browsing.ui.common.modifiers.EnumerationValue;
 import org.simantics.browsing.ui.content.Labeler.DialogModifier;
+import org.simantics.browsing.ui.graph.impl.GetEnumerationValue;
 import org.simantics.common.format.Formatter;
 import org.simantics.databoard.Bindings;
 import org.simantics.databoard.Datatypes;
@@ -62,6 +65,7 @@ import org.simantics.ui.fonts.Fonts;
 import org.simantics.ui.selection.WorkbenchSelectionElement;
 import org.simantics.ui.selection.WorkbenchSelectionUtils;
 import org.simantics.utils.datastructures.collections.CollectionUtils;
+import org.simantics.utils.strings.AlphanumComparator;
 import org.simantics.utils.ui.AdaptionUtils;
 import org.simantics.utils.ui.ErrorLogger;
 import org.simantics.utils.ui.ISelectionUtils;
@@ -198,7 +202,9 @@ public class All {
                        Resource parameterResource = parameter.getRepresents(graph);
                        if(graph.sync(new IsEnumeratedValue(parameterResource))) {
                                Map<String, Resource> map = graph.sync(new InstanceEnumerationMap(parameterResource));
-                               return new ArrayList<String>(map.keySet());
+                               ArrayList<String> values = new ArrayList<>(map.keySet());
+                               Collections.sort(values, AlphanumComparator.COMPARATOR);
+                               return values;
                        } else if(graph.isInstanceOf(parameterResource, L0.Boolean)) {
                                return CollectionUtils.toList("true", "false");
                        }
@@ -463,6 +469,14 @@ public class All {
                                        value = formatterFunction.apply(property.getValue(graph));
                                }
                        }
+
+                       Resource possibleValue = context.getParent(graph).getPossibleRepresents(graph);
+                       if(possibleValue != null) {
+                               if(graph.syncRequest(new IsEnumeratedValue(possibleValue))) {
+                       return GetEnumerationValue.getEnumerationValueName(graph, possibleValue);
+                               }
+                       }
+
                        if(value == null) {
 
                                Variant variant = property.getVariantValue(graph);
@@ -518,8 +532,14 @@ public class All {
                                String parsedLabel = (String)_value;
                                Object value = parsedLabel;
 
+                               boolean isEnumeration = false;
+                               Resource possibleValue = context.getParent(graph).getPossibleRepresents(graph);
+                               if(possibleValue != null) {
+                                       isEnumeration = graph.syncRequest(new IsEnumeratedValue(possibleValue));
+                               }
+
                                Datatype type = context.getParent(graph).getPossibleDatatype(graph);
-                               if (type != null) {
+                               if (type != null && !isEnumeration) {
 
                                        Binding binding = Bindings.getBinding(type);