Great to see that.
I have still one small confusion that why r647904 will pass the test if
superType is null, since what r647921 did for the part is as below.
@@ -276,7 +292,8 @@
// Sub is PropertyDescriptor
if (subIndexedType == null) {
// Same property type
- if (subType.getName().equals(superType.getName())) {
+ if (subType != null &&
+ subType.getName().equals(superType.getName()))
{
if ((subGet == null) && (superGet != null)) {
subDesc.setReadMethod(superGet);
}
Anyway I am happy to see the issue will be fixed.
On Tue, Dec 9, 2008 at 5:03 PM, Kevin Zhou <[EMAIL PROTECTED]> wrote:
> Has successfully recreate this defect.
> I think the null value of superType is the root cause for this defect.
>
>
> On Tue, Dec 9, 2008 at 2:59 PM, Kevin Zhou <[EMAIL PROTECTED]> wrote:
>
> > Thereinto, StandBeanInfo.mergeProps method is used to merge the
> > PropertyDescriptor with superclass.
> > The "superType" is the type of one of its super classes's propreties.
> >
> >
> > On Tue, Dec 9, 2008 at 2:53 PM, Kevin Zhou <[EMAIL PROTECTED]>
> wrote:
> >
> >> From the trace, the NPE is thrown from StandBeanInfo.mergeProps() (line
> >> 295):
> >> if (subType != null &&subType.getName().equals(superType.getName())) {
> >> //295
> >> ...
> >> }
> >> where "superType" may be null.
> >> Next Action: Will Construct test framework for this, and check whether
> >> this is the root cause for this defect.
> >>
> >>
> >> On Tue, Dec 9, 2008 at 2:17 PM, chunrong lai <[EMAIL PROTECTED]
> >wrote:
> >>
> >>>
> >>> hi, colleagues:
> >>> Sorry for the late report. But I see that the struts test suite is
> >>> breaking due to r647921 with below stackTrace:
> >>>
> >>> Caused by: java.lang.NullPointerException
> >>> at
> >>> java.beans.StandardBeanInfo.mergeProps(StandardBeanInfo.java:295)
> >>> at
> >>> java.beans.StandardBeanInfo.mergeBeanInfo(StandardBeanInfo.java:209)
> >>> at
> java.beans.Introspector.getBeanInfoImpl(Introspector.java:282)
> >>> at
> >>> java.beans.Introspector.getBeanInfoImplAndInit(Introspector.java:347)
> >>> at java.beans.Introspector.getBeanInfo(Introspector.java:162)
> >>> at
> >>> freemarker.ext.beans.BeansWrapper.populateClassMapWithBeanInfo(BeansW
> >>> rapper.java:844)
> >>> ... 52 more
> >>>
> >>> To reproduce the error one needs to (reproducible in windows and
> >>> Linux platforms)
> >>> (1) Start a webserver
> >>> (1.1) Extract apache-tomcat-6.0.18.tar.gz from (
> >>> http://tomcat.apache.org/download-60.cgi) and cd the extracted
> directory
> >>> "apache-tomcat-6.0.18".
> >>> (1.2) Create apache-tomcat-6.0.18/my_base,
> >>> apache-tomcat-6.0.18/struts_test,
> apache-tomcat-6.0.18/struts_test/logs,
> >>> apache-tomcat-6.0.18/struts_test/temp,
> >>> apache-tomcat-6.0.18/struts_test/webapps/,
> >>> apache-tomcat-6.0.18/struts_test/work,
> >>> (1.3) Copy struts2-showcase-2.0.6.war (in
> >>> struts-2.0.6-all/apps/ extracted from
> >>> http://archive.apache.org/dist/struts/binaries/struts-2.0.6-all.zip)
> to
> >>> apache-tomcat-6.0.18/struts_test, copy apache-tomcat-6.0.18/conf to
> >>> apache-tomcat-6.0.18/struts_test
> >>> (1.4) set
> >>> CATALINA_BASE=…./apache-tomcat-6.0.18/my_base/struts_test, set
> >>> JRE_HOME=......
> >>> (1.5) cd …./apache-tomcat-6.0.18/, $bin/catalina.sh run (or
> >>> catalina.bat for windows platform)
> >>>
> >>> (2) Run the attached test case seperatedly
> >>> (2.1) Unzip the htmlunit-2.3.zip from
> >>> http://sourceforge.net/project/showfiles.php?group_id=47038 and
> include
> >>> the jar files from "htmlunit-2.3/lib into CLASSPATH
> >>> (2.2) Compile and run the attached test case (also listed below),
> >>> check the content of the result named debug.html to see the reported
> >>> exception
> >>>
> >>> import java.io.*;
> >>> import java.net.URL;
> >>> import java.lang.Thread;
> >>> import java.util.*;
> >>> import java.io.FileOutputStream;
> >>> import com.gargoylesoftware.htmlunit.WebClient;
> >>> import com.gargoylesoftware.htmlunit.html.HtmlPage;
> >>>
> >>> public class struts_test_debug{
> >>> public static void test_1(){
> >>> try{
> >>> URL baseurl=new URL("http://localhost:8080");
> >>> String p = "/struts2-showcase-2.0.6/tags/non-ui/debug.jsp";
> >>> final WebClient webClient = new WebClient();
> >>> final HtmlPage page = (HtmlPage)webClient.getPage(new
> >>> URL(baseurl,p));
> >>> //get the source code of webpage
> >>> String pHtml = page.getWebResponse().getContentAsString();
> >>> writeFile(pHtml);
> >>> System.out.println("Generated file: 'Debug.html' in local");
> >>> }catch(Exception e){}
> >>> }
> >>>
> >>> public static void main(String args[]){
> >>> System.out.println("test start!");
> >>> System.out.println("Reading remote file ...");
> >>> test_1();
> >>> System.out.println("test finished!");
> >>> }
> >>> public static void writeFile(String pHtml){
> >>> try{
> >>> FileOutputStream out = new FileOutputStream("Debug.html",false);
> >>> out.write(pHtml.getBytes());
> >>> }catch(Exception e){}
> >>> }
> >>> }
> >>>
> >>>
> >>> From [EMAIL PROTECTED] Subject svn commit: r647921 - in
> >>> /harmony/enhanced/classlib/trunk/modules/beans/src:
> >>> main/java/java/beans/StandardBeanInfo.java
> >>>
> test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
> >>> Date Mon, 14 Apr 2008 18:00:13 GMT
> >>>
> >>> Author: ayza
> >>> Date: Mon Apr 14 11:00:08 2008
> >>> New Revision: 647921
> >>>
> >>> URL: http://svn.apache.org/viewvc?rev=647921&view=rev
> >>> Log:
> >>> Applying patches from HARMONY-5675 ([classlib][beans] Introspector
> unable to determine set
> >>> method correctly)
> >>>
> >>> Modified:
> >>>
> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
> >>>
> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
> >>>
> >>> Modified:
> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
> >>> URL:
> http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java?rev=647921&r1=647920&r2=647921&view=diff
> >>>
> ==============================================================================
> >>> ---
> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
> >>> (original)
> >>> +++
> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
> >>> Mon Apr 14 11:00:08 2008
> >>> @@ -47,6 +47,22 @@
> >>>
> >>> private static final String SUFFIX_LISTEN = "Listener";
> //$NON-NLS-1$
> >>>
> >>> + private static final String STR_NORMAL = "normal"; //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_INDEXED = "indexed"; //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_VALID = "valid"; //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_INVALID = "invalid"; //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_PROPERTY_TYPE = "PropertyType";
> //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_IS_CONSTRAINED = "isConstrained";
> //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_SETTERS = "setters"; //$NON-NLS-1$
> >>> +
> >>> + private static final String STR_GETTERS = "getters"; //$NON-NLS-1$
> >>> +
> >>> private boolean explicitMethods = false;
> >>>
> >>> private boolean explicitProperties = false;
> >>> @@ -276,7 +292,8 @@
> >>> // Sub is PropertyDescriptor
> >>> if (subIndexedType == null) {
> >>> // Same property type
> >>> - if (subType.getName().equals(superType.getName()))
> {
> >>> + if (subType != null &&
> >>> +
> subType.getName().equals(superType.getName())) {
> >>> if ((subGet == null) && (superGet != null)) {
> >>> subDesc.setReadMethod(superGet);
> >>> }
> >>> @@ -481,8 +498,6 @@
> >>> * Introspects the supplied class and returns a list of the public
> methods
> >>> * of the class
> >>> *
> >>> - * @param beanClass -
> >>> - * the class
> >>> * @return An array of MethodDescriptors with the public methods.
> null if
> >>> * there are no public methods
> >>> */
> >>> @@ -533,8 +548,8 @@
> >>> * Introspects the supplied class and returns a list of the
> Properties of
> >>> * the class
> >>> *
> >>> - * @param beanClass -
> >>> - * the Class
> >>> + * @param stopClass -
> >>> + * the to introspecting at
> >>> * @return The list of Properties as an array of
> PropertyDescriptors
> >>> * @throws IntrospectionException
> >>> */
> >>> @@ -557,6 +572,9 @@
> >>> introspectSet(theMethods[i].getMethod(), propertyTable);
> >>> }
> >>>
> >>> + // fix possible getter & setter collisions
> >>> + fixGetSet(propertyTable);
> >>> +
> >>> // If there are listener methods, should be bound.
> >>> MethodDescriptor[] allMethods = introspectMethods(true);
> >>> if (stopClass != null) {
> >>> @@ -586,17 +604,17 @@
> >>> if (table == null) {
> >>> continue;
> >>> }
> >>> - String normalTag = (String) table.get("normal");
> //$NON-NLS-1$
> >>> - String indexedTag = (String) table.get("indexed");
> //$NON-NLS-1$
> >>> + String normalTag = (String) table.get(STR_NORMAL);
> >>> + String indexedTag = (String) table.get(STR_INDEXED);
> >>>
> >>> if ((normalTag == null) && (indexedTag == null)) {
> >>> continue;
> >>> }
> >>>
> >>> - Method get = (Method) table.get("normalget");
> //$NON-NLS-1$
> >>> - Method set = (Method) table.get("normalset");
> //$NON-NLS-1$
> >>> - Method indexedGet = (Method) table.get("indexedget");
> //$NON-NLS-1$
> >>> - Method indexedSet = (Method) table.get("indexedset");
> //$NON-NLS-1$
> >>> + Method get = (Method) table.get(STR_NORMAL + PREFIX_GET);
> >>> + Method set = (Method) table.get(STR_NORMAL + PREFIX_SET);
> >>> + Method indexedGet = (Method) table.get(STR_INDEXED +
> PREFIX_GET);
> >>> + Method indexedSet = (Method) table.get(STR_INDEXED +
> PREFIX_SET);
> >>>
> >>> PropertyDescriptor propertyDesc = null;
> >>> if (indexedTag == null) {
> >>> @@ -619,7 +637,7 @@
> >>> } else {
> >>> propertyDesc.setBound(false);
> >>> }
> >>> - if (table.get("isConstrained") == Boolean.TRUE) {
> //$NON-NLS-1$
> >>> + if (table.get(STR_IS_CONSTRAINED) == Boolean.TRUE) {
> //$NON-NLS-1$
> >>> propertyDesc.setConstrained(true);
> >>> }
> >>> propertyList.add(propertyDesc);
> >>> @@ -659,13 +677,20 @@
> >>> @SuppressWarnings("unchecked")
> >>> private static void introspectGet(Method theMethod,
> >>> HashMap<String, HashMap> propertyTable) {
> >>> - String methodName = theMethod.getName();
> >>> - if (methodName == null) {
> >>> +
> >>> + String methodName = theMethod.getName();
> >>> + int prefixLength = 0;
> >>> + String propertyName;
> >>> + Class propertyType;
> >>> + Class[] paramTypes;
> >>> + HashMap table;
> >>> + ArrayList<Method> getters;
> >>> +
> >>> + if (methodName == null) {
> >>> return;
> >>> }
> >>>
> >>> - int prefixLength = 0;
> >>> - if (methodName.startsWith(PREFIX_GET)) {
> >>> + if (methodName.startsWith(PREFIX_GET)) {
> >>> prefixLength = PREFIX_GET.length();
> >>> }
> >>>
> >>> @@ -677,153 +702,325 @@
> >>> return;
> >>> }
> >>>
> >>> - String propertyName =
> decapitalize(methodName.substring(prefixLength));
> >>> - // validate property name
> >>> + propertyName =
> decapitalize(methodName.substring(prefixLength));
> >>> +
> >>> + // validate property name
> >>> if (!isValidProperty(propertyName)) {
> >>> return;
> >>> }
> >>>
> >>> - Class propertyType = theMethod.getReturnType();
> >>> + // validate return type
> >>> + propertyType = theMethod.getReturnType();
> >>>
> >>> - // check return type getMethod
> >>> - if (propertyType.getName().equals(Void.TYPE.getName())) {
> >>> - return;
> >>> - }
> >>> + if (propertyType == null || propertyType == void.class) {
> >>> + return;
> >>> + }
> >>>
> >>> // isXXX return boolean
> >>> if (prefixLength == 2) {
> >>> - if
> (!propertyType.getName().equals(Boolean.TYPE.getName())) {
> >>> + if (!(propertyType == boolean.class)) {
> >>> return;
> >>> }
> >>> }
> >>>
> >>> - // indexed get method
> >>> - Class[] paramTypes = theMethod.getParameterTypes();
> >>> -
> >>> - if (paramTypes.length > 1) {
> >>> + // validate parameter types
> >>> + paramTypes = theMethod.getParameterTypes();
> >>> + if (paramTypes.length > 1 ||
> >>> + (paramTypes.length == 1 && paramTypes[0] !=
> int.class)) {
> >>> return;
> >>> }
> >>>
> >>> - String tag = "normal"; //$NON-NLS-1$
> >>> -
> >>> - if (paramTypes.length == 1) {
> >>> - if
> (paramTypes[0].getName().equals(Integer.TYPE.getName())) {
> >>> - tag = "indexed"; //$NON-NLS-1$
> >>> - } else {
> >>> - return;
> >>> - }
> >>> + //
> >>>
> >>> - }
> >>> -
> >>> - HashMap table = propertyTable.get(propertyName);
> >>> + table = propertyTable.get(propertyName);
> >>> if (table == null) {
> >>> table = new HashMap();
> >>> propertyTable.put(propertyName, table);
> >>> }
> >>>
> >>> - // the "get" propertyType is conflict with "set"
> propertyType
> >>> - Class oldPropertyType = (Class) table.get(tag +
> "PropertyType"); //$NON-NLS-1$
> >>> - if ((oldPropertyType != null)
> >>> - &&
> (!oldPropertyType.getName().equals(propertyType.getName()))) {
> >>> - table.put(tag, "invalid"); //$NON-NLS-1$
> >>> - table.remove(tag + "set"); //$NON-NLS-1$
> >>> - } else {
> >>> - table.put(tag, "valid"); //$NON-NLS-1$
> >>> - }
> >>> -
> >>> - table.put(tag + "PropertyType", propertyType);
> //$NON-NLS-1$
> >>> + getters = (ArrayList<Method>) table.get(STR_GETTERS);
> >>> + if (getters == null) {
> >>> + getters = new ArrayList<Method>();
> >>> + table.put(STR_GETTERS, getters);
> >>> + }
> >>>
> >>> - // According to the spec "is" method should be used prior
> to "get"
> >>> - if (prefixLength == 3) {
> >>> - if (!table.containsKey(tag + "get")) {
> //$NON-NLS-1$
> >>> - table.put(tag + "get", theMethod);
> //$NON-NLS-1$
> >>> - }
> >>> - } else {
> >>> - table.put(tag + "get", theMethod); //$NON-NLS-1$
> >>> - }
> >>> - }
> >>> + // add current method as a valid getter
> >>> + getters.add(theMethod);
> >>> + }
> >>>
> >>> @SuppressWarnings("unchecked")
> >>> private static void introspectSet(Method theMethod,
> >>> HashMap<String, HashMap> propertyTable) {
> >>> - String methodName = theMethod.getName();
> >>> - if (methodName == null) {
> >>> - return;
> >>> - }
> >>>
> >>> - int prefixLength = 0;
> >>> - if (methodName.startsWith(PREFIX_SET)) {
> >>> - prefixLength = PREFIX_GET.length();
> >>> - }
> >>> + String methodName = theMethod.getName();
> >>> + String propertyName;
> >>> + Class returnType;
> >>> + Class[] paramTypes;
> >>>
> >>> - if (prefixLength == 0) {
> >>> + if (methodName == null || !methodName.startsWith(PREFIX_SET))
> {
> >>> return;
> >>> }
> >>>
> >>> - String propertyName =
> decapitalize(methodName.substring(prefixLength));
> >>> + propertyName = decapitalize(methodName.substring(
> >>> + PREFIX_SET.length()));
> >>>
> >>> // validate property name
> >>> if (!isValidProperty(propertyName)) {
> >>> return;
> >>> }
> >>>
> >>> - Class returnType = theMethod.getReturnType();
> >>> + // validate return type
> >>> + returnType = theMethod.getReturnType();
> >>>
> >>> - if (!returnType.getName().equals(Void.TYPE.getName())) {
> >>> +// if (!returnType.getName().equals(Void.TYPE.getName())) {
> >>> + if (!(returnType == void.class)) {
> >>> return;
> >>> }
> >>>
> >>> - // indexed get method
> >>> - Class[] paramTypes = theMethod.getParameterTypes();
> >>> + // validate param types
> >>> + paramTypes = theMethod.getParameterTypes();
> >>>
> >>> - if ((paramTypes.length == 0) || (paramTypes.length > 2)) {
> >>> + if (paramTypes.length == 0 || paramTypes.length > 2 ||
> >>> + (paramTypes.length == 2 && paramTypes[0] !=
> int.class)) {
> >>> return;
> >>> }
> >>>
> >>> - String tag = "normal"; //$NON-NLS-1$
> >>> -
> >>> - Class propertyType = paramTypes[0];
> >>> -
> >>> - if (paramTypes.length == 2) {
> >>> - if
> (paramTypes[0].getName().equals(Integer.TYPE.getName())) {
> >>> - tag = "indexed"; //$NON-NLS-1$
> >>> - propertyType = paramTypes[1];
> >>> - } else {
> >>> - return;
> >>> - }
> >>> - }
> >>> + //
> >>>
> >>> HashMap table = propertyTable.get(propertyName);
> >>> if (table == null) {
> >>> table = new HashMap();
> >>> + propertyTable.put(propertyName, table);
> >>> }
> >>>
> >>> - Class oldPropertyType = (Class) table.get(tag +
> "PropertyType"); //$NON-NLS-1$
> >>> - if ((oldPropertyType != null)
> >>> - &&
> (!oldPropertyType.getName().equals(propertyType.getName()))) {
> >>> - table.put(tag, "invalid"); //$NON-NLS-1$
> >>> - return;
> >>> + ArrayList<Method> setters = (ArrayList<Method>)
> table.get(STR_SETTERS);
> >>> + if (setters == null) {
> >>> + setters = new ArrayList<Method>();
> >>> + table.put(STR_SETTERS, setters);
> >>> }
> >>>
> >>> - table.put(tag, "valid"); //$NON-NLS-1$
> >>> - table.put(tag + "set", theMethod); //$NON-NLS-1$
> >>> - table.put(tag + "PropertyType", propertyType); //$NON-NLS-1$
> >>> -
> >>> // handle constrained
> >>> Class[] exceptions = theMethod.getExceptionTypes();
> >>> for (Class e : exceptions) {
> >>> if (e.equals(PropertyVetoException.class)) {
> >>> - table.put("isConstrained", Boolean.TRUE);
> //$NON-NLS-1$
> >>> + table.put(STR_IS_CONSTRAINED, Boolean.TRUE);
> //$NON-NLS-1$
> >>> + }
> >>> + }
> >>> +
> >>> + // add new setter
> >>> + setters.add(theMethod);
> >>> + }
> >>> +
> >>> + /**
> >>> + * Checks and fixs all cases when several incompatible checkers /
> >>> + * getters were specified for single property.
> >>> + * @param propertyTable
> >>> + * @throws IntrospectionException
> >>> + */
> >>> + private void fixGetSet(HashMap<String, HashMap> propertyTable)
> >>> + throws IntrospectionException {
> >>> +
> >>> + if (propertyTable == null) {
> >>> + return;
> >>> + }
> >>> +
> >>> + for (String key : propertyTable.keySet()) {
> >>> + HashMap<String, Object> table = propertyTable.get(key);
> >>> + ArrayList<Method> getters = (ArrayList<Method>)
> table.get(STR_GETTERS);
> >>> + ArrayList<Method> setters = (ArrayList<Method>)
> table.get(STR_SETTERS);
> >>> +
> >>> + Method normalGetter = null;
> >>> + Method indexedGetter = null;
> >>> + Method normalSetter = null;
> >>> + Method indexedSetter = null;
> >>> +
> >>> + Class normalPropType = null;
> >>> + Class indexedPropType = null;
> >>> +
> >>> + if (getters == null) {
> >>> + getters = new ArrayList<Method>();
> >>> + }
> >>> +
> >>> + if (setters == null) {
> >>> + setters = new ArrayList<Method>();
> >>> + }
> >>> +
> >>> + // retrieve getters
> >>> + for (Method getter: getters) {
> >>> + // checks if it's a normal getter
> >>> + if (getter.getParameterTypes() == null ||
> >>> + getter.getParameterTypes().length == 0) {
> >>> + // normal getter found
> >>> + if (normalGetter == null ||
> >>> + getter.getName().startsWith(PREFIX_IS)) {
> >>> + normalGetter = getter;
> >>> + }
> >>> + }
> >>> +
> >>> + // checks if it's an indexed getter
> >>> + if (getter.getParameterTypes() != null &&
> >>> + getter.getParameterTypes().length == 1 &&
> >>> + getter.getParameterTypes()[0] == int.class) {
> >>> + // indexed getter found
> >>> + if (indexedGetter == null ||
> >>> + getter.getName().startsWith(PREFIX_IS)) {
> >>> + indexedGetter = getter;
> >>> + }
> >>> + }
> >>> + }
> >>> +
> >>> + // retrieve normal setter
> >>> + if (normalGetter != null) {
> >>> + // Now we will try to look for normal setter of the
> same type.
> >>> + Class propertyType = normalGetter.getReturnType();
> >>> +
> >>> + for (Method setter: setters) {
> >>> + if (setter.getParameterTypes().length == 1 &&
> >>> +
> propertyType.equals(setter.getParameterTypes()[0]))
> >>> + {
> >>> + normalSetter = setter;
> >>> + break;
> >>> + }
> >>> + }
> >>> + } else {
> >>> + // Normal getter wasn't defined. Let's look for the
> last
> >>> + // defined setter
> >>> +
> >>> + for (Method setter: setters) {
> >>> + if (setter.getParameterTypes().length == 1) {
> >>> + normalSetter = setter;
> >>> + }
> >>> + }
> >>> }
> >>> +
> >>> + // retrieve indexed setter
> >>> + if (indexedGetter != null) {
> >>> + // Now we will try to look for indexed setter of the
> same type.
> >>> + Class propertyType = indexedGetter.getReturnType();
> >>> +
> >>> + for (Method setter: setters) {
> >>> + if (setter.getParameterTypes().length == 2 &&
> >>> + setter.getParameterTypes()[0] == int.class
> &&
> >>> +
> propertyType.equals(setter.getParameterTypes()[1]))
> >>> + {
> >>> + indexedSetter = setter;
> >>> + break;
> >>> + }
> >>> + }
> >>> + } else {
> >>> + // Indexed getter wasn't defined. Let's look for the
> last
> >>> + // defined indexed setter
> >>> +
> >>> + for (Method setter: setters) {
> >>> + if (setter.getParameterTypes().length == 2 &&
> >>> + setter.getParameterTypes()[0] ==
> int.class) {
> >>> + indexedSetter = setter;
> >>> + }
> >>> + }
> >>> + }
> >>> +
> >>> + // determine property type
> >>> + if (normalGetter != null) {
> >>> + normalPropType = normalGetter.getReturnType();
> >>> + } else if (normalSetter != null) {
> >>> + normalPropType = normalSetter.getParameterTypes()[0];
> >>> + }
> >>> +
> >>> + // determine indexed getter/setter type
> >>> + if (indexedGetter != null) {
> >>> + indexedPropType = indexedGetter.getReturnType();
> >>> + } else if (indexedSetter != null) {
> >>> + indexedPropType =
> indexedSetter.getParameterTypes()[1];
> >>> + }
> >>> +
> >>> + // convert array-typed normal getters to indexed getters
> >>> + if (normalGetter != null &&
> normalGetter.getReturnType().isArray())
> >>> + {
> >>> +
> >>> + }
> >>> +
> >>> + // RULES
> >>> + // These rules were created after performing extensive
> black-box
> >>> + // testing of RI
> >>> +
> >>> + // RULE1
> >>> + // Both normal getter and setter of the same type were
> defined;
> >>> + // no indexed getter/setter *PAIR* of the other type
> defined
> >>> + if (normalGetter != null && normalSetter != null &&
> >>> + (indexedGetter == null || indexedSetter == null)
> &&
> >>> + normalPropType != indexedPropType) {
> >>> +// String tag = normalPropType.isArray() ?
> >>> +// STR_INDEXED : STR_NORMAL;
> >>> + String tag = STR_NORMAL;
> >>> +
> >>> + table.put(tag, STR_VALID);
> >>> + table.put(tag + PREFIX_GET, normalGetter);
> >>> + table.put(tag + PREFIX_SET, normalSetter);
> >>> + table.put(tag + STR_PROPERTY_TYPE, normalPropType);
> >>> + continue;
> >>> + }
> >>> +
> >>> + // RULE2
> >>> + // normal getter and/or setter was defined; no indexed
> >>> + // getters & setters defined
> >>> + if ((normalGetter != null || normalSetter != null) &&
> >>> + indexedGetter == null && indexedSetter == null) {
> >>> +// String tag = normalPropType.isArray() ?
> >>> +// STR_INDEXED : STR_NORMAL;
> >>> + String tag = STR_NORMAL;
> >>> +
> >>> + table.put(tag, STR_VALID);
> >>> + table.put(tag + PREFIX_GET, normalGetter);
> >>> + table.put(tag + PREFIX_SET, normalSetter);
> >>> + table.put(tag + STR_PROPERTY_TYPE, normalPropType);
> >>> + continue;
> >>> + }
> >>> +
> >>> + // RULE3
> >>> + // mix of normal / indexed getters and setters are
> defined. Types
> >>> + // are compatible
> >>> + if ((normalGetter != null || normalSetter != null) &&
> >>> + (indexedGetter != null || indexedSetter != null)
> &&
> >>> + normalPropType.isArray() &&
> >>> + normalPropType.getComponentType() ==
> indexedPropType) {
> >>> + table.put(STR_NORMAL, STR_VALID);
> >>> + table.put(STR_NORMAL + PREFIX_GET, normalGetter);
> >>> + table.put(STR_NORMAL + PREFIX_SET, normalSetter);
> >>> + table.put(STR_NORMAL + STR_PROPERTY_TYPE,
> normalPropType);
> >>> +
> >>> + table.put(STR_INDEXED, STR_VALID);
> >>> + table.put(STR_INDEXED + PREFIX_GET, indexedGetter);
> >>> + table.put(STR_INDEXED + PREFIX_SET, indexedSetter);
> >>> + table.put(STR_INDEXED + STR_PROPERTY_TYPE,
> indexedPropType);
> >>> +
> >>> + continue;
> >>> + }
> >>> +
> >>> + // RULE4
> >>> + // no normal normal getter / setter.
> >>> + // Only indexed getter and/or setter is given
> >>> + // no normal setters / getters defined
> >>> + if (normalSetter == null && normalGetter == null &&
> >>> + (indexedGetter != null || indexedSetter != null))
> {
> >>> + table.put(STR_INDEXED, STR_VALID);
> >>> + table.put(STR_INDEXED + PREFIX_GET, indexedGetter);
> >>> + table.put(STR_INDEXED + PREFIX_SET, indexedSetter);
> >>> + table.put(STR_INDEXED + STR_PROPERTY_TYPE,
> >>> + indexedPropType);
> >>> + continue;
> >>> + }
> >>> +
> >>> + // default rule - invalid property
> >>> + table.put(STR_NORMAL, STR_INVALID);
> >>> + table.put(STR_INDEXED, STR_INVALID);
> >>> }
> >>> - propertyTable.put(propertyName, table);
> >>> +
> >>> }
> >>>
> >>> /**
> >>> * Introspects the supplied Bean class and returns a list of the
> Events of
> >>> * the class
> >>> *
> >>> - * @param beanClass
> >>> * @return the events
> >>> * @throws IntrospectionException
> >>> */
> >>>
> >>> Modified:
> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
> >>> URL:
> http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java?rev=647921&r1=647920&r2=647921&view=diff
> >>>
> ==============================================================================
> >>> ---
> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
> >>> (original)
> >>> +++
> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
> >>> Mon Apr 14 11:00:08 2008
> >>> @@ -2331,4 +2331,254 @@
> >>> assertFalse(pd.getName().equals("invisible"));
> >>> }
> >>> }
> >>> +
> >>> + /**
> >>> + * Tests tricky cases when several conflicting set/get methods are
> defined.
> >>> + * All these tests pass on RI.
> >>> + * This is a regression test for HARMONY-5675
> >>> + * @throws IntrospectionException
> >>> + */
> >>> + public void test5675() throws IntrospectionException {
> >>> + BeanInfo bInfo;
> >>> +
> >>> + for (Class clz: new Class[] {TstBean5675.class,
> TstBean5675_2.class}) {
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(clz);
> >>> +
> >>> + for (PropertyDescriptor desc:
> bInfo.getPropertyDescriptors()) {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNotNull("invalid get method",
> desc.getReadMethod());
> >>> + assertEquals("get method has invalid return type",
> >>> + Integer.class,
> desc.getReadMethod().getReturnType());
> >>> + assertNotNull("invalid set method",
> desc.getWriteMethod());
> >>> + assertEquals("invalid set method",
> >>> + "setProp1",
> desc.getWriteMethod().getName());
> >>> + assertNotNull("set method don't have any
> parameters",
> >>> +
> desc.getWriteMethod().getParameterTypes());
> >>> + assertEquals("set method has invalid parameters",
> >>> + Integer.class,
> >>> +
> desc.getWriteMethod().getParameterTypes()[0]);
> >>> + }
> >>> + }
> >>> + }
> >>> +
> >>> + for (Class clz : new Class[] {TstBean5675_3.class,
> TstBean5675_5.class,
> >>> + TstBean5675_6.class}) {
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(clz);
> >>> +
> >>> + for (PropertyDescriptor desc:
> bInfo.getPropertyDescriptors()) {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNull("Non-null get method",
> desc.getReadMethod());
> >>> + assertNull("Non-null set method",
> desc.getWriteMethod());
> >>> + }
> >>> + }
> >>> + }
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(TstBean5675_4.class);
> >>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors())
> {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNotNull("invalid get method",
> desc.getReadMethod());
> >>> + assertEquals("get method has invalid return type",
> >>> + Integer.class,
> desc.getReadMethod().getReturnType());
> >>> + assertNull("Non-null set method",
> desc.getWriteMethod());
> >>> + }
> >>> + }
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(TstBean5675_7.class);
> >>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors())
> {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNull("Non-null get method",
> desc.getReadMethod());
> >>> + assertEquals("invalid set method",
> >>> + "setProp1", desc.getWriteMethod().getName());
> >>> + assertNotNull("set method don't have any parameters",
> >>> + desc.getWriteMethod().getParameterTypes());
> >>> + assertEquals("set method has invalid parameters",
> >>> + Integer.class,
> >>> + desc.getWriteMethod().getParameterTypes()[0]);
> >>> + }
> >>> + }
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(TstBean5675_8.class);
> >>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors())
> {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNotNull("invalid get method",
> desc.getReadMethod());
> >>> + assertEquals("get method has invalid return type",
> >>> + Integer[].class,
> desc.getReadMethod().getReturnType());
> >>> + assertNull("Non-null set method",
> desc.getWriteMethod());
> >>> + }
> >>> + }
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(TstBean5675_9.class);
> >>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors())
> {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNull("Non-null get method",
> desc.getReadMethod());
> >>> + assertNotNull("invalid set method",
> desc.getWriteMethod());
> >>> + assertEquals("invalid set method",
> >>> + "setProp1", desc.getWriteMethod().getName());
> >>> + assertNotNull("set method don't have any parameters",
> >>> + desc.getWriteMethod().getParameterTypes());
> >>> + assertEquals("set method has invalid parameters",
> >>> + Integer[].class,
> >>> + desc.getWriteMethod().getParameterTypes()[0]);
> >>> + }
> >>> + }
> >>> +
> >>> + bInfo = Introspector.getBeanInfo(TstBean5675_10.class);
> >>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors())
> {
> >>> +
> >>> + if (desc.getName().equals("prop1")) {
> >>> + assertNotNull("invalid get method",
> desc.getReadMethod());
> >>> + assertEquals("get method has invalid return type",
> >>> + Integer[].class,
> desc.getReadMethod().getReturnType());
> >>> + assertNotNull("invalid set method",
> desc.getWriteMethod());
> >>> + assertEquals("invalid set method",
> >>> + "setProp1", desc.getWriteMethod().getName());
> >>> + assertNotNull("set method don't have any parameters",
> >>> + desc.getWriteMethod().getParameterTypes());
> >>> + assertEquals("set method has invalid parameters",
> >>> + Integer[].class,
> >>> + desc.getWriteMethod().getParameterTypes()[0]);
> >>> + }
> >>> + }
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675 {
> >>> +
> >>> + public void setProp1(String uri) {}
> >>> +
> >>> + public void setProp1(Integer i) {}
> >>> +
> >>> +
> >>> + public Integer getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> + }
> >>> +
> >>> +
> >>> + class TstBean5675_2 {
> >>> +
> >>> + public Integer getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public String getProp1(int n) {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public void setProp1(Integer val) {}
> >>> +
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675_3 {
> >>> +
> >>> + public String getProp1(int n) {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public void setProp1(int n, String uri) {}
> >>> +
> >>> + public void setProp1(Integer i) {}
> >>> +
> >>> + public Integer getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675_4 {
> >>> +
> >>> + public void setProp1(String val) {}
> >>> +
> >>> + public Integer getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675_5 {
> >>> +
> >>> + public Integer getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> +// public void setProp1(Integer val) {}
> >>> +
> >>> + public String getProp1(int n) {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public void setProp1(int n, String uri) {}
> >>> +
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675_6 {
> >>> +
> >>> + public Integer getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> +// public void setProp1(Integer val) {}
> >>> +//
> >>> +// public String getProp1(int n) {
> >>> +// return null;
> >>> +// }
> >>> +
> >>> + public void setProp1(int n, String uri) {}
> >>> +
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675_7 {
> >>> + public void setProp1(String val) {}
> >>> + public void setProp1(Integer val) {}
> >>> + }
> >>> +
> >>> + class TstBean5675_8 {
> >>> + public Integer[] getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> + //public void setProp1(Integer[] val) {}
> >>> +
> >>> + public Integer getProp1(int n) {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public void setProp1(int n, Integer val) {}
> >>> + }
> >>> +
> >>> + class TstBean5675_9 {
> >>> + public void setProp1(Integer[] val) {}
> >>> +
> >>> + public Integer getProp1(int n) {
> >>> + return null;
> >>> + }
> >>> +
> >>> + }
> >>> +
> >>> + class TstBean5675_10 {
> >>> + public Integer[] getProp1() {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public void setProp1(Integer[] val) {}
> >>> +
> >>> + public Integer getProp1(int n) {
> >>> + return null;
> >>> + }
> >>> +
> >>> + public void setProp1(int n, Integer val) {}
> >>> + }
> >>> +
> >>> }
> >>>
> >>>
> >>>
> >>
> >
>