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 }