src/share/classes/sun/reflect/annotation/AnnotationParser.java

Print this page

        

*** 67,77 **** Class<?> container) { if (rawAnnotations == null) return Collections.emptyMap(); try { ! return parseAnnotations2(rawAnnotations, constPool, container); } catch(BufferUnderflowException e) { throw new AnnotationFormatError("Unexpected end of annotations."); } catch(IllegalArgumentException e) { // Type mismatch in constant pool throw new AnnotationFormatError(e); --- 67,105 ---- Class<?> container) { if (rawAnnotations == null) return Collections.emptyMap(); try { ! return parseAnnotations2(rawAnnotations, constPool, container, null); ! } catch(BufferUnderflowException e) { ! throw new AnnotationFormatError("Unexpected end of annotations."); ! } catch(IllegalArgumentException e) { ! // Type mismatch in constant pool ! throw new AnnotationFormatError(e); ! } ! } ! ! /** ! * Like {@link #parseAnnotations(byte[], sun.reflect.ConstantPool, Class)} ! * with an additional parameter {@code selectAnnotationClasses} which selects the ! * annotation types to parse (other than selected are quickly skipped).<p> ! * This method is only used to parse select meta annotations in the construction ! * phase of {@link AnnotationType} instances to prevent infinite recursion. ! * ! * @param selectAnnotationClasses an array of annotation types to select when parsing ! */ ! @SafeVarargs ! static Map<Class<? extends Annotation>, Annotation> parseSelectAnnotations( ! byte[] rawAnnotations, ! ConstantPool constPool, ! Class<?> container, ! Class<? extends Annotation> ... selectAnnotationClasses) { ! if (rawAnnotations == null) ! return Collections.emptyMap(); ! ! try { ! return parseAnnotations2(rawAnnotations, constPool, container, selectAnnotationClasses); } catch(BufferUnderflowException e) { throw new AnnotationFormatError("Unexpected end of annotations."); } catch(IllegalArgumentException e) { // Type mismatch in constant pool throw new AnnotationFormatError(e);
*** 79,104 **** } private static Map<Class<? extends Annotation>, Annotation> parseAnnotations2( byte[] rawAnnotations, ConstantPool constPool, ! Class<?> container) { Map<Class<? extends Annotation>, Annotation> result = new LinkedHashMap<Class<? extends Annotation>, Annotation>(); ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); int numAnnotations = buf.getShort() & 0xFFFF; for (int i = 0; i < numAnnotations; i++) { ! Annotation a = parseAnnotation(buf, constPool, container, false); if (a != null) { Class<? extends Annotation> klass = a.annotationType(); ! AnnotationType type = AnnotationType.getInstance(klass); ! if (type.retention() == RetentionPolicy.RUNTIME) ! if (result.put(klass, a) != null) throw new AnnotationFormatError( "Duplicate annotation for class: "+klass+": " + a); } } return result; } /** * Parses the parameter annotations described by the specified byte array. --- 107,133 ---- } private static Map<Class<? extends Annotation>, Annotation> parseAnnotations2( byte[] rawAnnotations, ConstantPool constPool, ! Class<?> container, ! Class<? extends Annotation>[] selectAnnotationClasses) { Map<Class<? extends Annotation>, Annotation> result = new LinkedHashMap<Class<? extends Annotation>, Annotation>(); ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); int numAnnotations = buf.getShort() & 0xFFFF; for (int i = 0; i < numAnnotations; i++) { ! Annotation a = parseAnnotation2(buf, constPool, container, false, selectAnnotationClasses); if (a != null) { Class<? extends Annotation> klass = a.annotationType(); ! if (AnnotationType.getInstance(klass).retention() == RetentionPolicy.RUNTIME && ! result.put(klass, a) != null) { throw new AnnotationFormatError( "Duplicate annotation for class: "+klass+": " + a); } } + } return result; } /** * Parses the parameter annotations described by the specified byte array.
*** 187,201 **** * * @param exceptionOnMissingAnnotationClass if true, throw * TypeNotPresentException if a referenced annotation type is not * available at runtime */ - @SuppressWarnings("unchecked") static Annotation parseAnnotation(ByteBuffer buf, ConstantPool constPool, Class<?> container, boolean exceptionOnMissingAnnotationClass) { int typeIndex = buf.getShort() & 0xFFFF; Class<? extends Annotation> annotationClass = null; String sig = "[unknown]"; try { try { --- 216,238 ---- * * @param exceptionOnMissingAnnotationClass if true, throw * TypeNotPresentException if a referenced annotation type is not * available at runtime */ static Annotation parseAnnotation(ByteBuffer buf, ConstantPool constPool, Class<?> container, boolean exceptionOnMissingAnnotationClass) { + return parseAnnotation2(buf, constPool, container, exceptionOnMissingAnnotationClass, null); + } + + @SuppressWarnings("unchecked") + private static Annotation parseAnnotation2(ByteBuffer buf, + ConstantPool constPool, + Class<?> container, + boolean exceptionOnMissingAnnotationClass, + Class<? extends Annotation>[] selectAnnotationClasses) { int typeIndex = buf.getShort() & 0xFFFF; Class<? extends Annotation> annotationClass = null; String sig = "[unknown]"; try { try {
*** 217,226 **** --- 254,267 ---- if (exceptionOnMissingAnnotationClass) throw e; skipAnnotation(buf, false); return null; } + if (selectAnnotationClasses != null && !contains(selectAnnotationClasses, annotationClass)) { + skipAnnotation(buf, false); + return null; + } AnnotationType type = null; try { type = AnnotationType.getInstance(annotationClass); } catch (IllegalArgumentException e) { skipAnnotation(buf, false);
*** 798,807 **** --- 839,859 ---- int length = buf.getShort() & 0xFFFF; for (int i = 0; i < length; i++) skipMemberValue(buf); } + /** + * Searches for given {@code element} in given {@code array} by identity. + * Returns {@code true} if found {@code false} if not. + */ + private static boolean contains(Object[] array, Object element) { + for (Object e : array) + if (e == element) + return true; + return false; + } + /* * This method converts the annotation map returned by the parseAnnotations() * method to an array. It is called by Field.getDeclaredAnnotations(), * Method.getDeclaredAnnotations(), and Constructor.getDeclaredAnnotations(). * This avoids the reflection classes to load the Annotation class until