]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Use type reflection tools from databoard in objmap2. 05/3105/1
authorReino Ruusu <reino.ruusu@semantum.fi>
Wed, 14 Aug 2019 15:30:18 +0000 (18:30 +0300)
committerReino Ruusu <reino.ruusu@semantum.fi>
Wed, 14 Aug 2019 15:30:18 +0000 (18:30 +0300)
gitlab #344

Change-Id: I489f462a0f1785bc52a7a7f94ff38f7cec612055

bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/BindingRequest.java
bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/ClassBindingFactory.java
bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/CompoundRelatedGetSetValueRuleFactory.java
bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/DataTypeUtils.java
bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedGetSetValueRuleFactory.java
bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedValueRuleFactory.java
bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/CompoundValueAccessor.java
bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/RelatedValueAccessor.java

index ac2d9cf1b7246f6be353c8a15aea887ce3b8d45b..55f809f5138dc2a02bd7b6a57bee7189a7d0101d 100644 (file)
@@ -14,6 +14,7 @@ package org.simantics.databoard.binding.reflection;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -44,6 +45,13 @@ public class BindingRequest {
        return new BindingRequest(fieldClass, annotations);
        }
        
+    public static BindingRequest create( Method method )
+    {
+        Annotation[] annotations = ClassBindingFactory.getMethodAnnotations(method);
+        Class<?> valueClass = method.getReturnType(); 
+        return new BindingRequest(valueClass, annotations);
+    }
+       
        /** Requested class */
     private Class<?> clazz;
     private ClassLoader cl;
index 1295c1099ac0c8731b3be597dd967370e0b52afc..ac860d3923d4661e3ef79a8bddbb88498cf4c94a 100644 (file)
@@ -18,6 +18,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -729,7 +730,23 @@ public class ClassBindingFactory {
        Class<?> fieldClass = list.remove(0);
        Class<?>[] parameterClasses = list.isEmpty() ? NO_CLASSES : list.toArray( NO_CLASSES );
        
-       if (Set.class.isAssignableFrom(fieldClass) && parameterClasses!=null &&parameterClasses.length==1) {
+       return getTypeAnnotations(annotations, fieldClass, parameterClasses);
+    }
+
+    public static Annotation[] getMethodAnnotations(Method method) 
+    {
+        Annotation[] annotations = method.getAnnotations().clone();
+        ArrayList<Class<?>> list = new ArrayList<Class<?>>();
+        getTypes( method.getGenericReturnType(), list );
+        Class<?> valueClass = list.remove(0);
+        Class<?>[] parameterClasses = list.isEmpty() ? NO_CLASSES : list.toArray( NO_CLASSES );
+        
+        return getTypeAnnotations(annotations, valueClass, parameterClasses);
+    }
+
+    private static Annotation[] getTypeAnnotations(Annotation[] annotations, Class<?> fieldClass,
+            Class<?>[] parameterClasses) {
+        if (Set.class.isAssignableFrom(fieldClass) && parameterClasses!=null &&parameterClasses.length==1) {
                Annotation[] a2 = new Annotation[annotations.length+1];
                System.arraycopy(annotations, 0, a2, 0, annotations.length);
                
index ab5b1c7a9f5943c5f2e180cd6ab9eaba97a16cb0..90900cbfa0763fdb7be4a58097524d559a4751f1 100644 (file)
@@ -14,10 +14,13 @@ package org.simantics.objmap.graph.annotations.factories;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingConstructionException;
+import org.simantics.databoard.binding.reflection.BindingRequest;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.layer0.Layer0;
 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;
 import org.simantics.objmap.graph.annotations.CompoundRelatedGetValue;
 import org.simantics.objmap.graph.annotations.CompoundRelatedSetValue;
@@ -43,6 +46,12 @@ public class CompoundRelatedGetSetValueRuleFactory<Range> implements IGetSetRule
                
 //             Class<? extends ValueAdapter> adapterClass = getterAnn.adapter();
                IRangeAccessor<Range,Object> rangeAccessor = new CompoundGetSetValueAccessor<Range,Object>(getter, setter);
+               Binding valueBinding = null;
+               try {
+                       valueBinding = Bindings.getBinding(BindingRequest.create(getter));
+               } catch (BindingConstructionException e) {
+               }
+               
 //        Resource valueType;
 //        if (adapterClass == IdentityAdapter.class) {
 //            valueType = dataTypeOfClass(g, getter.getReturnType());
@@ -59,7 +68,8 @@ public class CompoundRelatedGetSetValueRuleFactory<Range> implements IGetSetRule
 //        }
                return new ValueRule<Resource,Range>(new CompoundValueAccessor(g.getResource(getterAnn.objRelation()),
                                                                                                                                           g.getResource(getterAnn.objType()),
-                                                                                                                                          g.getResource(getterAnn.valRelation())),
+                                                                                                                                          g.getResource(getterAnn.valRelation()),
+                                                                                                                                          valueBinding),
                                        rangeAccessor);
        }
        
@@ -69,42 +79,5 @@ public class CompoundRelatedGetSetValueRuleFactory<Range> implements IGetSetRule
                CompoundRelatedSetValue setterAnn = (CompoundRelatedSetValue)annotation;
                return getterAnn.objRelation().equals(setterAnn.value());
        }
