< prev index next >

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

Print this page




  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
  23  * questions.
  24  */
  25 
  26 package sun.reflect.annotation;
  27 
  28 import java.io.ObjectInputStream;
  29 import java.lang.annotation.*;
  30 import java.lang.reflect.*;
  31 import java.io.Serializable;
  32 import java.util.*;
  33 import java.util.stream.Collectors;
  34 import java.security.AccessController;
  35 import java.security.PrivilegedAction;
  36 
  37 /**
  38  * InvocationHandler for dynamic proxy implementation of Annotation.
  39  *
  40  * @author  Josh Bloch
  41  * @since   1.5
  42  */
  43 class AnnotationInvocationHandler implements InvocationHandler, Serializable {
  44     private static final long serialVersionUID = 6182022883658399397L;
  45     private final Class<? extends Annotation> type;
  46     private final Map<String, Object> memberValues;
  47 
  48     AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) {
  49         Class<?>[] superInterfaces = type.getInterfaces();
  50         if (!type.isAnnotation() ||
  51             superInterfaces.length != 1 ||
  52             superInterfaces[0] != java.lang.annotation.Annotation.class)
  53             throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");


 146         boolean firstMember = true;
 147         for (Map.Entry<String, Object> e : memberValues.entrySet()) {
 148             if (firstMember)
 149                 firstMember = false;
 150             else
 151                 result.append(", ");
 152 
 153             result.append(e.getKey());
 154             result.append('=');
 155             result.append(memberValueToString(e.getValue()));
 156         }
 157         result.append(')');
 158         return result.toString();
 159     }
 160 
 161     /**
 162      * Translates a member value (in "dynamic proxy return form") into a string.
 163      */
 164     private static String memberValueToString(Object value) {
 165         Class<?> type = value.getClass();
 166         if (!type.isArray()) {   // primitive, string, class, enum const,
 167                                  // or annotation
 168             if (type == Class.class)
 169                 return classValueToString((Class<?>) value);










 170             else
 171                 return value.toString();
 172         }
 173 
 174         if (type == byte[].class)
 175             return Arrays.toString((byte[]) value);
 176         if (type == char[].class)
 177             return Arrays.toString((char[]) value);
 178         if (type == double[].class)
 179             return Arrays.toString((double[]) value);
 180         if (type == float[].class)
 181             return Arrays.toString((float[]) value);
 182         if (type == int[].class)
 183             return Arrays.toString((int[]) value);
 184         if (type == long[].class)
 185             return Arrays.toString((long[]) value);
 186         if (type == short[].class)
 187             return Arrays.toString((short[]) value);
 188         if (type == boolean[].class)
 189             return Arrays.toString((boolean[]) value);
 190         if (type == Class[].class)
 191             return classArrayValueToString((Class<?>[])value);
 192         return Arrays.toString((Object[]) value);












 193     }
 194 
 195     /**
 196      * Translates a Class value to a form suitable for use in the
 197      * string representation of an annotation.
 198      */
 199     private static String classValueToString(Class<?> clazz) {
 200         return clazz.getName() + ".class" ;




































































































 201     }
 202 
 203     private static String classArrayValueToString(Class<?>[] classes) {
 204         return Arrays.stream(classes)
 205             .map(AnnotationInvocationHandler::classValueToString)
 206             .collect(Collectors.joining(", ", "{", "}"));
 207     }
 208 
 209     /**
 210      * Implementation of dynamicProxy.equals(Object o)
 211      */
 212     private Boolean equalsImpl(Object proxy, Object o) {
 213         if (o == proxy)
 214             return true;
 215 
 216         if (!type.isInstance(o))
 217             return false;
 218         for (Method memberMethod : getMemberMethods()) {
 219             String member = memberMethod.getName();
 220             Object ourValue = memberValues.get(member);
 221             Object hisValue = null;
 222             AnnotationInvocationHandler hisHandler = asOneOfUs(o);
 223             if (hisHandler != null) {
 224                 hisValue = hisHandler.memberValues.get(member);
 225             } else {
 226                 try {




  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
  23  * questions.
  24  */
  25 
  26 package sun.reflect.annotation;
  27 
  28 import java.io.ObjectInputStream;
  29 import java.lang.annotation.*;
  30 import java.lang.reflect.*;
  31 import java.io.Serializable;
  32 import java.util.*;
  33 import java.util.stream.*;
  34 import java.security.AccessController;
  35 import java.security.PrivilegedAction;
  36 
  37 /**
  38  * InvocationHandler for dynamic proxy implementation of Annotation.
  39  *
  40  * @author  Josh Bloch
  41  * @since   1.5
  42  */
  43 class AnnotationInvocationHandler implements InvocationHandler, Serializable {
  44     private static final long serialVersionUID = 6182022883658399397L;
  45     private final Class<? extends Annotation> type;
  46     private final Map<String, Object> memberValues;
  47 
  48     AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) {
  49         Class<?>[] superInterfaces = type.getInterfaces();
  50         if (!type.isAnnotation() ||
  51             superInterfaces.length != 1 ||
  52             superInterfaces[0] != java.lang.annotation.Annotation.class)
  53             throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");


 146         boolean firstMember = true;
 147         for (Map.Entry<String, Object> e : memberValues.entrySet()) {
 148             if (firstMember)
 149                 firstMember = false;
 150             else
 151                 result.append(", ");
 152 
 153             result.append(e.getKey());
 154             result.append('=');
 155             result.append(memberValueToString(e.getValue()));
 156         }
 157         result.append(')');
 158         return result.toString();
 159     }
 160 
 161     /**
 162      * Translates a member value (in "dynamic proxy return form") into a string.
 163      */
 164     private static String memberValueToString(Object value) {
 165         Class<?> type = value.getClass();
 166         if (!type.isArray()) {
 167             // primitive value, string, class, enum const, or annotation
 168             if (type == Class.class)
 169                 return toSourceString((Class<?>) value);
 170             else if (type == String.class)
 171                 return  toSourceString((String) value);
 172             if (type == Character.class)
 173                 return toSourceString((char) value);
 174             else if (type == double.class)
 175                 return  toSourceString((double) value);
 176             else if (type == float.class)
 177                 return  toSourceString((float) value);
 178             else if (type == long.class)
 179                 return  toSourceString((long) value);
 180             else
 181                 return value.toString();
 182         } else {
 183             Stream<String> stringStream;
 184             if (type == byte[].class)
 185                 stringStream = convert((byte[]) value);
 186             else if (type == char[].class)
 187                 stringStream = convert((char[]) value);
 188             else if (type == double[].class)
 189                 stringStream = DoubleStream.of((double[]) value)
 190                     .mapToObj(AnnotationInvocationHandler::toSourceString);
 191             else if (type == float[].class)
 192                 stringStream = convert((float[]) value);
 193             else if (type == int[].class)
 194                 stringStream = IntStream.of((int[]) value).mapToObj(String::valueOf);
 195             else if (type == long[].class) {
 196                 stringStream = LongStream.of((long[]) value)
 197                     .mapToObj(AnnotationInvocationHandler::toSourceString);
 198             } else if (type == short[].class)
 199                 stringStream = convert((short[]) value);
 200             else if (type == boolean[].class)
 201                 stringStream = convert((boolean[]) value);
 202             else if (type == Class[].class)
 203                 stringStream =
 204                     Arrays.stream((Class<?>[]) value).
 205                     map(AnnotationInvocationHandler::toSourceString);
 206             else if (type == String[].class)
 207                 stringStream =
 208                     Arrays.stream((String[])value).
 209                     map(AnnotationInvocationHandler::toSourceString);
 210             else
 211                 stringStream = Arrays.stream((Object[])value).map(Objects::toString);
 212 
 213             return stringStreamToString(stringStream);
 214         }
 215     }
 216 
 217     /**
 218      * Translates a Class value to a form suitable for use in the
 219      * string representation of an annotation.
 220      */
 221     private static String toSourceString(Class<?> clazz) {
 222         Class<?> finalComponent = clazz;
 223         StringBuilder arrayBackets = new StringBuilder();
 224 
 225         while(finalComponent.isArray()) {
 226             finalComponent = finalComponent.getComponentType();
 227             arrayBackets.append("[]");
 228         }
 229 
 230         return finalComponent.getName() + arrayBackets.toString() + ".class" ;
 231     }
 232 
 233     private static String toSourceString(float f) {
 234         if (Float.isFinite(f))
 235             return Float.toString(f) + "f" ;
 236         else {
 237             if (Float.isInfinite(f)) {
 238                 return (f < 0.0f) ? "-1.0f/0.0f": "1.0f/0.0f";
 239             } else
 240                 return "0.0f/0.0f";
 241         }
 242     }
 243 
 244     private static String toSourceString(double d) {
 245         if (Double.isFinite(d))
 246             return Double.toString(d);
 247         else {
 248             if (Double.isInfinite(d)) {
 249                 return (d < 0.0f) ? "-1.0/0.0": "1.0/0.0";
 250             } else
 251                 return "0.0/0.0";
 252         }
 253     }
 254 
 255     private static String toSourceString(char c) {
 256         StringBuilder sb = new StringBuilder();
 257         sb.append("'");
 258         if (c == '\'')
 259             sb.append("\\'");
 260         else
 261             sb.append(c);
 262         sb.append("'");
 263         return sb.toString();
 264     }
 265 
 266     private static String toSourceString(long ell) {
 267         return (Math.abs(ell) <= Integer.MAX_VALUE) ?
 268             String.valueOf(ell) :
 269             (String.valueOf(ell) + "L");
 270     }
 271 
 272     /**
 273      * Return a string suitable for use in the string representation
 274      * of an annotation.
 275      */
 276     private static String toSourceString(String s) {
 277         StringBuilder sb = new StringBuilder();
 278         sb.append('"');
 279         // Escape embedded quote characters, if present, but don't do
 280         // anything more heroic.
 281         if (s.indexOf('"') != -1) {
 282             s = s.replace("\"", "\\\"");
 283         }
 284         sb.append(s);
 285         sb.append('"');
 286         return sb.toString();
 287     }
 288 
 289     private static Stream<String> convert(byte[] values) {
 290         List<String> list = new ArrayList<>(values.length);
 291         for (byte b : values)
 292             list.add(Byte.toString(b));
 293         return list.stream();
 294     }
 295 
 296     private static Stream<String> convert(char[] values) {
 297         List<String> list = new ArrayList<>(values.length);
 298         for (char c : values)
 299             list.add(toSourceString(c));
 300         return list.stream();
 301     }
 302 
 303     private static Stream<String> convert(float[] values) {
 304         List<String> list = new ArrayList<>(values.length);
 305         for (float f : values) {
 306             list.add(toSourceString(f));
 307         }
 308         return list.stream();
 309     }
 310 
 311     private static Stream<String> convert(short[] values) {
 312         List<String> list = new ArrayList<>(values.length);
 313         for (short s : values)
 314             list.add(Short.toString(s));
 315         return list.stream();
 316     }
 317 
 318     private static Stream<String> convert(boolean[] values) {
 319         List<String> list = new ArrayList<>(values.length);
 320         for (boolean b : values)
 321             list.add(Boolean.toString(b));
 322         return list.stream();
 323     }
 324 
 325     private static String stringStreamToString(Stream<String> stream) {
 326         return stream.collect(Collectors.joining(", ", "{", "}"));


 327     }
 328 
 329     /**
 330      * Implementation of dynamicProxy.equals(Object o)
 331      */
 332     private Boolean equalsImpl(Object proxy, Object o) {
 333         if (o == proxy)
 334             return true;
 335 
 336         if (!type.isInstance(o))
 337             return false;
 338         for (Method memberMethod : getMemberMethods()) {
 339             String member = memberMethod.getName();
 340             Object ourValue = memberValues.get(member);
 341             Object hisValue = null;
 342             AnnotationInvocationHandler hisHandler = asOneOfUs(o);
 343             if (hisHandler != null) {
 344                 hisValue = hisHandler.memberValues.get(member);
 345             } else {
 346                 try {


< prev index next >