1 /* 2 * Copyright (c) 1997, 2011, 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 26 package com.sun.tools.internal.jxc.ap; 27 28 import java.lang.annotation.Annotation; 29 import java.lang.reflect.InvocationTargetException; 30 import java.util.ArrayList; 31 import java.util.Collection; 32 import java.util.List; 33 34 import javax.lang.model.element.AnnotationMirror; 35 import javax.lang.model.element.Element; 36 import javax.lang.model.element.ExecutableElement; 37 import javax.lang.model.element.TypeElement; 38 import javax.lang.model.element.VariableElement; 39 import javax.lang.model.type.MirroredTypeException; 40 import javax.lang.model.type.MirroredTypesException; 41 import javax.lang.model.type.TypeMirror; 42 import com.sun.xml.internal.bind.v2.model.annotation.AbstractInlineAnnotationReaderImpl; 43 import com.sun.xml.internal.bind.v2.model.annotation.AnnotationReader; 44 import com.sun.xml.internal.bind.v2.model.annotation.Locatable; 45 import com.sun.xml.internal.bind.v2.model.annotation.LocatableAnnotation; 46 47 /** 48 * {@link AnnotationReader} implementation that reads annotation inline from Annoation Processing. 49 * 50 * @author Kohsuke Kawaguchi (kk@kohsuke.org) 51 */ 52 public final class InlineAnnotationReaderImpl extends AbstractInlineAnnotationReaderImpl<TypeMirror, TypeElement, VariableElement, ExecutableElement> { 53 54 /** The singleton instance. */ 55 public static final InlineAnnotationReaderImpl theInstance = new InlineAnnotationReaderImpl(); 56 57 private InlineAnnotationReaderImpl() {} 58 59 public <A extends Annotation> A getClassAnnotation(Class<A> a, TypeElement clazz, Locatable srcPos) { 60 return LocatableAnnotation.create(clazz.getAnnotation(a),srcPos); 61 } 62 63 public <A extends Annotation> A getFieldAnnotation(Class<A> a, VariableElement f, Locatable srcPos) { 64 return LocatableAnnotation.create(f.getAnnotation(a),srcPos); 65 } 66 67 public boolean hasFieldAnnotation(Class<? extends Annotation> annotationType, VariableElement f) { 68 return f.getAnnotation(annotationType)!=null; 69 } 70 71 public boolean hasClassAnnotation(TypeElement clazz, Class<? extends Annotation> annotationType) { 72 return clazz.getAnnotation(annotationType)!=null; 73 } 74 75 public Annotation[] getAllFieldAnnotations(VariableElement field, Locatable srcPos) { 76 return getAllAnnotations(field,srcPos); 77 } 78 79 public <A extends Annotation> A getMethodAnnotation(Class<A> a, ExecutableElement method, Locatable srcPos) { 80 return LocatableAnnotation.create(method.getAnnotation(a),srcPos); 81 } 82 83 public boolean hasMethodAnnotation(Class<? extends Annotation> a, ExecutableElement method) { 84 return method.getAnnotation(a)!=null; 85 } 86 87 public Annotation[] getAllMethodAnnotations(ExecutableElement method, Locatable srcPos) { 88 return getAllAnnotations(method,srcPos); 89 } 90 91 /** 92 * Gets all the annotations on the given declaration. 93 */ 94 private Annotation[] getAllAnnotations(Element decl, Locatable srcPos) { 95 List<Annotation> r = new ArrayList<Annotation>(); 96 97 for( AnnotationMirror m : decl.getAnnotationMirrors() ) { 98 try { 99 String fullName = ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName().toString(); 100 Class<? extends Annotation> type = 101 SecureLoader.getClassClassLoader(getClass()).loadClass(fullName).asSubclass(Annotation.class); 102 Annotation annotation = decl.getAnnotation(type); 103 if(annotation!=null) 104 r.add( LocatableAnnotation.create(annotation,srcPos) ); 105 } catch (ClassNotFoundException e) { 106 // just continue 107 } 108 } 109 110 return r.toArray(new Annotation[r.size()]); 111 } 112 113 public <A extends Annotation> A getMethodParameterAnnotation(Class<A> a, ExecutableElement m, int paramIndex, Locatable srcPos) { 114 VariableElement[] params = m.getParameters().toArray(new VariableElement[m.getParameters().size()]); 115 return LocatableAnnotation.create( 116 params[paramIndex].getAnnotation(a), srcPos ); 117 } 118 119 public <A extends Annotation> A getPackageAnnotation(Class<A> a, TypeElement clazz, Locatable srcPos) { 120 return LocatableAnnotation.create(clazz.getEnclosingElement().getAnnotation(a), srcPos); 121 } 122 123 public TypeMirror getClassValue(Annotation a, String name) { 124 try { 125 a.annotationType().getMethod(name).invoke(a); 126 assert false; 127 throw new IllegalStateException("should throw a MirroredTypeException"); 128 } catch (IllegalAccessException e) { 129 throw new IllegalAccessError(e.getMessage()); 130 } catch (InvocationTargetException e) { 131 if( e.getCause() instanceof MirroredTypeException ) { 132 MirroredTypeException me = (MirroredTypeException)e.getCause(); 133 return me.getTypeMirror(); 134 } 135 // impossible 136 throw new RuntimeException(e); 137 } catch (NoSuchMethodException e) { 138 throw new NoSuchMethodError(e.getMessage()); 139 } 140 } 141 142 public TypeMirror[] getClassArrayValue(Annotation a, String name) { 143 try { 144 a.annotationType().getMethod(name).invoke(a); 145 assert false; 146 throw new IllegalStateException("should throw a MirroredTypesException"); 147 } catch (IllegalAccessException e) { 148 throw new IllegalAccessError(e.getMessage()); 149 } catch (InvocationTargetException e) { 150 if( e.getCause() instanceof MirroredTypesException ) { 151 MirroredTypesException me = (MirroredTypesException)e.getCause(); 152 Collection<? extends TypeMirror> r = me.getTypeMirrors(); 153 return r.toArray(new TypeMirror[r.size()]); 154 } 155 // *********************** TODO: jdk6 bug. Fixed in java7 156 // According to the javadocs it should throw the MirroredTypesException 157 if( e.getCause() instanceof MirroredTypeException ) { 158 MirroredTypeException me = (MirroredTypeException)e.getCause(); 159 TypeMirror tr = me.getTypeMirror(); 160 TypeMirror[] trArr = new TypeMirror[1]; 161 trArr[0] = tr; 162 return trArr; 163 } 164 // ******************************************* 165 // impossible 166 throw new RuntimeException(e); 167 } catch (NoSuchMethodException e) { 168 throw new NoSuchMethodError(e.getMessage()); 169 } 170 } 171 172 protected String fullName(ExecutableElement m) { 173 return ((TypeElement) m.getEnclosingElement()).getQualifiedName().toString()+'#'+m.getSimpleName(); 174 } 175 }