|
Java example source code file (TypeAnnotationParser.java)
The TypeAnnotationParser.java Java example source code/* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.reflect.annotation; import java.lang.annotation.*; import java.lang.reflect.*; import java.nio.ByteBuffer; import java.nio.BufferUnderflowException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import sun.misc.JavaLangAccess; import sun.reflect.ConstantPool; import static sun.reflect.annotation.TypeAnnotation.*; /** * TypeAnnotationParser implements the logic needed to parse * TypeAnnotations from an array of bytes. */ public final class TypeAnnotationParser { private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0]; /** * Build an AnnotatedType from the parameters supplied. * * This method and {@code buildAnnotatedTypes} are probably * the entry points you are looking for. * * @param rawAnnotations the byte[] encoding of all type annotations on this declaration * @param cp the ConstantPool needed to parse the embedded Annotation * @param decl the declaration this type annotation is on * @param container the Class this type annotation is on (may be the same as decl) * @param type the type the AnnotatedType corresponds to * @param filter the type annotation targets included in this AnnotatedType */ public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations, ConstantPool cp, AnnotatedElement decl, Class<?> container, Type type, TypeAnnotationTarget filter) { TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations, cp, decl, container); List<TypeAnnotation> l = new ArrayList<>(tas.length); for (TypeAnnotation t : tas) { TypeAnnotationTargetInfo ti = t.getTargetInfo(); if (ti.getTarget() == filter) l.add(t); } TypeAnnotation[] typeAnnotations = l.toArray(new TypeAnnotation[0]); return AnnotatedTypeFactory.buildAnnotatedType(type, LocationInfo.BASE_LOCATION, typeAnnotations, typeAnnotations, decl); } /** * Build an array of AnnotatedTypes from the parameters supplied. * * This method and {@code buildAnnotatedType} are probably * the entry points you are looking for. * * @param rawAnnotations the byte[] encoding of all type annotations on this declaration * @param cp the ConstantPool needed to parse the embedded Annotation * @param decl the declaration this type annotation is on * @param container the Class this type annotation is on (may be the same as decl) * @param types the Types the AnnotatedTypes corresponds to * @param filter the type annotation targets that included in this AnnotatedType */ public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations, ConstantPool cp, AnnotatedElement decl, Class<?> container, Type[] types, TypeAnnotationTarget filter) { int size = types.length; AnnotatedType[] result = new AnnotatedType[size]; Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE); @SuppressWarnings("rawtypes") ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation> TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations, cp, decl, container); for (TypeAnnotation t : tas) { TypeAnnotationTargetInfo ti = t.getTargetInfo(); if (ti.getTarget() == filter) { int pos = ti.getCount(); if (l[pos] == null) { ArrayList<TypeAnnotation> tmp = new ArrayList<>(tas.length); l[pos] = tmp; } @SuppressWarnings("unchecked") ArrayList<TypeAnnotation> tmp = l[pos]; tmp.add(t); } } for (int i = 0; i < size; i++) { @SuppressWarnings("unchecked") ArrayList<TypeAnnotation> list = l[i]; TypeAnnotation[] typeAnnotations; if (list != null) { typeAnnotations = list.toArray(new TypeAnnotation[list.size()]); } else { typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY; } result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i], LocationInfo.BASE_LOCATION, typeAnnotations, typeAnnotations, decl); } return result; } // Class helpers /** * Build an AnnotatedType for the class decl's supertype. * * @param rawAnnotations the byte[] encoding of all type annotations on this declaration * @param cp the ConstantPool needed to parse the embedded Annotation * @param decl the Class which annotated supertype is being built */ public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations, ConstantPool cp, Class<?> decl) { Type supertype = decl.getGenericSuperclass(); if (supertype == null) return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE; return buildAnnotatedType(rawAnnotations, cp, decl, decl, supertype, TypeAnnotationTarget.CLASS_EXTENDS); } /** * Build an array of AnnotatedTypes for the class decl's implemented * interfaces. * * @param rawAnnotations the byte[] encoding of all type annotations on this declaration * @param cp the ConstantPool needed to parse the embedded Annotation * @param decl the Class whose annotated implemented interfaces is being built */ public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations, ConstantPool cp, Class<?> decl) { if (decl == Object.class || decl.isArray() || decl.isPrimitive() || decl == Void.TYPE) return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY; return buildAnnotatedTypes(rawAnnotations, cp, decl, decl, decl.getGenericInterfaces(), TypeAnnotationTarget.CLASS_IMPLEMENTS); } // TypeVariable helpers /** * Parse regular annotations on a TypeVariable declared on genericDecl. * * Regular Annotations on TypeVariables are stored in the type * annotation byte[] in the class file. * * @param genericsDecl the declaration declaring the type variable * @param typeVarIndex the 0-based index of this type variable in the declaration */ public static <D extends GenericDeclaration> Annotation[] parseTypeVariableAnnotations(D genericDecl, int typeVarIndex) { AnnotatedElement decl; TypeAnnotationTarget predicate; if (genericDecl instanceof Class) { decl = (Class<?>)genericDecl; predicate = TypeAnnotationTarget.CLASS_TYPE_PARAMETER; } else if (genericDecl instanceof Executable) { decl = (Executable)genericDecl; predicate = TypeAnnotationTarget.METHOD_TYPE_PARAMETER; } else { throw new AssertionError("Unknown GenericDeclaration " + genericDecl + "\nthis should not happen."); } List<TypeAnnotation> typeVarAnnos = TypeAnnotation.filter(parseAllTypeAnnotations(decl), predicate); List<Annotation> res = new ArrayList<>(typeVarAnnos.size()); for (TypeAnnotation t : typeVarAnnos) if (t.getTargetInfo().getCount() == typeVarIndex) res.add(t.getAnnotation()); return res.toArray(new Annotation[0]); } /** * Build an array of AnnotatedTypes for the declaration decl's bounds. * * @param bounds the bounds corresponding to the annotated bounds * @param decl the declaration whose annotated bounds is being built * @param typeVarIndex the index of this type variable on the decl */ public static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds, D decl, int typeVarIndex) { return parseAnnotatedBounds(bounds, decl, typeVarIndex, LocationInfo.BASE_LOCATION); } //helper for above private static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds, D decl, int typeVarIndex, LocationInfo loc) { List<TypeAnnotation> candidates = fetchBounds(decl); if (bounds != null) { int startIndex = 0; AnnotatedType[] res = new AnnotatedType[bounds.length]; Arrays.fill(res, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE); // Adjust bounds index // // Figure out if the type annotations for this bound starts with 0 // or 1. The spec says within a bound the 0:th type annotation will // always be on an bound of a Class type (not Interface type). So // if the programmer starts with an Interface type for the first // (and following) bound(s) the implicit Object bound is considered // the first (that is 0:th) bound and type annotations start on // index 1. if (bounds.length > 0) { Type b0 = bounds[0]; if (!(b0 instanceof Class<?>)) { startIndex = 1; } else { Class<?> c = (Class)b0; if (c.isInterface()) { startIndex = 1; } } } for (int i = 0; i < bounds.length; i++) { List<TypeAnnotation> l = new ArrayList<>(candidates.size()); for (TypeAnnotation t : candidates) { TypeAnnotationTargetInfo tInfo = t.getTargetInfo(); if (tInfo.getSecondaryIndex() == i + startIndex && tInfo.getCount() == typeVarIndex) { l.add(t); } res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], loc, l.toArray(new TypeAnnotation[0]), candidates.toArray(new TypeAnnotation[0]), (AnnotatedElement)decl); } } return res; } return new AnnotatedType[0]; } private static <D extends GenericDeclaration> List Other Java examples (source code examples)Here is a short list of links related to this Java TypeAnnotationParser.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.