svn changeset:18385/svn branch:6.6tags/6.7.0.beta1
* @param propertyType | * @param propertyType | ||||
* @return true if the property was added | * @return true if the property was added | ||||
*/ | */ | ||||
public boolean addNestedContainerProperty(String propertyId, | |||||
Class<?> propertyType) { | |||||
public boolean addNestedContainerProperty(String propertyId) { | |||||
return addContainerProperty(propertyId, new NestedPropertyDescriptor( | return addContainerProperty(propertyId, new NestedPropertyDescriptor( | ||||
propertyId, propertyType)); | |||||
propertyId, type)); | |||||
} | } | ||||
@Override | @Override |
* @throws NoSuchMethodException | * @throws NoSuchMethodException | ||||
* if no getter found | * if no getter found | ||||
*/ | */ | ||||
protected static Method initGetterMethod(String propertyName, | |||||
final Class<?> beanClass) throws NoSuchMethodException { | |||||
static Method initGetterMethod(String propertyName, final Class<?> beanClass) | |||||
throws NoSuchMethodException { | |||||
propertyName = propertyName.substring(0, 1).toUpperCase() | propertyName = propertyName.substring(0, 1).toUpperCase() | ||||
+ propertyName.substring(1); | + propertyName.substring(1); | ||||
return getMethod; | return getMethod; | ||||
} | } | ||||
protected static Class<?> convertPrimitiveType(Class<?> type) { | |||||
static Class<?> convertPrimitiveType(Class<?> type) { | |||||
// Gets the return type from get method | // Gets the return type from get method | ||||
if (type.isPrimitive()) { | if (type.isPrimitive()) { | ||||
if (type.equals(Boolean.TYPE)) { | if (type.equals(Boolean.TYPE)) { | ||||
* type into which the value should be converted | * type into which the value should be converted | ||||
* @return converted value | * @return converted value | ||||
*/ | */ | ||||
protected static Object convertValue(Object value, Class<?> type) { | |||||
static Object convertValue(Object value, Class<?> type) { | |||||
if (null == value || type.isAssignableFrom(value.getClass())) { | if (null == value || type.isAssignableFrom(value.getClass())) { | ||||
return value; | return value; | ||||
} | } |
ClassNotFoundException { | ClassNotFoundException { | ||||
in.defaultReadObject(); | in.defaultReadObject(); | ||||
initialize(instance, propertyName); | |||||
initialize(instance.getClass(), propertyName); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public NestedMethodProperty(Object instance, String propertyName) { | public NestedMethodProperty(Object instance, String propertyName) { | ||||
this.instance = instance; | this.instance = instance; | ||||
initialize(instance, propertyName); | |||||
initialize(instance.getClass(), propertyName); | |||||
} | |||||
/** | |||||
* For internal use to deduce property type etc. without a bean instance. | |||||
* Calling {@link #setValue(Object)} or {@link #getValue()} on properties | |||||
* constructed this way is not supported. | |||||
* | |||||
* @param instanceClass | |||||
* class of the top-level bean | |||||
* @param propertyName | |||||
*/ | |||||
NestedMethodProperty(Class<?> instanceClass, String propertyName) { | |||||
instance = null; | |||||
initialize(instanceClass, propertyName); | |||||
} | } | ||||
/** | /** | ||||
* Initializes most of the internal fields based on the top-level bean | * Initializes most of the internal fields based on the top-level bean | ||||
* instance and property name (dot-separated string). | * instance and property name (dot-separated string). | ||||
* | * | ||||
* @param instance | |||||
* top-level bean to which the property applies | |||||
* @param beanClass | |||||
* class of the top-level bean to which the property applies | |||||
* @param propertyName | * @param propertyName | ||||
* dot separated nested property name | * dot separated nested property name | ||||
* @throws IllegalArgumentException | * @throws IllegalArgumentException | ||||
* if the property name is invalid | * if the property name is invalid | ||||
*/ | */ | ||||
private void initialize(Object instance, String propertyName) | |||||
private void initialize(Class<?> beanClass, String propertyName) | |||||
throws IllegalArgumentException { | throws IllegalArgumentException { | ||||
List<Method> getMethods = new ArrayList<Method>(); | List<Method> getMethods = new ArrayList<Method>(); | ||||
String lastSimplePropertyName = propertyName; | String lastSimplePropertyName = propertyName; | ||||
Class<?> lastClass = instance.getClass(); | |||||
Class<?> lastClass = beanClass; | |||||
// first top-level property, then go deeper in a loop | // first top-level property, then go deeper in a loop | ||||
Class<?> propertyClass = instance.getClass(); | |||||
Class<?> propertyClass = beanClass; | |||||
String[] simplePropertyNames = propertyName.split("\\."); | String[] simplePropertyNames = propertyName.split("\\."); | ||||
if (propertyName.endsWith(".") || 0 == simplePropertyNames.length) { | if (propertyName.endsWith(".") || 0 == simplePropertyNames.length) { | ||||
throw new IllegalArgumentException("Invalid property name '" | throw new IllegalArgumentException("Invalid property name '" |
* Creates a property descriptor that can create MethodProperty instances to | * Creates a property descriptor that can create MethodProperty instances to | ||||
* access the underlying bean property. | * access the underlying bean property. | ||||
* | * | ||||
* The property is only validated when trying to access its value. | |||||
* | |||||
* @param name | * @param name | ||||
* of the property in a dotted path format, e.g. "address.street" | * of the property in a dotted path format, e.g. "address.street" | ||||
* @param propertyType | |||||
* type (class) of the property | |||||
* @param beanType | |||||
* type (class) of the top-level bean | |||||
* @throws IllegalArgumentException | |||||
* if the property name is invalid | |||||
*/ | */ | ||||
public NestedPropertyDescriptor(String name, Class<?> propertyType) { | |||||
public NestedPropertyDescriptor(String name, Class<BT> beanType) | |||||
throws IllegalArgumentException { | |||||
this.name = name; | this.name = name; | ||||
this.propertyType = propertyType; | |||||
NestedMethodProperty property = new NestedMethodProperty(beanType, name); | |||||
this.propertyType = property.getType(); | |||||
} | } | ||||
public String getName() { | public String getName() { |
container.addBean(new NestedMethodPropertyTest.Person("John", | container.addBean(new NestedMethodPropertyTest.Person("John", | ||||
new NestedMethodPropertyTest.Address("Ruukinkatu 2-4", 20540))); | new NestedMethodPropertyTest.Address("Ruukinkatu 2-4", 20540))); | ||||
assertTrue(container.addNestedContainerProperty("address.street", | |||||
String.class)); | |||||
assertTrue(container.addNestedContainerProperty("address.street")); | |||||
assertEquals("Ruukinkatu 2-4", | assertEquals("Ruukinkatu 2-4", | ||||
container.getContainerProperty("John", "address.street") | container.getContainerProperty("John", "address.street") | ||||
.getValue()); | .getValue()); |
20540)); | 20540)); | ||||
container.addBean(john); | container.addBean(john); | ||||
assertTrue(container.addNestedContainerProperty("address.street", | |||||
String.class)); | |||||
assertTrue(container.addNestedContainerProperty("address.street")); | |||||
assertEquals("Ruukinkatu 2-4", | assertEquals("Ruukinkatu 2-4", | ||||
container.getContainerProperty(john, "address.street") | container.getContainerProperty(john, "address.street") | ||||
.getValue()); | .getValue()); |
public void testNestedPropertyDescriptorSerialization() throws Exception { | public void testNestedPropertyDescriptorSerialization() throws Exception { | ||||
NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>( | NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>( | ||||
"name", String.class); | |||||
"name", Person.class); | |||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||||
new ObjectOutputStream(baos).writeObject(pd); | new ObjectOutputStream(baos).writeObject(pd); |