< prev index next >

src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java

Print this page

        

@@ -28,11 +28,11 @@
 import java.io.ObjectInputStream;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.io.Serializable;
 import java.util.*;
-import java.util.stream.Collectors;
+import java.util.stream.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
 /**
  * InvocationHandler for dynamic proxy implementation of Annotation.

@@ -161,51 +161,171 @@
     /**
      * Translates a member value (in "dynamic proxy return form") into a string.
      */
     private static String memberValueToString(Object value) {
         Class<?> type = value.getClass();
-        if (!type.isArray()) {   // primitive, string, class, enum const,
-                                 // or annotation
+        if (!type.isArray()) {
+            // primitive value, string, class, enum const, or annotation
             if (type == Class.class)
-                return classValueToString((Class<?>) value);
+                return toSourceString((Class<?>) value);
+            else if (type == String.class)
+                return  toSourceString((String) value);
+            if (type == Character.class)
+                return toSourceString((char) value);
+            else if (type == Double.class)
+                return  toSourceString((double) value);
+            else if (type == Float.class)
+                return  toSourceString((float) value);
+            else if (type == Long.class)
+                return  toSourceString((long) value);
             else
                 return value.toString();
-        }
-
+        } else {
+            Stream<String> stringStream;
         if (type == byte[].class)
-            return Arrays.toString((byte[]) value);
-        if (type == char[].class)
-            return Arrays.toString((char[]) value);
-        if (type == double[].class)
-            return Arrays.toString((double[]) value);
-        if (type == float[].class)
-            return Arrays.toString((float[]) value);
-        if (type == int[].class)
-            return Arrays.toString((int[]) value);
-        if (type == long[].class)
-            return Arrays.toString((long[]) value);
-        if (type == short[].class)
-            return Arrays.toString((short[]) value);
-        if (type == boolean[].class)
-            return Arrays.toString((boolean[]) value);
-        if (type == Class[].class)
-            return classArrayValueToString((Class<?>[])value);
-        return Arrays.toString((Object[]) value);
+                stringStream = convert((byte[]) value);
+            else if (type == char[].class)
+                stringStream = convert((char[]) value);
+            else if (type == double[].class)
+                stringStream = DoubleStream.of((double[]) value)
+                    .mapToObj(AnnotationInvocationHandler::toSourceString);
+            else if (type == float[].class)
+                stringStream = convert((float[]) value);
+            else if (type == int[].class)
+                stringStream = IntStream.of((int[]) value).mapToObj(String::valueOf);
+            else if (type == long[].class) {
+                stringStream = LongStream.of((long[]) value)
+                    .mapToObj(AnnotationInvocationHandler::toSourceString);
+            } else if (type == short[].class)
+                stringStream = convert((short[]) value);
+            else if (type == boolean[].class)
+                stringStream = convert((boolean[]) value);
+            else if (type == Class[].class)
+                stringStream =
+                    Arrays.stream((Class<?>[]) value).
+                    map(AnnotationInvocationHandler::toSourceString);
+            else if (type == String[].class)
+                stringStream =
+                    Arrays.stream((String[])value).
+                    map(AnnotationInvocationHandler::toSourceString);
+            else
+                stringStream = Arrays.stream((Object[])value).map(Objects::toString);
+
+            return stringStreamToString(stringStream);
+        }
     }
 
     /**
      * Translates a Class value to a form suitable for use in the
      * string representation of an annotation.
      */
-    private static String classValueToString(Class<?> clazz) {
-        return clazz.getName() + ".class" ;
+    private static String toSourceString(Class<?> clazz) {
+        Class<?> finalComponent = clazz;
+        StringBuilder arrayBackets = new StringBuilder();
+
+        while(finalComponent.isArray()) {
+            finalComponent = finalComponent.getComponentType();
+            arrayBackets.append("[]");
+        }
+
+        return finalComponent.getName() + arrayBackets.toString() + ".class" ;
+    }
+
+    private static String toSourceString(float f) {
+        if (Float.isFinite(f))
+            return Float.toString(f) + "f" ;
+        else {
+            if (Float.isInfinite(f)) {
+                return (f < 0.0f) ? "-1.0f/0.0f": "1.0f/0.0f";
+            } else
+                return "0.0f/0.0f";
+        }
+    }
+
+    private static String toSourceString(double d) {
+        if (Double.isFinite(d))
+            return Double.toString(d);
+        else {
+            if (Double.isInfinite(d)) {
+                return (d < 0.0f) ? "-1.0/0.0": "1.0/0.0";
+            } else
+                return "0.0/0.0";
+        }
+    }
+
+    private static String toSourceString(char c) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("'");
+        if (c == '\'')
+            sb.append("\\'");
+        else
+            sb.append(c);
+        sb.append("'");
+        return sb.toString();
+    }
+
+    private static String toSourceString(long ell) {
+        return (Math.abs(ell) <= Integer.MAX_VALUE) ?
+            String.valueOf(ell) :
+            (String.valueOf(ell) + "L");
+    }
+
+    /**
+     * Return a string suitable for use in the string representation
+     * of an annotation.
+     */
+    private static String toSourceString(String s) {
+        StringBuilder sb = new StringBuilder();
+        sb.append('"');
+        // Escape embedded quote characters, if present, but don't do
+        // anything more heroic.
+        if (s.indexOf('"') != -1) {
+            s = s.replace("\"", "\\\"");
+        }
+        sb.append(s);
+        sb.append('"');
+        return sb.toString();
+    }
+
+    private static Stream<String> convert(byte[] values) {
+        List<String> list = new ArrayList<>(values.length);
+        for (byte b : values)
+            list.add(Byte.toString(b));
+        return list.stream();
+    }
+
+    private static Stream<String> convert(char[] values) {
+        List<String> list = new ArrayList<>(values.length);
+        for (char c : values)
+            list.add(toSourceString(c));
+        return list.stream();
+    }
+
+    private static Stream<String> convert(float[] values) {
+        List<String> list = new ArrayList<>(values.length);
+        for (float f : values) {
+            list.add(toSourceString(f));
+        }
+        return list.stream();
+    }
+
+    private static Stream<String> convert(short[] values) {
+        List<String> list = new ArrayList<>(values.length);
+        for (short s : values)
+            list.add(Short.toString(s));
+        return list.stream();
+    }
+
+    private static Stream<String> convert(boolean[] values) {
+        List<String> list = new ArrayList<>(values.length);
+        for (boolean b : values)
+            list.add(Boolean.toString(b));
+        return list.stream();
     }
 
-    private static String classArrayValueToString(Class<?>[] classes) {
-        return Arrays.stream(classes)
-            .map(AnnotationInvocationHandler::classValueToString)
-            .collect(Collectors.joining(", ", "{", "}"));
+    private static String stringStreamToString(Stream<String> stream) {
+        return stream.collect(Collectors.joining(", ", "{", "}"));
     }
 
     /**
      * Implementation of dynamicProxy.equals(Object o)
      */
< prev index next >