]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableUtils.java
Merge commit 'ad8333027322fda6b9a8a524c7a7e15a54c52f38'
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / variable / VariableUtils.java
1 package org.simantics.db.layer0.variable;\r
2 \r
3 import java.util.Map;\r
4 \r
5 import org.simantics.databoard.Bindings;\r
6 import org.simantics.databoard.adapter.AdaptException;\r
7 import org.simantics.databoard.adapter.Adapter;\r
8 import org.simantics.databoard.adapter.AdapterConstructionException;\r
9 import org.simantics.databoard.binding.Binding;\r
10 import org.simantics.databoard.type.Datatype;\r
11 import org.simantics.db.Resource;\r
12 import org.simantics.db.Statement;\r
13 import org.simantics.db.WriteGraph;\r
14 import org.simantics.db.common.request.EnumerationMap;\r
15 import org.simantics.db.common.request.IsEnumeratedValue;\r
16 import org.simantics.db.common.utils.CommonDBUtils;\r
17 import org.simantics.db.exception.DatabaseException;\r
18 import org.simantics.db.exception.RuntimeDatabaseException;\r
19 import org.simantics.db.layer0.util.Layer0Utils;\r
20 import org.simantics.layer0.Layer0;\r
21 import org.simantics.scl.runtime.function.Function4;\r
22 import org.simantics.scl.runtime.function.FunctionImpl4;\r
23 \r
24 public class VariableUtils {\r
25 \r
26         final private static Binding datatype_binding = Bindings.getBindingUnchecked(Datatype.class);\r
27         \r
28         public static Function4<WriteGraph, Variable, Object, Object, String> defaultInputModifier = new FunctionImpl4<WriteGraph, Variable, Object, Object, String>() {\r
29 \r
30                 public String apply(WriteGraph graph, Variable variable, Object value, Object _binding) {\r
31                         try {\r
32                                 return safeApply(graph, variable, value, _binding);\r
33                         } catch (DatabaseException e) {\r
34                                 throw new RuntimeDatabaseException(e);\r
35                         }\r
36                 }\r
37 \r
38                 public String safeApply(WriteGraph graph, Variable variable, Object value, Object _binding) throws DatabaseException {\r
39 \r
40                 Binding binding = (Binding)_binding;\r
41                 \r
42                         Variable parent = variable.getParent(graph);\r
43                         Resource property = variable.getPossiblePredicateResource(graph);\r
44                         Resource container = parent.getPossibleRepresents(graph);\r
45                         if(container == null) return null;\r
46                         if(property == null) return null;\r
47 \r
48                         CommonDBUtils.selectClusterSet(graph, container);\r
49 \r
50                         Statement object = graph.getPossibleStatement(container, property);\r
51                         if(object == null) return null;\r
52 \r
53                         Resource objectResource = object.getObject();\r
54                         if(graph.sync(new IsEnumeratedValue(objectResource))) {\r
55 \r
56                                 Layer0 L0 = Layer0.getInstance(graph);\r
57                                 Resource type = graph.getSingleObject(objectResource, L0.PartOf);\r
58                                 \r
59                                 Map<String, Resource> enumMap = graph.syncRequest(new EnumerationMap(type));\r
60                                 Resource newLiteral = enumMap.get(value);\r
61                                 graph.deny(container, property, objectResource);\r
62                                 graph.claim(container, property, newLiteral);\r
63                                 \r
64                                 return null;\r
65                                 \r
66                         }\r
67 \r
68                         Layer0 L0 = Layer0.getInstance(graph);\r
69                         Statement dt = graph.getPossibleStatement(objectResource, L0.HasDataType);\r
70                         if (dt == null) {\r
71                                 throw new DatabaseException("Can't write variable " + variable.getURI(graph) + " since its literal resource " + objectResource + " does not contain a datatype statement"); \r
72                         }\r
73 \r
74                         boolean needsCustomDatatype = !dt.isAsserted(objectResource);\r
75                         Datatype correctDatatype = graph.getValue(dt.getObject(), datatype_binding);\r
76                         Binding correctBinding = Bindings.getBinding(correctDatatype);\r
77 \r
78                         try {\r
79                                 Adapter adapter = Bindings.getTypeAdapter(binding, correctBinding);\r
80                                 Object correctValue = adapter.adapt(value);\r
81                                 if (correctValue == value) {\r
82                                         // Adapter is passthrough, i.e. the specified binding can be\r
83                                         // considered correct for the value.\r
84                                         correctBinding = binding;\r
85                                 }\r
86                                 value = correctValue;\r
87                         } catch (AdapterConstructionException e) {\r
88                                 throw new DatabaseException("Can't adapt values from source datatype '" + binding.type().toSingleLineString() + "' to target '" + correctDatatype.toSingleLineString() + "'");\r
89                         } catch (AdaptException e) {\r
90                                 throw new DatabaseException("Can't adapt value " + value + " from source datatype '" + binding.type().toSingleLineString() + "' to target '" + correctDatatype.toSingleLineString() + "'");\r
91                         }\r
92 \r
93                         if (object.isAsserted(container)) {\r
94                                 String sclType = needsCustomDatatype ? Layer0Utils.getSCLType(correctDatatype) : null;\r
95 \r
96                                 Resource type = graph.getPossibleType(objectResource, L0.Literal);\r
97                                 objectResource = graph.newResource();\r
98                                 graph.claim(objectResource, L0.InstanceOf, null, type);\r
99                                 graph.claim(container, property, objectResource);\r
100                                 if(needsCustomDatatype) {\r
101                                         graph.addLiteral(objectResource, L0.HasDataType, L0.HasDataType_Inverse, L0.DataType, correctDatatype, datatype_binding);\r
102                                         graph.addLiteral(objectResource, L0.HasValueType, L0.HasValueType_Inverse, L0.String, sclType, Bindings.STRING);\r
103                                 }\r
104                         }\r
105                         \r
106                         graph.claimValue(objectResource, value, correctBinding);\r
107                         return null;\r
108                         \r
109                 }\r
110                 \r
111         };\r
112         \r
113 }\r