Fixed ComponentTypeCommands.setUnit to support unit == null
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / userComponent / ComponentTypeCommands.java
index fdd2649b0f925210b6a18f50973554365430155a..74ae599e3797f6a06d9c07f2c9ed6bc7d4789843 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.modeling.userComponent;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-import java.util.Map;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.adapter.AdaptException;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.parser.repository.DataTypeSyntaxError;\r
-import org.simantics.databoard.parser.repository.DataValueRepository;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.type.NumberType;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.CommentMetadata;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ServiceException;\r
-import org.simantics.db.layer0.request.ModelInstances;\r
-import org.simantics.db.layer0.util.Layer0Utils;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.modeling.NewSymbol;\r
-import org.simantics.operation.Layer0X;\r
-import org.simantics.scl.runtime.tuple.Tuple;\r
-import org.simantics.scl.runtime.tuple.Tuple3;\r
-import org.simantics.selectionview.SelectionViewResources;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.structural2.utils.StructuralUtils;\r
-\r
-public class ComponentTypeCommands {\r
-\r
-    public static void applyCode(WriteGraph g, Resource componentType, String code) throws DatabaseException {\r
-        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
-        g.claimLiteral(componentType, STR.ProceduralComponentType_code, code, Bindings.STRING);\r
-    }\r
-\r
-    public static Resource createConnectionPoint(WriteGraph g, Resource componentType, Resource cp) throws DatabaseException {\r
-        return StructuralUtils.createConnectionPoint(g, componentType, cp);\r
-    }\r
-\r
-    public static Resource createMonitorPropertyWithDefaults(WriteGraph g, Resource componentType) throws DatabaseException {\r
-\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
-        ModelingResources MOD = ModelingResources.getInstance(g);\r
-\r
-        Resource monitorType = g.getPossibleObject(componentType, STR.ComponentType_HasDefaultMonitorValueType);\r
-        if(monitorType == null) monitorType = MOD.MonitorValue;\r
-\r
-        Resource relation = createPropertyWithDefaultsBase(g, componentType, "newProperty");\r
-        g.claim(relation, L0.HasRange, monitorType);\r
-\r
-        Resource assertion = g.newResource();\r
-        g.claim(componentType, L0.Asserts, assertion);\r
-        g.claim(assertion, L0.InstanceOf, L0.Assertion);\r
-        g.claim(assertion, L0.HasPredicate, relation);\r
-        \r
-        Resource value = g.newResource();\r
-        g.claim(value, L0.InstanceOf, monitorType);\r
-        g.claimLiteral(value, L0.HasValueType, L0.String, "Double", Bindings.STRING);\r
-        g.claimLiteral(value, L0.SCLValue_expression, L0.String, "", Bindings.STRING);\r
-        g.claim(assertion, L0.HasObject, value);\r
-        \r
-        return relation;\r
-        \r
-    }\r
-\r
-    public static Resource createPropertyWithDefaults(WriteGraph g, Resource componentType) throws DatabaseException {\r
-        g.markUndoPoint();\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-\r
-        Resource relation = createPropertyWithDefaultsBase(g, componentType, "newProperty");\r
-\r
-        Resource assertion = g.newResource();\r
-        g.claim(componentType, L0.Asserts, assertion);\r
-        g.claim(assertion, L0.InstanceOf, L0.Assertion);\r
-        g.claim(assertion, L0.HasPredicate, relation);\r
-        \r
-        Resource value = g.newResource();\r
-        g.claim(value, L0.InstanceOf, L0.Literal);\r
-        g.claimLiteral(value, L0.HasDataType, L0.DataType, Datatypes.DOUBLE, Bindings.getBindingUnchecked(Datatype.class));\r
-        g.claimLiteral(value, L0.HasValueType, L0.String, "Double", Bindings.STRING);\r
-        g.claimValue(value, 0.0, Bindings.DOUBLE);\r
-        g.claim(assertion, L0.HasObject, value);\r
-        \r
-        return relation;\r
-        \r
-    }\r
-\r
-    public static Resource createPropertyWithDefaultsBase(WriteGraph g, Resource componentType, String defaultName) throws DatabaseException {\r
-\r
-       Layer0 L0 = Layer0.getInstance(g);\r
-        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
-        ModelingResources MOD = ModelingResources.getInstance(g);\r
-\r
-        String name = NameUtils.findFreshEscapedName(g, defaultName, componentType);\r
-\r
-        Resource relation = g.newResource();\r
-        g.claim(relation, L0.SubrelationOf, null, L0.HasProperty);\r
-        boolean hadProperty = false;\r
-        for(Resource type : g.getObjects(componentType, STR.ComponentType_HasDefaultPropertyRelationType)) {\r
-               if(g.isInheritedFrom(type, STR.Property)) hadProperty = true;\r
-            g.claim(relation, L0.InstanceOf, type);\r
-        }\r
-        if(!hadProperty)\r
-               g.claim(relation, L0.InstanceOf, STR.Property);\r
-        \r
-        g.claimLiteral(relation, L0.HasName, name);\r
-        g.claim(componentType, L0.ConsistsOf, L0.PartOf, relation);\r
-        g.claim(relation, L0.HasDomain, L0.DomainOf, componentType);\r
-\r
-        Resource invRelation = g.newResource();\r
-        g.claim(invRelation, L0.SubrelationOf, null, L0.PropertyOf);\r
-        g.claim(relation, L0.ConsistsOf, L0.PartOf, invRelation);\r
-        g.claimLiteral(invRelation, L0.HasName, "Inverse");\r
-        g.claim(relation, L0.InverseOf, invRelation);\r
-\r
-        g.claimLiteral(relation, L0.RequiresValueType, "Double");\r
-\r
-        SelectionViewResources SEL = SelectionViewResources.getInstance(g);\r
-        Resource category = g.getPossibleObject(relation, SEL.HasStandardPropertyInfo);\r
-        if(category == null) {\r
-               g.claim(relation, SEL.HasStandardPropertyInfo, MOD.UserDefinedPropertyInfo);\r
-        }\r
-        if(!g.isInstanceOf(relation, SEL.GenericParameterType))\r
-               g.claim(relation, L0.InstanceOf, SEL.GenericParameterType);\r
-        \r
-        CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
-        g.addMetadata(cm.add("Created new property " + name + " for " + g.getRelatedValue2(componentType, L0.HasName, Bindings.STRING) + " " + componentType.toString()));\r
-\r
-        return relation;\r
-    }\r
-    \r
-    public static Resource createProperty(WriteGraph graph, Resource componentType, String name, String type, String unit, String range, String label, String description) throws DatabaseException {\r
-       \r
-       Resource property = createPropertyWithDefaults(graph, componentType);\r
-       rename(graph, property, name);\r
-       setRequiredType(graph, componentType, property, type);\r
-       convertDefaultValue(graph, componentType, property, type);\r
-       //setDefaultValue(graph, type, relation, valueText)\r
-       if (!type.equals("String")) {\r
-               setUnit(graph, componentType, property, unit);\r
-               setRange(graph, componentType, property, range);        \r
-       }\r
-       setLabel(graph, property, label);\r
-       setDescription(graph, property, description);\r
-       \r
-       return property;\r
-    }\r
-\r
-    public static void removeProperty(WriteGraph g, Resource componentType, Resource property) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        for(Resource assertion : g.getObjects(property, L0.HasPredicateInverse))\r
-            g.deny(assertion);\r
-        g.deny(property);\r
-        \r
-        String name = g.getPossibleRelatedValue2(componentType, L0.HasName);\r
-        \r
-        CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
-        g.addMetadata(cm.add("Removed property " + property + " from component/annotation " + name + ", resource "+ componentType));\r
-    }\r
-\r
-    public static void rename(WriteGraph g, Resource resource, String newName) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        String prevName = g.getPossibleRelatedValue2(resource, L0.HasName);\r
-        g.claimLiteral(resource, L0.HasName, newName);\r
-        \r
-        CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
-        g.addMetadata(cm.add("Renamed component/annotation type from " + prevName + " to " + newName + ", resource " + resource  ));\r
-    }\r
-\r
-    public static void setRequiredType(WriteGraph g, Resource property,\r
-            String requiredType) throws DatabaseException {\r
-        setRequiredType(g, null, property, requiredType);\r
-    }\r
-\r
-    public static void setRequiredType(WriteGraph g, Resource componentType, Resource property,\r
-            String requiredType) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        g.claimLiteral(property, L0.RequiresValueType, requiredType);\r
-\r
-        if (componentType != null) {\r
-            StructuralResource2 STR = StructuralResource2.getInstance(g);\r
-            for (Resource assertedValue : g.getAssertedObjects(componentType, property)) {\r
-                if (g.isInstanceOf(assertedValue, STR.MonitorValue)) {\r
-                    g.claimLiteral(assertedValue, L0.HasValueType, requiredType);\r
-                }\r
-            }\r
-        }\r
-\r
-        CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
-        g.addMetadata(cm.add("Set required type "+ requiredType + " for component/annotation " + property));\r
-    }\r
-    \r
-    public static void editType(WriteGraph graph, Resource componentType, Resource property, boolean convertDefaultValue, String newValue) throws DatabaseException {\r
-        ComponentTypeCommands.setRequiredType(graph, componentType, property, newValue);\r
-        if (convertDefaultValue) {\r
-            ComponentTypeCommands.convertDefaultValue(graph, componentType, property, newValue);\r
-            Map<String, Resource> instances = graph.sync(new ModelInstances(componentType, componentType));\r
-            for(Resource instance : instances.values()) {\r
-                ComponentTypeCommands.convertInstantiatedValue(graph, instance, property, newValue);\r
-            }\r
-        }\r
-    }\r
-\r
-    static class AssertionMap extends UnaryRead<Resource, Map<Resource,Resource>> {\r
-        public AssertionMap(Resource parameter) {\r
-            super(parameter);\r
-        }\r
-\r
-        @Override\r
-        public Map<Resource, Resource> perform(ReadGraph graph)\r
-                throws DatabaseException {\r
-            THashMap<Resource,Resource> result = new THashMap<Resource, Resource>();\r
-            Layer0 L0 = Layer0.getInstance(graph);\r
-            for(Resource assertion : graph.getObjects(parameter, L0.Asserts))\r
-                result.put(graph.getSingleObject(assertion, L0.HasPredicate), \r
-                        graph.getSingleObject(assertion, L0.HasObject));\r
-            return result;\r
-        }\r
-    }\r
-\r
-    public static Resource getAssertedObject(ReadGraph g, Resource type, Resource relation) throws DatabaseException {\r
-        return g.syncRequest(new AssertionMap(type)).get(relation);\r
-    }\r
-\r
-    public static void setMonitorExpression(WriteGraph g, Resource type, Resource relation,\r
-            String valueText) throws DatabaseException {\r
-\r
-        Resource object = getAssertedObject(g, type, relation);\r
-        if(object == null) {\r
-            System.err.println("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + \r
-                    " in " + NameUtils.getSafeName(g, type) + ".");\r
-            return;\r
-        }\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        g.claimLiteral(object, L0.SCLValue_expression, valueText, Bindings.STRING);\r
-        \r
-    }\r
-\r
-    public static void setDefaultValue(WriteGraph g, Resource type, Resource relation,\r
-            String valueText) throws DatabaseException {\r
-\r
-       Resource object = getAssertedObject(g, type, relation);\r
-        if(object == null) {\r
-            System.err.println("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + \r
-                    " in " + NameUtils.getSafeName(g, type) + ".");\r
-            return;\r
-        }\r
-        \r
-        if(valueText.length() > 0 && valueText.charAt(0) == '=') {\r
-               \r
-               String expression = valueText.substring(1);\r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               ModelingResources MOD = ModelingResources.getInstance(g);\r
-               if(!g.isInstanceOf(object, MOD.SCLValue)) {\r
-                       Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);\r
-                       g.deny(assertion, L0.HasObject, object);\r
-                       object = g.newResource();\r
-                       g.claim(object, L0.InstanceOf, MOD.SCLValue);\r
-                       g.claim(assertion, L0.HasObject, object);\r
-               }\r
-               g.claimLiteral(object, L0.SCLValue_expression, L0.String, expression, Bindings.STRING);\r
-            Layer0Utils.addCommentMetadata(g, "Modified " + g.getRelatedValue2(relation, Layer0.getInstance(g).HasName, Bindings.STRING) + " with new expression '" + expression + "'");\r
-            \r
-        } else {\r
-               \r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               ModelingResources MOD = ModelingResources.getInstance(g);\r
-               if(g.isInstanceOf(object, MOD.SCLValue)) {\r
-                       Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);\r
-                       g.deny(assertion, L0.HasObject, object);\r
-                       object = g.newResource();\r
-                       String sclType = g.getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING);\r
-                Datatype newDatatype = TypeConversion.convertSCLTypeToDatatype(sclType);\r
-                       g.claim(object, L0.InstanceOf, L0.Literal);\r
-                Binding ntb = Bindings.getBindingUnchecked(Datatype.class);\r
-                g.claimLiteral(object, L0.HasDataType, L0.DataType, newDatatype, ntb);\r
-                       g.claim(assertion, L0.HasObject, object);\r
-               }\r
-               \r
-               Datatype dt = g.getDataType(object);\r
-               Binding binding = Bindings.getBinding(dt);\r
-               Object value;\r
-               try {\r
-                       value = binding.parseValue(valueText, new DataValueRepository());\r
-                       g.claimValue(object, value, binding);\r
-                       Layer0Utils.addCommentMetadata(g, "Modified " + g.getRelatedValue2(relation, Layer0.getInstance(g).HasName, Bindings.STRING) + " with new value " + value.toString());\r
-               } catch (DataTypeSyntaxError e) {\r
-                       e.printStackTrace();\r
-               } catch (BindingException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               \r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * @param graph graph write transaction handle\r
-     * @param type component type to edit\r
-     * @param relation component type property relation to edit\r
-     * @param unit <code>null</code> to remove unit description\r
-     * @throws DatabaseException\r
-     */\r
-    public static void setUnit(WriteGraph graph, Resource type, Resource relation, String unit) throws DatabaseException {\r
-        Resource object = getAssertedObject(graph, type, relation);\r
-        if (object == null) {\r
-            System.err.println("Didn't find assertion for " + NameUtils.getSafeName(graph, relation) + \r
-                    " in " + NameUtils.getSafeName(graph, type) + ".");\r
-            return;\r
-        }\r
-\r
-        Datatype dt = graph.getDataType(object);\r
-        if (dt instanceof NumberType) {\r
-            NumberType nt = (NumberType) dt;\r
-            Binding ntb = Bindings.getBindingUnchecked(Datatype.class);\r
-            nt.setUnit(unit);\r
-\r
-            Layer0 L0 = Layer0.getInstance(graph);\r
-            Layer0X L0X = Layer0X.getInstance(graph);\r
-            \r
-            String oldUnit = graph.getPossibleRelatedValue2(relation, L0X.HasUnit, Bindings.STRING);\r
-\r
-            graph.claimLiteral(object, L0.HasDataType, L0.DataType, nt, ntb);\r
-            graph.claimLiteral(relation, L0X.RequiresDataType, L0.DataType, nt, ntb);\r
-            graph.claimLiteral(relation, L0X.HasUnit, unit, Bindings.STRING);\r
-            \r
-            CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-            graph.addMetadata(cm.add("Setted unit from " + oldUnit + " to " + unit + " for component/annotation " + type));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * @param graph graph write transaction handle\r
-     * @param type component type to modify\r
-     * @param relation property relation of a component type\r
-     * @param newRange new range definition or <code>null</code> to remove range restriction\r
-     * @throws DatabaseException \r
-     */\r
-    public static void setRange(WriteGraph graph, Resource type, Resource relation, String newRange) throws DatabaseException {\r
-        Resource object = getAssertedObject(graph, type, relation);\r
-        if (object == null) {\r
-            System.err.println("Didn't find assertion for " + NameUtils.getSafeName(graph, relation) + \r
-                    " in " + NameUtils.getSafeName(graph, type) + ".");\r
-            return;\r
-        }\r
-\r
-        Datatype dt = graph.getDataType(object);\r
-        if (dt instanceof NumberType) {\r
-            NumberType nt = (NumberType) dt;\r
-            Binding ntb = Bindings.getBindingUnchecked(Datatype.class);\r
-            nt.setRange(newRange);\r
-\r
-            Layer0 L0 = Layer0.getInstance(graph);\r
-            Layer0X L0X = Layer0X.getInstance(graph);\r
-\r
-            graph.claimLiteral(object, L0.HasDataType, L0.DataType, nt, ntb);\r
-            graph.claimLiteral(relation, L0X.RequiresDataType, L0.DataType, nt, ntb);\r
-            \r
-            CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-            graph.addMetadata(cm.add("Setted range " + newRange + " for component/annotation " + type));\r
-        }\r
-    }\r
-\r
-    public static Tuple getDatatypeValueAndBinding(ReadGraph g, Resource object, String newSCLType) throws DatabaseException {\r
-\r
-        Datatype newDatatype = TypeConversion.convertSCLTypeToDatatype(newSCLType);\r
-        if(newDatatype == null) {\r
-            System.err.println("Couldn't convert default value to <" + newSCLType + ">.");\r
-            return null;\r
-        }\r
-        Binding newBinding = Bindings.getBinding(newDatatype);\r
-\r
-        Datatype oldDatatype = g.getDataType(object);\r
-        Binding oldBinding = Bindings.getBinding(oldDatatype);\r
-\r
-        Object oldValue = g.getValue(object, oldBinding);\r
-        Object newValue;\r
-        try {\r
-            newValue = Bindings.adapt(oldValue, oldBinding, newBinding);\r
-        } catch (AdaptException e) {\r
-            try {\r
-                newValue = newBinding.createDefault();\r
-            } catch (BindingException e1) {\r
-                e1.printStackTrace();\r
-                return null;\r
-            }\r
-        }\r
-\r
-        return new Tuple3(newDatatype, newValue, newBinding);\r
-\r
-    }\r
-\r
-    public static void convertDefaultValue(WriteGraph g,\r
-            Resource type, Resource relation, String newSCLType) throws DatabaseException {\r
-        Resource object = getAssertedObject(g, type, relation);\r
-        if(object == null) {\r
-            System.err.println("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + \r
-                    " in " + NameUtils.getSafeName(g, type) + ".");\r
-            return;\r
-        }\r
-\r
-        Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);\r
-        if (tuple == null)\r
-            return;\r
-\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        g.claimLiteral(object, L0.HasDataType, L0.DataType, tuple.get(0), Bindings.getBindingUnchecked(Datatype.class));\r
-        g.claimLiteral(object, L0.HasValueType, g.<String>getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING), Bindings.STRING);\r
-        g.claimValue(object, tuple.get(1), (Binding)tuple.get(2));\r
-\r
-    }\r
-\r
-    public static void convertInstantiatedValue(WriteGraph g, Resource instance, Resource relation, String newSCLType)\r
-            throws DatabaseException {\r
-\r
-        Statement stm = g.getPossibleStatement(instance, relation);\r
-        if(stm != null && !stm.isAsserted(instance)) {\r
-\r
-            Resource object = stm.getObject();\r
-\r
-            // We can only convert literals\r
-            Layer0 L0 = Layer0.getInstance(g);\r
-            if(!g.isInstanceOf(object, L0.Literal)) return;\r
-\r
-            Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);\r
-\r
-            g.claimLiteral(object, L0.HasDataType, L0.DataType, tuple.get(0), Bindings.getBindingUnchecked(Datatype.class));\r
-            g.claimLiteral(object, L0.HasValueType, g.<String>getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING), Bindings.STRING);\r
-            g.claimValue(object, tuple.get(1), (Binding)tuple.get(2));\r
-\r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * @param graph graph write transaction handle\r
-     * @param relation component type property relation to edit\r
-     * @param newDescription new label or <code>null</code> to remove label\r
-     * @throws DatabaseException \r
-     */\r
-    public static void setLabel(WriteGraph graph, Resource relation, String newLabel) throws DatabaseException {\r
-        setProperty(graph, relation, Layer0.getInstance(graph).HasLabel, newLabel);\r
-        \r
-        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-        graph.addMetadata(cm.add("Setted label " + newLabel + " for component/annotation " + relation));\r
-    }\r
-\r
-    /**\r
-     * @param graph graph write transaction handle\r
-     * @param relation component type property relation to edit\r
-     * @param newDescription new description or <code>null</code> if new description\r
-     * @throws DatabaseException \r
-     */\r
-    public static void setDescription(WriteGraph graph, Resource relation, String newDescription) throws DatabaseException {\r
-        setProperty(graph, relation, Layer0.getInstance(graph).HasDescription, newDescription);        \r
-        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-        graph.addMetadata(cm.add("Setted description " + newDescription + " for component/annotation " + relation));\r
-    }\r
-\r
-    /**\r
-     * @param graph graph write transaction handle\r
-     * @param relation component type property relation to edit\r
-     * @param newValue new property value or <code>null</code> to remove property\r
-     * @throws DatabaseException \r
-     */\r
-    public static void setProperty(WriteGraph graph, Resource relation, Resource property, String newValue) throws DatabaseException {\r
-        if (newValue != null) {\r
-            graph.claimLiteral(relation, property, newValue, Bindings.STRING);\r
-        } else {\r
-            graph.denyValue(relation, property);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * @param graph\r
-     * @param componentType\r
-     * @return the created symbol\r
-     */\r
-    public static Resource createSymbol(WriteGraph graph, Resource componentType) throws DatabaseException {\r
-        return NewSymbol.createSymbol(graph, componentType);\r
-    }\r
-\r
-    /**\r
-     * Converts to a <code>camelCase</code> name to a more user-readable\r
-     * <code>Camel Case</code> label.\r
-     * \r
-     * <p>\r
-     * Examples\r
-     * <pre>\r
-     * "fooBarBazBAR" => "Foo Bar Baz BAR"\r
-     * " fooBarBazBAR" => " Foo Bar Baz BAR"\r
-     * "_fooBarBazBAR" => "_Foo Bar Baz BAR"\r
-     * "_FooBarBazBAR" => "_Foo Bar Baz BAR"\r
-     * " _ fooBarBazBAR" => " _ Foo Bar Baz BAR"\r
-     * </pre>\r
-     * \r
-     * @param str camelCase SCL identifier name\r
-     * @return labelified Camel Case string\r
-     */\r
-    public static String camelCaseNameToLabel(String str) {\r
-        int len = str.length();\r
-        StringBuilder sb = new StringBuilder(len*2);\r
-\r
-        boolean wasLastUpper = false;\r
-        boolean isFirstEncounteredLetter = true;\r
-\r
-        for (int i = 0; i < len; ++i) {\r
-            char ch = str.charAt(i);\r
-\r
-            boolean space = Character.isWhitespace(ch);\r
-            if (space) {\r
-                sb.append(ch);\r
-                continue;\r
-            }\r
-\r
-            boolean isUpperCaseLetter = Character.isUpperCase(ch);\r
-            boolean isLetterOrDigit = Character.isLetterOrDigit(ch);\r
-            if (!isFirstEncounteredLetter && isUpperCaseLetter && !wasLastUpper && isLetterOrDigit) {\r
-                sb.append(' ');\r
-                sb.append(ch);\r
-            } else {\r
-                if (isLetterOrDigit && isFirstEncounteredLetter)\r
-                    sb.append(Character.toUpperCase(ch));\r
-                else\r
-                    sb.append(ch);\r
-                if (isFirstEncounteredLetter)\r
-                    isFirstEncounteredLetter = !isLetterOrDigit;\r
-            }\r
-            wasLastUpper = isUpperCaseLetter;\r
-        }\r
-        return sb.toString();\r
-    }\r
-\r
-    public static void saveProceduralCodeWithUC(WriteGraph graph, Resource componentType, String newText) throws DatabaseException {\r
-        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-        Resource code = graph.getPossibleObject(componentType, STR.ProceduralComponentType_code);\r
-        saveProceduralCode(graph, code, newText);\r
-    }\r
-    \r
-    public static void saveProceduralCode(WriteGraph graph, Resource resource, String newText) throws ServiceException {\r
-        graph.claimValue(resource, newText, Bindings.STRING);\r
-        Layer0Utils.addCommentMetadata(graph, "Saved Procedural Component Type SCL Code");\r
-    }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012 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
+ *******************************************************************************/
+package org.simantics.modeling.userComponent;
+
+import java.util.Map;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
+import org.simantics.databoard.parser.repository.DataValueRepository;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.type.NumberType;
+import org.simantics.db.ReadGraph;
+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.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.util.Layer0Utils;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.NewSymbol;
+import org.simantics.operation.Layer0X;
+import org.simantics.scl.runtime.tuple.Tuple;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.map.hash.THashMap;
+
+public class ComponentTypeCommands {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ComponentTypeCommands.class);
+
+    public static void applyCode(WriteGraph g, Resource componentType, String code) throws DatabaseException {
+        StructuralResource2 STR = StructuralResource2.getInstance(g);
+        g.claimLiteral(componentType, STR.ProceduralComponentType_code, code, Bindings.STRING);
+    }
+
+    public static Resource createConnectionPoint(WriteGraph g, Resource componentType, Resource cp) throws DatabaseException {
+        return StructuralUtils.createConnectionPoint(g, componentType, cp);
+    }
+
+    public static Resource createMonitorPropertyWithDefaults(WriteGraph g, Resource componentType) throws DatabaseException {
+
+        Layer0 L0 = Layer0.getInstance(g);
+        StructuralResource2 STR = StructuralResource2.getInstance(g);
+        ModelingResources MOD = ModelingResources.getInstance(g);
+
+        Resource monitorType = g.getPossibleObject(componentType, STR.ComponentType_HasDefaultMonitorValueType);
+        if(monitorType == null) monitorType = MOD.MonitorValue;
+
+        Resource relation = createPropertyWithDefaultsBase(g, componentType, "newProperty");
+        g.claim(relation, L0.HasRange, monitorType);
+
+        Resource assertion = g.newResource();
+        g.claim(componentType, L0.Asserts, assertion);
+        g.claim(assertion, L0.InstanceOf, L0.Assertion);
+        g.claim(assertion, L0.HasPredicate, relation);
+        
+        Resource value = g.newResource();
+        g.claim(value, L0.InstanceOf, monitorType);
+        g.claimLiteral(value, L0.HasValueType, L0.String, "Double", Bindings.STRING);
+        g.claimLiteral(value, L0.SCLValue_expression, L0.String, "", Bindings.STRING);
+        g.claim(assertion, L0.HasObject, value);
+        
+        return relation;
+        
+    }
+
+    public static Resource createPropertyWithDefaults(WriteGraph g, Resource componentType) throws DatabaseException {
+        g.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(g);
+
+        Resource relation = createPropertyWithDefaultsBase(g, componentType, "newProperty");
+
+        Resource assertion = g.newResource();
+        g.claim(componentType, L0.Asserts, assertion);
+        g.claim(assertion, L0.InstanceOf, L0.Assertion);
+        g.claim(assertion, L0.HasPredicate, relation);
+        
+        Resource value = g.newResource();
+        g.claim(value, L0.InstanceOf, L0.Literal);
+        g.claimLiteral(value, L0.HasDataType, L0.DataType, Datatypes.DOUBLE, Bindings.getBindingUnchecked(Datatype.class));
+        g.claimLiteral(value, L0.HasValueType, L0.String, "Double", Bindings.STRING);
+        g.claimValue(value, 0.0, Bindings.DOUBLE);
+        g.claim(assertion, L0.HasObject, value);
+        
+        return relation;
+        
+    }
+
+    public static Resource createPropertyWithDefaultsBase(WriteGraph g, Resource componentType, String defaultName) throws DatabaseException {
+
+       Layer0 L0 = Layer0.getInstance(g);
+        StructuralResource2 STR = StructuralResource2.getInstance(g);
+        ModelingResources MOD = ModelingResources.getInstance(g);
+
+        String name = NameUtils.findFreshEscapedName(g, defaultName, componentType);
+
+        Resource relation = g.newResource();
+        g.claim(relation, L0.SubrelationOf, null, L0.HasProperty);
+        boolean hadProperty = false;
+        for(Resource type : g.getObjects(componentType, STR.ComponentType_HasDefaultPropertyRelationType)) {
+               if(g.isInheritedFrom(type, STR.Property)) hadProperty = true;
+            g.claim(relation, L0.InstanceOf, type);
+        }
+        if(!hadProperty)
+               g.claim(relation, L0.InstanceOf, STR.Property);
+        
+        g.claimLiteral(relation, L0.HasName, name);
+        g.claim(componentType, L0.ConsistsOf, L0.PartOf, relation);
+        g.claim(relation, L0.HasDomain, L0.DomainOf, componentType);
+
+        Resource invRelation = g.newResource();
+        g.claim(invRelation, L0.SubrelationOf, null, L0.PropertyOf);
+        g.claim(relation, L0.ConsistsOf, L0.PartOf, invRelation);
+        g.claimLiteral(invRelation, L0.HasName, "Inverse");
+        g.claim(relation, L0.InverseOf, invRelation);
+
+        g.claimLiteral(relation, L0.RequiresValueType, "Double");
+
+        SelectionViewResources SEL = SelectionViewResources.getInstance(g);
+        Resource category = g.getPossibleObject(relation, SEL.HasStandardPropertyInfo);
+        if(category == null) {
+               g.claim(relation, SEL.HasStandardPropertyInfo, MOD.UserDefinedPropertyInfo);
+        }
+        if(!g.isInstanceOf(relation, SEL.GenericParameterType))
+               g.claim(relation, L0.InstanceOf, SEL.GenericParameterType);
+        
+        CommentMetadata cm = g.getMetadata(CommentMetadata.class);
+        g.addMetadata(cm.add("Created new property " + name + " for " + g.getRelatedValue2(componentType, L0.HasName, Bindings.STRING) + " " + componentType.toString()));
+
+        return relation;
+    }
+    
+    public static Resource createProperty(WriteGraph graph, Resource componentType, String name, String type, String unit, String range, String label, String description) throws DatabaseException {
+       
+       Resource property = createPropertyWithDefaults(graph, componentType);
+       rename(graph, property, name);
+       setRequiredType(graph, componentType, property, type);
+       convertDefaultValue(graph, componentType, property, type);
+       //setDefaultValue(graph, type, relation, valueText)
+       if (!type.equals("String")) {
+               setUnit(graph, componentType, property, unit);
+               setRange(graph, componentType, property, range);        
+       }
+       setLabel(graph, property, label);
+       setDescription(graph, property, description);
+       
+       return property;
+    }
+
+    public static void removeProperty(WriteGraph g, Resource componentType, Resource property) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        for(Resource assertion : g.getObjects(property, L0.HasPredicateInverse))
+            g.deny(assertion);
+        g.deny(property);
+        
+        String name = g.getPossibleRelatedValue2(componentType, L0.HasName);
+        
+        CommentMetadata cm = g.getMetadata(CommentMetadata.class);
+        g.addMetadata(cm.add("Removed property " + property + " from component/annotation " + name + ", resource "+ componentType));
+    }
+
+    public static void rename(WriteGraph g, Resource resource, String newName) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        String prevName = g.getPossibleRelatedValue2(resource, L0.HasName);
+        g.claimLiteral(resource, L0.HasName, newName);
+        
+        CommentMetadata cm = g.getMetadata(CommentMetadata.class);
+        g.addMetadata(cm.add("Renamed component/annotation type from " + prevName + " to " + newName + ", resource " + resource  ));
+    }
+
+    public static void setRequiredType(WriteGraph g, Resource property,
+            String requiredType) throws DatabaseException {
+        setRequiredType(g, null, property, requiredType);
+    }
+
+    public static void setRequiredType(WriteGraph g, Resource componentType, Resource property,
+            String requiredType) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        g.claimLiteral(property, L0.RequiresValueType, requiredType);
+
+        if (componentType != null) {
+            StructuralResource2 STR = StructuralResource2.getInstance(g);
+            for (Resource assertedValue : g.getAssertedObjects(componentType, property)) {
+                if (g.isInstanceOf(assertedValue, STR.MonitorValue)) {
+                    g.claimLiteral(assertedValue, L0.HasValueType, requiredType);
+                }
+            }
+        }
+
+        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);
+        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);
+            }
+        }
+    }
+
+    static class AssertionMap extends UnaryRead<Resource, Map<Resource,Resource>> {
+        public AssertionMap(Resource parameter) {
+            super(parameter);
+        }
+
+        @Override
+        public Map<Resource, Resource> perform(ReadGraph graph)
+                throws DatabaseException {
+            THashMap<Resource,Resource> result = new THashMap<Resource, Resource>();
+            Layer0 L0 = Layer0.getInstance(graph);
+            for(Resource assertion : graph.getObjects(parameter, L0.Asserts))
+                result.put(graph.getSingleObject(assertion, L0.HasPredicate), 
+                        graph.getSingleObject(assertion, L0.HasObject));
+            return result;
+        }
+    }
+
+    public static Resource getAssertedObject(ReadGraph g, Resource type, Resource relation) throws DatabaseException {
+        return g.syncRequest(new AssertionMap(type)).get(relation);
+    }
+
+    public static void setMonitorExpression(WriteGraph g, Resource type, Resource relation,
+            String valueText) throws DatabaseException {
+
+        Resource object = getAssertedObject(g, type, relation);
+        if(object == null) {
+            LOGGER.warn("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + 
+                    " in " + NameUtils.getSafeName(g, type) + ".");
+            return;
+        }
+        Layer0 L0 = Layer0.getInstance(g);
+        g.claimLiteral(object, L0.SCLValue_expression, valueText, Bindings.STRING);
+        
+    }
+
+    public static void setDefaultValue(WriteGraph g, Resource type, Resource relation,
+            String valueText) throws DatabaseException {
+
+       Resource object = getAssertedObject(g, type, relation);
+        if(object == null) {
+            LOGGER.warn("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + 
+                    " in " + NameUtils.getSafeName(g, type) + ".");
+            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);
+                       g.deny(assertion, L0.HasObject, object);
+                       object = g.newResource();
+                       g.claim(object, L0.InstanceOf, MOD.SCLValue);
+                       g.claim(assertion, L0.HasObject, object);
+               }
+               g.claimLiteral(object, L0.SCLValue_expression, L0.String, expression, Bindings.STRING);
+            Layer0Utils.addCommentMetadata(g, "Modified " + g.getRelatedValue2(relation, Layer0.getInstance(g).HasName, Bindings.STRING) + " with new expression '" + expression + "'");
+            
+        } else {
+               
+               Layer0 L0 = Layer0.getInstance(g);
+               ModelingResources MOD = ModelingResources.getInstance(g);
+               if(g.isInstanceOf(object, MOD.SCLValue)) {
+                       Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);
+                       g.deny(assertion, L0.HasObject, object);
+                       object = g.newResource();
+                       String sclType = g.getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING);
+                Datatype newDatatype = TypeConversion.convertSCLTypeToDatatype(sclType);
+                       g.claim(object, L0.InstanceOf, L0.Literal);
+                Binding ntb = Bindings.getBindingUnchecked(Datatype.class);
+                g.claimLiteral(object, L0.HasDataType, L0.DataType, newDatatype, ntb);
+                       g.claim(assertion, L0.HasObject, object);
+               }
+               
+               Datatype dt = g.getDataType(object);
+               Binding binding = Bindings.getBinding(dt);
+               Object value;
+               try {
+                       value = binding.parseValue(valueText, new DataValueRepository());
+                       g.claimValue(object, value, binding);
+                       Layer0Utils.addCommentMetadata(g, "Modified " + g.getRelatedValue2(relation, Layer0.getInstance(g).HasName, Bindings.STRING) + " with new value " + value.toString());
+               } catch (DataTypeSyntaxError e) {
+                       e.printStackTrace();
+               } catch (BindingException e) {
+                       e.printStackTrace();
+               }
+               
+        }
+
+    }
+
+    /**
+     * @param graph graph write transaction handle
+     * @param type component type to edit
+     * @param relation component type property relation to edit
+     * @param unit <code>null</code> to remove unit description
+     * @throws DatabaseException
+     */
+    public static void setUnit(WriteGraph graph, Resource type, Resource relation, String unit) throws DatabaseException {
+        Resource object = getAssertedObject(graph, type, relation);
+        if (object == null) {
+            LOGGER.warn("Didn't find assertion for " + NameUtils.getSafeName(graph, relation) + 
+                    " in " + NameUtils.getSafeName(graph, type) + ".");
+            return;
+        }
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        Layer0X L0X = Layer0X.getInstance(graph);
+        boolean hasRequiresDataType = graph.hasStatement(relation, L0X.RequiresDataType);
+        if (hasRequiresDataType) {
+            Datatype dt = graph.getDataType(object);
+            if (dt instanceof NumberType) {
+                NumberType nt = (NumberType) Bindings.DATATYPE.cloneUnchecked(dt);
+                nt.setUnit(unit);
+                graph.claimLiteral(object, L0.HasDataType, L0.DataType, nt, Bindings.DATATYPE);
+                graph.claimLiteral(relation, L0X.RequiresDataType, L0.DataType, nt, Bindings.DATATYPE);
+            }
+        }
+
+        String oldUnit = graph.getPossibleRelatedValue2(relation, L0X.HasUnit, Bindings.STRING);
+        if (unit != null) {
+            graph.claimLiteral(relation, L0X.HasUnit, L0.String, unit, Bindings.STRING);
+        } else {
+            graph.denyValue(relation, L0X.HasUnit);
+        }
+
+        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+        graph.addMetadata(cm.add("Set unit from " + oldUnit + " to " + unit + " for component/annotation " + type + " property " + relation));
+    }
+
+    /**
+     * @param graph graph write transaction handle
+     * @param type component type to modify
+     * @param relation property relation of a component type
+     * @param newRange new range definition or <code>null</code> to remove range restriction
+     * @throws DatabaseException 
+     */
+    public static void setRange(WriteGraph graph, Resource type, Resource relation, String newRange) throws DatabaseException {
+        Resource object = getAssertedObject(graph, type, relation);
+        if (object == null) {
+            LOGGER.warn("Didn't find assertion for " + NameUtils.getSafeName(graph, relation) + 
+                    " in " + NameUtils.getSafeName(graph, type) + ".");
+            return;
+        }
+
+        Datatype dt = graph.getDataType(object);
+        if (dt instanceof NumberType) {
+            NumberType nt = (NumberType) dt;
+            Binding ntb = Bindings.getBindingUnchecked(Datatype.class);
+            nt.setRange(newRange);
+
+            Layer0 L0 = Layer0.getInstance(graph);
+            Layer0X L0X = Layer0X.getInstance(graph);
+
+            graph.claimLiteral(object, L0.HasDataType, L0.DataType, nt, ntb);
+            graph.claimLiteral(relation, L0X.RequiresDataType, L0.DataType, nt, ntb);
+            
+            CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+            graph.addMetadata(cm.add("Setted range " + newRange + " for component/annotation " + type));
+        }
+    }
+
+    public static Tuple getDatatypeValueAndBinding(ReadGraph g, Resource object, String newSCLType) throws DatabaseException {
+
+        Datatype newDatatype = TypeConversion.convertSCLTypeToDatatype(newSCLType);
+        if(newDatatype == null) {
+            LOGGER.warn("Couldn't convert default value to <" + newSCLType + ">.");
+            return null;
+        }
+        Binding newBinding = Bindings.getBinding(newDatatype);
+
+        Datatype oldDatatype = g.getDataType(object);
+        Binding oldBinding = Bindings.getBinding(oldDatatype);
+
+        Object oldValue = g.getValue(object, oldBinding);
+        Object newValue;
+        try {
+            newValue = Bindings.adapt(oldValue, oldBinding, newBinding);
+        } catch (AdaptException e) {
+            try {
+                newValue = newBinding.createDefault();
+            } catch (BindingException e1) {
+                e1.printStackTrace();
+                return null;
+            }
+        }
+
+        return new Tuple3(newDatatype, newValue, newBinding);
+
+    }
+
+    public static void convertDefaultValue(WriteGraph g,
+            Resource type, Resource relation, String newSCLType) throws DatabaseException {
+        Resource object = getAssertedObject(g, type, relation);
+        if(object == null) {
+            LOGGER.warn("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + 
+                    " in " + NameUtils.getSafeName(g, type) + ".");
+            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)
+            throws DatabaseException {
+
+        Statement stm = g.getPossibleStatement(instance, relation);
+        if(stm != null && !stm.isAsserted(instance)) {
+
+            Resource object = stm.getObject();
+
+            // We can only convert literals
+            Layer0 L0 = Layer0.getInstance(g);
+            if(!g.isInstanceOf(object, L0.Literal)) return;
+
+            Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);
+
+            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));
+
+        }
+
+    }
+
+    /**
+     * @param graph graph write transaction handle
+     * @param relation component type property relation to edit
+     * @param newDescription new label or <code>null</code> to remove label
+     * @throws DatabaseException 
+     */
+    public static void setLabel(WriteGraph graph, Resource relation, String newLabel) throws DatabaseException {
+        setProperty(graph, relation, Layer0.getInstance(graph).HasLabel, newLabel);
+        
+        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+        graph.addMetadata(cm.add("Setted label " + newLabel + " for component/annotation " + relation));
+    }
+
+    /**
+     * @param graph graph write transaction handle
+     * @param relation component type property relation to edit
+     * @param newDescription new description or <code>null</code> if new description
+     * @throws DatabaseException 
+     */
+    public static void setDescription(WriteGraph graph, Resource relation, String newDescription) throws DatabaseException {
+        setProperty(graph, relation, Layer0.getInstance(graph).HasDescription, newDescription);        
+        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+        graph.addMetadata(cm.add("Setted description " + newDescription + " for component/annotation " + relation));
+    }
+
+    /**
+     * @param graph graph write transaction handle
+     * @param relation component type property relation to edit
+     * @param newValue new property value or <code>null</code> to remove property
+     * @throws DatabaseException 
+     */
+    public static void setProperty(WriteGraph graph, Resource relation, Resource property, String newValue) throws DatabaseException {
+        if (newValue != null) {
+            graph.claimLiteral(relation, property, newValue, Bindings.STRING);
+        } else {
+            graph.denyValue(relation, property);
+        }
+    }
+
+    /**
+     * @param graph
+     * @param componentType
+     * @return the created symbol
+     */
+    public static Resource createSymbol(WriteGraph graph, Resource componentType) throws DatabaseException {
+        return NewSymbol.createSymbol(graph, componentType);
+    }
+
+    /**
+     * Converts to a <code>camelCase</code> name to a more user-readable
+     * <code>Camel Case</code> label.
+     * 
+     * <p>
+     * Examples
+     * <pre>
+     * "fooBarBazBAR" => "Foo Bar Baz BAR"
+     * " fooBarBazBAR" => " Foo Bar Baz BAR"
+     * "_fooBarBazBAR" => "_Foo Bar Baz BAR"
+     * "_FooBarBazBAR" => "_Foo Bar Baz BAR"
+     * " _ fooBarBazBAR" => " _ Foo Bar Baz BAR"
+     * </pre>
+     * 
+     * @param str camelCase SCL identifier name
+     * @return labelified Camel Case string
+     */
+    public static String camelCaseNameToLabel(String str) {
+        int len = str.length();
+        StringBuilder sb = new StringBuilder(len*2);
+
+        boolean wasLastUpper = false;
+        boolean isFirstEncounteredLetter = true;
+
+        for (int i = 0; i < len; ++i) {
+            char ch = str.charAt(i);
+
+            boolean space = Character.isWhitespace(ch);
+            if (space) {
+                sb.append(ch);
+                continue;
+            }
+
+            boolean isUpperCaseLetter = Character.isUpperCase(ch);
+            boolean isLetterOrDigit = Character.isLetterOrDigit(ch);
+            if (!isFirstEncounteredLetter && isUpperCaseLetter && !wasLastUpper && isLetterOrDigit) {
+                sb.append(' ');
+                sb.append(ch);
+            } else {
+                if (isLetterOrDigit && isFirstEncounteredLetter)
+                    sb.append(Character.toUpperCase(ch));
+                else
+                    sb.append(ch);
+                if (isFirstEncounteredLetter)
+                    isFirstEncounteredLetter = !isLetterOrDigit;
+            }
+            wasLastUpper = isUpperCaseLetter;
+        }
+        return sb.toString();
+    }
+
+    public static void saveProceduralCodeWithUC(WriteGraph graph, Resource componentType, String newText) throws DatabaseException {
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);
+        Resource code = graph.getPossibleObject(componentType, STR.ProceduralComponentType_code);
+        saveProceduralCode(graph, code, newText);
+    }
+    
+    public static void saveProceduralCode(WriteGraph graph, Resource resource, String newText) throws ServiceException {
+        graph.claimValue(resource, newText, Bindings.STRING);
+        Layer0Utils.addCommentMetadata(graph, "Saved Procedural Component Type SCL Code");
+    }
+}