Author: niallp
Date: Tue Aug 19 15:51:19 2008
New Revision: 687190
URL: http://svn.apache.org/viewvc?rev=687190&view=rev
Log:
BEANUTILS-319 PropertyUtils's getPropertyType() fails for DynaBeans contained
within a normal bean - thanks to Erik Erskine for the patch
Modified:
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/TestBean.java
Modified:
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
URL:
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java?rev=687190&r1=687189&r2=687190&view=diff
==============================================================================
---
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
(original)
+++
commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/PropertyUtilsBean.java
Tue Aug 19 15:51:19 2008
@@ -881,19 +881,10 @@
// Resolve nested references
while (resolver.hasNested(name)) {
String next = resolver.next(name);
- Object nestedBean = null;
- if (bean instanceof Map) {
- nestedBean = getPropertyOfMapBean((Map)bean, next);
- } else if (resolver.isMapped(next)) {
- nestedBean = getMappedProperty(bean, next);
- } else if (resolver.isIndexed(next)) {
- nestedBean = getIndexedProperty(bean, next);
- } else {
- nestedBean = getSimpleProperty(bean, next);
- }
+ Object nestedBean = getProperty(bean, next);
if (nestedBean == null) {
throw new NestedNullException
- ("Null property value for '" + name +
+ ("Null property value for '" + next +
"' on bean class '" + bean.getClass() + "'");
}
bean = nestedBean;
@@ -1176,6 +1167,22 @@
bean.getClass() + "'");
}
+ // Resolve nested references
+ while (resolver.hasNested(name)) {
+ String next = resolver.next(name);
+ Object nestedBean = getProperty(bean, next);
+ if (nestedBean == null) {
+ throw new NestedNullException
+ ("Null property value for '" + next +
+ "' on bean class '" + bean.getClass() + "'");
+ }
+ bean = nestedBean;
+ name = resolver.remove(name);
+ }
+
+ // Remove any subscript from the final name value
+ name = resolver.getProperty(name);
+
// Special handling for DynaBeans
if (bean instanceof DynaBean) {
DynaProperty descriptor =
@@ -1376,6 +1383,31 @@
bean.getClass() + "'");
}
+ // Resolve nested references
+ while (resolver.hasNested(name)) {
+ String next = resolver.next(name);
+ Object nestedBean = null;
+ try {
+ nestedBean = getProperty(bean, next);
+ } catch (IllegalAccessException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ return false;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ if (nestedBean == null) {
+ throw new NestedNullException
+ ("Null property value for '" + next +
+ "' on bean class '" + bean.getClass() + "'");
+ }
+ bean = nestedBean;
+ name = resolver.remove(name);
+ }
+
+ // Remove any subscript from the final name value
+ name = resolver.getProperty(name);
+
// Treat WrapDynaBean as special case - may be a write-only property
// (see Jira issue# BEANUTILS-61)
if (bean instanceof WrapDynaBean) {
@@ -1442,6 +1474,31 @@
bean.getClass() + "'");
}
+ // Resolve nested references
+ while (resolver.hasNested(name)) {
+ String next = resolver.next(name);
+ Object nestedBean = null;
+ try {
+ nestedBean = getProperty(bean, next);
+ } catch (IllegalAccessException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ return false;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ if (nestedBean == null) {
+ throw new NestedNullException
+ ("Null property value for '" + next +
+ "' on bean class '" + bean.getClass() + "'");
+ }
+ bean = nestedBean;
+ name = resolver.remove(name);
+ }
+
+ // Remove any subscript from the final name value
+ name = resolver.getProperty(name);
+
// Treat WrapDynaBean as special case - may be a read-only property
// (see Jira issue# BEANUTILS-61)
if (bean instanceof WrapDynaBean) {
Modified:
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java
URL:
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java?rev=687190&r1=687189&r2=687190&view=diff
==============================================================================
---
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java
(original)
+++
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java
Tue Aug 19 15:51:19 2008
@@ -208,6 +208,15 @@
beanPrivateSubclass = PrivateBeanFactory.createSubclass();
beanPublicSubclass = new TestBeanPublicSubclass();
+ DynaProperty[] properties = new DynaProperty[] {
+ new DynaProperty("stringProperty", String.class),
+ new DynaProperty("nestedBean", TestBean.class),
+ new DynaProperty("nullDynaBean", DynaBean.class)
+ };
+ BasicDynaClass dynaClass = new BasicDynaClass("nestedDynaBean",
BasicDynaBean.class, properties);
+ BasicDynaBean nestedDynaBean = new BasicDynaBean(dynaClass);
+ nestedDynaBean.set("nestedBean", bean);
+ bean.setNestedDynaBean(nestedDynaBean);
}
@@ -1777,6 +1786,28 @@
clazz = PropertyUtils.getPropertyType(bean,
"nested.writeOnlyProperty");
assertEquals("writeOnlyProperty type", String.class, clazz);
+ // Nested DynaBean
+ clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean");
+ assertEquals("nestedDynaBean type", DynaBean.class, clazz);
+ clazz = PropertyUtils.getPropertyType(bean,
"nestedDynaBean.stringProperty");
+ assertEquals("nestedDynaBean.stringProperty type", String.class,
clazz);
+ clazz = PropertyUtils.getPropertyType(bean,
"nestedDynaBean.nestedBean");
+ assertEquals("nestedDynaBean.nestedBean type", TestBean.class,
clazz);
+ clazz = PropertyUtils.getPropertyType(bean,
"nestedDynaBean.nestedBean.nestedDynaBean");
+ assertEquals("nestedDynaBean.nestedBean.nestedDynaBean type",
DynaBean.class, clazz);
+ clazz = PropertyUtils.getPropertyType(bean,
"nestedDynaBean.nestedBean.nestedDynaBean.stringProperty");
+
assertEquals("nestedDynaBean.nestedBean.nestedDynaBean.stringPropert type",
String.class, clazz);
+
+ // test Null
+ clazz = PropertyUtils.getPropertyType(bean,
"nestedDynaBean.nullDynaBean");
+ assertEquals("nestedDynaBean.nullDynaBean type", DynaBean.class,
clazz);
+ try {
+ clazz = PropertyUtils.getPropertyType(bean,
"nestedDynaBean.nullDynaBean.foo");
+ fail("Expected NestedNullException for
nestedDynaBean.nullDynaBean.foo");
+ } catch (NestedNullException e) {
+ // expected
+ }
+
} catch (Exception e) {
fail("Exception: " + e.getMessage());
}
@@ -2243,7 +2274,6 @@
* Test isReadable() method.
*/
public void testIsReadable() {
- TestBean bean = new TestBean();
String property = null;
try {
property = "stringProperty";
@@ -2264,13 +2294,63 @@
fail("Property " + property +" isReadable Threw exception: " + t);
}
+ try {
+ property = "nestedDynaBean";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.stringProperty";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nestedBean";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nestedBean.nestedDynaBean";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
+
+ try {
+ property =
"nestedDynaBean.nestedBean.nestedDynaBean.stringProperty";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nullDynaBean";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nullDynaBean.foo";
+ assertTrue("Property " + property +" isReadable expeced TRUE",
PropertyUtils.isReadable(bean, property));
+ fail("Property " + property +" isReadable expected
NestedNullException");
+ } catch (NestedNullException e) {
+ // expected result
+ } catch (Throwable t) {
+ fail("Property " + property +" isReadable Threw exception: " + t);
+ }
}
/**
* Test isWriteable() method.
*/
public void testIsWriteable() {
- TestBean bean = new TestBean();
String property = null;
try {
property = "stringProperty";
@@ -2291,6 +2371,58 @@
fail("Property " + property +" isWriteable Threw exception: " + t);
}
+ try {
+ property = "nestedDynaBean";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.stringProperty";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ } catch (Throwable t) {
+ t.printStackTrace();
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nestedBean";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nestedBean.nestedDynaBean";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
+
+ try {
+ property =
"nestedDynaBean.nestedBean.nestedDynaBean.stringProperty";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nullDynaBean";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ } catch (Throwable t) {
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
+
+ try {
+ property = "nestedDynaBean.nullDynaBean.foo";
+ assertTrue("Property " + property +" isWriteable expeced TRUE",
PropertyUtils.isWriteable(bean, property));
+ fail("Property " + property +" isWriteable expected
NestedNullException");
+ } catch (NestedNullException e) {
+ // expected result
+ } catch (Throwable t) {
+ fail("Property " + property +" isWriteable Threw exception: " + t);
+ }
}
Modified:
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/TestBean.java
URL:
http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/TestBean.java?rev=687190&r1=687189&r2=687190&view=diff
==============================================================================
---
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/TestBean.java
(original)
+++
commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/TestBean.java
Tue Aug 19 15:51:19 2008
@@ -414,6 +414,19 @@
public void setAnotherNested( TestBean anotherNested ) {
this.anotherNested = anotherNested;
}
+
+ /**
+ * Another nested reference to another test bean,
+ */
+ private DynaBean nestedDynaBean = null;
+
+ public DynaBean getNestedDynaBean() {
+ return nestedDynaBean;
+ }
+
+ public void setNestedDynaBean(DynaBean nestedDynaBean) {
+ this.nestedDynaBean = nestedDynaBean;
+ }
/*
* Another nested reference to a bean containing mapp properties