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.

CrosscuttingMembersSet.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.util.ArrayList;
  14. import java.util.HashMap;
  15. import java.util.HashSet;
  16. import java.util.Iterator;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.Set;
  20. import org.aspectj.weaver.patterns.DeclareParents;
  21. /**
  22. * This holds on to all CrosscuttingMembers for a world. It handles
  23. * management of change.
  24. *
  25. * @author Jim Hugunin
  26. */
  27. public class CrosscuttingMembersSet {
  28. private World world;
  29. //FIXME AV - ? we may need a sequencedHashMap there to ensure source based precedence for @AJ advice
  30. private Map members = new HashMap();
  31. private List shadowMungers = null;
  32. private List typeMungers = null;
  33. private List lateTypeMungers = null;
  34. private List declareSofts = null;
  35. private List declareParents = null;
  36. private List declareAnnotationOnTypes = null;
  37. private List declareAnnotationOnFields = null;
  38. private List declareAnnotationOnMethods= null; // includes ctors
  39. private List declareDominates = null;
  40. public CrosscuttingMembersSet(World world) {
  41. this.world = world;
  42. }
  43. /**
  44. * @return whether or not that was a change to the global signature
  45. * XXX for efficiency we will need a richer representation than this
  46. */
  47. public boolean addOrReplaceAspect(ResolvedTypeX aspectType) {
  48. CrosscuttingMembers xcut = (CrosscuttingMembers)members.get(aspectType);
  49. if (xcut == null) {
  50. members.put(aspectType, aspectType.collectCrosscuttingMembers());
  51. clearCaches();
  52. return true;
  53. } else {
  54. if (xcut.replaceWith(aspectType.collectCrosscuttingMembers())) {
  55. clearCaches();
  56. return true;
  57. } else {
  58. return false;
  59. }
  60. }
  61. }
  62. public void addAdviceLikeDeclares(ResolvedTypeX aspectType) {
  63. CrosscuttingMembers xcut = (CrosscuttingMembers)members.get(aspectType);
  64. xcut.addDeclares(aspectType.collectDeclares(true));
  65. }
  66. public boolean deleteAspect(TypeX aspectType) {
  67. boolean isAspect = members.remove(aspectType) != null;
  68. clearCaches();
  69. return isAspect;
  70. }
  71. public boolean containsAspect(TypeX aspectType) {
  72. return members.containsKey(aspectType);
  73. }
  74. //XXX only for testing
  75. public void addFixedCrosscuttingMembers(ResolvedTypeX aspectType) {
  76. members.put(aspectType, aspectType.crosscuttingMembers);
  77. clearCaches();
  78. }
  79. private void clearCaches() {
  80. shadowMungers = null;
  81. typeMungers = null;
  82. lateTypeMungers = null;
  83. declareSofts = null;
  84. declareParents = null;
  85. declareDominates = null;
  86. }
  87. public List getShadowMungers() {
  88. if (shadowMungers == null) {
  89. ArrayList ret = new ArrayList();
  90. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  91. ret.addAll(((CrosscuttingMembers)i.next()).getShadowMungers());
  92. }
  93. shadowMungers = ret;
  94. }
  95. return shadowMungers;
  96. }
  97. public List getTypeMungers() {
  98. if (typeMungers == null) {
  99. ArrayList ret = new ArrayList();
  100. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  101. ret.addAll(((CrosscuttingMembers)i.next()).getTypeMungers());
  102. }
  103. typeMungers = ret;
  104. }
  105. return typeMungers;
  106. }
  107. public List getLateTypeMungers() {
  108. if (lateTypeMungers == null) {
  109. ArrayList ret = new ArrayList();
  110. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  111. ret.addAll(((CrosscuttingMembers)i.next()).getLateTypeMungers());
  112. }
  113. lateTypeMungers = ret;
  114. }
  115. return lateTypeMungers;
  116. }
  117. public List getDeclareSofts() {
  118. if (declareSofts == null) {
  119. ArrayList ret = new ArrayList();
  120. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  121. ret.addAll(((CrosscuttingMembers)i.next()).getDeclareSofts());
  122. }
  123. declareSofts = ret;
  124. }
  125. return declareSofts;
  126. }
  127. public List getDeclareParents() {
  128. if (declareParents == null) {
  129. ArrayList ret = new ArrayList();
  130. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  131. ret.addAll(((CrosscuttingMembers)i.next()).getDeclareParents());
  132. }
  133. declareParents = ret;
  134. }
  135. return declareParents;
  136. }
  137. // DECAT Merge multiple together
  138. public List getDeclareAnnotationOnTypes() {
  139. if (declareAnnotationOnTypes == null) {
  140. ArrayList ret = new ArrayList();
  141. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  142. ret.addAll(((CrosscuttingMembers)i.next()).getDeclareAnnotationOnTypes());
  143. }
  144. declareAnnotationOnTypes = ret;
  145. }
  146. return declareAnnotationOnTypes;
  147. }
  148. public List getDeclareAnnotationOnFields() {
  149. if (declareAnnotationOnFields == null) {
  150. ArrayList ret = new ArrayList();
  151. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  152. ret.addAll(((CrosscuttingMembers)i.next()).getDeclareAnnotationOnFields());
  153. }
  154. declareAnnotationOnFields = ret;
  155. }
  156. return declareAnnotationOnFields;
  157. }
  158. /**
  159. * Return an amalgamation of the declare @method/@constructor statements.
  160. */
  161. public List getDeclareAnnotationOnMethods() {
  162. if (declareAnnotationOnMethods == null) {
  163. ArrayList ret = new ArrayList();
  164. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  165. ret.addAll(((CrosscuttingMembers)i.next()).getDeclareAnnotationOnMethods());
  166. }
  167. declareAnnotationOnMethods = ret;
  168. }
  169. return declareAnnotationOnMethods;
  170. }
  171. public List getDeclareDominates() {
  172. if (declareDominates == null) {
  173. ArrayList ret = new ArrayList();
  174. for (Iterator i = members.values().iterator(); i.hasNext(); ) {
  175. ret.addAll(((CrosscuttingMembers)i.next()).getDeclareDominates());
  176. }
  177. declareDominates = ret;
  178. }
  179. return declareDominates;
  180. }
  181. public ResolvedTypeX findAspectDeclaringParents(DeclareParents p) {
  182. Set result = new HashSet();
  183. Set keys = this.members.keySet();
  184. for (Iterator iter = keys.iterator(); iter.hasNext();) {
  185. ResolvedTypeX element = (ResolvedTypeX) iter.next();
  186. for (Iterator i = ((CrosscuttingMembers)members.get(element)).getDeclareParents().iterator(); i.hasNext(); ) {
  187. DeclareParents dp = (DeclareParents)i.next();
  188. return element;
  189. }
  190. }
  191. return null;
  192. }
  193. }