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.

Aspects14.java 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*******************************************************************************
  2. * Copyright (c) 2006 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * variant of Aspects in the aspectj5rt project - this one isn't Java5 - Andy Clement
  11. *******************************************************************************/
  12. package org.aspectj.lang;
  13. import java.lang.reflect.InvocationTargetException;
  14. import java.lang.reflect.Method;
  15. import java.lang.reflect.Modifier;
  16. /**
  17. * For users working on a level of Java prior to Java5, Aspects14 handles generic aspectOf methods when they
  18. * are not available in the aspects but added later on through load time weaving. Users on Java5 should use
  19. * the class Aspects instead.
  20. * Aspects14.aspectOf(..) is doing reflective calls to the aspect aspectOf, so for better performance
  21. * consider using ajc compilation of the aspects and using them as a binary dependancies in your project.
  22. */
  23. public class Aspects14 {
  24. private final static Class[] EMPTY_CLASS_ARRAY = new Class[0];
  25. private final static Class[] PEROBJECT_CLASS_ARRAY = new Class[]{Object.class};
  26. private final static Class[] PERTYPEWITHIN_CLASS_ARRAY = new Class[]{Class.class};
  27. private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0];
  28. private final static String ASPECTOF = "aspectOf";
  29. private final static String HASASPECT = "hasAspect";
  30. /**
  31. * Returns the singleton aspect or the percflow / percflowbelow associated with the current thread
  32. *
  33. * @param aspectClass aspect class for which to discover the aspect instance
  34. * @return an aspect instance
  35. * @throws NoAspectBoundException if no such aspect
  36. */
  37. public static Object aspectOf(Class aspectClass) throws NoAspectBoundException {
  38. try {
  39. return getSingletonOrThreadAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY);
  40. } catch (InvocationTargetException e) {
  41. //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs
  42. throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause());
  43. } catch (Exception e) {
  44. throw new NoAspectBoundException(aspectClass.getName(), e);
  45. }
  46. }
  47. /**
  48. * Returns the perthis / pertarget aspect
  49. * @param aspectClass aspect class for which to discover the aspect instance
  50. * @param perObject object for which to discover the aspect instance
  51. * @return an aspect instance
  52. * @throws NoAspectBoundException if no such aspect, or no aspect bound
  53. */
  54. public static Object aspectOf(Class aspectClass, Object perObject) throws NoAspectBoundException {
  55. try {
  56. return getPerObjectAspectOf(aspectClass).invoke(null, new Object[]{perObject});
  57. } catch (InvocationTargetException e) {
  58. //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs
  59. throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause());
  60. } catch (Exception e) {
  61. throw new NoAspectBoundException(aspectClass.getName(), e);
  62. }
  63. }
  64. /**
  65. * Returns the pertypewithin aspect
  66. * @param aspectClass aspect class for which to discover the aspect instance
  67. * @param perTypeWithin class
  68. * @return the aspect instance
  69. * @throws NoAspectBoundException if no such aspect, or no aspect bound
  70. */
  71. public static Object aspectOf(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException {
  72. try {
  73. return getPerTypeWithinAspectOf(aspectClass).invoke(null, new Object[]{perTypeWithin});
  74. } catch (InvocationTargetException e) {
  75. // FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs
  76. throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause());
  77. } catch (Exception e) {
  78. throw new NoAspectBoundException(aspectClass.getName(), e);
  79. }
  80. }
  81. /**
  82. * Returns true if singleton aspect or percflow / percflowbelow aspect is bound
  83. *
  84. * @param aspectClass aspect class for which to check the aspect instance
  85. * @return true if an aspect instance is bound
  86. * @throws NoAspectBoundException if not bound
  87. */
  88. public static boolean hasAspect(Class aspectClass) throws NoAspectBoundException {
  89. try {
  90. return ((Boolean)getSingletonOrThreadHasAspect(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY)).booleanValue();
  91. } catch (Exception e) {
  92. return false;
  93. }
  94. }
  95. /**
  96. * Returns true if the perthis / pertarget aspect is bound
  97. * @param aspectClass aspect class for which to check the aspect instance
  98. * @param perObject the this/target for which to check for an aspect
  99. * @return true if aspect instance exists for the class/object combination
  100. * @throws NoAspectBoundException if not bound
  101. */
  102. public static boolean hasAspect(Class aspectClass, Object perObject) throws NoAspectBoundException {
  103. try {
  104. return ((Boolean)getPerObjectHasAspect(aspectClass).invoke(null, new Object[]{perObject})).booleanValue();
  105. } catch (Exception e) {
  106. return false;
  107. }
  108. }
  109. /**
  110. * Returns true if the pertypewithin aspect is bound
  111. * @param aspectClass aspect class for which to check the aspect instance
  112. * @param perTypeWithin class
  113. * @return true if aspect instance exists for this aspect class/pertypewithin class combination
  114. * @throws NoAspectBoundException if not bound
  115. */
  116. public static boolean hasAspect(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException {
  117. try {
  118. return ((Boolean)getPerTypeWithinHasAspect(aspectClass).invoke(null, new Object[]{perTypeWithin})).booleanValue();
  119. } catch (Exception e) {
  120. return false;
  121. }
  122. }
  123. // -- aspectOf
  124. private static Method getSingletonOrThreadAspectOf(Class aspectClass) throws NoSuchMethodException {
  125. Method method = aspectClass.getDeclaredMethod(ASPECTOF, EMPTY_CLASS_ARRAY);
  126. return checkAspectOf(method, aspectClass);
  127. }
  128. private static Method getPerObjectAspectOf(Class aspectClass) throws NoSuchMethodException {
  129. Method method = aspectClass.getDeclaredMethod(ASPECTOF, PEROBJECT_CLASS_ARRAY);
  130. return checkAspectOf(method, aspectClass);
  131. }
  132. private static Method getPerTypeWithinAspectOf(Class aspectClass) throws NoSuchMethodException {
  133. Method method = aspectClass.getDeclaredMethod(ASPECTOF, PERTYPEWITHIN_CLASS_ARRAY);
  134. return checkAspectOf(method, aspectClass);
  135. }
  136. private static Method checkAspectOf(Method method, Class aspectClass) throws NoSuchMethodException {
  137. method.setAccessible(true);
  138. if (!method.isAccessible()
  139. || !Modifier.isPublic(method.getModifiers())
  140. || !Modifier.isStatic(method.getModifiers())) {
  141. throw new NoSuchMethodException(aspectClass.getName() + ".aspectOf(..) is not accessible public static");
  142. }
  143. return method;
  144. }
  145. // -- hasAspect
  146. private static Method getSingletonOrThreadHasAspect(Class aspectClass) throws NoSuchMethodException {
  147. Method method = aspectClass.getDeclaredMethod(HASASPECT, EMPTY_CLASS_ARRAY);
  148. return checkHasAspect(method, aspectClass);
  149. }
  150. private static Method getPerObjectHasAspect(Class aspectClass) throws NoSuchMethodException {
  151. Method method = aspectClass.getDeclaredMethod(HASASPECT, PEROBJECT_CLASS_ARRAY);
  152. return checkHasAspect(method, aspectClass);
  153. }
  154. private static Method getPerTypeWithinHasAspect(Class aspectClass) throws NoSuchMethodException {
  155. Method method = aspectClass.getDeclaredMethod(HASASPECT, PERTYPEWITHIN_CLASS_ARRAY);
  156. return checkHasAspect(method, aspectClass);
  157. }
  158. private static Method checkHasAspect(Method method, Class aspectClass) throws NoSuchMethodException {
  159. method.setAccessible(true);
  160. if (!method.isAccessible()
  161. || !Modifier.isPublic(method.getModifiers())
  162. || !Modifier.isStatic(method.getModifiers())) {
  163. throw new NoSuchMethodException(aspectClass.getName() + ".hasAspect(..) is not accessible public static");
  164. }
  165. return method;
  166. }
  167. }