From 9ff83e6542fff1ae1796419fc3ba42a3b0e47b3d Mon Sep 17 00:00:00 2001 From: "J. Brisbin" Date: Tue, 19 Apr 2011 12:49:35 -0500 Subject: [PATCH] DATADOC-98 - Fixes for multi-dimensional arrays and lists --- .../data/mapping/BasicMappingContext.java | 3 +- .../data/mapping/BasicPersistentProperty.java | 220 +++++++++--------- .../mapping/model/PersistentProperty.java | 111 ++++----- .../mapping/model/PreferredConstructor.java | 102 ++++---- 4 files changed, 228 insertions(+), 208 deletions(-) diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicMappingContext.java b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicMappingContext.java index b0319188c..a34e4af9a 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicMappingContext.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicMappingContext.java @@ -306,6 +306,7 @@ public class BasicMappingContext implements MappingContext, InitializingBean, Ap for (int i = 0; i < paramTypes.length; i++) { Class targetType = Object.class; + Class rawType = constructor.getParameterTypes()[i]; if (paramTypes[i] instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) paramTypes[i]; targetType = getTargetType(ptype); @@ -317,7 +318,7 @@ public class BasicMappingContext implements MappingContext, InitializingBean, Ap } } String paramName = (null != paramNames ? paramNames[i] : "param" + i); - preferredConstructor.addParameter(paramName, targetType, targetType.getDeclaredAnnotations()); + preferredConstructor.addParameter(paramName, targetType, rawType, targetType.getDeclaredAnnotations()); } if (constructor.isAnnotationPresent(PersistenceConstructor.class)) { diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicPersistentProperty.java b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicPersistentProperty.java index e488ae8a3..2d404d231 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicPersistentProperty.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/BasicPersistentProperty.java @@ -16,6 +16,12 @@ package org.springframework.data.mapping; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.annotation.Id; @@ -25,134 +31,134 @@ import org.springframework.data.mapping.model.PersistentEntity; import org.springframework.data.mapping.model.PersistentProperty; import org.springframework.data.util.TypeInformation; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.Map; - /** * Simple impementation of {@link PersistentProperty}. - * + * * @author Jon Brisbin * @author Oliver Gierke */ public class BasicPersistentProperty implements PersistentProperty { - protected final String name; - protected final PropertyDescriptor propertyDescriptor; - protected final TypeInformation information; - protected final Field field; - protected Association association; - protected Value value; - protected boolean isTransient = false; - protected PersistentEntity owner; + protected final String name; + protected final PropertyDescriptor propertyDescriptor; + protected final TypeInformation information; + protected final Class rawType; + protected final Field field; + protected Association association; + protected Value value; + protected boolean isTransient = false; + protected PersistentEntity owner; - public BasicPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, TypeInformation information) { - this.name = field.getName(); - this.information = information.getProperty(this.name); - this.propertyDescriptor = propertyDescriptor; - this.field = field; - this.isTransient = Modifier.isTransient(field.getModifiers()) || field.isAnnotationPresent(Transient.class); - if (field.isAnnotationPresent(Value.class)) { - this.value = field.getAnnotation(Value.class); - // Fields with @Value annotations are considered the same as transient fields - this.isTransient = true; - } - if (field.isAnnotationPresent(Autowired.class)) { - this.isTransient = true; - } - } + public BasicPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, TypeInformation information) { + this.name = field.getName(); + this.rawType = field.getType(); + this.information = information.getProperty(this.name); + this.propertyDescriptor = propertyDescriptor; + this.field = field; + this.isTransient = Modifier.isTransient(field.getModifiers()) || field.isAnnotationPresent(Transient.class); + if (field.isAnnotationPresent(Value.class)) { + this.value = field.getAnnotation(Value.class); + // Fields with @Value annotations are considered the same as transient fields + this.isTransient = true; + } + if (field.isAnnotationPresent(Autowired.class)) { + this.isTransient = true; + } + } - public Object getOwner() { - return owner; - } + public Object getOwner() { + return owner; + } - public void setOwner(Object owner) { - if (null != owner && owner.getClass().isAssignableFrom(PersistentEntity.class)) { - this.owner = (PersistentEntity) owner; - } - } + public void setOwner(Object owner) { + if (null != owner && owner.getClass().isAssignableFrom(PersistentEntity.class)) { + this.owner = (PersistentEntity) owner; + } + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public Class getType() { - return information.getType(); - } - - public TypeInformation getTypeInformation() { - return information; - } + public Class getType() { + return information.getType(); + } - public PropertyDescriptor getPropertyDescriptor() { - return propertyDescriptor; - } + public Class getRawType() { + return this.rawType; + } - public Field getField() { - return field; - } + public TypeInformation getTypeInformation() { + return information; + } - public Value getValueAnnotation() { - return value; - } + public PropertyDescriptor getPropertyDescriptor() { + return propertyDescriptor; + } - public boolean isTransient() { - return isTransient; - } + public Field getField() { + return field; + } - public boolean isAssociation() { - return null != association; - } + public Value getValueAnnotation() { + return value; + } - public Association getAssociation() { - return association; - } + public boolean isTransient() { + return isTransient; + } - public void setAssociation(Association association) { - this.association = association; - } + public boolean isAssociation() { + return null != association; + } - public boolean isCollection() { - return Collection.class.isAssignableFrom(getType()) || isArray(); - } - - public boolean isMap() { - return Map.class.isAssignableFrom(getType()); - } - - /* (non-Javadoc) - * @see org.springframework.data.mapping.model.PersistentProperty#isArray() - */ - public boolean isArray() { - return getType().isArray(); - } + public Association getAssociation() { + return association; + } - public boolean isComplexType() { - if (isCollection() || isArray()) { - return !MappingBeanHelper.isSimpleType(getComponentType()); - } else { - return !MappingBeanHelper.isSimpleType(getType()); - } - } - - public boolean isEntity() { - return isComplexType() && !isTransient() && !isCollection() && !isMap(); - } + public void setAssociation(Association association) { + this.association = association; + } - public Class getComponentType() { - return isMap() || isCollection() ? information.getComponentType().getType() : null; - } - - /* (non-Javadoc) - * @see org.springframework.data.mapping.model.PersistentProperty#getMapValueType() - */ - public Class getMapValueType() { - return isMap() ? information.getMapValueType().getType() : null; - } + public boolean isCollection() { + return Collection.class.isAssignableFrom(getType()) || isArray(); + } - public boolean isIdProperty() { - return field.isAnnotationPresent(Id.class); - } + public boolean isMap() { + return Map.class.isAssignableFrom(getType()); + } + + /* (non-Javadoc) + * @see org.springframework.data.mapping.model.PersistentProperty#isArray() + */ + public boolean isArray() { + return getType().isArray(); + } + + public boolean isComplexType() { + if (isCollection() || isArray()) { + return !MappingBeanHelper.isSimpleType(getComponentType()); + } else { + return !MappingBeanHelper.isSimpleType(getType()); + } + } + + public boolean isEntity() { + return isComplexType() && !isTransient() && !isCollection() && !isMap(); + } + + public Class getComponentType() { + return isMap() || isCollection() ? information.getComponentType().getType() : null; + } + + /* (non-Javadoc) + * @see org.springframework.data.mapping.model.PersistentProperty#getMapValueType() + */ + public Class getMapValueType() { + return isMap() ? information.getMapValueType().getType() : null; + } + + public boolean isIdProperty() { + return field.isAnnotationPresent(Id.class); + } } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PersistentProperty.java b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PersistentProperty.java index 388c7b720..13617cad9 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PersistentProperty.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PersistentProperty.java @@ -1,13 +1,13 @@ package org.springframework.data.mapping.model; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.util.TypeInformation; - import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.util.Collection; import java.util.Map; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.util.TypeInformation; + /** * @author Graeme Rocher * @author Jon Brisbin @@ -15,66 +15,73 @@ import java.util.Map; */ public interface PersistentProperty { - Object getOwner(); + Object getOwner(); - /** - * The name of the property - * - * @return The property name - */ - String getName(); + /** + * The name of the property + * + * @return The property name + */ + String getName(); - /** - * The type of the property - * - * @return The property type - */ - Class getType(); - - TypeInformation getTypeInformation(); + /** + * The type of the property + * + * @return The property type + */ + Class getType(); - PropertyDescriptor getPropertyDescriptor(); + TypeInformation getTypeInformation(); - Field getField(); + PropertyDescriptor getPropertyDescriptor(); - Value getValueAnnotation(); + Field getField(); - boolean isTransient(); + Value getValueAnnotation(); - boolean isAssociation(); + boolean isTransient(); - Association getAssociation(); + boolean isAssociation(); - boolean isCollection(); - - boolean isMap(); - - boolean isArray(); + Association getAssociation(); - boolean isComplexType(); + boolean isCollection(); - /** - * Returns whether the property has to be regarded as entity which means its type will be also be considered to be a - * {@link PersistentEntity}. - * - * @return - */ - boolean isEntity(); + boolean isMap(); - /** - * Returns the component type of the type if it is a {@link Collection}. Will return the type of the key if the - * property is a {@link Map}. - * - * @return the component type, the map's key type or {@literal null} if neither {@link Collection} nor {@link Map}. - */ - Class getComponentType(); - - /** - * Returns the type of the values if the property is a {@link Map}. - * - * @return the map's value type or {@literal null} if no {@link Map} - */ - Class getMapValueType(); + boolean isArray(); - boolean isIdProperty(); + boolean isComplexType(); + + /** + * Returns whether the property has to be regarded as entity which means its type will be also be considered to be a + * {@link PersistentEntity}. + * + * @return + */ + boolean isEntity(); + + /** + * Returns the component type of the type if it is a {@link Collection}. Will return the type of the key if the + * property is a {@link Map}. + * + * @return the component type, the map's key type or {@literal null} if neither {@link Collection} nor {@link Map}. + */ + Class getComponentType(); + + /** + * Returns the raw type as it's pulled from from the reflected property. + * + * @return the raw type of the property. + */ + Class getRawType(); + + /** + * Returns the type of the values if the property is a {@link Map}. + * + * @return the map's value type or {@literal null} if no {@link Map} + */ + Class getMapValueType(); + + boolean isIdProperty(); } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PreferredConstructor.java b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PreferredConstructor.java index 0f26fc6d6..5cab4be07 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PreferredConstructor.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/mapping/model/PreferredConstructor.java @@ -16,74 +16,80 @@ package org.springframework.data.mapping.model; -import org.springframework.beans.factory.annotation.Value; - import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.LinkedList; import java.util.List; +import org.springframework.beans.factory.annotation.Value; + /** * @author Jon Brisbin */ public class PreferredConstructor { - protected Constructor constructor; - protected List parameters = new LinkedList(); + protected Constructor constructor; + protected List parameters = new LinkedList(); - public PreferredConstructor(Constructor constructor) { - this.constructor = constructor; - } + public PreferredConstructor(Constructor constructor) { + this.constructor = constructor; + } - public Constructor getConstructor() { - return constructor; - } + public Constructor getConstructor() { + return constructor; + } - public List getParameters() { - return parameters; - } + public List getParameters() { + return parameters; + } - public void addParameter(String name, Class type, Annotation[] annotations) { - parameters.add(new Parameter(name, type, annotations)); - } + public void addParameter(String name, Class type, Class rawType, Annotation[] annotations) { + parameters.add(new Parameter(name, type, rawType, annotations)); + } - public static class Parameter { - protected final String name; - protected final Class type; - protected final Annotation[] annotations; - protected Value value; + public static class Parameter { + protected final String name; + protected final Class type; + protected final Class rawType; + protected final Annotation[] annotations; + protected Value value; - public Parameter(String name, Class type, Annotation[] annotations) { - this.name = name; - this.type = type; - this.annotations = annotations; - for (Annotation anno : annotations) { - if (anno.annotationType() == Value.class) { - this.value = (Value) anno; - break; - } - } - } + public Parameter(String name, Class type, Class rawType, Annotation[] annotations) { + this.name = name; + this.type = type; + this.rawType = rawType; + this.annotations = annotations; + for (Annotation anno : annotations) { + if (anno.annotationType() == Value.class) { + this.value = (Value) anno; + break; + } + } + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public Class getType() { - return type; - } + public Class getType() { + return type; + } - public Annotation[] getAnnotations() { - return annotations; - } + public Class getRawType() { + return rawType; + } - public Value getValue() { - return value; - } - } + public Annotation[] getAnnotations() { + return annotations; + } - public static interface ParameterValueProvider { - Object getParameterValue(Parameter parameter); - } + public Value getValue() { + return value; + } + } + + public static interface ParameterValueProvider { + Object getParameterValue(Parameter parameter); + } }