DATADOC-98 - Fixes for multi-dimensional arrays and lists

This commit is contained in:
J. Brisbin
2011-04-19 12:49:35 -05:00
parent 9b645aa370
commit 9ff83e6542
4 changed files with 228 additions and 208 deletions

View File

@@ -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)) {

View File

@@ -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 <jbrisbin@vmware.com>
* @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);
}
}

View File

@@ -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();
}

View File

@@ -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 <jbrisbin@vmware.com>
*/
public class PreferredConstructor<T> {
protected Constructor<T> constructor;
protected List<Parameter> parameters = new LinkedList<Parameter>();
protected Constructor<T> constructor;
protected List<Parameter> parameters = new LinkedList<Parameter>();
public PreferredConstructor(Constructor<T> constructor) {
this.constructor = constructor;
}
public PreferredConstructor(Constructor<T> constructor) {
this.constructor = constructor;
}
public Constructor<T> getConstructor() {
return constructor;
}
public Constructor<T> getConstructor() {
return constructor;
}
public List<Parameter> getParameters() {
return parameters;
}
public List<Parameter> 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);
}
}