Author: niallp Date: Tue Aug 19 19:05:45 2008 New Revision: 687223 URL: http://svn.apache.org/viewvc?rev=687223&view=rev Log: BEANUTILS-265 Allow access to non public class's public methods from a public sub-classes - thanks to Tom Schindl and Romain Muller
Modified: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MethodUtils.java commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java Modified: commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MethodUtils.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MethodUtils.java?rev=687223&r1=687222&r2=687223&view=diff ============================================================================== --- commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MethodUtils.java (original) +++ commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/MethodUtils.java Tue Aug 19 19:05:45 2008 @@ -773,12 +773,22 @@ return (null); } + boolean sameClass = true; if (clazz == null) { clazz = method.getDeclaringClass(); + } else { + sameClass = clazz.equals(method.getDeclaringClass()); + if (!method.getDeclaringClass().isAssignableFrom(clazz)) { + throw new IllegalArgumentException(clazz.getName() + + " is not assignable from " + method.getDeclaringClass().getName()); + } } // If the class is public, we are done if (Modifier.isPublic(clazz.getModifiers())) { + if (!sameClass && !Modifier.isPublic(method.getDeclaringClass().getModifiers())) { + setMethodAccessible(method); // Default access superclass workaround + } return (method); } Modified: commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java?rev=687223&r1=687222&r2=687223&view=diff ============================================================================== --- commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java (original) +++ commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java Tue Aug 19 19:05:45 2008 @@ -565,7 +565,35 @@ MethodUtils.invokeMethod(bean, "setFoo", "alpha"); assertEquals("Set value (foo:2)", bean.getFoo(), "alpha"); MethodUtils.invokeMethod(bean, "setBar", "beta"); - assertEquals("Set value (bar:2)", bean.getFoo(), "alpha"); + assertEquals("Set value (bar:2)", bean.getBar(), "beta"); + + Method method = null; + try { + method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setFoo", String.class); + } catch (Throwable t) { + fail("getAccessibleMethod() setFoo threw " + t); + } + assertNotNull("getAccessibleMethod() setFoo is Null", method); + try { + method.invoke(bean, new Object[] {"1111"}); + } catch (Throwable t) { + fail("Invoking setFoo threw " + t); + } + assertEquals("Set value (foo:3)", "1111", bean.getFoo()); + + try { + method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setBar", String.class); + } catch (Throwable t) { + fail("getAccessibleMethod() setBar threw " + t); + } + assertNotNull("getAccessibleMethod() setBar is Null", method); + try { + method.invoke(bean, new Object[] {"2222"}); + } catch (Throwable t) { + fail("Invoking setBar threw " + t); + } + assertEquals("Set value (bar:3)", "2222", bean.getBar()); + } public void testParentMethod() throws Exception { 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=687223&r1=687222&r2=687223&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 19:05:45 2008 @@ -31,6 +31,7 @@ import org.apache.commons.beanutils.priv.PrivateBeanFactory; import org.apache.commons.beanutils.priv.PrivateDirect; +import org.apache.commons.beanutils.priv.PublicSubBean; import junit.framework.TestCase; import junit.framework.Test; @@ -1816,6 +1817,34 @@ /** + * Test accessing a public sub-bean of a package scope bean + */ + public void testGetPublicSubBean_of_PackageBean() { + + PublicSubBean bean = new PublicSubBean(); + bean.setFoo("foo-start"); + bean.setBar("bar-start"); + Object result = null; + + // Get Foo + try { + result = PropertyUtils.getProperty(bean, "foo"); + } catch (Throwable t) { + fail("getProperty(foo) threw " + t); + } + assertEquals("foo property", "foo-start", result); + + // Get Bar + try { + result = PropertyUtils.getProperty(bean, "bar"); + } catch (Throwable t) { + fail("getProperty(bar) threw " + t); + } + assertEquals("bar property", "bar-start", result); + } + + + /** * Test getting accessible property reader methods for a specified * list of properties of our standard test bean. */ @@ -4188,6 +4217,32 @@ PropertyUtils.setMappedProperty(bean, "noGetterMappedProperty", "Epsilon", "Epsilon"); assertEquals("Cannot set mapped no-getter property", "MAP:Epsilon", bean.getSecret()); } + + /** + * Test accessing a public sub-bean of a package scope bean + */ + public void testSetPublicSubBean_of_PackageBean() { + + PublicSubBean bean = new PublicSubBean(); + bean.setFoo("foo-start"); + bean.setBar("bar-start"); + + // Set Foo + try { + PropertyUtils.setProperty(bean, "foo", "foo-updated"); + } catch (Throwable t) { + fail("setProperty(foo) threw " + t); + } + assertEquals("foo property", "foo-updated", bean.getFoo()); + + // Set Bar + try { + PropertyUtils.setProperty(bean, "bar", "bar-updated"); + } catch (Throwable t) { + fail("setProperty(bar) threw " + t); + } + assertEquals("bar property", "bar-updated", bean.getBar()); + } /** * There is an issue in setNestedProperty/getNestedProperty when the