+package org.simantics.db.layer0.variable;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.reference.ChildReference;\r
+import org.simantics.databoard.accessor.reference.IndexReference;\r
+import org.simantics.databoard.accessor.reference.NameReference;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.ArrayBinding;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.RecordBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+\r
+public class SubliteralPropertyVariable extends StandardGraphPropertyVariable {\r
+ \r
+ private final ChildReference reference;\r
+\r
+ public SubliteralPropertyVariable(ReadGraph graph, Variable parent, Resource predicate, ChildReference reference) throws DatabaseException {\r
+ super(graph, parent, null, predicate);\r
+ this.reference = reference;\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(ReadGraph graph) throws DatabaseException {\r
+ Datatype parentType = parent.getDatatype(graph);\r
+ if(parentType instanceof ArrayType) {\r
+ ArrayType at = (ArrayType)parentType;\r
+ return at.getComponentType(0);\r
+ } else if(parentType instanceof RecordType) {\r
+ RecordType rt = (RecordType)parentType;\r
+ NameReference nr = (NameReference)reference;\r
+ return rt.getComponent(nr.name).type;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getValue(ReadGraph graph) throws DatabaseException {\r
+ Object parentValue = parent.getValue(graph);\r
+ Datatype parentType = parent.getDatatype(graph);\r
+ Binding parentBinding = Bindings.getBinding(parentType);\r
+ if (parentType instanceof ArrayType) {\r
+ ArrayBinding ab = (ArrayBinding)parentBinding;\r
+ IndexReference ref = (IndexReference)reference;\r
+ try {\r
+ return (T)ab.get(parentValue, ref.index);\r
+ } catch (IndexOutOfBoundsException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ } else if (parentType instanceof RecordType) {\r
+ RecordBinding rb = (RecordBinding)parentBinding;\r
+ NameReference ref = (NameReference)reference;\r
+ try {\r
+ return (T)rb.getComponentObject(parentValue, ref.name);\r
+ } catch (IndexOutOfBoundsException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ }\r
+\r
+ throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
+ Object parentValue = parent.getValue(graph);\r
+ Datatype parentType = parent.getDatatype(graph);\r
+ Binding parentBinding = Bindings.getBinding(parentType);\r
+ if (parentType instanceof ArrayType) {\r
+ ArrayBinding ab = (ArrayBinding)parentBinding;\r
+ IndexReference ref = (IndexReference)reference;\r
+ try {\r
+ Object indexValue = ab.get(parentValue, ref.index);\r
+ return (T) Bindings.adapt(indexValue, ab.getComponentBinding(), binding);\r
+ } catch (IndexOutOfBoundsException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (AdaptException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ } else if (parentType instanceof RecordType) {\r
+ RecordBinding rb = (RecordBinding)parentBinding;\r
+ NameReference ref = (NameReference)reference;\r
+ try {\r
+ Object nameValue = (T)rb.getComponentObject(parentValue, ref.name); \r
+ return (T) Bindings.adapt(nameValue, rb.getComponentBinding(ref.name), binding);\r
+ } catch (IndexOutOfBoundsException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (AdaptException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ }\r
+\r
+ throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");\r
+ }\r
+\r
+ @Override\r
+ public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException {\r
+ Object parentValue = parent.getValue(graph);\r
+ Datatype parentType = parent.getDatatype(graph);\r
+ Binding parentBinding = Bindings.getBinding(parentType);\r
+ if(parentType instanceof ArrayType) {\r
+ ArrayBinding ab = (ArrayBinding)parentBinding;\r
+ IndexReference ref = (IndexReference)reference;\r
+ try {\r
+ Object copy = parentBinding.clone(parentValue);\r
+ Object indexValue = Bindings.adapt(value, binding, ab.getComponentBinding());\r
+ ab.set(copy, ref.index, indexValue);\r
+ parent.setValue(graph, copy, parentBinding);\r
+ } catch (IndexOutOfBoundsException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (AdaptException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ } else if(parentType instanceof RecordType) {\r
+ RecordBinding rb = (RecordBinding)parentBinding;\r
+ NameReference ref = (NameReference)reference;\r
+ try {\r
+ Object copy = parentBinding.clone(parentValue);\r
+ Object indexValue = Bindings.adapt(value, binding, rb.getComponentBinding(ref.name));\r
+ rb.setComponent(copy, ref.name, indexValue);\r
+ parent.setValue(graph, copy, parentBinding);\r
+ } catch (IndexOutOfBoundsException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ } catch (AdaptException e) {\r
+ throw new RuntimeDatabaseException(e);\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String getName(ReadGraph graph) throws DatabaseException {\r
+ return reference.toString(true);\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ \r
+ if(!super.equals(obj)) return false;\r
+ \r
+ if(!(obj instanceof SubliteralPropertyVariable)) return false;\r
+ \r
+ SubliteralPropertyVariable other = (SubliteralPropertyVariable)obj;\r
+ \r
+ return reference.equals(other.reference);\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public int hashCode() {\r
+ return super.hashCode() + 31 * reference.hashCode();\r
+ }\r
+ \r
+}\r