]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/userComponent/ComponentTypeCommands.java
Support enumerated property types in UC interface (2nd try)
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / userComponent / ComponentTypeCommands.java
index 74ae599e3797f6a06d9c07f2c9ed6bc7d4789843..9cf93fac5ce83d9067b99d7ebbb7e0da6a272f63 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);
                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,72 @@ 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;
+                        }
+                    }
+                } else {
+                       return;
+                }
+            }
+        }
+
         Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);
         if (tuple == null)
             return;
 
-        Layer0 L0 = Layer0.getInstance(g);
+        if(g.sync(new IsEnumeratedValue(object))) {
+            Resource assertion = findAssertionWithPO(g, type, relation, object);
+            object = g.newResource();
+            g.claim(object, L0.InstanceOf, L0.Literal);
+            if(assertion != null) {
+                g.deny(assertion, L0.HasObject);
+                g.claim(assertion, L0.HasObject, object);
+            }
+        }
+
         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)) {
 
+            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);