From 0618281a42577cb71aee6013a60654e17564a410 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Fri, 2 Mar 2007 19:05:57 +0000 Subject: [PATCH] AnnotationInvocationHandler.java: Generify in a few places. 2007-03-02 Andrew Haley * sun/reflect/annotation/AnnotationInvocationHandler.java: Generify in a few places. (equals): Rewrite to use invoke on local proxy. (deepToString): Remove most of it. (toString): Make nonstatic. (arrayClone): Delete. (coerce): New method. (invoke): Rewrite to handle gcj's structures correctly. * java/lang/natClass.cc (getDeclaredAnnotations): Fix test for null loader. * sources.am: Regenerate. * Makefile.am: Likewise. From-SVN: r122483 --- libjava/ChangeLog | 15 ++ libjava/Makefile.in | 2 +- .../AnnotationInvocationHandler.class | Bin 7471 -> 8487 bytes libjava/sources.am | 2 +- .../annotation/AnnotationInvocationHandler.h | 8 +- .../AnnotationInvocationHandler.java | 195 +++++++++++------- 6 files changed, 141 insertions(+), 81 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 96cdf2dcbda..bddc9986302 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,18 @@ +2007-03-02 Andrew Haley + + * sun/reflect/annotation/AnnotationInvocationHandler.java: + Generify in a few places. + (equals): Rewrite to use invoke on local proxy. + (deepToString): Remove most of it. + (toString): Make nonstatic. + (arrayClone): Delete. + (coerce): New method. + (invoke): Rewrite to handle gcj's structures correctly. + * java/lang/natClass.cc (getDeclaredAnnotations): Fix test for + null loader. + * sources.am: Regenerate. + * Makefile.am: Likewise. + 2007-03-02 Andrew Haley * sun/reflect/annotation/AnnotationInvocationHandler.java: diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 96cd2d11bd7..99433510638 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -7194,7 +7194,7 @@ sun/reflect/Reflection.java sun_reflect_header_files = $(patsubst %.java,%.h,$(sun_reflect_source_files)) sun_reflect_annotation_source_files = \ -classpath/sun/reflect/annotation/AnnotationInvocationHandler.java \ +sun/reflect/annotation/AnnotationInvocationHandler.java \ classpath/sun/reflect/annotation/AnnotationParser.java \ classpath/sun/reflect/annotation/AnnotationType.java \ classpath/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java \ diff --git a/libjava/classpath/lib/sun/reflect/annotation/AnnotationInvocationHandler.class b/libjava/classpath/lib/sun/reflect/annotation/AnnotationInvocationHandler.class index e70c2bbcd7bc9690fa424e057de8da781a0544e5..2e3036326cd7ca9a73a09b9a126cfb5d9e205d46 100644 GIT binary patch literal 8487 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 AXaE2J literal 7471 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 *); private: diff --git a/libjava/sun/reflect/annotation/AnnotationInvocationHandler.java b/libjava/sun/reflect/annotation/AnnotationInvocationHandler.java index ccfe86039cc..f883faa16ac 100644 --- a/libjava/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/libjava/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -1,5 +1,5 @@ /* sun.reflect.annotation.AnnotationInvocationHandler - Copyright (C) 2006 + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -8,7 +8,7 @@ GNU Classpath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GNU Classpath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -43,9 +43,9 @@ import java.lang.annotation.Annotation; import java.lang.annotation.AnnotationTypeMismatchException; import java.lang.annotation.IncompleteAnnotationException; import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.lang.reflect.Array; import java.util.Arrays; import java.util.Iterator; import java.util.Map; @@ -62,21 +62,21 @@ public final class AnnotationInvocationHandler implements InvocationHandler, Serializable { private static final long serialVersionUID = 6182022883658399397L; - private final Class type; - private final Map memberValues; + private final Class type; + private final Map memberValues; /** * Construct a new invocation handler for an annotation proxy. * Note that the VM is responsible for filling the memberValues map * with the default values of all the annotation members. */ - public AnnotationInvocationHandler(Class type, Map memberValues) + public AnnotationInvocationHandler(Class type, Map memberValues) { this.type = type; - this.memberValues = memberValues; + this.memberValues = (Map)memberValues; } - public static Annotation create(Class type, Map memberValues) + public static Annotation create(Class type, Map memberValues) { for (Method m : type.getDeclaredMethods()) { @@ -106,7 +106,7 @@ public final class AnnotationInvocationHandler * (can) use different representations of annotations that reuse this * method. */ - public static boolean equals(Class type, Map memberValues, Object other) + public boolean equals(Object proxy, Object other) { if (type.isInstance(other)) { @@ -118,8 +118,12 @@ public final class AnnotationInvocationHandler for (int i = 0; i < methods.length; i++) { String key = methods[i].getName(); - Object val = methods[i].invoke(other, new Object[0]); - if (! deepEquals(memberValues.get(key), val)) + Object val = methods[i].invoke(other, (Object[])null); + Object thisVal + = invoke(proxy, + methods[i], + (Object[])null); + if (! deepEquals(thisVal, val)) { return false; } @@ -127,11 +131,7 @@ public final class AnnotationInvocationHandler return true; } } - catch (IllegalAccessException _) - { - // Ignore exception, like the JDK - } - catch (InvocationTargetException _) + catch (Throwable _) { // Ignore exception, like the JDK } @@ -217,45 +217,30 @@ public final class AnnotationInvocationHandler * (can) use different representations of annotations that reuse this * method. */ - public static int hashCode(Class type, Map memberValues) + public int hashCode() { int h = 0; Iterator iter = memberValues.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); - Object val = memberValues.get(key); - h += deepHashCode(val) ^ 127 * key.hashCode(); + try + { + Object val + = invoke(null, + type.getDeclaredMethod((String)key, (Class[])null), + (Object[])null); + h += deepHashCode(val) ^ 127 * key.hashCode(); + } + catch (Throwable _) + { + } } return h; } private static String deepToString(Object obj) { - if (obj instanceof boolean[]) - return Arrays.toString((boolean[]) obj); - - if (obj instanceof byte[]) - return Arrays.toString((byte[]) obj); - - if (obj instanceof char[]) - return Arrays.toString((char[]) obj); - - if (obj instanceof short[]) - return Arrays.toString((short[]) obj); - - if (obj instanceof int[]) - return Arrays.toString((int[]) obj); - - if (obj instanceof float[]) - return Arrays.toString((float[]) obj); - - if (obj instanceof long[]) - return Arrays.toString((long[]) obj); - - if (obj instanceof double[]) - return Arrays.toString((double[]) obj); - if (obj instanceof Object[]) return Arrays.toString((Object[]) obj); @@ -267,7 +252,7 @@ public final class AnnotationInvocationHandler * (can) use different representations of annotations that reuse this * method. */ - public static String toString(Class type, Map memberValues) + public String toString() { StringBuffer sb = new StringBuffer(); sb.append('@').append(type.getName()).append('('); @@ -284,6 +269,7 @@ public final class AnnotationInvocationHandler return sb.toString(); } + private static Class getBoxedReturnType(Method method) { Class returnType = method.getReturnType(); @@ -315,51 +301,106 @@ public final class AnnotationInvocationHandler return returnType; } - private Object arrayClone(Object obj) + // This is slightly awkward. When the value of an annotation is an + // array, libgcj constructs an Object[], but the value() method + // returns an arrays of the appropriate primitive type. We should + // perhaps save the resulting array rather than the Object[]. + + private Object coerce(Object val, Class dstType) + throws ArrayStoreException { - if (obj instanceof boolean[]) - return ((boolean[]) obj).clone(); + if (! val.getClass().isArray()) + return val; - if (obj instanceof byte[]) - return ((byte[]) obj).clone(); + Object[] srcArray = (Object[])val; + final int len = srcArray.length; - if (obj instanceof char[]) - return ((char[]) obj).clone(); + if (dstType.getComponentType().isPrimitive()) + { + if (dstType == boolean[].class) + { + boolean[] dst = new boolean[len]; + for (int i = 0; i < len; i++) + dst[i] = (Boolean)srcArray[i]; + return dst; + } - if (obj instanceof short[]) - return ((short[]) obj).clone(); + if (dstType == byte[].class) + { + byte[] dst = new byte[len]; + for (int i = 0; i < len; i++) + dst[i] = (Byte)srcArray[i]; + return dst; + } - if (obj instanceof int[]) - return ((int[]) obj).clone(); + if (dstType == char[].class) + { + char[] dst = new char[len]; + for (int i = 0; i < len; i++) + dst[i] = (Character)srcArray[i]; + return dst; + } - if (obj instanceof float[]) - return ((float[]) obj).clone(); + if (dstType == short[].class) + { + short[] dst = new short[len]; + for (int i = 0; i < len; i++) + dst[i] = (Short)srcArray[i]; + return dst; + } - if (obj instanceof long[]) - return ((long[]) obj).clone(); + if (dstType == int[].class) + { + int[] dst = new int[len]; + for (int i = 0; i < len; i++) + dst[i] = (Integer)srcArray[i]; + return dst; + } - if (obj instanceof double[]) - return ((double[]) obj).clone(); + if (dstType == long[].class) + { + long[] dst = new long[len]; + for (int i = 0; i < len; i++) + dst[i] = (Long)srcArray[i]; + return dst; + } - if (obj instanceof Object[]) - return ((Object[]) obj).clone(); + if (dstType == float[].class) + { + float[] dst = new float[len]; + for (int i = 0; i < len; i++) + dst[i] = (Float)srcArray[i]; + return dst; + } - return obj; + if (dstType == double[].class) + { + double[] dst = new double[len]; + for (int i = 0; i < len; i++) + dst[i] = (Double)srcArray[i]; + return dst; + } + } + + Object dst = Array.newInstance(dstType.getComponentType(), len); + System.arraycopy((Object)srcArray, 0, dst, 0, len); + return dst; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName().intern(); + if (args == null || args.length == 0) { if (methodName == "toString") { - return toString(type, memberValues); + return toString(); } else if (methodName == "hashCode") { - return Integer.valueOf(hashCode(type, memberValues)); + return Integer.valueOf(hashCode()); } else if (methodName == "annotationType") { @@ -372,15 +413,19 @@ public final class AnnotationInvocationHandler { throw new IncompleteAnnotationException(type, methodName); } + try + { + if (val.getClass().isArray()) + val = coerce((Object[])val, method.getReturnType()); + } + catch (ArrayStoreException _) + { + throw new AnnotationTypeMismatchException + (method, val.getClass().getName()); + } if (! getBoxedReturnType(method).isInstance(val)) - { - throw new AnnotationTypeMismatchException(method, - val.getClass().getName()); - } - if (val.getClass().isArray()) - { - val = arrayClone(val); - } + throw (new AnnotationTypeMismatchException + (method, val.getClass().getName())); return val; } } @@ -388,7 +433,7 @@ public final class AnnotationInvocationHandler { if (methodName == "equals") { - return Boolean.valueOf(equals(type, memberValues, args[0])); + return Boolean.valueOf(equals(proxy, args[0])); } } throw new InternalError("Invalid annotation proxy");