--- old/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java 2016-08-02 09:38:47.278087321 -0700 +++ new/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java 2016-08-02 09:38:47.158087317 -0700 @@ -30,7 +30,7 @@ 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; @@ -163,47 +163,167 @@ */ 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 stringStream; + if (type == byte[].class) + 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); - 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); + 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 convert(byte[] values) { + List list = new ArrayList<>(values.length); + for (byte b : values) + list.add(Byte.toString(b)); + return list.stream(); + } + + private static Stream convert(char[] values) { + List list = new ArrayList<>(values.length); + for (char c : values) + list.add(toSourceString(c)); + return list.stream(); + } + + private static Stream convert(float[] values) { + List list = new ArrayList<>(values.length); + for (float f : values) { + list.add(toSourceString(f)); + } + return list.stream(); + } + + private static Stream convert(short[] values) { + List list = new ArrayList<>(values.length); + for (short s : values) + list.add(Short.toString(s)); + return list.stream(); + } + + private static Stream convert(boolean[] values) { + List 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 stream) { + return stream.collect(Collectors.joining(", ", "{", "}")); } /**