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.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. public class AnnotationImpl implements InvocationHandler {
  24. private Annotation annotation;
  25. private ClassPool pool;
  26. private ClassLoader classLoader;
  27. /**
  28. * Constructs an annotation object.
  29. *
  30. * @param cl class loader for obtaining annotation types.
  31. * @param clazz the annotation type.
  32. * @param cp class pool for containing an annotation
  33. * type (or null).
  34. * @param anon the annotation.
  35. */
  36. public static Object make(ClassLoader cl, Class clazz, ClassPool cp,
  37. Annotation anon) {
  38. AnnotationImpl handler = new AnnotationImpl(anon, cp, cl);
  39. return Proxy.newProxyInstance(cl, new Class[] { clazz }, handler);
  40. }
  41. private AnnotationImpl(Annotation a, ClassPool cp, ClassLoader loader) {
  42. annotation = a;
  43. pool = cp;
  44. classLoader = loader;
  45. }
  46. public String getTypeName()
  47. {
  48. return annotation.getTypeName();
  49. }
  50. public Object invoke(Object proxy, Method method, Object[] args)
  51. throws Throwable
  52. {
  53. String name = method.getName();
  54. if (Object.class == method.getDeclaringClass())
  55. {
  56. if ("equals".equals(name))
  57. {
  58. Object obj = args[0];
  59. if (obj == null || obj instanceof Proxy == false)
  60. return Boolean.FALSE;
  61. Object other = Proxy.getInvocationHandler(obj);
  62. if (this.equals(other))
  63. return Boolean.TRUE;
  64. else
  65. return Boolean.FALSE;
  66. }
  67. if ("toString".equals(name))
  68. return annotation.getTypeName() + '@' + hashCode();
  69. if ("hashCode".equals(name))
  70. return new Integer(hashCode());
  71. }
  72. MemberValue mv = annotation.getMemberValue(name);
  73. if (mv == null)
  74. return getDefault(name, method);
  75. else
  76. return mv.getValue(classLoader, pool, method);
  77. }
  78. private Object getDefault(String name, Method method)
  79. throws ClassNotFoundException, RuntimeException
  80. {
  81. String classname = annotation.getTypeName();
  82. if (pool != null)
  83. try {
  84. CtClass cc = pool.get(classname);
  85. ClassFile cf = cc.getClassFile2();
  86. MethodInfo minfo = cf.getMethod(name);
  87. if (minfo != null) {
  88. AnnotationDefaultAttribute ainfo
  89. = (AnnotationDefaultAttribute)
  90. minfo.getAttribute(AnnotationDefaultAttribute.tag);
  91. if (ainfo != null) {
  92. MemberValue mv = ainfo.getDefaultValue();
  93. return mv.getValue(classLoader, pool, method);
  94. }
  95. }
  96. }
  97. catch (NotFoundException e) {
  98. throw new RuntimeException("cannot find a class file: "
  99. + classname);
  100. }
  101. throw new RuntimeException("no default value: " + classname + "."
  102. + name + "()");
  103. }
  104. }