[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [cp-patches] gnu.java.beans.IntrospectionIncubator - fix for bug #10
From: |
Robert Schuster |
Subject: |
Re: [cp-patches] gnu.java.beans.IntrospectionIncubator - fix for bug #10938 |
Date: |
Mon, 08 Nov 2004 13:00:05 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.7.3) Gecko/20040930 |
One small question: does it handle public static void set*(*) methods
correctly as well?
It does. In fact it did so already before I started fumbling around in
IntrospectionIncubator.
I committed the version of the patch in this mail. It has no algorithmic
changes but I put a very long expression in a separate method
and added another bunch of documentation to the class.
cu
robert
Index: ChangeLog
===================================================================
RCS file: /cvsroot/classpath/classpath/ChangeLog,v
retrieving revision 1.2761
diff -u -r1.2761 ChangeLog
--- ChangeLog 8 Nov 2004 09:41:25 -0000 1.2761
+++ ChangeLog 8 Nov 2004 11:46:28 -0000
@@ -1,3 +1,11 @@
+2004-11-08 Robert Schuster <address@hidden>
+
+ Fixed regression:
+ * gnu/java/beans/IntrospectionIncubator.java:
+ (addMethod): corrected classification of normal and property methods
+ (capitalize): added documentation
+ (DoubleKey): [class] added documentation
+
2004-11-08 Jeroen Frijters <address@hidden>
* java/net/URLStreamHandler.java
Index: gnu/java/beans/IntrospectionIncubator.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/gnu/java/beans/IntrospectionIncubator.java,v
retrieving revision 1.13
diff -u -r1.13 IntrospectionIncubator.java
--- gnu/java/beans/IntrospectionIncubator.java 6 Nov 2004 22:19:05 -0000
1.13
+++ gnu/java/beans/IntrospectionIncubator.java 8 Nov 2004 11:46:29 -0000
@@ -57,9 +57,10 @@
/**
** IntrospectionIncubator takes in a bunch of Methods, and
- ** Introspects only those Methods you give it.
- ** Note that non-public and static methods are silently
- ** discarded.
+ ** Introspects only those Methods you give it.<br/>
+ **
+ ** See address@hidden addMethod(Method)} for details which rules apply to
+ ** the methods.
**
** @author John Keiser
** @author Robert Schuster
@@ -79,39 +80,75 @@
public IntrospectionIncubator() {
}
- /* Paving the way for automatic Introspection */
+ /** Examines the given method and files it in a suitable collection.
+ * It files the method as a property method if it finds:
+ * <lu>
+ * <li>boolean "is" getter</li>
+ * <li>"get" style getter</li>
+ * <li>single argument setter</li>
+ * <li>indiced setter and getter</li>
+ * </ul>
+ * It files the method as a listener method if all of these rules apply:
+ * <lu>
+ * <li>the method name starts with "add" or "remove"</li>
+ * <li>there is only a single argument</li>
+ * <li>the argument type is a subclass of
<code>java.util.EventListener</code></li>
+ * </ul>
+ * All public methods are filed as such.
+ *
+ * @param method The method instance to examine.
+ */
public void addMethod(Method method) {
- if(Modifier.isPublic(method.getModifiers()) &&
- !Modifier.isStatic(method.getModifiers())) {
+ if(Modifier.isPublic(method.getModifiers())) {
String name =
ClassHelper.getTruncatedName(method.getName());
Class retType = method.getReturnType();
Class[] params = method.getParameterTypes();
boolean isVoid = retType.equals(java.lang.Void.TYPE);
Class methodClass = method.getDeclaringClass();
- if(propertyStopClass == null ||
(propertyStopClass.isAssignableFrom(methodClass) &&
!propertyStopClass.equals(methodClass))) {
- if(name.startsWith("is")
+
+ /* Accepts the method for examination if no stop class
is given or the method is declared in a subclass of the stop class.
+ * The rules for this are described in address@hidden
java.beans.Introspector.getBeanInfo(Class, Class)}.
+ * This block finds out whether the method is a
suitable getter or setter method (or read/write method).
+ */
+ if(isReachable(propertyStopClass, methodClass)) {
+ /* At this point a method may regarded as a
property's read or write method if its name
+ * starts with "is", "get" or "set". However,
if a method is static it cannot be part
+ * of a property.
+ */
+ if(Modifier.isStatic(method.getModifiers())) {
+ // files method as other because it is
static
+ otherMethods.addElement(method);
+ } else if(name.startsWith("is")
&& retType.equals(java.lang.Boolean.TYPE)
&& params.length == 0) {
+ // files method as boolean "is" style
getter
addToPropertyHash(name,method,IS);
} else if(name.startsWith("get") && !isVoid) {
if(params.length == 0) {
+ // files as legal non-argument
getter
addToPropertyHash(name,method,GET);
} else if(params.length == 1 &&
params[0].equals(java.lang.Integer.TYPE)) {
+ // files as legal indiced getter
addToPropertyHash(name,method,GET_I);
} else {
+ // files as other because the
method's signature is not Bean-like
otherMethods.addElement(method);
}
} else if(name.startsWith("set") && isVoid) {
if(params.length == 1) {
+ // files as legal
single-argument setter method
addToPropertyHash(name,method,SET);
} else if(params.length == 2 &&
params[0].equals(java.lang.Integer.TYPE)) {
+ // files as legal indiced
setter method
addToPropertyHash(name,method,SET_I);
} else {
+ // files as other because the
method's signature is not Bean-like
otherMethods.addElement(method);
}
}
}
- if(eventStopClass == null ||
(eventStopClass.isAssignableFrom(methodClass) &&
!eventStopClass.equals(methodClass))) {
+
+ if(isReachable(eventStopClass, methodClass)) {
if(name.startsWith("add")
&& isVoid
&& params.length == 1
@@ -124,9 +161,12 @@
addToListenerHash(name,method,REMOVE);
}
}
- if(methodStopClass == null ||
(methodStopClass.isAssignableFrom(methodClass) &&
!methodStopClass.equals(methodClass))) {
+
+ if(isReachable(methodStopClass, methodClass)) {
+ // files as reachable public method
otherMethods.addElement(method);
}
+
}
}
@@ -293,7 +333,6 @@
methods[funcType] = method;
}
-
void addToListenerHash(String name, Method method, int funcType) {
String newName;
Class type;
@@ -321,6 +360,26 @@
methods[funcType] = method;
}
+ /* Determines whether <code>stopClass</code> is <code>null</code>
+ * or <code>declaringClass<code> is a true subclass of
<code>stopClass</code>.
+ * This expression is useful to detect whether a method should be
introspected or not.
+ * The rules for this are described in address@hidden
java.beans.Introspector.getBeanInfo(Class, Class)}.
+ */
+ static boolean isReachable(Class stopClass, Class declaringClass) {
+ return stopClass == null ||
(stopClass.isAssignableFrom(declaringClass) &&
!stopClass.equals(declaringClass));
+ }
+
+ /** Transforms a property name into a part of a method name.
+ * E.g. "value" becomes "Value" which can then concatenated with
+ * "set", "get" or "is" to form a valid method name.
+ *
+ * Implementation notes:
+ * If "" is the argument, it is returned without changes.
+ * If <code>null</code> is the argument, <code>null</code> is returned.
+ *
+ * @param name Name of a property.
+ * @return Part of a method name of a property.
+ */
static String capitalize(String name) {
try {
if(Character.isUpperCase(name.charAt(0))) {
@@ -338,6 +397,14 @@
}
}
+/** This class is a hashmap key that consists of a <code>Class</code> and a
+ * <code>String</code> element.
+ *
+ * It is used for XXX: find out what this is used for
+ *
+ * @author John Keiser
+ * @author Robert Schuster
+ */
class DoubleKey {
Class type;
String name;