View Javadoc

1   /***************************************************************************************
2    * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package org.codehaus.aspectwerkz.aspect.management;
9   
10  import org.codehaus.aspectwerkz.DeploymentModel;
11  import org.codehaus.aspectwerkz.expression.ExpressionContext;
12  
13  import java.util.ArrayList;
14  import java.util.Arrays;
15  import java.util.Iterator;
16  import java.util.List;
17  
18  /***
19   * Manages pointcuts and introductions defined by a specfic aspect.
20   * 
21   * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
22   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
23   */
24  public class PointcutManager {
25      /***
26       * Holds references to all the pointcuts.
27       */
28      protected final List m_pointcuts = new ArrayList();
29  
30      /***
31       * Holds references to all the pointcuts that has a cflow pointcut.
32       */
33      protected final List m_cflowPointcuts = new ArrayList();
34  
35      /***
36       * Holds references to all the the introductions.
37       */
38      protected String[] m_introductions = new String[0];
39  
40      /***
41       * The name of the aspect.
42       */
43      protected final String m_name;
44  
45      /***
46       * The deployment model for the aspect.
47       */
48      protected final int m_deploymentModel;
49  
50      /***
51       * Creates a new aspect.
52       * 
53       * @param name the name of the aspect
54       */
55      public PointcutManager(final String name) {
56          this(name, DeploymentModel.PER_JVM);
57      }
58  
59      /***
60       * Creates a new aspect.
61       * 
62       * @param name the name of the aspect
63       * @param deploymentModel the deployment model for the aspect
64       */
65      public PointcutManager(final String name, final int deploymentModel) {
66          if (name == null) {
67              throw new IllegalArgumentException("name can not be null");
68          }
69          if (deploymentModel < 0) {
70              throw new IllegalArgumentException(deploymentModel + " is not a valid deployement model type");
71          }
72          m_name = name;
73          m_deploymentModel = deploymentModel;
74      }
75  
76      /***
77       * Returns the name of the aspect.
78       * 
79       * @return the aspect name
80       */
81      public String getName() {
82          return m_name;
83      }
84  
85      /***
86       * Returns the deployment model for the aspect.
87       * 
88       * @return the deployment model
89       */
90      public int getDeploymentModel() {
91          return m_deploymentModel;
92      }
93  
94      /***
95       * Returns the deployment model for the aspect.
96       * 
97       * @return the deployment model
98       */
99      public String getDeploymentModelAsString() {
100         return DeploymentModel.getDeploymentModelAsString(m_deploymentModel);
101     }
102 
103     /***
104      * Adds an introduction to the open class.
105      * 
106      * @param introduction the name of the introduction to add
107      */
108     public final void addIntroduction(final String introduction) {
109         synchronized (m_introductions) {
110             final String[] tmp = new String[m_introductions.length + 1];
111             java.lang.System.arraycopy(m_introductions, 0, tmp, 0, m_introductions.length);
112             tmp[m_introductions.length] = introduction;
113             m_introductions = new String[m_introductions.length + 1];
114             java.lang.System.arraycopy(tmp, 0, m_introductions, 0, tmp.length);
115         }
116     }
117 
118     /***
119      * Adds an array with introductions to the open class. <br/>
120      * 
121      * @param introductions the introductions to add
122      */
123     public final void addIntroductions(final String[] introductions) {
124         synchronized (m_introductions) {
125             final String[] clone = new String[introductions.length];
126             java.lang.System.arraycopy(introductions, 0, clone, 0, introductions.length);
127             final String[] tmp = new String[m_introductions.length + introductions.length];
128             int i;
129             for (i = 0; i < m_introductions.length; i++) {
130                 tmp[i] = m_introductions[i];
131             }
132             for (int j = 0; j < clone.length; i++, j++) {
133                 tmp[i] = clone[j];
134             }
135             m_introductions = new String[tmp.length];
136             java.lang.System.arraycopy(tmp, 0, m_introductions, 0, tmp.length);
137         }
138     }
139 
140     /***
141      * Adds a new pointcut.
142      * 
143      * @param pointcut the pointcut to add
144      */
145     public void addPointcut(final Pointcut pointcut) {
146         synchronized (m_pointcuts) {
147             synchronized (m_cflowPointcuts) {
148                 m_pointcuts.add(pointcut);
149                 if (pointcut.getExpressionInfo().hasCflowPointcut()) {
150                     m_cflowPointcuts.add(new Pointcut(pointcut.getAspectManager(), pointcut.getExpressionInfo()));
151                 }
152             }
153         }
154     }
155 
156     /***
157      * Returns the introductions for the open class.
158      * 
159      * @return an array with the introductions for the class
160      */
161     public String[] getIntroductions() {
162         return m_introductions;
163     }
164 
165     /***
166      * Returns the pointcut for a specific expression.
167      * 
168      * @param expression the expression
169      * @return the pointcut, or null
170      */
171     public Pointcut getPointcut(final String expression) {
172         for (Iterator it = m_pointcuts.iterator(); it.hasNext();) {
173             Pointcut pointcut = (Pointcut) it.next();
174             if (pointcut.getExpressionInfo().getExpressionAsString().equals(expression)) {
175                 return pointcut;
176             }
177         }
178         return null;
179     }
180 
181     /***
182      * Returns the cflow pointcut for a specific expression.
183      * 
184      * @param expression the expression
185      * @return the pointcut, or null
186      */
187     public Pointcut getCflowPointcut(final String expression) {
188         for (Iterator it = m_cflowPointcuts.iterator(); it.hasNext();) {
189             Pointcut pointcut = (Pointcut) it.next();
190             if (pointcut.getExpressionInfo().getExpressionAsString().equals(expression)) {
191                 return pointcut;
192             }
193         }
194         return null;
195     }
196 
197     /***
198      * Returns all the pointcuts defined by a specific aspect.
199      * 
200      * @return the pointcuts
201      */
202     public List getPointcuts() {
203         return m_pointcuts;
204     }
205 
206     /***
207      * Returns all the pointcuts defined by a specific aspect that has a cflow pointcut referenced.
208      * 
209      * @return the pointcuts
210      */
211     public List getCflowPointcuts() {
212         return m_cflowPointcuts;
213     }
214 
215     /***
216      * Returns all the pointcuts for the join point specified.
217      * 
218      * @param ctx the expression context
219      * @return the pointcuts that parse
220      */
221     public List getPointcuts(final ExpressionContext ctx) {
222         if (ctx == null) {
223             throw new IllegalArgumentException("context can not be null");
224         }
225         List pointcutList = new ArrayList();
226         for (Iterator it = m_pointcuts.iterator(); it.hasNext();) {
227             Pointcut pointcut = (Pointcut) it.next();
228             if (pointcut.getExpressionInfo().getExpression().match(ctx)) {
229                 pointcutList.add(pointcut);
230             }
231         }
232         return pointcutList;
233     }
234 
235     /***
236      * Returns all the cflow pointcuts for the join point specified.
237      * 
238      * @param ctx the expression context
239      * @return the pointcuts that parse
240      */
241     public List getCflowPointcuts(final ExpressionContext ctx) {
242         if (ctx == null) {
243             throw new IllegalArgumentException("context can not be null");
244         }
245         List pointcutList = new ArrayList();
246         for (Iterator it = m_cflowPointcuts.iterator(); it.hasNext();) {
247             Pointcut pointcut = (Pointcut) it.next();
248             if (pointcut.getExpressionInfo().getCflowExpression().match(ctx)) {
249                 pointcutList.add(pointcut);
250             }
251         }
252         return pointcutList;
253     }
254 
255     public boolean equals(Object o) {
256         if (this == o) {
257             return true;
258         }
259         if (!(o instanceof PointcutManager)) {
260             return false;
261         }
262         final PointcutManager pointcutManager = (PointcutManager) o;
263         if (m_deploymentModel != pointcutManager.m_deploymentModel) {
264             return false;
265         }
266         if (!Arrays.equals(m_introductions, pointcutManager.m_introductions)) {
267             return false;
268         }
269         if (!m_name.equals(pointcutManager.m_name)) {
270             return false;
271         }
272         if (!m_pointcuts.equals(pointcutManager.m_pointcuts)) {
273             return false;
274         }
275         if (!m_cflowPointcuts.equals(pointcutManager.m_cflowPointcuts)) {
276             return false;
277         }
278         return true;
279     }
280 
281     public int hashCode() {
282         int result;
283         result = m_pointcuts.hashCode();
284         result = m_cflowPointcuts.hashCode();
285         result = (29 * result) + m_name.hashCode();
286         result = (29 * result) + m_deploymentModel;
287         return result;
288     }
289 }