< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 128         }
 129         if (type == boolean[].class) {
 130             boolean[] booleanArray = (boolean[])array;
 131             return booleanArray.clone();
 132         }
 133 
 134         Object[] objectArray = (Object[])array;
 135         return objectArray.clone();
 136     }
 137 
 138 
 139     /**
 140      * Implementation of dynamicProxy.toString()
 141      */
 142     private String toStringImpl() {
 143         StringBuilder result = new StringBuilder(128);
 144         result.append('@');
 145         result.append(type.getName());
 146         result.append('(');
 147         boolean firstMember = true;
 148         for (Map.Entry<String, Object> e : memberValues.entrySet()) {


 149             if (firstMember)
 150                 firstMember = false;
 151             else
 152                 result.append(", ");
 153 
 154             result.append(e.getKey());


 155             result.append('=');


 156             result.append(memberValueToString(e.getValue()));
 157         }
 158         result.append(')');
 159         return result.toString();
 160     }
 161 
 162     /**
 163      * Translates a member value (in "dynamic proxy return form") into a string.
 164      */
 165     private static String memberValueToString(Object value) {
 166         Class<?> type = value.getClass();
 167         if (!type.isArray()) {
 168             // primitive value, string, class, enum const, or annotation
 169             if (type == Class.class)
 170                 return toSourceString((Class<?>) value);
 171             else if (type == String.class)
 172                 return  toSourceString((String) value);
 173             if (type == Character.class)
 174                 return toSourceString((char) value);
 175             else if (type == Double.class)
 176                 return  toSourceString((double) value);
 177             else if (type == Float.class)
 178                 return  toSourceString((float) value);
 179             else if (type == Long.class)
 180                 return  toSourceString((long) value);


 181             else
 182                 return value.toString();
 183         } else {
 184             Stream<String> stringStream;
 185             if (type == byte[].class)
 186                 stringStream = convert((byte[]) value);
 187             else if (type == char[].class)
 188                 stringStream = convert((char[]) value);
 189             else if (type == double[].class)
 190                 stringStream = DoubleStream.of((double[]) value)
 191                     .mapToObj(AnnotationInvocationHandler::toSourceString);
 192             else if (type == float[].class)
 193                 stringStream = convert((float[]) value);
 194             else if (type == int[].class)
 195                 stringStream = IntStream.of((int[]) value).mapToObj(String::valueOf);
 196             else if (type == long[].class) {
 197                 stringStream = LongStream.of((long[]) value)
 198                     .mapToObj(AnnotationInvocationHandler::toSourceString);
 199             } else if (type == short[].class)
 200                 stringStream = convert((short[]) value);


 211             else
 212                 stringStream = Arrays.stream((Object[])value).map(Objects::toString);
 213 
 214             return stringStreamToString(stringStream);
 215         }
 216     }
 217 
 218     /**
 219      * Translates a Class value to a form suitable for use in the
 220      * string representation of an annotation.
 221      */
 222     private static String toSourceString(Class<?> clazz) {
 223         Class<?> finalComponent = clazz;
 224         StringBuilder arrayBackets = new StringBuilder();
 225 
 226         while(finalComponent.isArray()) {
 227             finalComponent = finalComponent.getComponentType();
 228             arrayBackets.append("[]");
 229         }
 230 
 231         return finalComponent.getName() + arrayBackets.toString() + ".class" ;
 232     }
 233 
 234     private static String toSourceString(float f) {
 235         if (Float.isFinite(f))
 236             return Float.toString(f) + "f" ;
 237         else {
 238             if (Float.isInfinite(f)) {
 239                 return (f < 0.0f) ? "-1.0f/0.0f": "1.0f/0.0f";
 240             } else
 241                 return "0.0f/0.0f";
 242         }
 243     }
 244 
 245     private static String toSourceString(double d) {
 246         if (Double.isFinite(d))
 247             return Double.toString(d);
 248         else {
 249             if (Double.isInfinite(d)) {
 250                 return (d < 0.0f) ? "-1.0/0.0": "1.0/0.0";
 251             } else
 252                 return "0.0/0.0";
 253         }
 254     }
 255 
 256     private static String toSourceString(char c) {
 257         StringBuilder sb = new StringBuilder(4);
 258         sb.append('\'');
 259         if (c == '\'')
 260             sb.append("\\'");
 261         else
 262             sb.append(c);
 263         return sb.append('\'')
 264                 .toString();




























 265     }
 266 
 267     private static String toSourceString(long ell) {
 268         String str = String.valueOf(ell);
 269         return (ell < Integer.MIN_VALUE || ell > Integer.MAX_VALUE)
 270                 ? (str + 'L') : str;
 271     }
 272 
 273     /**
 274      * Return a string suitable for use in the string representation
 275      * of an annotation.
 276      */
 277     private static String toSourceString(String s) {
 278         StringBuilder sb = new StringBuilder();
 279         sb.append('"');
 280         // Escape embedded quote characters, if present, but don't do
 281         // anything more heroic.
 282         sb.append(s.replace("\"", "\\\""));
 283         sb.append('"');
 284         return sb.toString();
 285     }
 286 
 287     private static Stream<String> convert(byte[] values) {
 288         List<String> list = new ArrayList<>(values.length);
 289         for (byte b : values)
 290             list.add(Byte.toString(b));
 291         return list.stream();
 292     }
 293 
 294     private static Stream<String> convert(char[] values) {
 295         List<String> list = new ArrayList<>(values.length);
 296         for (char c : values)
 297             list.add(toSourceString(c));
 298         return list.stream();
 299     }
 300 
 301     private static Stream<String> convert(float[] values) {
 302         List<String> list = new ArrayList<>(values.length);
 303         for (float f : values) {
 304             list.add(toSourceString(f));
 305         }
 306         return list.stream();
 307     }
 308 
 309     private static Stream<String> convert(short[] values) {
 310         List<String> list = new ArrayList<>(values.length);


   1 /*
   2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 128         }
 129         if (type == boolean[].class) {
 130             boolean[] booleanArray = (boolean[])array;
 131             return booleanArray.clone();
 132         }
 133 
 134         Object[] objectArray = (Object[])array;
 135         return objectArray.clone();
 136     }
 137 
 138 
 139     /**
 140      * Implementation of dynamicProxy.toString()
 141      */
 142     private String toStringImpl() {
 143         StringBuilder result = new StringBuilder(128);
 144         result.append('@');
 145         result.append(type.getName());
 146         result.append('(');
 147         boolean firstMember = true;
 148         Set<Map.Entry<String, Object>> entries = memberValues.entrySet();
 149         boolean loneValue = entries.size() == 1;
 150         for (Map.Entry<String, Object> e : entries) {
 151             if (firstMember)
 152                 firstMember = false;
 153             else
 154                 result.append(", ");
 155 
 156             String key = e.getKey();
 157             if (!loneValue || !"value".equals(key)) {
 158                 result.append(key);
 159                 result.append('=');
 160             }
 161             loneValue = false;
 162             result.append(memberValueToString(e.getValue()));
 163         }
 164         result.append(')');
 165         return result.toString();
 166     }
 167 
 168     /**
 169      * Translates a member value (in "dynamic proxy return form") into a string.
 170      */
 171     private static String memberValueToString(Object value) {
 172         Class<?> type = value.getClass();
 173         if (!type.isArray()) {
 174             // primitive value, string, class, enum const, or annotation
 175             if (type == Class.class)
 176                 return toSourceString((Class<?>) value);
 177             else if (type == String.class)
 178                 return  toSourceString((String) value);
 179             if (type == Character.class)
 180                 return toSourceString((char) value);
 181             else if (type == Double.class)
 182                 return  toSourceString((double) value);
 183             else if (type == Float.class)
 184                 return  toSourceString((float) value);
 185             else if (type == Long.class)
 186                 return  toSourceString((long) value);
 187             else if (type == Byte.class)
 188                 return  toSourceString((byte) value);
 189             else
 190                 return value.toString();
 191         } else {
 192             Stream<String> stringStream;
 193             if (type == byte[].class)
 194                 stringStream = convert((byte[]) value);
 195             else if (type == char[].class)
 196                 stringStream = convert((char[]) value);
 197             else if (type == double[].class)
 198                 stringStream = DoubleStream.of((double[]) value)
 199                     .mapToObj(AnnotationInvocationHandler::toSourceString);
 200             else if (type == float[].class)
 201                 stringStream = convert((float[]) value);
 202             else if (type == int[].class)
 203                 stringStream = IntStream.of((int[]) value).mapToObj(String::valueOf);
 204             else if (type == long[].class) {
 205                 stringStream = LongStream.of((long[]) value)
 206                     .mapToObj(AnnotationInvocationHandler::toSourceString);
 207             } else if (type == short[].class)
 208                 stringStream = convert((short[]) value);


 219             else
 220                 stringStream = Arrays.stream((Object[])value).map(Objects::toString);
 221 
 222             return stringStreamToString(stringStream);
 223         }
 224     }
 225 
 226     /**
 227      * Translates a Class value to a form suitable for use in the
 228      * string representation of an annotation.
 229      */
 230     private static String toSourceString(Class<?> clazz) {
 231         Class<?> finalComponent = clazz;
 232         StringBuilder arrayBackets = new StringBuilder();
 233 
 234         while(finalComponent.isArray()) {
 235             finalComponent = finalComponent.getComponentType();
 236             arrayBackets.append("[]");
 237         }
 238 
 239         return finalComponent.getName() + arrayBackets.toString() + ".class";
 240     }
 241 
 242     private static String toSourceString(float f) {
 243         if (Float.isFinite(f))
 244             return Float.toString(f) + "f" ;
 245         else {
 246             if (Float.isInfinite(f)) {
 247                 return (f < 0.0f) ? "-1.0f/0.0f": "1.0f/0.0f";
 248             } else
 249                 return "0.0f/0.0f";
 250         }
 251     }
 252 
 253     private static String toSourceString(double d) {
 254         if (Double.isFinite(d))
 255             return Double.toString(d);
 256         else {
 257             if (Double.isInfinite(d)) {
 258                 return (d < 0.0f) ? "-1.0/0.0": "1.0/0.0";
 259             } else
 260                 return "0.0/0.0";
 261         }
 262     }
 263 
 264     private static String toSourceString(char c) {
 265         StringBuilder sb = new StringBuilder(4);
 266         sb.append('\'');
 267         sb.append(quote(c));
 268         return sb.append('\'') .toString();
 269     }
 270 
 271     /**
 272      * Escapes a character if it has an escape sequence or is
 273      * non-printable ASCII.  Leaves non-ASCII characters alone.
 274      */
 275     private static String quote(char ch) {
 276         switch (ch) {
 277         case '\b':  return "\\b";
 278         case '\f':  return "\\f";
 279         case '\n':  return "\\n";
 280         case '\r':  return "\\r";
 281         case '\t':  return "\\t";
 282         case '\'':  return "\\'";
 283         case '\"':  return "\\\"";
 284         case '\\':  return "\\\\";
 285         default:
 286             return (isPrintableAscii(ch))
 287                 ? String.valueOf(ch)
 288                 : String.format("\\u%04x", (int) ch);
 289         }
 290     }
 291 
 292     /**
 293      * Is a character printable ASCII?
 294      */
 295     private static boolean isPrintableAscii(char ch) {
 296         return ch >= ' ' && ch <= '~';
 297     }
 298 
 299     private static String toSourceString(byte b) {
 300         return String.format("(byte)0x%02x", b);
 301     }
 302 
 303     private static String toSourceString(long ell) {
 304         return String.valueOf(ell) + "L";


 305     }
 306 
 307     /**
 308      * Return a string suitable for use in the string representation
 309      * of an annotation.
 310      */
 311     private static String toSourceString(String s) {
 312         StringBuilder sb = new StringBuilder();
 313         sb.append('"');
 314         for (int i = 0; i < s.length(); i++) {
 315             sb.append(quote(s.charAt(i)));
 316         }
 317         sb.append('"');
 318         return sb.toString();
 319     }
 320 
 321     private static Stream<String> convert(byte[] values) {
 322         List<String> list = new ArrayList<>(values.length);
 323         for (byte b : values)
 324             list.add(toSourceString(b));
 325         return list.stream();
 326     }
 327 
 328     private static Stream<String> convert(char[] values) {
 329         List<String> list = new ArrayList<>(values.length);
 330         for (char c : values)
 331             list.add(toSourceString(c));
 332         return list.stream();
 333     }
 334 
 335     private static Stream<String> convert(float[] values) {
 336         List<String> list = new ArrayList<>(values.length);
 337         for (float f : values) {
 338             list.add(toSourceString(f));
 339         }
 340         return list.stream();
 341     }
 342 
 343     private static Stream<String> convert(short[] values) {
 344         List<String> list = new ArrayList<>(values.length);


< prev index next >