1 package org.simantics.db.layer0.variable;
\r
3 import java.text.Format;
\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
27 public class SubliteralPropertyVariableDeprecated extends AbstractPropertyVariable {
\r
29 private final Variable parent;
\r
30 private final ChildReference reference;
\r
32 public SubliteralPropertyVariableDeprecated(Variable parent, ChildReference reference) {
\r
33 this.parent = parent;
\r
34 this.reference = reference;
\r
38 public Variable getPredicate(ReadGraph graph) throws DatabaseException {
\r
39 return parent.getPredicate(graph);
\r
43 public Resource getPropertyResource(ReadGraph graph) throws DatabaseException {
\r
44 if (parent instanceof AbstractPropertyVariable) {
\r
45 return ((AbstractPropertyVariable) parent).getPropertyResource(graph);
\r
47 throw new RuntimeDatabaseException("not supported for parent " + parent);
\r
51 public Resource getContainerResource(ReadGraph graph) throws DatabaseException {
\r
52 if (parent instanceof AbstractPropertyVariable) {
\r
53 return ((AbstractPropertyVariable) parent).getContainerResource(graph);
\r
55 throw new RuntimeDatabaseException("not supported for parent " + parent);
\r
58 static class DisplayPropertyVariable extends ValueProxyVariable {
\r
60 private String suffix;
\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
68 public boolean equals(Object obj) {
\r
71 if (!(obj instanceof DisplayPropertyVariable))
\r
73 DisplayPropertyVariable other = (DisplayPropertyVariable) obj;
\r
74 return proxy.equals(other.proxy) && suffix.equals(suffix);
\r
78 public int hashCode() {
\r
79 return proxy.hashCode() * 31 + suffix.hashCode();
\r
84 public String getURI(ReadGraph graph) throws DatabaseException {
\r
85 return parent.getURI(graph) + Role.PROPERTY.getIdentifier() + getName(graph);
\r
89 public String getName(ReadGraph graph) throws DatabaseException {
\r
90 return Variables.DISPLAY_PROPERTY;
\r
94 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
\r
95 return Datatypes.STRING;
\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
106 public <T> T getPossibleValue(ReadGraph graph) throws DatabaseException {
\r
107 return getPossibleValue(graph, Bindings.STRING);
\r
110 @SuppressWarnings("unchecked")
\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
118 public <T> T getValue(ReadGraph graph) throws DatabaseException {
\r
119 return getValue(graph, Bindings.STRING);
\r
122 @SuppressWarnings("unchecked")
\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
128 public Variant getVariantValue(ReadGraph graph) throws DatabaseException {
\r
129 return new Variant(Bindings.STRING, getValue(graph, Bindings.STRING));
\r
134 static class DisplayUnitVariable extends ValueProxyVariable {
\r
136 public DisplayUnitVariable(Variable proxy, Variable parent) {
\r
137 super(proxy, parent);
\r
140 public boolean equals(Object obj) {
\r
143 if (!(obj instanceof DisplayUnitVariable))
\r
145 DisplayUnitVariable other = (DisplayUnitVariable) obj;
\r
146 return proxy.equals(other.proxy);
\r
150 public int hashCode() {
\r
151 return proxy.hashCode() * 53;
\r
155 public String getURI(ReadGraph graph) throws DatabaseException {
\r
156 return parent.getURI(graph) + Role.PROPERTY.getIdentifier() + getName(graph);
\r
160 public String getName(ReadGraph graph) throws DatabaseException {
\r
161 return Variables.DISPLAY_UNIT;
\r
165 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
\r
166 return Datatypes.STRING;
\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
177 public <T> T getPossibleValue(ReadGraph graph) throws DatabaseException {
\r
178 return getPossibleValue(graph, Bindings.STRING);
\r
182 public <T> T getPossibleValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
183 return proxy.getPossiblePropertyValue(graph, Variables.DISPLAY_UNIT, Bindings.STRING);
\r
187 public <T> T getValue(ReadGraph graph) throws DatabaseException {
\r
188 return getValue(graph, Bindings.STRING);
\r
192 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
193 return proxy.getPropertyValue(graph, Variables.DISPLAY_UNIT, binding);
\r
196 public Variant getVariantValue(ReadGraph graph) throws DatabaseException {
\r
197 return new Variant(Bindings.STRING, getValue(graph, Bindings.STRING));
\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
207 String format = formatter.format(reference);
\r
208 if (format != null)
\r
210 } catch (IllegalArgumentException e) {
\r
211 // Ignore it this, use default formatting.
\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
219 return reference.toString();
\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
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
234 return new ConstantPropertyVariable(this, name, value, Bindings.STRING);
\r
235 } else if (Variables.PREDICATE.equals(name)) {
\r
236 Object value = getPossiblePredicate(graph);
\r
238 return new ConstantPropertyVariable(this, name, value, null);
\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
253 @SuppressWarnings("unchecked")
\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
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
270 throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");
\r
273 @SuppressWarnings("unchecked")
\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
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
293 throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");
\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
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
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
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
339 if (componentClass.equals(String.class))
\r
340 return Bindings.STRING_ARRAY;
\r
341 return new GenericArrayBinding(arrayClass, new ArrayType(binding.type()), binding);
\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
353 // Only adapt if necessary.
\r
354 return Bindings.adapt(indexValue, from, to);
\r
358 public String getName(ReadGraph graph) throws DatabaseException {
\r
359 return reference.toString(false);
\r
363 // public Object getSerialized(ReadGraph graph) throws DatabaseException {
\r
364 // return reference.toString(false);
\r
368 public Variable getParent(ReadGraph graph) throws DatabaseException {
\r
373 public Role getRole(ReadGraph graph) throws DatabaseException {
\r
378 public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException {
\r
379 return new StringRVIPart(Role.CHILD, reference.toString(false));
\r
383 public boolean equals(Object obj) {
\r
384 if (!super.equals(obj))
\r
386 if (!(obj instanceof SubliteralPropertyVariableDeprecated))
\r
388 SubliteralPropertyVariableDeprecated other = (SubliteralPropertyVariableDeprecated) obj;
\r
389 return reference.equals(other.reference);
\r
393 public int hashCode() {
\r
394 return super.hashCode() * 31 + reference.hashCode();
\r