You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AnnotationImpl.java 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later.
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. */
  15. package javassist.bytecode.annotation;
  16. import javassist.ClassPool;
  17. import javassist.CtClass;
  18. import javassist.NotFoundException;
  19. import javassist.bytecode.AnnotationDefaultAttribute;
  20. import javassist.bytecode.ClassFile;
  21. import javassist.bytecode.MethodInfo;
  22. import java.lang.reflect.*;
  23. /**
  24. * Internal-use only. This is a helper class internally used for implementing
  25. * <code>toAnnotationType()</code> in <code>Annotation</code>.
  26. */
  27. public class AnnotationImpl implements InvocationHandler {
  28. private Annotation annotation;
  29. private ClassPool pool;
  30. private ClassLoader classLoader;
  31. /**
  32. * Constructs an annotation object.
  33. *
  34. * @param cl class loader for obtaining annotation types.
  35. * @param clazz the annotation type.
  36. * @param cp class pool for containing an annotation
  37. * type (or null).
  38. * @param anon the annotation.
  39. */
  40. public static Object make(ClassLoader cl, Class clazz, ClassPool cp,
  41. Annotation anon) {
  42. AnnotationImpl handler = new AnnotationImpl(anon, cp, cl);
  43. return Proxy.newProxyInstance(cl, new Class[] { clazz }, handler);
  44. }
  45. private AnnotationImpl(Annotation a, ClassPool cp, ClassLoader loader) {
  46. annotation = a;
  47. pool = cp;
  48. classLoader = loader;
  49. }
  50. /**
  51. * Obtains the name of the annotation type.
  52. */
  53. public String getTypeName() {
  54. return annotation.getTypeName();
  55. }
  56. /**
  57. * Executes a method invocation on a proxy instance.
  58. */
  59. public Object invoke(Object proxy, Method method, Object[] args)
  60. throws Throwable
  61. {
  62. String name = method.getName();
  63. if (Object.class == method.getDeclaringClass()) {
  64. if ("equals".equals(name)) {
  65. Object obj = args[0];
  66. if (obj == null || obj instanceof Proxy == false)
  67. return Boolean.FALSE;
  68. Object other = Proxy.getInvocationHandler(obj);
  69. if (this.equals(other))
  70. return Boolean.TRUE;
  71. else
  72. return Boolean.FALSE;
  73. }
  74. else if ("toString".equals(name))
  75. return annotation.getTypeName() + '@' + hashCode();
  76. else if ("hashCode".equals(name))
  77. return new Integer(hashCode());
  78. }
  79. MemberValue mv = annotation.getMemberValue(name);
  80. if (mv == null)
  81. return getDefault(name, method);
  82. else
  83. return mv.getValue(classLoader, pool, method);
  84. }
  85. private Object getDefault(String name, Method method)
  86. throws ClassNotFoundException, RuntimeException
  87. {
  88. String classname = annotation.getTypeName();
  89. if (pool != null)
  90. try {
  91. CtClass cc = pool.get(classname);
  92. ClassFile cf = cc.getClassFile2();
  93. MethodInfo minfo = cf.getMethod(name);
  94. if (minfo != null) {
  95. AnnotationDefaultAttribute ainfo
  96. = (AnnotationDefaultAttribute)
  97. minfo.getAttribute(AnnotationDefaultAttribute.tag);
  98. if (ainfo != null) {
  99. MemberValue mv = ainfo.getDefaultValue();
  100. return mv.getValue(classLoader, pool, method);
  101. }
  102. }
  103. }
  104. catch (NotFoundException e) {
  105. throw new RuntimeException("cannot find a class file: "
  106. + classname);
  107. }
  108. throw new RuntimeException("no default value: " + classname + "."
  109. + name + "()");
  110. }
  111. }