-       
-       public static Resource dataTypeOfClass(ReadGraph g, Class<?> clazz) {
-        Layer0 b = Layer0.getInstance(g);
-        if(clazz.equals(Double.class) || clazz.equals(double.class))
-            return b.Double;
-        else if(clazz.equals(String.class))
-            return b.String;
-        else if(clazz.equals(Integer.class) || clazz.equals(int.class))
-            return b.Integer;
-        else if(clazz.equals(Float.class) || clazz.equals(float.class))
-            return b.Float;
-        else if(clazz.equals(Boolean.class) || clazz.equals(boolean.class))
-            return b.Boolean;
-        else if(clazz.equals(Long.class) || clazz.equals(long.class))
-            return b.Long;
-        else if(clazz.equals(Byte.class) || clazz.equals(byte.class))
-            return b.Byte;
-        
-        else if(clazz.equals(double[].class))
-            return b.DoubleArray;
-        else if(clazz.equals(int[].class))
-            return b.IntegerArray;
-        else if(clazz.equals(byte[].class))
-            return b.ByteArray;
-        else if(clazz.equals(float[].class))
-            return b.FloatArray;
-        else if(clazz.equals(boolean[].class))
-            return b.BooleanArray;
-        else if(clazz.equals(String[].class))
-            return b.StringArray;
-        else if(clazz.equals(long[].class))
-            return b.LongArray;
-        else {
-               System.out.println("Couldn't find a data type for " + clazz);
-            return null;
-        }
-    }
 
 }
