Author: max.ross
Date: 2007-09-03 22:24:33 -0400 (Mon, 03 Sep 2007)
New Revision: 13991
Modified:
shards/trunk/src/java/org/hibernate/shards/strategy/exit/ExitOperationUtils.java
shards/trunk/src/test/org/hibernate/shards/strategy/exit/ExitOperationUtilsTest.java
Log:
HSHARDS-43
Fix bug preventing sorting by fields with private getters.
Thanks to Aviad for the patch!
Modified:
shards/trunk/src/java/org/hibernate/shards/strategy/exit/ExitOperationUtils.java
===================================================================
---
shards/trunk/src/java/org/hibernate/shards/strategy/exit/ExitOperationUtils.java 2007-09-04
01:57:18 UTC (rev 13990)
+++
shards/trunk/src/java/org/hibernate/shards/strategy/exit/ExitOperationUtils.java 2007-09-04
02:24:33 UTC (rev 13991)
@@ -65,7 +65,7 @@
try {
StringBuilder propertyPath = new StringBuilder();
for(int i=0; i < propertyName.length(); i++) {
- String s =propertyName.substring(i,i+1);
+ String s = propertyName.substring(i,i+1);
if (i == 0 || propertyName.charAt(i-1) == '.') {
propertyPath.append(StringUtil.capitalize(s));
} else {
@@ -75,8 +75,8 @@
String[] methods = ("get" +
propertyPath.toString().replaceAll("\\.",
".get")).split("\\.");
Object root = obj;
for (String method : methods) {
- Class clazz = root.getClass();
- Method m = clazz.getMethod(method);
+ Method m = findPotentiallyPrivateMethod(root.getClass(), method);
+ m.setAccessible(true);
root = m.invoke(root);
if (root == null) {
break;
@@ -94,4 +94,23 @@
}
}
+ static Method findPotentiallyPrivateMethod(Class clazz, String methodName)
+ throws NoSuchMethodException {
+ try {
+ return clazz.getMethod(methodName);
+ } catch (NoSuchMethodException nsme) {
+ // that's ok, we'll try the slower approach
+ }
+
+ // we need to make sure we can access private methods on subclasses, and
+ // the only way to do that is to work our way up the class hierarchy
+ while (clazz != null) {
+ try {
+ return clazz.getDeclaredMethod(methodName);
+ } catch (NoSuchMethodException e) {
+ clazz = (Class) clazz.getGenericSuperclass();
+ }
+ }
+ throw new NoSuchMethodException(methodName);
+ }
}
Modified:
shards/trunk/src/test/org/hibernate/shards/strategy/exit/ExitOperationUtilsTest.java
===================================================================
---
shards/trunk/src/test/org/hibernate/shards/strategy/exit/ExitOperationUtilsTest.java 2007-09-04
01:57:18 UTC (rev 13990)
+++
shards/trunk/src/test/org/hibernate/shards/strategy/exit/ExitOperationUtilsTest.java 2007-09-04
02:24:33 UTC (rev 13991)
@@ -25,40 +25,66 @@
*/
public class ExitOperationUtilsTest extends TestCase {
- private class MyInt {
- private final Integer i;
+ private class MyInt {
+ private final Integer i;
- private final String name;
+ private final String name;
- private MyInt innerMyInt;
+ private final String rank;
- public MyInt(int i, String name) {
- this.i = i;
- this.name = name;
- }
+ private MyInt innerMyInt;
- public MyInt getInnerMyInt() {
- return innerMyInt;
- }
+ public MyInt(int i, String name, String rank) {
+ this.i = i;
+ this.name = name;
+ this.rank = rank;
+ }
- public void setInnerMyInt(MyInt innerMyInt) {
- this.innerMyInt = innerMyInt;
- }
+ // these private methods, while unused, are used to verify that the method
+ // works for private methods
+ private MyInt getInnerMyInt() {
+ return innerMyInt;
+ }
- public Number getValue() {
- return i;
- }
+ private void setInnerMyInt(MyInt innerMyInt) {
+ this.innerMyInt = innerMyInt;
+ }
- public String getName() {
- return name;
- }
+ private Number getValue() {
+ return i;
+ }
+ private String getName() {
+ return name;
}
+ protected String getRank() {
+ return rank;
+ }
+ }
+ private class MySubInt extends MyInt {
+
+ public MySubInt(int i, String name, String rank) {
+ super(i, name, rank);
+ }
+ }
+
public void testGetPropertyValue() throws Exception {
- MyInt myInt = new MyInt(1,"one");
- myInt.setInnerMyInt(new MyInt(5, "five"));
+ MyInt myInt = new MySubInt(1,"one", "a");
+ myInt.setInnerMyInt(new MySubInt(5, "five", "b"));
+
+ assertEquals(1, ExitOperationUtils.getPropertyValue(myInt,"value"));
+ assertEquals("one",
ExitOperationUtils.getPropertyValue(myInt,"name"));
+ assertEquals("a",
ExitOperationUtils.getPropertyValue(myInt,"rank"));
+
assertEquals(5,
ExitOperationUtils.getPropertyValue(myInt,"innerMyInt.value"));
assertEquals("five",
ExitOperationUtils.getPropertyValue(myInt,"innerMyInt.name"));
+ assertEquals("b",
ExitOperationUtils.getPropertyValue(myInt,"innerMyInt.rank"));
+ try {
+ ExitOperationUtils.getPropertyValue(myInt,"innerMyInt.doesNotExist");
+ fail("expected rte");
+ } catch (RuntimeException rte) {
+ // good
+ }
}
}
Show replies by date