Author: jgbutler
Date: Thu Oct 5 10:47:54 2006
New Revision: 453298
URL: http://svn.apache.org/viewvc?view=rev&rev=453298
Log:
Fix for IBATIS-353 - Probe exception when using inheritance hierarchies
Modified:
ibatis/trunk/java/mapper/mapper2/build/version.properties
ibatis/trunk/java/mapper/mapper2/doc/release.txt
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/common/beans/ClassInfo.java
Modified: ibatis/trunk/java/mapper/mapper2/build/version.properties
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/build/version.properties?view=diff&rev=453298&r1=453297&r2=453298
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/build/version.properties (original)
+++ ibatis/trunk/java/mapper/mapper2/build/version.properties Thu Oct 5
10:47:54 2006
@@ -1,5 +1,5 @@
#Build version info
-#Sat Sep 02 20:22:53 MDT 2006
+#Thu Oct 05 12:35:41 CDT 2006
version=2.2.0
-buildDate=2006/09/02 20\:22
-buildNum=642
+buildDate=2006/10/05 12\:35
+buildNum=648
Modified: ibatis/trunk/java/mapper/mapper2/doc/release.txt
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/doc/release.txt?view=diff&rev=453298&r1=453297&r2=453298
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/doc/release.txt (original)
+++ ibatis/trunk/java/mapper/mapper2/doc/release.txt Thu Oct 5 10:47:54 2006
@@ -6,6 +6,7 @@
------------------------------
o Implemented transaction level PreparedStatement caching.
o Fixed IBATIS-335 - Don't call setQueryTimeout if no value specified
+ o Fixed IBATIS-353 - Probe exception when using inheritance hierarchies
------------------------------
2.2.0 - Aug 15, 2006
Modified:
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/common/beans/ClassInfo.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/common/beans/ClassInfo.java?view=diff&rev=453298&r1=453297&r2=453298
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/common/beans/ClassInfo.java
(original)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/common/beans/ClassInfo.java
Thu Oct 5 10:47:54 2006
@@ -117,27 +117,56 @@
}
private Method[] getAllMethodsForClass(Class cls) {
- Set uniqueMethodNames = new HashSet();
- List allMethods = new ArrayList();
+ if (cls.isInterface()) {
+ // interfaces only have public methods - so the
+ // simple call is all we need (this will also get superinterface methods)
+ return cls.getMethods();
+ } else {
+ // need to get all the declared methods in this class
+ // and any super-class - then need to set access appropriatly
+ // for private methods
+ return getClassMethods(cls);
+ }
+ }
+
+ /**
+ * This method returns an array containing all methods
+ * declared in this class and any superclass.
+ * We use this method, instead of the simpler Class.getMethods(),
+ * because we want to look for private methods as well.
+ *
+ * @param cls
+ * @return
+ */
+ private Method[] getClassMethods(Class cls) {
+ HashMap uniqueMethods = new HashMap();
Class currentClass = cls;
while (currentClass != null) {
- addMethods(currentClass, uniqueMethodNames, allMethods);
+ addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods());
+
+ // we also need to look for interface methods -
+ // because the class may be abstract
Class[] interfaces = currentClass.getInterfaces();
- for (int i=0; i<interfaces.length; i++) {
- addMethods(interfaces[i], uniqueMethodNames, allMethods);
+ for (int i = 0; i < interfaces.length; i++) {
+ addUniqueMethods(uniqueMethods, interfaces[i].getMethods());
}
+
currentClass = currentClass.getSuperclass();
}
- return (Method[]) allMethods.toArray(new Method[allMethods.size()]);
+
+ Collection methods = uniqueMethods.values();
+
+ return (Method[]) methods.toArray(new Method[methods.size()]);
}
- private void addMethods(Class currentClass, Set uniqueMethodNames, List
allMethods) {
- Method[] methods = currentClass.getDeclaredMethods();
- for (int i=0; i < methods.length; i++) {
+ private void addUniqueMethods(HashMap uniqueMethods, Method[] methods) {
+ for (int i = 0; i < methods.length; i++) {
Method currentMethod = methods[i];
- String methodName = currentMethod.getName() +
currentMethod.getParameterTypes().length;
- if (!uniqueMethodNames.contains(methodName)) {
- uniqueMethodNames.add(methodName);
+ String signature = getSignature(currentMethod);
+ // check to see if the method is already known
+ // if it is known, then an extended class must have
+ // overridden a method
+ if (!uniqueMethods.containsKey(signature)) {
if (canAccessPrivateMethods()) {
try {
currentMethod.setAccessible(true);
@@ -145,9 +174,27 @@
// Ignored. This is only a final precaution, nothing we can do.
}
}
- allMethods.add(currentMethod);
+
+ uniqueMethods.put(signature, currentMethod);
+ }
+ }
+ }
+
+ private String getSignature(Method method) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(method.getName());
+ Class[] parameters = method.getParameterTypes();
+
+ for (int i = 0; i < parameters.length; i++) {
+ if (i == 0) {
+ sb.append(':');
+ } else {
+ sb.append(',');
}
+ sb.append(parameters[i].getName());
}
+
+ return sb.toString();
}
private boolean canAccessPrivateMethods() {