index cd745a5230bd97b0c7bec4631dee01d4d822a61b..6d3f33a1b23e98c1932f1a167b004b3ead6d73c2 100644 (file)
  *******************************************************************************/
 package org.simantics.objmap.graph.annotations.factories;
 
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.binding.error.DatatypeConstructionException;
+import org.simantics.databoard.type.ArrayType;
+import org.simantics.databoard.type.BooleanType;
+import org.simantics.databoard.type.ByteType;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.type.DoubleType;
+import org.simantics.databoard.type.FloatType;
+import org.simantics.databoard.type.IntegerType;
+import org.simantics.databoard.type.LongType;
+import org.simantics.databoard.type.OptionalType;
+import org.simantics.databoard.type.StringType;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.layer0.Layer0;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DataTypeUtils {
     
+    private static final Logger LOGGER = LoggerFactory.getLogger(DataTypeUtils.class);
+
     public static Resource dataTypeOfClass(ReadGraph g, Class<?> clazz) {
         Layer0 b = Layer0.getInstance(g);
         if(clazz.equals(Double.class) || clazz.equals(double.class))
@@ -49,9 +65,59 @@ public class DataTypeUtils {
         else if(clazz.equals(long[].class))
             return b.LongArray;
         else {
-               System.out.println("Couldn't find a data type for " + clazz);
+            try {
+                Datatype type = Datatypes.getDatatype(clazz);
+                final Resource result = dataTypeOfDatatype(g, type);
+                if (result != null)
+                    return result;
+            } catch (DatatypeConstructionException e) {
+            }
+            
+            LOGGER.error("No literal type found for class {}", clazz);
             return null;
         }
     }
-    
+
+    public static Resource dataTypeOfDatatype(ReadGraph g, Datatype type) {
+        if (type instanceof OptionalType)
+            return dataTypeOfDatatype(g, ((OptionalType) type).getComponentType());
+        
+        Layer0 b = Layer0.getInstance(g);
+        if (type instanceof DoubleType)
+            return b.Double;
+        else if(type instanceof StringType)
+            return b.String;
+        else if(type instanceof IntegerType)
+            return b.Integer;
+        else if(type instanceof FloatType)
+            return b.Float;
+        else if(type instanceof BooleanType)
+            return b.Boolean;
+        else if(type instanceof LongType)
+            return b.Long;
+        else if(type instanceof ByteType)
+            return b.Byte;
+        
+        else if (type instanceof ArrayType) {
+            type = ((ArrayType) type).componentType();
+            
+            if (type instanceof DoubleType)
+                return b.DoubleArray;
+            else if(type instanceof IntegerType)
+                return b.IntegerArray;
+            else if(type instanceof ByteType)
+                return b.ByteArray;
+            else if(type instanceof FloatType)
+                return b.FloatArray;
+            else if(type instanceof BooleanType)
+                return b.BooleanArray;
+            else if(type instanceof StringType)
+                return b.StringArray;
+            else if(type instanceof LongType)
+                return b.LongArray;
+        }
+        
+        LOGGER.error("No literal type found for data type {}", type);
+        return null;
+    }
 }
index 994811feef05cc85385ccce8e0d504cad3035b79..5c57a75c3c2d3279281209ffa1dfe786d33a59c9 100644 (file)
@@ -14,6 +14,10 @@ package org.simantics.objmap.graph.annotations.factories;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingConstructionException;
+import org.simantics.databoard.binding.reflection.BindingRequest;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
@@ -47,8 +51,14 @@ public class RelatedGetSetValueRuleFactory<Range> implements IGetSetRuleFactory<
                Class<? extends ValueAdapter> adapterClass = getterAnn.adapter();
                 IRangeAccessor<Range,Object> rangeAccessor = new GetSetValueAccessor<Range,Object>(getter, setter);
         Resource valueType;
+        Binding valueBinding = null;
         if (adapterClass == IdentityAdapter.class) {
-            valueType = dataTypeOfClass(g, getter.getReturnType());
+            try {
+                valueBinding = Bindings.getBinding(BindingRequest.create(getter));
+            } catch (BindingConstructionException e) {
+                return null;
+            }
+            valueType = DataTypeUtils.dataTypeOfDatatype(g, valueBinding.type());
         } else {
                try{
                         ValueAdapter adapter = adapterClass.newInstance();
@@ -60,7 +70,7 @@ public class RelatedGetSetValueRuleFactory<Range> implements IGetSetRuleFactory<
                  throw new RuntimeException(e);
              }
         }
-               return new ValueRule<Resource,Range>(new RelatedValueAccessor(g.getResource(getterAnn.value()), valueType),
+               return new ValueRule<Resource,Range>(new RelatedValueAccessor(g.getResource(getterAnn.value()), valueType, valueBinding),
                                        rangeAccessor);
        }
        
index ca226c60554edc91a625dffa889b492acbd06dc0..adb2f6215e3a76c8d45f76a9122f5feef2ec7ec6 100644 (file)
@@ -14,12 +14,15 @@ package org.simantics.objmap.graph.annotations.factories;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingConstructionException;
+import org.simantics.databoard.binding.reflection.BindingRequest;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.ResourceNotFoundException;
 import org.simantics.db.exception.ServiceException;
 import org.simantics.db.exception.ValidationException;
-
 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;
 import org.simantics.objmap.graph.annotations.RelatedValue;
 import org.simantics.objmap.graph.rules.ValueRule;
@@ -41,8 +44,14 @@ public class RelatedValueRuleFactory<Range> implements IFieldRuleFactory<Resourc
         Class<? extends ValueAdapter> adapterClass = annotation.adapter();
         IRangeAccessor<Range,Object> rangeAccessor = new FieldAccessor<Range,Object>(field);
         Resource valueType;
+        Binding valueBinding = null;
         if (adapterClass == IdentityAdapter.class) {
-            valueType = DataTypeUtils.dataTypeOfClass(g, field.getType());
+            try {
+                valueBinding = Bindings.getBinding(BindingRequest.create(field));
+                valueType = DataTypeUtils.dataTypeOfDatatype(g, valueBinding.type());
+            } catch (BindingConstructionException e) {
+                return null;
+            }
         } else {
             try {
                 ValueAdapter adapter = adapterClass.newInstance();
@@ -54,7 +63,7 @@ public class RelatedValueRuleFactory<Range> implements IFieldRuleFactory<Resourc
                 throw new RuntimeException(e);
             }
         }
-        return new ValueRule<Resource,Range>(new RelatedValueAccessor(g.getResource(annotation.value()), valueType), rangeAccessor);
+        return new ValueRule<Resource,Range>(new RelatedValueAccessor(g.getResource(annotation.value()), valueType, valueBinding), rangeAccessor);
     }
 
 }
