[hibernate-commits] Hibernate SVN: r13991 - in shards/trunk/src: test/org/hibernate/shards/strategy/exit and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Sep 3 22:24:34 EDT 2007


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
+    }
   }
 }




More information about the hibernate-commits mailing list