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