index 1c7e267c7d869d80cc6d89743b0683c015cd5468..53eb0116829fe8181c61dc1147bf96d7b7cf78d9 100644 (file)
  *******************************************************************************/
 package org.simantics.objmap.graph.rules.domain;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.simantics.databoard.binding.Binding;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ServiceException;
 import org.simantics.layer0.Layer0;
 import org.simantics.objmap.exceptions.MappingException;
-import org.simantics.objmap.graph.annotations.factories.CompoundRelatedGetSetValueRuleFactory;
+import org.simantics.objmap.graph.annotations.factories.DataTypeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -38,11 +39,13 @@ public class CompoundValueAccessor implements IDomainAccessor<Resource,Object> {
        Resource objRelation;
        Resource objType;
        Resource valRelation;
+       Binding valueBinding;
 
-       public CompoundValueAccessor(Resource objRelation, Resource objType, Resource valRelation) {
+       public CompoundValueAccessor(Resource objRelation, Resource objType, Resource valRelation, Binding valueBinding) {
                this.objRelation = objRelation;
                this.objType = objType;
                this.valRelation = valRelation;
+               this.valueBinding = valueBinding;
        }
 
        @Override
@@ -54,15 +57,17 @@ public class CompoundValueAccessor implements IDomainAccessor<Resource,Object> {
                    Map<String,Object> map = new HashMap<String, Object>();
                    for (Statement c : coll) {
                        String name = g.getRelatedValue(c.getObject(), l0.HasName);
-                       if (!map.containsKey(name) || !c.isAsserted(element))
-                               map.put(name, g.getRelatedValue(c.getObject(), valRelation));
+                       if (!map.containsKey(name) || !c.isAsserted(element)) {
+                                       final Object value = getValue(g, c.getObject());
+                                       map.put(name, value);
+                               }
                    }
                        return map;
                } catch (DatabaseException e) {
                        throw new MappingException(e);
                }
        }
-       
+
        @Override
        public boolean set(WriteGraph g, Resource element, Object v)
                        throws MappingException {
@@ -82,6 +87,7 @@ public class CompoundValueAccessor implements IDomainAccessor<Resource,Object> {
                                valueMap.put(name, g.getRelatedValue(c.getObject(), valRelation));
                        }
                    }
+                   
                    boolean changed = false;
                    for (String key : values.keySet()) {
                        Object value = values.get(key);
@@ -98,34 +104,40 @@ public class CompoundValueAccessor implements IDomainAccessor<Resource,Object> {
                        }
                        
                        Statement valueStatement = g.getPossibleStatement(stm.getObject(), valRelation);
-                       Resource valueType = CompoundRelatedGetSetValueRuleFactory.dataTypeOfClass(g, value.getClass());
+                       Resource valueType = valueBinding != null ?
+                                       DataTypeUtils.dataTypeOfDatatype(g, valueBinding.type()) :
+                                       DataTypeUtils.dataTypeOfClass(g, value.getClass());
+                                       
                                if(valueStatement == null) {
-                                       
                                        Resource valueResource = g.newResource();
-                                       g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null,  valueType);
+                                       g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null, valueType);
                                        g.claim(stm.getObject(), valRelation, valueResource);
-                                       g.claimValue(valueResource, value);                             
+                                       claimValue(g, valueResource, value);
                                } else {
-                                                                       
-                                       
                                        if (!valueStatement.isAsserted(stm.getObject()))
                                                g.claimValue(valueStatement.getObject(), value);
                                        else {
                                                Resource valueResource = g.newResource();
-                                               g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null,
-                                                               valueType);
+                                               g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null, valueType);
                                                g.claim(stm.getObject(), valRelation, valueResource);
-                                               g.claimValue(valueResource, value);
+                                               claimValue(g, valueResource, value);
                                        }
                                }
                    }
-                   return changed;
                    
+                   return changed;
                } catch (DatabaseException e) {
                        throw new MappingException(e);
                }
                
        }
