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); ! } ! } ! ! /** ! * An overload of {@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 ! public static Map<Class<? extends Annotation>, Annotation> parseAnnotations( ! 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 = parseAnnotation(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.
*** 149,159 **** for (int i = 0; i < numParameters; i++) { int numAnnotations = buf.getShort() & 0xFFFF; List<Annotation> annotations = new ArrayList<Annotation>(numAnnotations); for (int j = 0; j < numAnnotations; j++) { ! Annotation a = parseAnnotation(buf, constPool, container, false); if (a != null) { AnnotationType type = AnnotationType.getInstance( a.annotationType()); if (type.retention() == RetentionPolicy.RUNTIME) annotations.add(a); --- 178,188 ---- for (int i = 0; i < numParameters; i++) { int numAnnotations = buf.getShort() & 0xFFFF; List<Annotation> annotations = new ArrayList<Annotation>(numAnnotations); for (int j = 0; j < numAnnotations; j++) { ! Annotation a = parseAnnotation(buf, constPool, container, false, null); if (a != null) { AnnotationType type = AnnotationType.getInstance( a.annotationType()); if (type.retention() == RetentionPolicy.RUNTIME) annotations.add(a);
*** 191,201 **** */ @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 { --- 220,231 ---- */ @SuppressWarnings("unchecked") static Annotation parseAnnotation(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 **** --- 247,260 ---- 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);
*** 305,315 **** return parseEnumValue((Class<? extends Enum<?>>)memberType, buf, constPool, container); case 'c': result = parseClassValue(buf, constPool, container); break; case '@': ! result = parseAnnotation(buf, constPool, container, true); break; case '[': return parseArray(memberType, buf, constPool, container); default: result = parseConst(tag, buf, constPool); --- 339,349 ---- return parseEnumValue((Class<? extends Enum<?>>)memberType, buf, constPool, container); case 'c': result = parseClassValue(buf, constPool, container); break; case '@': ! result = parseAnnotation(buf, constPool, container, true, null); break; case '[': return parseArray(memberType, buf, constPool, container); default: result = parseConst(tag, buf, constPool);
*** 718,728 **** int tag = 0; for (int i = 0; i < length; i++) { tag = buf.get(); if (tag == '@') { ! result[i] = parseAnnotation(buf, constPool, container, true); } else { skipMemberValue(tag, buf); typeMismatch = true; } } --- 752,762 ---- int tag = 0; for (int i = 0; i < length; i++) { tag = buf.get(); if (tag == '@') { ! result[i] = parseAnnotation(buf, constPool, container, true, null); } else { skipMemberValue(tag, buf); typeMismatch = true; } }
*** 798,807 **** --- 832,849 ---- int length = buf.getShort() & 0xFFFF; for (int i = 0; i < length; i++) skipMemberValue(buf); } + // utility + 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