--- old/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java 2012-02-05 21:53:15.000000000 -0800 +++ /dev/null 2012-01-26 22:16:29.967853990 -0800 @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2004, 2010, 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 com.sun.tools.apt.mirror.declaration; - - -import java.lang.annotation.*; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.util.*; -import sun.reflect.annotation.*; - -import com.sun.mirror.type.TypeMirror; -import com.sun.mirror.type.MirroredTypeException; -import com.sun.mirror.type.MirroredTypesException; -import com.sun.tools.apt.mirror.AptEnv; -import com.sun.tools.javac.code.*; -import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.util.Name; -import com.sun.tools.javac.util.Pair; - - -/** - * A generator of dynamic proxy implementations of - * java.lang.annotation.Annotation. - * - *

The "dynamic proxy return form" of an attribute element value is - * the form used by sun.reflect.annotation.AnnotationInvocationHandler. - */ -@SuppressWarnings("deprecation") -class AnnotationProxyMaker { - - private final AptEnv env; - private final Attribute.Compound attrs; - private final Class annoType; - - - private AnnotationProxyMaker(AptEnv env, - Attribute.Compound attrs, - Class annoType) { - this.env = env; - this.attrs = attrs; - this.annoType = annoType; - } - - - /** - * Returns a dynamic proxy for an annotation mirror. - */ - public static A generateAnnotation( - AptEnv env, Attribute.Compound attrs, Class annoType) { - AnnotationProxyMaker apm = new AnnotationProxyMaker(env, attrs, annoType); - return annoType.cast(apm.generateAnnotation()); - } - - - /** - * Returns a dynamic proxy for an annotation mirror. - */ - private Annotation generateAnnotation() { - return AnnotationParser.annotationForMap(annoType, - getAllReflectedValues()); - } - - /** - * Returns a map from element names to their values in "dynamic - * proxy return form". Includes all elements, whether explicit or - * defaulted. - */ - private Map getAllReflectedValues() { - Map res = new LinkedHashMap(); - - for (Map.Entry entry : - getAllValues().entrySet()) { - MethodSymbol meth = entry.getKey(); - Object value = generateValue(meth, entry.getValue()); - if (value != null) { - res.put(meth.name.toString(), value); - } else { - // Ignore this element. May lead to - // IncompleteAnnotationException somewhere down the line. - } - } - return res; - } - - /** - * Returns a map from element symbols to their values. - * Includes all elements, whether explicit or defaulted. - */ - private Map getAllValues() { - Map res = - new LinkedHashMap(); - - // First find the default values. - ClassSymbol sym = (ClassSymbol) attrs.type.tsym; - for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) { - if (e.sym.kind == Kinds.MTH) { - MethodSymbol m = (MethodSymbol) e.sym; - Attribute def = m.defaultValue; - if (def != null) { - res.put(m, def); - } - } - } - // Next find the explicit values, possibly overriding defaults. - for (Pair p : attrs.values) { - res.put(p.fst, p.snd); - } - return res; - } - - /** - * Converts an element value to its "dynamic proxy return form". - * Returns an exception proxy on some errors, but may return null if - * a useful exception cannot or should not be generated at this point. - */ - private Object generateValue(MethodSymbol meth, Attribute attr) { - ValueVisitor vv = new ValueVisitor(meth); - return vv.getValue(attr); - } - - - private class ValueVisitor implements Attribute.Visitor { - - private MethodSymbol meth; // annotation element being visited - private Class runtimeType; // runtime type of annotation element - private Object value; // value in "dynamic proxy return form" - - ValueVisitor(MethodSymbol meth) { - this.meth = meth; - } - - Object getValue(Attribute attr) { - Method method; // runtime method of annotation element - try { - method = annoType.getMethod(meth.name.toString()); - } catch (NoSuchMethodException e) { - return null; - } - runtimeType = method.getReturnType(); - attr.accept(this); - if (!(value instanceof ExceptionProxy) && - !AnnotationType.invocationHandlerReturnType(runtimeType) - .isInstance(value)) { - typeMismatch(method, attr); - } - return value; - } - - - public void visitConstant(Attribute.Constant c) { - value = Constants.decodeConstant(c.value, c.type); - } - - public void visitClass(Attribute.Class c) { - value = new MirroredTypeExceptionProxy( - env.typeMaker.getType(c.type)); - } - - public void visitArray(Attribute.Array a) { - Type elemtype = env.jctypes.elemtype(a.type); - - if (elemtype.tsym == env.symtab.classType.tsym) { // Class[] - // Construct a proxy for a MirroredTypesException - ArrayList elems = new ArrayList(); - for (int i = 0; i < a.values.length; i++) { - Type elem = ((Attribute.Class) a.values[i]).type; - elems.add(env.typeMaker.getType(elem)); - } - value = new MirroredTypesExceptionProxy(elems); - - } else { - int len = a.values.length; - Class runtimeTypeSaved = runtimeType; - runtimeType = runtimeType.getComponentType(); - try { - Object res = Array.newInstance(runtimeType, len); - for (int i = 0; i < len; i++) { - a.values[i].accept(this); - if (value == null || value instanceof ExceptionProxy) { - return; - } - try { - Array.set(res, i, value); - } catch (IllegalArgumentException e) { - value = null; // indicates a type mismatch - return; - } - } - value = res; - } finally { - runtimeType = runtimeTypeSaved; - } - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public void visitEnum(Attribute.Enum e) { - if (runtimeType.isEnum()) { - String constName = e.value.toString(); - try { - value = Enum.valueOf((Class)runtimeType, constName); - } catch (IllegalArgumentException ex) { - value = new EnumConstantNotPresentExceptionProxy( - (Class>)runtimeType, constName); - } - } else { - value = null; // indicates a type mismatch - } - } - - public void visitCompound(Attribute.Compound c) { - try { - Class nested = - runtimeType.asSubclass(Annotation.class); - value = generateAnnotation(env, c, nested); - } catch (ClassCastException ex) { - value = null; // indicates a type mismatch - } - } - - public void visitError(Attribute.Error e) { - value = null; // indicates a type mismatch - } - - - /** - * Sets "value" to an ExceptionProxy indicating a type mismatch. - */ - private void typeMismatch(Method method, final Attribute attr) { - class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy { - private static final long serialVersionUID = 8473323277815075163L; - transient final Method method; - AnnotationTypeMismatchExceptionProxy(Method method) { - this.method = method; - } - public String toString() { - return ""; // eg: @Anno(value=) - } - protected RuntimeException generateException() { - return new AnnotationTypeMismatchException(method, - attr.type.toString()); - } - } - value = new AnnotationTypeMismatchExceptionProxy(method); - } - } - - - /** - * ExceptionProxy for MirroredTypeException. - * The toString, hashCode, and equals methods foward to the underlying - * type. - */ - private static final class MirroredTypeExceptionProxy extends ExceptionProxy { - private static final long serialVersionUID = 6662035281599933545L; - - private MirroredTypeException ex; - - MirroredTypeExceptionProxy(TypeMirror t) { - // It would be safer if we could construct the exception in - // generateException(), but there would be no way to do - // that properly following deserialization. - ex = new MirroredTypeException(t); - } - - public String toString() { - return ex.getQualifiedName(); - } - - public int hashCode() { - TypeMirror t = ex.getTypeMirror(); - return (t != null) - ? t.hashCode() - : ex.getQualifiedName().hashCode(); - } - - public boolean equals(Object obj) { - TypeMirror t = ex.getTypeMirror(); - return t != null && - obj instanceof MirroredTypeExceptionProxy && - t.equals( - ((MirroredTypeExceptionProxy) obj).ex.getTypeMirror()); - } - - protected RuntimeException generateException() { - return (RuntimeException) ex.fillInStackTrace(); - } - } - - - /** - * ExceptionProxy for MirroredTypesException. - * The toString, hashCode, and equals methods foward to the underlying - * types. - */ - private static final class MirroredTypesExceptionProxy extends ExceptionProxy { - private static final long serialVersionUID = -6670822532616693951L; - - private MirroredTypesException ex; - - MirroredTypesExceptionProxy(Collection ts) { - // It would be safer if we could construct the exception in - // generateException(), but there would be no way to do - // that properly following deserialization. - ex = new MirroredTypesException(ts); - } - - public String toString() { - return ex.getQualifiedNames().toString(); - } - - public int hashCode() { - Collection ts = ex.getTypeMirrors(); - return (ts != null) - ? ts.hashCode() - : ex.getQualifiedNames().hashCode(); - } - - public boolean equals(Object obj) { - Collection ts = ex.getTypeMirrors(); - return ts != null && - obj instanceof MirroredTypesExceptionProxy && - ts.equals( - ((MirroredTypesExceptionProxy) obj).ex.getTypeMirrors()); - } - - protected RuntimeException generateException() { - return (RuntimeException) ex.fillInStackTrace(); - } - } -}