+
+       private void claimValue(WriteGraph g, Resource valueResource, Object value) throws ServiceException {
+               if (valueBinding != null)
+                       g.claimValue(valueResource, value, valueBinding);
+               else
+                       g.claimValue(valueResource, value);
+       }
        
        private Statement getStatement(ReadGraph g, Resource s, Resource p, Resource o) throws DatabaseException{
                for (Statement stm : g.getStatements(s, p)) {
@@ -135,19 +147,8 @@ public class CompoundValueAccessor implements IDomainAccessor<Resource,Object> {
                return null;
        }
        
-       private boolean equals(Object o1, Object o2) {
-               if (o1 instanceof boolean[])
-                       Arrays.equals((boolean[])o1,(boolean[])o2);
-               if (o1 instanceof int[])
-                       Arrays.equals((int[])o1,(int[])o2);
-               if (o1 instanceof float[])
-                       Arrays.equals((float[])o1,(float[])o2);
-               if (o1 instanceof double[])
-                       Arrays.equals((double[])o1,(double[])o2);
-               if (o1 instanceof byte[])
-                       Arrays.equals((byte[])o1,(byte[])o2);
-               return o1.equals(o2);
-               
+       private Object getValue(ReadGraph g, final Resource object) throws DatabaseException {
+               return valueBinding != null ? g.getRelatedValue(object, valRelation, valueBinding) : g.getRelatedValue(object, valRelation);
        }
 
 }
index 9ede881774873f5c8ba6feabe8bcec4a13f878fc..585b468e60c049217a4ec2e74db26011b6663648 100644 (file)
@@ -13,15 +13,20 @@ package org.simantics.objmap.graph.rules.domain;
 
 import java.util.Arrays;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.OptionalBinding;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.exception.BindingException;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.DoesNotContainValueException;
+import org.simantics.db.exception.ServiceException;
 import org.simantics.layer0.Layer0;
 import org.simantics.objmap.exceptions.MappingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Accesses a value attached to the element by given functional relation.
@@ -33,10 +38,12 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
     
        Resource relation;
        Resource valueType;
+       Binding valueBinding;
 
-       public RelatedValueAccessor(Resource relation, Resource valueType) {
+       public RelatedValueAccessor(Resource relation, Resource valueType, Binding valueBinding) {
                this.relation = relation;
                this.valueType = valueType;
+               this.valueBinding = valueBinding;
        }
 
        @Override
@@ -46,12 +53,12 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
                        Resource valueResource = g.getPossibleObject(element, relation);
                        if(valueResource == null)
                                return null;
-                       return g.getValue(valueResource);
+                       return getValue(g, valueResource);
                } catch (DatabaseException e) {
                        throw new MappingException(e);
                }
        }
-       
+
        @Override
        public boolean set(WriteGraph g, Resource element, Object value)
                        throws MappingException {
@@ -65,7 +72,8 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
                                g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null,
                                                valueType);
                                g.claim(element, relation, valueResource);
-                               g.claimValue(valueResource, value);                             
+                               claimValue(g, valueResource, value);
+                               
                                return true;
                        }
                        else {
@@ -77,7 +85,7 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
                                                return false;
                                        }
                                }                               
-                               Object currentValue = g.getValue(valueStatement.getObject());
+                               Object currentValue = getValue(g, valueStatement.getObject());
                                if(equals(currentValue,value))
                                        return false;
                                if (!valueStatement.isAsserted(element))
@@ -87,7 +95,7 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
                                        g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null,
                                                        valueType);
                                        g.claim(element, relation, valueResource);
-                                       g.claimValue(valueResource, value);
+                                       claimValue(g, valueResource, value);
                                }
                                return true;
                        }
@@ -96,8 +104,32 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
                }
                
        }
+
+       private Object getValue(ReadGraph g, Resource valueResource)
+                       throws DoesNotContainValueException, BindingException, ServiceException {
+               if (valueBinding != null) {
+                       return g.getValue(valueResource, getBaseBinding(valueBinding));
+               }
+               else {
+                       return g.getValue(valueResource);
+               }
+       }
+       
+       private void claimValue(WriteGraph g, Resource valueResource, Object value) throws ServiceException {
+               if (valueBinding != null)
+                       g.claimValue(valueResource, value, getBaseBinding(valueBinding));
+               else
+                       g.claimValue(valueResource, value);
+       }
+
+       private static Binding getBaseBinding(Binding binding) {
+               return binding instanceof OptionalBinding ? ((OptionalBinding)binding).getComponentBinding() : binding;
+       }
        
        private boolean equals(Object o1, Object o2) {
+               if (valueBinding != null)
+                       return valueBinding.equals(o1, o2);
+               
                if (o1 instanceof boolean[])
                        Arrays.equals((boolean[])o1,(boolean[])o2);
                if (o1 instanceof int[])
@@ -109,7 +141,6 @@ public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
                if (o1 instanceof byte[])
                        Arrays.equals((byte[])o1,(byte[])o2);
                return o1.equals(o2);
-               
        }
 
 }