1 package org.simantics.db.layer0.variable;
3 import org.simantics.databoard.Bindings;
4 import org.simantics.databoard.accessor.reference.ChildReference;
5 import org.simantics.databoard.accessor.reference.IndexReference;
6 import org.simantics.databoard.accessor.reference.NameReference;
7 import org.simantics.databoard.adapter.AdaptException;
8 import org.simantics.databoard.binding.ArrayBinding;
9 import org.simantics.databoard.binding.Binding;
10 import org.simantics.databoard.binding.RecordBinding;
11 import org.simantics.databoard.binding.error.BindingException;
12 import org.simantics.databoard.type.ArrayType;
13 import org.simantics.databoard.type.Datatype;
14 import org.simantics.databoard.type.RecordType;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.WriteGraph;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.db.exception.RuntimeDatabaseException;
21 public class SubliteralPropertyVariable extends StandardGraphPropertyVariable {
23 private final ChildReference reference;
25 public SubliteralPropertyVariable(ReadGraph graph, Variable parent, Resource predicate, ChildReference reference) throws DatabaseException {
26 super(graph, parent, null, predicate);
27 this.reference = reference;
31 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
32 Datatype parentType = parent.getDatatype(graph);
33 if(parentType instanceof ArrayType) {
34 ArrayType at = (ArrayType)parentType;
35 return at.getComponentType(0);
36 } else if(parentType instanceof RecordType) {
37 RecordType rt = (RecordType)parentType;
38 NameReference nr = (NameReference)reference;
39 return rt.getComponent(nr.name).type;
44 @SuppressWarnings("unchecked")
46 public <T> T getValue(ReadGraph graph) throws DatabaseException {
47 Object parentValue = parent.getValue(graph);
48 Datatype parentType = parent.getDatatype(graph);
49 Binding parentBinding = Bindings.getBinding(parentType);
50 if (parentType instanceof ArrayType) {
51 ArrayBinding ab = (ArrayBinding)parentBinding;
52 IndexReference ref = (IndexReference)reference;
54 return (T)ab.get(parentValue, ref.index);
55 } catch (IndexOutOfBoundsException e) {
56 throw new RuntimeDatabaseException(e);
57 } catch (BindingException e) {
58 throw new RuntimeDatabaseException(e);
60 } else if (parentType instanceof RecordType) {
61 RecordBinding rb = (RecordBinding)parentBinding;
62 NameReference ref = (NameReference)reference;
64 return (T)rb.getComponentObject(parentValue, ref.name);
65 } catch (IndexOutOfBoundsException e) {
66 throw new RuntimeDatabaseException(e);
67 } catch (BindingException e) {
68 throw new RuntimeDatabaseException(e);
72 throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");
75 @SuppressWarnings("unchecked")
77 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
78 Object parentValue = parent.getValue(graph);
79 Datatype parentType = parent.getDatatype(graph);
80 Binding parentBinding = Bindings.getBinding(parentType);
81 if (parentType instanceof ArrayType) {
82 ArrayBinding ab = (ArrayBinding)parentBinding;
83 IndexReference ref = (IndexReference)reference;
85 Object indexValue = ab.get(parentValue, ref.index);
86 return (T) Bindings.adapt(indexValue, ab.getComponentBinding(), binding);
87 } catch (IndexOutOfBoundsException e) {
88 throw new RuntimeDatabaseException(e);
89 } catch (BindingException e) {
90 throw new RuntimeDatabaseException(e);
91 } catch (AdaptException e) {
92 throw new RuntimeDatabaseException(e);
94 } else if (parentType instanceof RecordType) {
95 RecordBinding rb = (RecordBinding)parentBinding;
96 NameReference ref = (NameReference)reference;
98 Object nameValue = (T)rb.getComponentObject(parentValue, ref.name);
99 return (T) Bindings.adapt(nameValue, rb.getComponentBinding(ref.name), binding);
100 } catch (IndexOutOfBoundsException e) {
101 throw new RuntimeDatabaseException(e);
102 } catch (BindingException e) {
103 throw new RuntimeDatabaseException(e);
104 } catch (AdaptException e) {
105 throw new RuntimeDatabaseException(e);
109 throw new RuntimeDatabaseException("parent variable data type " + parentType + " is not an ArrayType");
113 public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException {
114 Object parentValue = parent.getValue(graph);
115 Datatype parentType = parent.getDatatype(graph);
116 Binding parentBinding = Bindings.getBinding(parentType);
117 if(parentType instanceof ArrayType) {
118 ArrayBinding ab = (ArrayBinding)parentBinding;
119 IndexReference ref = (IndexReference)reference;
121 Object copy = parentBinding.clone(parentValue);
122 Object indexValue = Bindings.adapt(value, binding, ab.getComponentBinding());
123 ab.set(copy, ref.index, indexValue);
124 parent.setValue(graph, copy, parentBinding);
125 } catch (IndexOutOfBoundsException e) {
126 throw new RuntimeDatabaseException(e);
127 } catch (BindingException e) {
128 throw new RuntimeDatabaseException(e);
129 } catch (AdaptException e) {
130 throw new RuntimeDatabaseException(e);
132 } else if(parentType instanceof RecordType) {
133 RecordBinding rb = (RecordBinding)parentBinding;
134 NameReference ref = (NameReference)reference;
136 Object copy = parentBinding.clone(parentValue);
137 Object indexValue = Bindings.adapt(value, binding, rb.getComponentBinding(ref.name));
138 rb.setComponent(copy, ref.name, indexValue);
139 parent.setValue(graph, copy, parentBinding);
140 } catch (IndexOutOfBoundsException e) {
141 throw new RuntimeDatabaseException(e);
142 } catch (BindingException e) {
143 throw new RuntimeDatabaseException(e);
144 } catch (AdaptException e) {
145 throw new RuntimeDatabaseException(e);
151 public String getName(ReadGraph graph) throws DatabaseException {
152 return reference.toString(true);
156 public boolean equals(Object obj) {
158 if(!super.equals(obj)) return false;
160 if(!(obj instanceof SubliteralPropertyVariable)) return false;
162 SubliteralPropertyVariable other = (SubliteralPropertyVariable)obj;
164 return reference.equals(other.reference);
169 public int hashCode() {
170 return super.hashCode() + 31 * reference.hashCode();