Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / userComponent / ComponentTypeCommands.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.userComponent;\r
13 \r
14 import gnu.trove.map.hash.THashMap;\r
15 \r
16 import java.util.Map;\r
17 \r
18 import org.simantics.databoard.Bindings;\r
19 import org.simantics.databoard.Datatypes;\r
20 import org.simantics.databoard.adapter.AdaptException;\r
21 import org.simantics.databoard.binding.Binding;\r
22 import org.simantics.databoard.binding.error.BindingException;\r
23 import org.simantics.databoard.parser.repository.DataTypeSyntaxError;\r
24 import org.simantics.databoard.parser.repository.DataValueRepository;\r
25 import org.simantics.databoard.type.Datatype;\r
26 import org.simantics.databoard.type.NumberType;\r
27 import org.simantics.db.ReadGraph;\r
28 import org.simantics.db.Resource;\r
29 import org.simantics.db.Statement;\r
30 import org.simantics.db.WriteGraph;\r
31 import org.simantics.db.common.CommentMetadata;\r
32 import org.simantics.db.common.request.UnaryRead;\r
33 import org.simantics.db.common.utils.NameUtils;\r
34 import org.simantics.db.exception.DatabaseException;\r
35 import org.simantics.db.exception.ServiceException;\r
36 import org.simantics.db.layer0.request.ModelInstances;\r
37 import org.simantics.db.layer0.util.Layer0Utils;\r
38 import org.simantics.layer0.Layer0;\r
39 import org.simantics.modeling.ModelingResources;\r
40 import org.simantics.modeling.NewSymbol;\r
41 import org.simantics.operation.Layer0X;\r
42 import org.simantics.scl.runtime.tuple.Tuple;\r
43 import org.simantics.scl.runtime.tuple.Tuple3;\r
44 import org.simantics.selectionview.SelectionViewResources;\r
45 import org.simantics.structural.stubs.StructuralResource2;\r
46 import org.simantics.structural2.utils.StructuralUtils;\r
47 \r
48 public class ComponentTypeCommands {\r
49 \r
50     public static void applyCode(WriteGraph g, Resource componentType, String code) throws DatabaseException {\r
51         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
52         g.claimLiteral(componentType, STR.ProceduralComponentType_code, code, Bindings.STRING);\r
53     }\r
54 \r
55     public static Resource createConnectionPoint(WriteGraph g, Resource componentType, Resource cp) throws DatabaseException {\r
56         return StructuralUtils.createConnectionPoint(g, componentType, cp);\r
57     }\r
58 \r
59     public static Resource createMonitorPropertyWithDefaults(WriteGraph g, Resource componentType) throws DatabaseException {\r
60 \r
61         Layer0 L0 = Layer0.getInstance(g);\r
62         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
63         ModelingResources MOD = ModelingResources.getInstance(g);\r
64 \r
65         Resource monitorType = g.getPossibleObject(componentType, STR.ComponentType_HasDefaultMonitorValueType);\r
66         if(monitorType == null) monitorType = MOD.MonitorValue;\r
67 \r
68         Resource relation = createPropertyWithDefaultsBase(g, componentType, "newProperty");\r
69         g.claim(relation, L0.HasRange, monitorType);\r
70 \r
71         Resource assertion = g.newResource();\r
72         g.claim(componentType, L0.Asserts, assertion);\r
73         g.claim(assertion, L0.InstanceOf, L0.Assertion);\r
74         g.claim(assertion, L0.HasPredicate, relation);\r
75         \r
76         Resource value = g.newResource();\r
77         g.claim(value, L0.InstanceOf, monitorType);\r
78         g.claimLiteral(value, L0.HasValueType, L0.String, "Double", Bindings.STRING);\r
79         g.claimLiteral(value, L0.SCLValue_expression, L0.String, "", Bindings.STRING);\r
80         g.claim(assertion, L0.HasObject, value);\r
81         \r
82         return relation;\r
83         \r
84     }\r
85 \r
86     public static Resource createPropertyWithDefaults(WriteGraph g, Resource componentType) throws DatabaseException {\r
87         g.markUndoPoint();\r
88         Layer0 L0 = Layer0.getInstance(g);\r
89 \r
90         Resource relation = createPropertyWithDefaultsBase(g, componentType, "newProperty");\r
91 \r
92         Resource assertion = g.newResource();\r
93         g.claim(componentType, L0.Asserts, assertion);\r
94         g.claim(assertion, L0.InstanceOf, L0.Assertion);\r
95         g.claim(assertion, L0.HasPredicate, relation);\r
96         \r
97         Resource value = g.newResource();\r
98         g.claim(value, L0.InstanceOf, L0.Literal);\r
99         g.claimLiteral(value, L0.HasDataType, L0.DataType, Datatypes.DOUBLE, Bindings.getBindingUnchecked(Datatype.class));\r
100         g.claimLiteral(value, L0.HasValueType, L0.String, "Double", Bindings.STRING);\r
101         g.claimValue(value, 0.0, Bindings.DOUBLE);\r
102         g.claim(assertion, L0.HasObject, value);\r
103         \r
104         return relation;\r
105         \r
106     }\r
107 \r
108     public static Resource createPropertyWithDefaultsBase(WriteGraph g, Resource componentType, String defaultName) throws DatabaseException {\r
109 \r
110         Layer0 L0 = Layer0.getInstance(g);\r
111         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
112         ModelingResources MOD = ModelingResources.getInstance(g);\r
113 \r
114         String name = NameUtils.findFreshEscapedName(g, defaultName, componentType);\r
115 \r
116         Resource relation = g.newResource();\r
117         g.claim(relation, L0.SubrelationOf, null, L0.HasProperty);\r
118         boolean hadProperty = false;\r
119         for(Resource type : g.getObjects(componentType, STR.ComponentType_HasDefaultPropertyRelationType)) {\r
120                 if(g.isInheritedFrom(type, STR.Property)) hadProperty = true;\r
121             g.claim(relation, L0.InstanceOf, type);\r
122         }\r
123         if(!hadProperty)\r
124                 g.claim(relation, L0.InstanceOf, STR.Property);\r
125         \r
126         g.claimLiteral(relation, L0.HasName, name);\r
127         g.claim(componentType, L0.ConsistsOf, L0.PartOf, relation);\r
128         g.claim(relation, L0.HasDomain, L0.DomainOf, componentType);\r
129 \r
130         Resource invRelation = g.newResource();\r
131         g.claim(invRelation, L0.SubrelationOf, null, L0.PropertyOf);\r
132         g.claim(relation, L0.ConsistsOf, L0.PartOf, invRelation);\r
133         g.claimLiteral(invRelation, L0.HasName, "Inverse");\r
134         g.claim(relation, L0.InverseOf, invRelation);\r
135 \r
136         g.claimLiteral(relation, L0.RequiresValueType, "Double");\r
137 \r
138         SelectionViewResources SEL = SelectionViewResources.getInstance(g);\r
139         Resource category = g.getPossibleObject(relation, SEL.HasStandardPropertyInfo);\r
140         if(category == null) {\r
141                 g.claim(relation, SEL.HasStandardPropertyInfo, MOD.UserDefinedPropertyInfo);\r
142         }\r
143         if(!g.isInstanceOf(relation, SEL.GenericParameterType))\r
144                 g.claim(relation, L0.InstanceOf, SEL.GenericParameterType);\r
145         \r
146         CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
147         g.addMetadata(cm.add("Created new property " + name + " for " + g.getRelatedValue2(componentType, L0.HasName, Bindings.STRING) + " " + componentType.toString()));\r
148 \r
149         return relation;\r
150     }\r
151     \r
152     public static Resource createProperty(WriteGraph graph, Resource componentType, String name, String type, String unit, String range, String label, String description) throws DatabaseException {\r
153         \r
154         Resource property = createPropertyWithDefaults(graph, componentType);\r
155         rename(graph, property, name);\r
156         setRequiredType(graph, componentType, property, type);\r
157         convertDefaultValue(graph, componentType, property, type);\r
158         //setDefaultValue(graph, type, relation, valueText)\r
159         if (!type.equals("String")) {\r
160                 setUnit(graph, componentType, property, unit);\r
161                 setRange(graph, componentType, property, range);        \r
162         }\r
163         setLabel(graph, property, label);\r
164         setDescription(graph, property, description);\r
165         \r
166         return property;\r
167     }\r
168 \r
169     public static void removeProperty(WriteGraph g, Resource componentType, Resource property) throws DatabaseException {\r
170         Layer0 L0 = Layer0.getInstance(g);\r
171         for(Resource assertion : g.getObjects(property, L0.HasPredicateInverse))\r
172             g.deny(assertion);\r
173         g.deny(property);\r
174         \r
175         String name = g.getPossibleRelatedValue2(componentType, L0.HasName);\r
176         \r
177         CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
178         g.addMetadata(cm.add("Removed property " + property + " from component/annotation " + name + ", resource "+ componentType));\r
179     }\r
180 \r
181     public static void rename(WriteGraph g, Resource resource, String newName) throws DatabaseException {\r
182         Layer0 L0 = Layer0.getInstance(g);\r
183         \r
184         String prevName = g.getPossibleRelatedValue2(resource, L0.HasName);\r
185         g.claimLiteral(resource, L0.HasName, newName);\r
186         \r
187         CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
188         g.addMetadata(cm.add("Renamed component/annotation type from " + prevName + " to " + newName + ", resource " + resource  ));\r
189     }\r
190 \r
191     public static void setRequiredType(WriteGraph g, Resource property,\r
192             String requiredType) throws DatabaseException {\r
193         setRequiredType(g, null, property, requiredType);\r
194     }\r
195 \r
196     public static void setRequiredType(WriteGraph g, Resource componentType, Resource property,\r
197             String requiredType) throws DatabaseException {\r
198         Layer0 L0 = Layer0.getInstance(g);\r
199         g.claimLiteral(property, L0.RequiresValueType, requiredType);\r
200 \r
201         if (componentType != null) {\r
202             StructuralResource2 STR = StructuralResource2.getInstance(g);\r
203             for (Resource assertedValue : g.getAssertedObjects(componentType, property)) {\r
204                 if (g.isInstanceOf(assertedValue, STR.MonitorValue)) {\r
205                     g.claimLiteral(assertedValue, L0.HasValueType, requiredType);\r
206                 }\r
207             }\r
208         }\r
209 \r
210         CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
211         g.addMetadata(cm.add("Set required type "+ requiredType + " for component/annotation " + property));\r
212     }\r
213     \r
214     public static void editType(WriteGraph graph, Resource componentType, Resource property, boolean convertDefaultValue, String newValue) throws DatabaseException {\r
215         ComponentTypeCommands.setRequiredType(graph, componentType, property, newValue);\r
216         if (convertDefaultValue) {\r
217             ComponentTypeCommands.convertDefaultValue(graph, componentType, property, newValue);\r
218             Map<String, Resource> instances = graph.sync(new ModelInstances(componentType, componentType));\r
219             for(Resource instance : instances.values()) {\r
220                 ComponentTypeCommands.convertInstantiatedValue(graph, instance, property, newValue);\r
221             }\r
222         }\r
223     }\r
224 \r
225     static class AssertionMap extends UnaryRead<Resource, Map<Resource,Resource>> {\r
226         public AssertionMap(Resource parameter) {\r
227             super(parameter);\r
228         }\r
229 \r
230         @Override\r
231         public Map<Resource, Resource> perform(ReadGraph graph)\r
232                 throws DatabaseException {\r
233             THashMap<Resource,Resource> result = new THashMap<Resource, Resource>();\r
234             Layer0 L0 = Layer0.getInstance(graph);\r
235             for(Resource assertion : graph.getObjects(parameter, L0.Asserts))\r
236                 result.put(graph.getSingleObject(assertion, L0.HasPredicate), \r
237                         graph.getSingleObject(assertion, L0.HasObject));\r
238             return result;\r
239         }\r
240     }\r
241 \r
242     public static Resource getAssertedObject(ReadGraph g, Resource type, Resource relation) throws DatabaseException {\r
243         return g.syncRequest(new AssertionMap(type)).get(relation);\r
244     }\r
245 \r
246     public static void setMonitorExpression(WriteGraph g, Resource type, Resource relation,\r
247             String valueText) throws DatabaseException {\r
248 \r
249         Resource object = getAssertedObject(g, type, relation);\r
250         if(object == null) {\r
251             System.err.println("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + \r
252                     " in " + NameUtils.getSafeName(g, type) + ".");\r
253             return;\r
254         }\r
255         Layer0 L0 = Layer0.getInstance(g);\r
256         g.claimLiteral(object, L0.SCLValue_expression, valueText, Bindings.STRING);\r
257         \r
258     }\r
259 \r
260     public static void setDefaultValue(WriteGraph g, Resource type, Resource relation,\r
261             String valueText) throws DatabaseException {\r
262 \r
263         Resource object = getAssertedObject(g, type, relation);\r
264         if(object == null) {\r
265             System.err.println("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + \r
266                     " in " + NameUtils.getSafeName(g, type) + ".");\r
267             return;\r
268         }\r
269         \r
270         if(valueText.length() > 0 && valueText.charAt(0) == '=') {\r
271                 \r
272                 String expression = valueText.substring(1);\r
273                 Layer0 L0 = Layer0.getInstance(g);\r
274                 ModelingResources MOD = ModelingResources.getInstance(g);\r
275                 if(!g.isInstanceOf(object, MOD.SCLValue)) {\r
276                         Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);\r
277                         g.deny(assertion, L0.HasObject, object);\r
278                         object = g.newResource();\r
279                         g.claim(object, L0.InstanceOf, MOD.SCLValue);\r
280                         g.claim(assertion, L0.HasObject, object);\r
281                 }\r
282                 g.claimLiteral(object, L0.SCLValue_expression, L0.String, expression, Bindings.STRING);\r
283             Layer0Utils.addCommentMetadata(g, "Modified " + g.getRelatedValue2(relation, Layer0.getInstance(g).HasName, Bindings.STRING) + " with new expression '" + expression + "'");\r
284             \r
285         } else {\r
286                 \r
287                 Layer0 L0 = Layer0.getInstance(g);\r
288                 ModelingResources MOD = ModelingResources.getInstance(g);\r
289                 if(g.isInstanceOf(object, MOD.SCLValue)) {\r
290                         Resource assertion = g.getSingleObject(object, L0.HasObjectInverse);\r
291                         g.deny(assertion, L0.HasObject, object);\r
292                         object = g.newResource();\r
293                         String sclType = g.getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING);\r
294                 Datatype newDatatype = TypeConversion.convertSCLTypeToDatatype(sclType);\r
295                         g.claim(object, L0.InstanceOf, L0.Literal);\r
296                 Binding ntb = Bindings.getBindingUnchecked(Datatype.class);\r
297                 g.claimLiteral(object, L0.HasDataType, L0.DataType, newDatatype, ntb);\r
298                         g.claim(assertion, L0.HasObject, object);\r
299                 }\r
300                 \r
301                 Datatype dt = g.getDataType(object);\r
302                 Binding binding = Bindings.getBinding(dt);\r
303                 Object value;\r
304                 try {\r
305                         value = binding.parseValue(valueText, new DataValueRepository());\r
306                         g.claimValue(object, value, binding);\r
307                         Layer0Utils.addCommentMetadata(g, "Modified " + g.getRelatedValue2(relation, Layer0.getInstance(g).HasName, Bindings.STRING) + " with new value " + value.toString());\r
308                 } catch (DataTypeSyntaxError e) {\r
309                         e.printStackTrace();\r
310                 } catch (BindingException e) {\r
311                         e.printStackTrace();\r
312                 }\r
313                 \r
314         }\r
315 \r
316     }\r
317 \r
318     /**\r
319      * @param graph graph write transaction handle\r
320      * @param type component type to edit\r
321      * @param relation component type property relation to edit\r
322      * @param unit <code>null</code> to remove unit description\r
323      * @throws DatabaseException\r
324      */\r
325     public static void setUnit(WriteGraph graph, Resource type, Resource relation, String unit) throws DatabaseException {\r
326         Resource object = getAssertedObject(graph, type, relation);\r
327         if (object == null) {\r
328             System.err.println("Didn't find assertion for " + NameUtils.getSafeName(graph, relation) + \r
329                     " in " + NameUtils.getSafeName(graph, type) + ".");\r
330             return;\r
331         }\r
332 \r
333         Datatype dt = graph.getDataType(object);\r
334         if (dt instanceof NumberType) {\r
335             NumberType nt = (NumberType) dt;\r
336             Binding ntb = Bindings.getBindingUnchecked(Datatype.class);\r
337             nt.setUnit(unit);\r
338 \r
339             Layer0 L0 = Layer0.getInstance(graph);\r
340             Layer0X L0X = Layer0X.getInstance(graph);\r
341             \r
342             String oldUnit = graph.getPossibleRelatedValue2(relation, L0X.HasUnit, Bindings.STRING);\r
343 \r
344             graph.claimLiteral(object, L0.HasDataType, L0.DataType, nt, ntb);\r
345             graph.claimLiteral(relation, L0X.RequiresDataType, L0.DataType, nt, ntb);\r
346             graph.claimLiteral(relation, L0X.HasUnit, unit, Bindings.STRING);\r
347             \r
348             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
349             graph.addMetadata(cm.add("Setted unit from " + oldUnit + " to " + unit + " for component/annotation " + type));\r
350         }\r
351     }\r
352 \r
353     /**\r
354      * @param graph graph write transaction handle\r
355      * @param type component type to modify\r
356      * @param relation property relation of a component type\r
357      * @param newRange new range definition or <code>null</code> to remove range restriction\r
358      * @throws DatabaseException \r
359      */\r
360     public static void setRange(WriteGraph graph, Resource type, Resource relation, String newRange) throws DatabaseException {\r
361         Resource object = getAssertedObject(graph, type, relation);\r
362         if (object == null) {\r
363             System.err.println("Didn't find assertion for " + NameUtils.getSafeName(graph, relation) + \r
364                     " in " + NameUtils.getSafeName(graph, type) + ".");\r
365             return;\r
366         }\r
367 \r
368         Datatype dt = graph.getDataType(object);\r
369         if (dt instanceof NumberType) {\r
370             NumberType nt = (NumberType) dt;\r
371             Binding ntb = Bindings.getBindingUnchecked(Datatype.class);\r
372             nt.setRange(newRange);\r
373 \r
374             Layer0 L0 = Layer0.getInstance(graph);\r
375             Layer0X L0X = Layer0X.getInstance(graph);\r
376 \r
377             graph.claimLiteral(object, L0.HasDataType, L0.DataType, nt, ntb);\r
378             graph.claimLiteral(relation, L0X.RequiresDataType, L0.DataType, nt, ntb);\r
379             \r
380             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
381             graph.addMetadata(cm.add("Setted range " + newRange + " for component/annotation " + type));\r
382         }\r
383     }\r
384 \r
385     public static Tuple getDatatypeValueAndBinding(ReadGraph g, Resource object, String newSCLType) throws DatabaseException {\r
386 \r
387         Datatype newDatatype = TypeConversion.convertSCLTypeToDatatype(newSCLType);\r
388         if(newDatatype == null) {\r
389             System.err.println("Couldn't convert default value to <" + newSCLType + ">.");\r
390             return null;\r
391         }\r
392         Binding newBinding = Bindings.getBinding(newDatatype);\r
393 \r
394         Datatype oldDatatype = g.getDataType(object);\r
395         Binding oldBinding = Bindings.getBinding(oldDatatype);\r
396 \r
397         Object oldValue = g.getValue(object, oldBinding);\r
398         Object newValue;\r
399         try {\r
400             newValue = Bindings.adapt(oldValue, oldBinding, newBinding);\r
401         } catch (AdaptException e) {\r
402             try {\r
403                 newValue = newBinding.createDefault();\r
404             } catch (BindingException e1) {\r
405                 e1.printStackTrace();\r
406                 return null;\r
407             }\r
408         }\r
409 \r
410         return new Tuple3(newDatatype, newValue, newBinding);\r
411 \r
412     }\r
413 \r
414     public static void convertDefaultValue(WriteGraph g,\r
415             Resource type, Resource relation, String newSCLType) throws DatabaseException {\r
416         Resource object = getAssertedObject(g, type, relation);\r
417         if(object == null) {\r
418             System.err.println("Didn't find assertion for " + NameUtils.getSafeName(g, relation) + \r
419                     " in " + NameUtils.getSafeName(g, type) + ".");\r
420             return;\r
421         }\r
422 \r
423         Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);\r
424         if (tuple == null)\r
425             return;\r
426 \r
427         Layer0 L0 = Layer0.getInstance(g);\r
428         g.claimLiteral(object, L0.HasDataType, L0.DataType, tuple.get(0), Bindings.getBindingUnchecked(Datatype.class));\r
429         g.claimLiteral(object, L0.HasValueType, g.<String>getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING), Bindings.STRING);\r
430         g.claimValue(object, tuple.get(1), (Binding)tuple.get(2));\r
431 \r
432     }\r
433 \r
434     public static void convertInstantiatedValue(WriteGraph g, Resource instance, Resource relation, String newSCLType)\r
435             throws DatabaseException {\r
436 \r
437         Statement stm = g.getPossibleStatement(instance, relation);\r
438         if(stm != null && !stm.isAsserted(instance)) {\r
439 \r
440             Resource object = stm.getObject();\r
441 \r
442             // We can only convert literals\r
443             Layer0 L0 = Layer0.getInstance(g);\r
444             if(!g.isInstanceOf(object, L0.Literal)) return;\r
445 \r
446             Tuple tuple = getDatatypeValueAndBinding(g, object, newSCLType);\r
447 \r
448             g.claimLiteral(object, L0.HasDataType, L0.DataType, tuple.get(0), Bindings.getBindingUnchecked(Datatype.class));\r
449             g.claimLiteral(object, L0.HasValueType, g.<String>getRelatedValue(relation, L0.RequiresValueType, Bindings.STRING), Bindings.STRING);\r
450             g.claimValue(object, tuple.get(1), (Binding)tuple.get(2));\r
451 \r
452         }\r
453 \r
454     }\r
455 \r
456     /**\r
457      * @param graph graph write transaction handle\r
458      * @param relation component type property relation to edit\r
459      * @param newDescription new label or <code>null</code> to remove label\r
460      * @throws DatabaseException \r
461      */\r
462     public static void setLabel(WriteGraph graph, Resource relation, String newLabel) throws DatabaseException {\r
463         setProperty(graph, relation, Layer0.getInstance(graph).HasLabel, newLabel);\r
464         \r
465         CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
466         graph.addMetadata(cm.add("Setted label " + newLabel + " for component/annotation " + relation));\r
467     }\r
468 \r
469     /**\r
470      * @param graph graph write transaction handle\r
471      * @param relation component type property relation to edit\r
472      * @param newDescription new description or <code>null</code> if new description\r
473      * @throws DatabaseException \r
474      */\r
475     public static void setDescription(WriteGraph graph, Resource relation, String newDescription) throws DatabaseException {\r
476         setProperty(graph, relation, Layer0.getInstance(graph).HasDescription, newDescription);        \r
477         CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
478         graph.addMetadata(cm.add("Setted description " + newDescription + " for component/annotation " + relation));\r
479     }\r
480 \r
481     /**\r
482      * @param graph graph write transaction handle\r
483      * @param relation component type property relation to edit\r
484      * @param newValue new property value or <code>null</code> to remove property\r
485      * @throws DatabaseException \r
486      */\r
487     public static void setProperty(WriteGraph graph, Resource relation, Resource property, String newValue) throws DatabaseException {\r
488         if (newValue != null) {\r
489             graph.claimLiteral(relation, property, newValue, Bindings.STRING);\r
490         } else {\r
491             graph.denyValue(relation, property);\r
492         }\r
493     }\r
494 \r
495     /**\r
496      * @param graph\r
497      * @param componentType\r
498      * @return the created symbol\r
499      */\r
500     public static Resource createSymbol(WriteGraph graph, Resource componentType) throws DatabaseException {\r
501         return NewSymbol.createSymbol(graph, componentType);\r
502     }\r
503 \r
504     /**\r
505      * Converts to a <code>camelCase</code> name to a more user-readable\r
506      * <code>Camel Case</code> label.\r
507      * \r
508      * <p>\r
509      * Examples\r
510      * <pre>\r
511      * "fooBarBazBAR" => "Foo Bar Baz BAR"\r
512      * " fooBarBazBAR" => " Foo Bar Baz BAR"\r
513      * "_fooBarBazBAR" => "_Foo Bar Baz BAR"\r
514      * "_FooBarBazBAR" => "_Foo Bar Baz BAR"\r
515      * " _ fooBarBazBAR" => " _ Foo Bar Baz BAR"\r
516      * </pre>\r
517      * \r
518      * @param str camelCase SCL identifier name\r
519      * @return labelified Camel Case string\r
520      */\r
521     public static String camelCaseNameToLabel(String str) {\r
522         int len = str.length();\r
523         StringBuilder sb = new StringBuilder(len*2);\r
524 \r
525         boolean wasLastUpper = false;\r
526         boolean isFirstEncounteredLetter = true;\r
527 \r
528         for (int i = 0; i < len; ++i) {\r
529             char ch = str.charAt(i);\r
530 \r
531             boolean space = Character.isWhitespace(ch);\r
532             if (space) {\r
533                 sb.append(ch);\r
534                 continue;\r
535             }\r
536 \r
537             boolean isUpperCaseLetter = Character.isUpperCase(ch);\r
538             boolean isLetterOrDigit = Character.isLetterOrDigit(ch);\r
539             if (!isFirstEncounteredLetter && isUpperCaseLetter && !wasLastUpper && isLetterOrDigit) {\r
540                 sb.append(' ');\r
541                 sb.append(ch);\r
542             } else {\r
543                 if (isLetterOrDigit && isFirstEncounteredLetter)\r
544                     sb.append(Character.toUpperCase(ch));\r
545                 else\r
546                     sb.append(ch);\r
547                 if (isFirstEncounteredLetter)\r
548                     isFirstEncounteredLetter = !isLetterOrDigit;\r
549             }\r
550             wasLastUpper = isUpperCaseLetter;\r
551         }\r
552         return sb.toString();\r
553     }\r
554 \r
555     public static void saveProceduralCodeWithUC(WriteGraph graph, Resource componentType, String newText) throws DatabaseException {\r
556         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
557         Resource code = graph.getPossibleObject(componentType, STR.ProceduralComponentType_code);\r
558         saveProceduralCode(graph, code, newText);\r
559     }\r
560     \r
561     public static void saveProceduralCode(WriteGraph graph, Resource resource, String newText) throws ServiceException {\r
562         graph.claimValue(resource, newText, Bindings.STRING);\r
563         Layer0Utils.addCommentMetadata(graph, "Saved Procedural Component Type SCL Code");\r
564     }\r
565 }\r