You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2008/05/22 11:25:54 UTC

svn commit: r659061 - in /harmony/enhanced/classlib/trunk/modules/beans/src: main/java/java/beans/ main/java/org/apache/harmony/beans/internal/nls/ test/java/org/apache/harmony/beans/tests/java/beans/ test/resources/xml/ test/support/java/org/apache/ha...

Author: tonywu
Date: Thu May 22 02:25:53 2008
New Revision: 659061

URL: http://svn.apache.org/viewvc?rev=659061&view=rev
Log:
Apply patch for HARMONY-5831 ([classlib][beans] XMLDecoder will throw exception for restrict method type check)

Added:
    harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner.xml   (with props)
    harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Ambiguous.xml   (with props)
    harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Null.xml   (with props)
    harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Specific.xml   (with props)
    harmony/enhanced/classlib/trunk/modules/beans/src/test/support/java/org/apache/harmony/beans/tests/support/MockOwnerClass.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLDecoder.java
    harmony/enhanced/classlib/trunk/modules/beans/src/main/java/org/apache/harmony/beans/internal/nls/messages.properties
    harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLDecoderTest.java

Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLDecoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLDecoder.java?rev=659061&r1=659060&r2=659061&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLDecoder.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/XMLDecoder.java Thu May 22 02:25:53 2008
@@ -17,6 +17,7 @@
 
 package java.beans;
 
+import java.beans.Statement.MethodComparator;
 import java.io.InputStream;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
@@ -27,6 +28,7 @@
 
 import javax.xml.parsers.SAXParserFactory;
 
+import org.apache.harmony.beans.internal.nls.Messages;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
@@ -331,10 +333,24 @@
                 }
                 Class[] c = new Class[args.size()];
                 for (int i = 0; i < args.size(); i++) {
-                    c[i] = args.get(i).getClass();
+                    Object arg = args.get(i);
+                    c[i] = (arg == null ? null: arg.getClass());
                 }
-                Method m = owner.getClass().getMethod(method, c);
-                return m.invoke(owner, args.toArray());
+
+                // Try actual match method
+                try {
+                    Method m = owner.getClass().getMethod(method, c);
+                    return m.invoke(owner, args.toArray());
+                } catch (NoSuchMethodException e) {
+                    // Do nothing
+                }
+
+                // Find the specific method matching the parameter
+                Method mostSpecificMethod = findMethod(
+                        owner instanceof Class ? (Class) owner : owner
+                                .getClass(), method, c);
+
+                return mostSpecificMethod.invoke(owner, args.toArray());
             }
 
             // execute
@@ -342,6 +358,75 @@
             return exp.getValue();
         }
 
+        private Method findMethod(Class clazz, String methodName,
+                Class[] clazzes) throws Exception {
+            Method[] methods = clazz.getMethods();
+            ArrayList<Method> matchMethods = new ArrayList<Method>();
+
+            // Add all matching methods into a ArrayList
+            for (Method method : methods) {
+                if (!methodName.equals(method.getName())) {
+                    continue;
+                }
+                Class[] parameterTypes = method.getParameterTypes();
+                if (parameterTypes.length != clazzes.length) {
+                    continue;
+                }
+                boolean match = true;
+                for (int i = 0; i < parameterTypes.length; i++) {
+                    boolean isNull = (clazzes[i] == null);
+                    boolean isPrimitive = isPrimitiveWrapper(clazzes[i], parameterTypes[i]);
+                    boolean isAssignable = isNull? false : parameterTypes[i].isAssignableFrom(clazzes[i]);
+                    if ( isNull || isPrimitive || isAssignable ) {
+                        continue;
+                    }
+                    match = false;
+                }
+                if (match) {
+                    matchMethods.add(method);
+                }
+            }
+
+            int size = matchMethods.size();
+            if (size == 1) {
+                // Only one method matches, just invoke it
+                return matchMethods.get(0);
+            } else if (size == 0) {
+                // Does not find any matching one, throw exception
+                throw new NoSuchMethodException(Messages.getString(
+                        "beans.41", methodName)); //$NON-NLS-1$
+            }
+
+            // There are more than one method matching the signature
+            // Find the most specific one to invoke
+            MethodComparator comparator = new MethodComparator(methodName,
+                    clazzes);
+            Method chosenOne = matchMethods.get(0);
+            matchMethods.remove(0);
+            for (Method method : matchMethods) {
+                int difference = comparator.compare(chosenOne, method);
+                if (difference > 0) {
+                    chosenOne = method;
+                } else if (difference == 0) {
+                    // if 2 methods have same relevance, throw exception
+                    throw new NoSuchMethodException(Messages.getString(
+                            "beans.62", methodName)); //$NON-NLS-1$
+                }
+            }
+            return chosenOne;
+        }
+
+        private boolean isPrimitiveWrapper(Class<?> wrapper, Class<?> base) {
+            return (base == boolean.class) && (wrapper == Boolean.class)
+                    || (base == byte.class) && (wrapper == Byte.class)
+                    || (base == char.class) && (wrapper == Character.class)
+                    || (base == short.class) && (wrapper == Short.class)
+                    || (base == int.class) && (wrapper == Integer.class)
+                    || (base == long.class) && (wrapper == Long.class)
+                    || (base == float.class) && (wrapper == Float.class)
+                    || (base == double.class) && (wrapper == Double.class);
+        }
+
         private String capitalize(String str) {
             StringBuffer buf = new StringBuffer(str);
             buf.setCharAt(0, Character.toUpperCase(buf.charAt(0)));

Modified: harmony/enhanced/classlib/trunk/modules/beans/src/main/java/org/apache/harmony/beans/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/org/apache/harmony/beans/internal/nls/messages.properties?rev=659061&r1=659060&r2=659061&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/main/java/org/apache/harmony/beans/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/main/java/org/apache/harmony/beans/internal/nls/messages.properties Thu May 22 02:25:53 2008
@@ -113,3 +113,4 @@
 beans.5F=Indexed write method must take a two arguments
 beans.60=Indexed write method must take an int as its first argument
 beans.61=Indexed write method is not compatible with indexed read method
+beans.62=Cannot decide which method to call to match {0}

Modified: harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLDecoderTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLDecoderTest.java?rev=659061&r1=659060&r2=659061&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLDecoderTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLDecoderTest.java Thu May 22 02:25:53 2008
@@ -24,6 +24,7 @@
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
 import java.util.Vector;
 import java.lang.reflect.Array;
 
@@ -33,6 +34,7 @@
 
 import org.apache.harmony.beans.tests.java.beans.EncoderTest.SampleBean;
 import org.apache.harmony.beans.tests.java.beans.XMLEncoderTest.DependencyBean;
+import org.apache.harmony.beans.tests.support.MockOwnerClass;
 import org.apache.harmony.beans.tests.support.mock.MockBean4Codec;
 import org.apache.harmony.beans.tests.support.mock.MockBean4Owner_Owner;
 import org.apache.harmony.beans.tests.support.mock.MockBean4Owner_Target;
@@ -254,6 +256,34 @@
         assertEquals(1, o1.getV());
         assertEquals(o1, t1.getV());
     }
