* @param propertyType
* @return true if the property was added
*/
- public boolean addNestedContainerProperty(String propertyId,
- Class<?> propertyType) {
+ public boolean addNestedContainerProperty(String propertyId) {
return addContainerProperty(propertyId, new NestedPropertyDescriptor(
- propertyId, propertyType));
+ propertyId, type));
}
@Override
* @throws NoSuchMethodException
* 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.substring(1);
return getMethod;
}
- protected static Class<?> convertPrimitiveType(Class<?> type) {
+ static Class<?> convertPrimitiveType(Class<?> type) {
// Gets the return type from get method
if (type.isPrimitive()) {
if (type.equals(Boolean.TYPE)) {
* type into which the value should be converted
* @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())) {
return value;
}
ClassNotFoundException {
in.defaultReadObject();
- initialize(instance, propertyName);
+ initialize(instance.getClass(), propertyName);
}
/**
*/
public NestedMethodProperty(Object instance, String propertyName) {
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
* 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
* dot separated nested property name
* @throws IllegalArgumentException
* if the property name is invalid
*/
- private void initialize(Object instance, String propertyName)
+ private void initialize(Class<?> beanClass, String propertyName)
throws IllegalArgumentException {
List<Method> getMethods = new ArrayList<Method>();
String lastSimplePropertyName = propertyName;
- Class<?> lastClass = instance.getClass();
+ Class<?> lastClass = beanClass;
// first top-level property, then go deeper in a loop
- Class<?> propertyClass = instance.getClass();
+ Class<?> propertyClass = beanClass;
String[] simplePropertyNames = propertyName.split("\\.");
if (propertyName.endsWith(".") || 0 == simplePropertyNames.length) {
throw new IllegalArgumentException("Invalid property name '"
* Creates a property descriptor that can create MethodProperty instances to
* access the underlying bean property.
*
- * The property is only validated when trying to access its value.
- *
* @param name
* 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.propertyType = propertyType;
+ NestedMethodProperty property = new NestedMethodProperty(beanType, name);
+ this.propertyType = property.getType();
}
public String getName() {
container.addBean(new NestedMethodPropertyTest.Person("John",
new NestedMethodPropertyTest.Address("Ruukinkatu 2-4", 20540)));
- assertTrue(container.addNestedContainerProperty("address.street",
- String.class));
+ assertTrue(container.addNestedContainerProperty("address.street"));
assertEquals("Ruukinkatu 2-4",
container.getContainerProperty("John", "address.street")
.getValue());
20540));
container.addBean(john);
- assertTrue(container.addNestedContainerProperty("address.street",
- String.class));
+ assertTrue(container.addNestedContainerProperty("address.street"));
assertEquals("Ruukinkatu 2-4",
container.getContainerProperty(john, "address.street")
.getValue());
public void testNestedPropertyDescriptorSerialization() throws Exception {
NestedPropertyDescriptor<Person> pd = new NestedPropertyDescriptor<Person>(
- "name", String.class);
+ "name", Person.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(pd);