1/* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 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 26package com.sun.xml.internal.bind.v2.model.annotation; 27 28import java.lang.annotation.Annotation; 29import java.lang.reflect.Field; 30import java.lang.reflect.InvocationTargetException; 31import java.lang.reflect.Method; 32import java.lang.reflect.Type; 33import java.util.HashMap; 34import java.util.Map; 35 36/** 37 * {@link AnnotationReader} that uses {@code java.lang.reflect} to 38 * read annotations from class files. 39 * 40 * @author Kohsuke Kawaguchi (kk@kohsuke.org) 41 */ 42public final class RuntimeInlineAnnotationReader extends AbstractInlineAnnotationReaderImpl<Type,Class,Field,Method> 43 implements RuntimeAnnotationReader { 44 45 public <A extends Annotation> A getFieldAnnotation(Class<A> annotation, Field field, Locatable srcPos) { 46 return LocatableAnnotation.create(field.getAnnotation(annotation),srcPos); 47 } 48 49 public boolean hasFieldAnnotation(Class<? extends Annotation> annotationType, Field field) { 50 return field.isAnnotationPresent(annotationType); 51 } 52 53 public boolean hasClassAnnotation(Class clazz, Class<? extends Annotation> annotationType) { 54 return clazz.isAnnotationPresent(annotationType); 55 } 56 57 public Annotation[] getAllFieldAnnotations(Field field, Locatable srcPos) { 58 Annotation[] r = field.getAnnotations(); 59 for( int i=0; i<r.length; i++ ) { 60 r[i] = LocatableAnnotation.create(r[i],srcPos); 61 } 62 return r; 63 } 64 65 public <A extends Annotation> A getMethodAnnotation(Class<A> annotation, Method method, Locatable srcPos) { 66 return LocatableAnnotation.create(method.getAnnotation(annotation),srcPos); 67 } 68 69 public boolean hasMethodAnnotation(Class<? extends Annotation> annotation, Method method) { 70 return method.isAnnotationPresent(annotation); 71 } 72 73 public Annotation[] getAllMethodAnnotations(Method method, Locatable srcPos) { 74 Annotation[] r = method.getAnnotations(); 75 for( int i=0; i<r.length; i++ ) { 76 r[i] = LocatableAnnotation.create(r[i],srcPos); 77 } 78 return r; 79 } 80 81 public <A extends Annotation> A getMethodParameterAnnotation(Class<A> annotation, Method method, int paramIndex, Locatable srcPos) { 82 Annotation[] pa = method.getParameterAnnotations()[paramIndex]; 83 for( Annotation a : pa ) { 84 if(a.annotationType()==annotation) 85 return LocatableAnnotation.create((A)a,srcPos); 86 } 87 return null; 88 } 89 90 public <A extends Annotation> A getClassAnnotation(Class<A> a, Class clazz, Locatable srcPos) { 91 return LocatableAnnotation.create(((Class<?>)clazz).getAnnotation(a),srcPos); 92 } 93 94 95 /** 96 * Cache for package-level annotations. 97 */ 98 private final Map<Class<? extends Annotation>,Map<Package,Annotation>> packageCache = 99 new HashMap<Class<? extends Annotation>,Map<Package,Annotation>>(); 100 101 public <A extends Annotation> A getPackageAnnotation(Class<A> a, Class clazz, Locatable srcPos) { 102 Package p = clazz.getPackage(); 103 if(p==null) return null; 104 105 Map<Package,Annotation> cache = packageCache.get(a); 106 if(cache==null) { 107 cache = new HashMap<Package,Annotation>(); 108 packageCache.put(a,cache); 109 } 110 111 if(cache.containsKey(p)) 112 return (A)cache.get(p); 113 else { 114 A ann = LocatableAnnotation.create(p.getAnnotation(a),srcPos); 115 cache.put(p,ann); 116 return ann; 117 } 118 } 119 120 public Class getClassValue(Annotation a, String name) { 121 try { 122 return (Class)a.annotationType().getMethod(name).invoke(a); 123 } catch (IllegalAccessException e) { 124 // impossible 125 throw new IllegalAccessError(e.getMessage()); 126 } catch (InvocationTargetException e) { 127 // impossible 128 throw new InternalError(Messages.CLASS_NOT_FOUND.format(a.annotationType(), e.getMessage())); 129 } catch (NoSuchMethodException e) { 130 throw new NoSuchMethodError(e.getMessage()); 131 } 132 } 133 134 public Class[] getClassArrayValue(Annotation a, String name) { 135 try { 136 return (Class[])a.annotationType().getMethod(name).invoke(a); 137 } catch (IllegalAccessException e) { 138 // impossible 139 throw new IllegalAccessError(e.getMessage()); 140 } catch (InvocationTargetException e) { 141 // impossible 142 throw new InternalError(e.getMessage()); 143 } catch (NoSuchMethodException e) { 144 throw new NoSuchMethodError(e.getMessage()); 145 } 146 } 147 148 protected String fullName(Method m) { 149 return m.getDeclaringClass().getName()+'#'+m.getName(); 150 } 151} 152