+    
+    public void testReadObject_Owner_Specific(){
+        String expectedValue = "expected value";
+        HashMap map = new HashMap();
+        map.put("key", expectedValue);
+        
+        XMLDecoder decoder = new XMLDecoder(this.getClass().getResourceAsStream(
+                "/xml/MockOwner.xml"), map);
+        String actualValue = (String) decoder.readObject();
+        assertEquals(expectedValue,actualValue);
+        
+        MockOwnerClass mock = new MockOwnerClass();
+        expectedValue = "I_Ljava.lang.String";
+        decoder = new XMLDecoder(this.getClass().getResourceAsStream(
+        "/xml/MockOwner_Specific.xml"), mock);
+        actualValue = (String) decoder.readObject();
+        assertEquals(expectedValue,actualValue);
+        
+        decoder = new XMLDecoder(this.getClass().getResourceAsStream(
+        "/xml/MockOwner_Ambiguous.xml"), mock);
+        actualValue = (String) decoder.readObject();
+        assertNull(actualValue);
+        
+        decoder = new XMLDecoder(this.getClass().getResourceAsStream(
+        "/xml/MockOwner_Null.xml"), mock);
+        actualValue = (String) decoder.readObject();
+        assertNull(actualValue);
+    }
 
     public void testReadObject_Owner_WithWriteStatement() {
         MockBean4Owner_Owner o2 = new MockBean4Owner_Owner();

Added: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner.xml?rev=659061&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner.xml (added)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner.xml Thu May 22 02:25:53 2008
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<java version='1.6.0' class='java.beans.XMLDecoder'>
+    <void property='owner'>
+        <void method='get' id='v'>
+            <string>key</string>
+        </void>
+    </void>
+    <object idref='v'/>
+</java>

Propchange: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Ambiguous.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Ambiguous.xml?rev=659061&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Ambiguous.xml (added)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Ambiguous.xml Thu May 22 02:25:53 2008
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<java version='1.6.0' class='java.beans.XMLDecoder'>
+    <void property='owner'>
+        <void method='get' id='v'>
+            <string>key</string>
+            <string>key</string>
+        </void>
+    </void>
+    <object idref='v'/>
+</java>

Propchange: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Ambiguous.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Null.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Null.xml?rev=659061&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Null.xml (added)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Null.xml Thu May 22 02:25:53 2008
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<java version='1.6.0' class='java.beans.XMLDecoder'>
+    <void property='owner'>
+        <void method='get' id='v'>
+            <null/>
+            <string>key</string>
+        </void>
+    </void>
+    <object idref='v'/>
+</java>

Propchange: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Null.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Specific.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Specific.xml?rev=659061&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Specific.xml (added)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Specific.xml Thu May 22 02:25:53 2008
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<java version='1.6.0' class='java.beans.XMLDecoder'>
+    <void property='owner'>
+        <void method='get' id='v'>
+            <int>2</int>
+            <string>key</string>
+        </void>
+    </void>
+    <object idref='v'/>
+</java>

Propchange: harmony/enhanced/classlib/trunk/modules/beans/src/test/resources/xml/MockOwner_Specific.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/beans/src/test/support/java/org/apache/harmony/beans/tests/support/MockOwnerClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/support/java/org/apache/harmony/beans/tests/support/MockOwnerClass.java?rev=659061&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/beans/src/test/support/java/org/apache/harmony/beans/tests/support/MockOwnerClass.java (added)
+++ harmony/enhanced/classlib/trunk/modules/beans/src/test/support/java/org/apache/harmony/beans/tests/support/MockOwnerClass.java Thu May 22 02:25:53 2008
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.harmony.beans.tests.support;
+
+public class MockOwnerClass {
+    static public String get(int a , String b){
+        return "I_Ljava.lang.String";
+    }
+
+    static public String get(Integer a, Object b){
+        return "Ljava.lang.Integer_Ljava.lang.Object";
+    }
+    
+    static public String get(Object a, String b){
+        return "Ljava.lang.Object_Ljava.lang.String";
+    }
+    
+    public String get(String b, Object a){
+        return "Ljava.lang.Object_Ljava.lang.String";
+    }
+}

Propchange: harmony/enhanced/classlib/trunk/modules/beans/src/test/support/java/org/apache/harmony/beans/tests/support/MockOwnerClass.java
------------------------------------------------------------------------------
    svn:eol-style = native