Has raised a Harmony JIRA [1].
[1] https://issues.apache.org/jira/browse/HARMONY-6038
On Tue, Dec 9, 2008 at 5:16 PM, chunrong lai <[EMAIL PROTECTED]> wrote:
> 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) {}
> > >>> + }
> > >>> +
> > >>> }
> > >>>
> > >>>
> > >>>
> > >>
> > >
> >
>