325N/A/*
325N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/Apackage com.sun.xml.internal.bind.v2.model.annotation;
325N/A
325N/Aimport java.lang.annotation.Annotation;
325N/Aimport java.lang.reflect.Field;
325N/Aimport java.lang.reflect.InvocationTargetException;
325N/Aimport java.lang.reflect.Method;
325N/Aimport java.lang.reflect.Type;
325N/Aimport java.util.HashMap;
325N/Aimport java.util.Map;
325N/A
325N/A/**
325N/A * {@link AnnotationReader} that uses {@code java.lang.reflect} to
325N/A * read annotations from class files.
325N/A *
325N/A * @author Kohsuke Kawaguchi (kk@kohsuke.org)
325N/A */
325N/Apublic final class RuntimeInlineAnnotationReader extends AbstractInlineAnnotationReaderImpl<Type,Class,Field,Method>
325N/A implements RuntimeAnnotationReader {
325N/A
325N/A public <A extends Annotation> A getFieldAnnotation(Class<A> annotation, Field field, Locatable srcPos) {
325N/A return LocatableAnnotation.create(field.getAnnotation(annotation),srcPos);
325N/A }
325N/A
325N/A public boolean hasFieldAnnotation(Class<? extends Annotation> annotationType, Field field) {
325N/A return field.isAnnotationPresent(annotationType);
325N/A }
325N/A
325N/A public boolean hasClassAnnotation(Class clazz, Class<? extends Annotation> annotationType) {
325N/A return clazz.isAnnotationPresent(annotationType);
325N/A }
325N/A
325N/A public Annotation[] getAllFieldAnnotations(Field field, Locatable srcPos) {
325N/A Annotation[] r = field.getAnnotations();
325N/A for( int i=0; i<r.length; i++ ) {
325N/A r[i] = LocatableAnnotation.create(r[i],srcPos);
325N/A }
325N/A return r;
325N/A }
325N/A
325N/A public <A extends Annotation> A getMethodAnnotation(Class<A> annotation, Method method, Locatable srcPos) {
325N/A return LocatableAnnotation.create(method.getAnnotation(annotation),srcPos);
325N/A }
325N/A
325N/A public boolean hasMethodAnnotation(Class<? extends Annotation> annotation, Method method) {
325N/A return method.isAnnotationPresent(annotation);
325N/A }
325N/A
325N/A public Annotation[] getAllMethodAnnotations(Method method, Locatable srcPos) {
325N/A Annotation[] r = method.getAnnotations();
325N/A for( int i=0; i<r.length; i++ ) {
325N/A r[i] = LocatableAnnotation.create(r[i],srcPos);
325N/A }
325N/A return r;
325N/A }
325N/A
325N/A public <A extends Annotation> A getMethodParameterAnnotation(Class<A> annotation, Method method, int paramIndex, Locatable srcPos) {
325N/A Annotation[] pa = method.getParameterAnnotations()[paramIndex];
325N/A for( Annotation a : pa ) {
325N/A if(a.annotationType()==annotation)
325N/A return LocatableAnnotation.create((A)a,srcPos);
325N/A }
325N/A return null;
325N/A }
325N/A
325N/A public <A extends Annotation> A getClassAnnotation(Class<A> a, Class clazz, Locatable srcPos) {
325N/A return LocatableAnnotation.create(((Class<?>)clazz).getAnnotation(a),srcPos);
325N/A }
325N/A
325N/A
325N/A /**
325N/A * Cache for package-level annotations.
325N/A */
325N/A private final Map<Class<? extends Annotation>,Map<Package,Annotation>> packageCache =
325N/A new HashMap<Class<? extends Annotation>,Map<Package,Annotation>>();
325N/A
325N/A public <A extends Annotation> A getPackageAnnotation(Class<A> a, Class clazz, Locatable srcPos) {
325N/A Package p = clazz.getPackage();
325N/A if(p==null) return null;
325N/A
325N/A Map<Package,Annotation> cache = packageCache.get(a);
325N/A if(cache==null) {
325N/A cache = new HashMap<Package,Annotation>();
325N/A packageCache.put(a,cache);
325N/A }
325N/A
325N/A if(cache.containsKey(p))
325N/A return (A)cache.get(p);
325N/A else {
325N/A A ann = LocatableAnnotation.create(p.getAnnotation(a),srcPos);
325N/A cache.put(p,ann);
325N/A return ann;
325N/A }
325N/A }
325N/A
325N/A public Class getClassValue(Annotation a, String name) {
325N/A try {
325N/A return (Class)a.annotationType().getMethod(name).invoke(a);
325N/A } catch (IllegalAccessException e) {
325N/A // impossible
325N/A throw new IllegalAccessError(e.getMessage());
325N/A } catch (InvocationTargetException e) {
325N/A // impossible
325N/A throw new InternalError(Messages.CLASS_NOT_FOUND.format(a.annotationType(), e.getMessage()));
325N/A } catch (NoSuchMethodException e) {
325N/A throw new NoSuchMethodError(e.getMessage());
325N/A }
325N/A }
325N/A
325N/A public Class[] getClassArrayValue(Annotation a, String name) {
325N/A try {
325N/A return (Class[])a.annotationType().getMethod(name).invoke(a);
325N/A } catch (IllegalAccessException e) {
325N/A // impossible
325N/A throw new IllegalAccessError(e.getMessage());
325N/A } catch (InvocationTargetException e) {
325N/A // impossible
325N/A throw new InternalError(e.getMessage());
325N/A } catch (NoSuchMethodException e) {
325N/A throw new NoSuchMethodError(e.getMessage());
325N/A }
325N/A }
325N/A
325N/A protected String fullName(Method m) {
325N/A return m.getDeclaringClass().getName()+'#'+m.getName();
325N/A }
325N/A}