From: Reino Ruusu Date: Wed, 14 Aug 2019 15:30:18 +0000 (+0300) Subject: Use type reflection tools from databoard in objmap2. X-Git-Tag: v1.43.0~136^2~115 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F05%2F3105%2F1;p=simantics%2Fplatform.git Use type reflection tools from databoard in objmap2. gitlab #344 Change-Id: I489f462a0f1785bc52a7a7f94ff38f7cec612055 --- diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/BindingRequest.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/BindingRequest.java index ac2d9cf1b..55f809f51 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/BindingRequest.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/BindingRequest.java @@ -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; diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/ClassBindingFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/ClassBindingFactory.java index 1295c1099..ac860d392 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/ClassBindingFactory.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/reflection/ClassBindingFactory.java @@ -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 &¶meterClasses.length==1) { + return getTypeAnnotations(annotations, fieldClass, parameterClasses); + } + + public static Annotation[] getMethodAnnotations(Method method) + { + Annotation[] annotations = method.getAnnotations().clone(); + ArrayList> list = new ArrayList>(); + 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 &¶meterClasses.length==1) { Annotation[] a2 = new Annotation[annotations.length+1]; System.arraycopy(annotations, 0, a2, 0, annotations.length); diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/CompoundRelatedGetSetValueRuleFactory.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/CompoundRelatedGetSetValueRuleFactory.java index ab5b1c7a9..90900cbfa 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/CompoundRelatedGetSetValueRuleFactory.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/CompoundRelatedGetSetValueRuleFactory.java @@ -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 implements IGetSetRule // Class adapterClass = getterAnn.adapter(); IRangeAccessor rangeAccessor = new CompoundGetSetValueAccessor(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 implements IGetSetRule // } return new ValueRule(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 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; - } - } } diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/DataTypeUtils.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/DataTypeUtils.java index cd745a523..6d3f33a1b 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/DataTypeUtils.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/DataTypeUtils.java @@ -11,12 +11,28 @@ *******************************************************************************/ 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; + } } diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedGetSetValueRuleFactory.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedGetSetValueRuleFactory.java index 994811fee..5c57a75c3 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedGetSetValueRuleFactory.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedGetSetValueRuleFactory.java @@ -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 implements IGetSetRuleFactory< Class adapterClass = getterAnn.adapter(); IRangeAccessor rangeAccessor = new GetSetValueAccessor(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 implements IGetSetRuleFactory< throw new RuntimeException(e); } } - return new ValueRule(new RelatedValueAccessor(g.getResource(getterAnn.value()), valueType), + return new ValueRule(new RelatedValueAccessor(g.getResource(getterAnn.value()), valueType, valueBinding), rangeAccessor); } diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedValueRuleFactory.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedValueRuleFactory.java index ca226c605..adb2f6215 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedValueRuleFactory.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/annotations/factories/RelatedValueRuleFactory.java @@ -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 implements IFieldRuleFactory adapterClass = annotation.adapter(); IRangeAccessor rangeAccessor = new FieldAccessor(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 implements IFieldRuleFactory(new RelatedValueAccessor(g.getResource(annotation.value()), valueType), rangeAccessor); + return new ValueRule(new RelatedValueAccessor(g.getResource(annotation.value()), valueType, valueBinding), rangeAccessor); } } diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/CompoundValueAccessor.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/CompoundValueAccessor.java index 1c7e267c7..53eb01168 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/CompoundValueAccessor.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/CompoundValueAccessor.java @@ -11,19 +11,20 @@ *******************************************************************************/ 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 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 { Map map = new HashMap(); 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 { 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 { } 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 { 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); } } diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/RelatedValueAccessor.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/RelatedValueAccessor.java index 9ede88177..585b468e6 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/RelatedValueAccessor.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/RelatedValueAccessor.java @@ -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 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 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 { 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 { 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 { 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 { } } + + 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 { if (o1 instanceof byte[]) Arrays.equals((byte[])o1,(byte[])o2); return o1.equals(o2); - } }