DATADOC-98 - Fixes for multi-dimensional arrays and lists
This commit is contained in:
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user