]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/SubliteralPropertyVariableDeprecated.java
Merge commit 'ad8333027322fda6b9a8a524c7a7e15a54c52f38'
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / variable / SubliteralPropertyVariableDeprecated.java
1 package org.simantics.db.layer0.variable;\r
2 \r
3 import java.text.Format;\r
4 \r
5 import org.simantics.databoard.Bindings;\r
6 import org.simantics.databoard.Datatypes;\r
7 import org.simantics.databoard.accessor.reference.ChildReference;\r
8 import org.simantics.databoard.accessor.reference.IndexReference;\r
9 import org.simantics.databoard.adapter.AdaptException;\r
10 import org.simantics.databoard.binding.ArrayBinding;\r
11 import org.simantics.databoard.binding.Binding;\r
12 import org.simantics.databoard.binding.error.BindingException;\r
13 import org.simantics.databoard.binding.mutable.Variant;\r
14 import org.simantics.databoard.binding.reflection.GenericArrayBinding;\r
15 import org.simantics.databoard.type.ArrayType;\r
16 import org.simantics.databoard.type.Datatype;\r
17 import org.simantics.db.ReadGraph;\r
18 import org.simantics.db.Resource;\r
19 import org.simantics.db.WriteGraph;\r
20 import org.simantics.db.exception.DatabaseException;\r
21 import org.simantics.db.exception.RuntimeDatabaseException;\r
22 import org.simantics.db.layer0.variable.RVI.RVIPart;\r
23 import org.simantics.db.layer0.variable.RVI.StringRVIPart;\r
24 import org.simantics.db.layer0.variable.Variables.Role;\r
25 import org.simantics.operation.Layer0X;\r
26 \r
27 public class SubliteralPropertyVariableDeprecated extends AbstractPropertyVariable {\r
28         \r
29         private final Variable parent;\r
30         private final ChildReference reference;\r
31 \r
32         public SubliteralPropertyVariableDeprecated(Variable parent, ChildReference reference) {\r
33                 this.parent = parent;\r
34                 this.reference = reference;\r
35         }\r
36 \r
37         @Override\r
38         public Variable getPredicate(ReadGraph graph) throws DatabaseException {\r
39                 return parent.getPredicate(graph);\r
40         }\r
41 \r
42         @Override\r
43         public Resource getPropertyResource(ReadGraph graph) throws DatabaseException {\r
44                 if (parent instanceof AbstractPropertyVariable) {\r
45                         return ((AbstractPropertyVariable) parent).getPropertyResource(graph);\r
46                 }\r
47                 throw new RuntimeDatabaseException("not supported for parent " + parent);\r
48         }\r
49 \r
50         @Override\r
51         public Resource getContainerResource(ReadGraph graph) throws DatabaseException {\r
52                 if (parent instanceof AbstractPropertyVariable) {\r
53                         return ((AbstractPropertyVariable) parent).getContainerResource(graph);\r
54                 }\r
55                 throw new RuntimeDatabaseException("not supported for parent " + parent);\r
56         }\r
57 \r
58         static class DisplayPropertyVariable extends ValueProxyVariable {\r
59 \r
60                 private String suffix;\r
61 \r
62                 public DisplayPropertyVariable(Variable proxy, Variable parent, String suffix) {\r
63                         super(proxy, parent);\r
64                         assert suffix != null;\r
65                         this.suffix = suffix;\r
66                 }\r
67 \r
68                 public boolean equals(Object obj) {\r
69                         if (this == obj)\r
70                                 return true;\r
71                         if (!(obj instanceof DisplayPropertyVariable))\r
72                                 return false;\r
73                         DisplayPropertyVariable other = (DisplayPropertyVariable) obj;\r
74                         return proxy.equals(other.proxy) && suffix.equals(suffix);\r
75                 }\r
76 \r
77                 @Override\r
78                 public int hashCode() {\r
79                         return proxy.hashCode() * 31 + suffix.hashCode();\r
80                 }\r
81 \r
82 \r
83                 @Override\r
84                 public String getURI(ReadGraph graph) throws DatabaseException {\r
85                         return parent.getURI(graph) + Role.PROPERTY.getIdentifier() + getName(graph);\r
86                 }\r
87 \r
88                 @Override\r
89                 public String getName(ReadGraph graph) throws DatabaseException {\r
90                         return Variables.DISPLAY_PROPERTY;\r
91                 }\r
92 \r
93                 @Override\r
94                 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {\r
95                         return Datatypes.STRING;\r
96                 }\r
97 \r
98                 @Override\r
99                 public RVI getRVI(ReadGraph graph) throws DatabaseException {\r
100                         return new RVIBuilder(parent.getRVI(graph))\r
101                                 .append(new StringRVIPart(Role.PROPERTY, getName(graph)))\r
102                                 .toRVI();\r
103                 }\r
104 \r
105                 @Override\r
106                 public <T> T getPossibleValue(ReadGraph graph) throws DatabaseException {\r
107                         return getPossibleValue(graph, Bindings.STRING);\r
108                 }\r
109 \r
110                 @SuppressWarnings("unchecked")\r
111                 @Override\r
112                 public <T> T getPossibleValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
113                         String str = proxy.getPossiblePropertyValue(graph, Variables.DISPLAY_PROPERTY, Bindings.STRING);\r
114                         return (T) (str != null ? str + " " + suffix : null);\r
115                 }\r
116 \r
117                 @Override\r
118                 public <T> T getValue(ReadGraph graph) throws DatabaseException {\r
119                         return getValue(graph, Bindings.STRING);\r
120                 }\r
121 \r
122                 @SuppressWarnings("unchecked")\r
123                 @Override\r
124                 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
125                         return (T) (proxy.getPropertyValue(graph, Variables.DISPLAY_PROPERTY, binding) + " " + suffix);\r
126                 }\r
127 \r
128                 public Variant getVariantValue(ReadGraph graph) throws DatabaseException {\r
129                         return new Variant(Bindings.STRING, getValue(graph, Bindings.STRING));\r
130                 }\r
131 \r
132         }\r
133 \r
134         static class DisplayUnitVariable extends ValueProxyVariable {\r
135 \r
136                 public DisplayUnitVariable(Variable proxy, Variable parent) {\r
137                         super(proxy, parent);\r
138                 }\r
139 \r
140                 public boolean equals(Object obj) {\r
141                         if (this == obj)\r
142                                 return true;\r
143                         if (!(obj instanceof DisplayUnitVariable))\r
144                                 return false;\r
145                         DisplayUnitVariable other = (DisplayUnitVariable) obj;\r
146                         return proxy.equals(other.proxy);\r
147                 }\r
148 \r
149                 @Override\r
150                 public int hashCode() {\r
151                         return proxy.hashCode() * 53;\r
152                 }\r
153 \r
154                 @Override\r
155                 public String getURI(ReadGraph graph) throws DatabaseException {\r
156                         return parent.getURI(graph) + Role.PROPERTY.getIdentifier() + getName(graph);\r
157                 }\r
158 \r
159                 @Override\r
160                 public String getName(ReadGraph graph) throws DatabaseException {\r
161                         return Variables.DISPLAY_UNIT;\r
162                 }\r
163 \r
164                 @Override\r
165                 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {\r
166                         return Datatypes.STRING;\r
167                 }\r
168 \r
169                 @Override\r
170                 public RVI getRVI(ReadGraph graph) throws DatabaseException {\r
171                         return new RVIBuilder(parent.getRVI(graph))\r
172                                 .append(new StringRVIPart(Role.PROPERTY, getName(graph)))\r
173                                 .toRVI();\r
174                 }\r
175 \r
176                 @Override\r
177                 public <T> T getPossibleValue(ReadGraph graph) throws DatabaseException {\r
178                         return getPossibleValue(graph, Bindings.STRING);\r
179                 }\r
180 \r
181                 @Override\r
182                 public <T> T getPossibleValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
183                         return proxy.getPossiblePropertyValue(graph, Variables.DISPLAY_UNIT, Bindings.STRING);\r
184                 }\r
185 \r
186                 @Override\r
187                 public <T> T getValue(ReadGraph graph) throws DatabaseException {\r
188                         return getValue(graph, Bindings.STRING);\r
189                 }\r
190 \r
191                 @Override\r
192                 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
193                         return proxy.getPropertyValue(graph, Variables.DISPLAY_UNIT, binding);\r
194                 }\r
195 \r
196                 public Variant getVariantValue(ReadGraph graph) throws DatabaseException {\r
197                         return new Variant(Bindings.STRING, getValue(graph, Bindings.STRING));\r
198                 }\r
199 \r
200         }\r
201 \r
202         protected String getReferenceString(ReadGraph graph) throws DatabaseException {\r
203                 Layer0X L0X = Layer0X.getInstance(graph);\r
204                 Format formatter = parent.getPossiblePropertyValue(graph, L0X.HasChildReferenceFormatter);\r
205                 if (formatter != null) {\r
206                         try {\r
207                                 String format = formatter.format(reference);\r
208                                 if (format != null)\r
209                                         return format;\r
210                         } catch (IllegalArgumentException e) {\r
211                                 // Ignore it this, use default formatting.\r
212                         }\r
213                 }\r
214                 if (reference instanceof IndexReference) {\r
215                         // Fallback logic [i] where 0 <= i <= N-1, N = sizeof(array)\r
216                         IndexReference index = (IndexReference) reference;\r
217                         return "[" + index.getIndex() + "]";\r
218                 }\r
219                 return reference.toString();\r
220         }\r
221 \r
222         public Variable getPossibleExtraProperty(ReadGraph graph, String name) throws DatabaseException {\r
223                 if (Variables.DISPLAY_PROPERTY.equals(name)) {\r
224                         return new DisplayPropertyVariable(parent, this, getReferenceString(graph));\r
225                 } else if (Variables.DISPLAY_UNIT.equals(name)) {\r
226                         return new DisplayUnitVariable(parent, this);\r
227                 } /*else if (Variables.DATATYPE.equals(name)) {\r
228                         Object value = getPossibleDatatype(graph);\r
229                         if (value != null)\r
230                                 return new ConstantPropertyVariable(this, name, value, datatype_binding);\r
231                 } else if (Variables.UNIT.equals(name)) {\r
232                         Object value = parent.getPossiblePropertyValue(graph, name);\r
233                         if (value != null)\r
234                                 return new ConstantPropertyVariable(this, name, value, Bindings.STRING);\r
235                 } else if (Variables.PREDICATE.equals(name)) {\r
236                         Object value = getPossiblePredicate(graph);\r
237                         if (value != null)\r
238                                 return new ConstantPropertyVariable(this, name, value, null);\r
239                 } */\r
240                 return null;\r
241         }\r
242 \r
243         @Override\r
244         public Datatype getDatatype(ReadGraph graph) throws DatabaseException {\r
245                 Datatype parentType = parent.getDatatype(graph);\r
246                 if(parentType instanceof ArrayType) {\r
247                         ArrayType at = (ArrayType)parentType;\r
248                         return at.getComponentType(0);\r
249                 }\r
250                 return null;\r
251         }\r
252 \r
253         @SuppressWarnings("unchecked")\r
254         @Override\r
255         public <T> T getValue(ReadGraph graph) throws DatabaseException {\r
256                 Object parentValue = parent.getValue(graph);\r
257                 Datatype parentType = parent.getDatatype(graph);\r
258                 Binding parentBinding = Bindings.getBinding(parentType);\r
259                 if (parentType instanceof ArrayType) {\r
260                         ArrayBinding ab = (ArrayBinding)parentBinding;\r
261                         IndexReference ref = (IndexReference)reference;\r
262                         try {\r
263                                 return (T)ab.get(parentValue, ref.index);\r
264                         } catch (IndexOutOfBoundsException e) {\r
265                                 throw new RuntimeDatabaseException(e);\r
266                         } catch (BindingException e) {\r
267                                 throw new RuntimeDatabaseException(e);\r
268                         }\r
269                 }\r
270                 throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");\r
271         }\r
272 \r
273         @SuppressWarnings("unchecked")\r
274         @Override\r
275         public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
276                 Object parentValue = parent.getValue(graph);\r
277                 Datatype parentType = parent.getDatatype(graph);\r
278                 Binding parentBinding = Bindings.getBinding(parentType);\r
279                 if (parentType instanceof ArrayType) {\r
280                         ArrayBinding ab = (ArrayBinding)parentBinding;\r
281                         IndexReference ref = (IndexReference)reference;\r
282                         try {\r
283                                 Object indexValue = ab.get(parentValue, ref.index);\r
284                                 return (T) Bindings.adapt(indexValue, ab.getComponentBinding(), binding);\r
285                         } catch (IndexOutOfBoundsException e) {\r
286                                 throw new RuntimeDatabaseException(e);\r
287                         } catch (BindingException e) {\r
288                                 throw new RuntimeDatabaseException(e);\r
289                         } catch (AdaptException e) {\r
290                                 throw new RuntimeDatabaseException(e);\r
291                         }\r
292                 }\r
293                 throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");\r
294         }\r
295 \r
296         @Override\r
297         public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException {\r
298                 Object parentValue = parent.getValue(graph);\r
299                 Datatype parentType = parent.getDatatype(graph);\r
300                 if(parentType instanceof ArrayType) {\r
301                         Binding parentBinding = Bindings.getBinding(parentType);\r
302                         ArrayBinding ab = (ArrayBinding)parentBinding;\r
303                         IndexReference ref = (IndexReference)reference;\r
304                         try {\r
305                                 Object indexValue = adaptValueForArray(parentValue, value, binding, ab.getComponentBinding());\r
306                                 if (indexValue == value) {\r
307                                         // Adaption was passthrough, trust specified binding and\r
308                                         // create a generic array binding out of it.\r
309                                         ab = resolveArrayBinding(parentValue.getClass(), binding);\r
310                                 }\r
311                                 ab.set(parentValue, ref.index, indexValue);\r
312                                 parent.setValue(graph, parentValue, ab);\r
313                         } catch (IndexOutOfBoundsException e) {\r
314                                 throw new RuntimeDatabaseException(e);\r
315                         } catch (BindingException e) {\r
316                                 throw new RuntimeDatabaseException(e);\r
317                         } catch (AdaptException e) {\r
318                                 throw new RuntimeDatabaseException(e);\r
319                         }\r
320                 }\r
321         }\r
322 \r
323         private ArrayBinding resolveArrayBinding(Class<? extends Object> arrayClass, Binding binding) {\r
324                 Class<?> componentClass = arrayClass.getComponentType();\r
325                 if (componentClass.isPrimitive()) {\r
326                         if (componentClass == boolean.class)\r
327                                 return Bindings.BOOLEAN_ARRAY;\r
328                         if (componentClass == byte.class)\r
329                                 return Bindings.BYTE_ARRAY;\r
330                         if (componentClass == int.class)\r
331                                 return Bindings.INT_ARRAY;\r
332                         if (componentClass == long.class)\r
333                                 return Bindings.LONG_ARRAY;\r
334                         if (componentClass == float.class)\r
335                                 return Bindings.FLOAT_ARRAY;\r
336                         if (componentClass == double.class)\r
337                                 return Bindings.DOUBLE_ARRAY;\r
338                 }\r
339                 if (componentClass.equals(String.class))\r
340                         return Bindings.STRING_ARRAY;\r
341                 return new GenericArrayBinding(arrayClass, new ArrayType(binding.type()), binding);\r
342         }\r
343 \r
344         private Object adaptValueForArray(Object array, Object indexValue, Binding from, Binding to) throws AdaptException {\r
345                 Class<?> arrayType = array.getClass();\r
346                 if (!arrayType.isArray())\r
347                         throw new AdaptException("array " + array + " is not of an array class");\r
348                 Class<?> arrayComponentType = arrayType.getComponentType();\r
349                 if (arrayComponentType.isAssignableFrom(indexValue.getClass())) {\r
350                         // Type match, be happy.\r
351                         return indexValue;\r
352                 }\r
353                 // Only adapt if necessary.\r
354                 return Bindings.adapt(indexValue, from, to);\r
355         }\r
356 \r
357         @Override\r
358         public String getName(ReadGraph graph) throws DatabaseException {\r
359                 return reference.toString(false);\r
360         }\r
361 \r
362 //      @Override\r
363 //      public Object getSerialized(ReadGraph graph) throws DatabaseException {\r
364 //              return reference.toString(false);\r
365 //      }\r
366 \r
367         @Override\r
368         public Variable getParent(ReadGraph graph) throws DatabaseException {\r
369                 return parent;\r
370         }\r
371 \r
372         @Override\r
373         public Role getRole(ReadGraph graph) throws DatabaseException {\r
374                 return Role.CHILD;\r
375         }\r
376 \r
377         @Override\r
378         public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException {\r
379                 return new StringRVIPart(Role.CHILD, reference.toString(false));\r
380         }\r
381 \r
382         @Override\r
383         public boolean equals(Object obj) {\r
384                 if (!super.equals(obj))\r
385                         return false;\r
386                 if (!(obj instanceof SubliteralPropertyVariableDeprecated))\r
387                         return false;\r
388                 SubliteralPropertyVariableDeprecated other = (SubliteralPropertyVariableDeprecated) obj;\r
389                 return reference.equals(other.reference);\r
390         }\r
391 \r
392         @Override\r
393         public int hashCode() {\r
394                 return super.hashCode() * 31 + reference.hashCode();\r
395         }\r
396 \r
397 }\r