I put this into gcj, but I am not going to check it in to Classpath yet.

This fixes a bug (IMO) in AnnotationInvocationHandler -- array return
values should be cloned.  It also adds a new 'create' helper method
that handles default values.  (This code has to exist somewhere and it
was convenient to put it here...)

I'm not checking this in because create relies on
Method.getDefaultValue, which does not exist in Classpath yet.

Tom

Index: ChangeLog
from  Tom Tromey  <[EMAIL PROTECTED]>

        * sun/reflect/annotation/AnnotationInvocationHandler.java
        (invoke): Clone array values before return.
        (create): New method.
        (arrayClone): Likewise.

Index: sun/reflect/annotation/AnnotationInvocationHandler.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/sun/reflect/annotation/AnnotationInvocationHandler.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 AnnotationInvocationHandler.java
--- sun/reflect/annotation/AnnotationInvocationHandler.java 12 Jun 2006 
09:50:10 -0000 1.1.2.1
+++ sun/reflect/annotation/AnnotationInvocationHandler.java 29 Nov 2006 
22:42:51 -0000
@@ -39,11 +39,13 @@
 package sun.reflect.annotation;
 
 import java.io.Serializable;
+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.util.Arrays;
 import java.util.Iterator;
 import java.util.Map;
@@ -74,6 +76,24 @@
         this.memberValues = memberValues;
     }
 
+    public static Annotation create(Class type, Map memberValues)
+    {
+      for (Method m : type.getDeclaredMethods())
+       {
+         String name = m.getName();
+         if (! memberValues.containsKey(name))
+           {
+             // FIXME: what to do about exceptions here?
+             memberValues.put(name, m.getDefaultValue());
+           }
+       }
+      AnnotationInvocationHandler handler
+       = new AnnotationInvocationHandler(type, memberValues);
+      return (Annotation) Proxy.newProxyInstance(type.getClassLoader(),
+                                                new Class[] { type },
+                                                handler);
+    }
+
     /**
      * Compare an instance of AnnotationInvocationHandler with another object.
      * Note that the other object does not have to be an
@@ -295,6 +315,38 @@
         return returnType;
     }
 
+    private Object arrayClone(Object obj)
+    {
+        if (obj instanceof boolean[])
+           return ((boolean[]) obj).clone();
+
+        if (obj instanceof byte[])
+           return ((byte[]) obj).clone();
+
+        if (obj instanceof char[])
+           return ((char[]) obj).clone();
+
+        if (obj instanceof short[])
+           return ((short[]) obj).clone();
+
+        if (obj instanceof int[])
+           return ((int[]) obj).clone();
+
+        if (obj instanceof float[])
+           return ((float[]) obj).clone();
+
+        if (obj instanceof long[])
+           return ((long[]) obj).clone();
+
+        if (obj instanceof double[])
+           return ((double[]) obj).clone();
+
+        if (obj instanceof Object[])
+           return ((Object[]) obj).clone();
+
+        return obj;
+    }
+
     public Object invoke(Object proxy, Method method, Object[] args)
       throws Throwable
     {
@@ -325,6 +377,10 @@
                     throw new AnnotationTypeMismatchException(method,
                         val.getClass().getName());
                 }
+               if (val.getClass().isArray())
+               {
+                   val = arrayClone(val);
+               }
                 return val;
             }
         }

Reply via email to