1 8 package org.codehaus.aspectwerkz.expression; 9 10 import org.codehaus.aspectwerkz.exception.DefinitionException; 11 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException; 12 import org.codehaus.aspectwerkz.expression.ast.ASTRoot; 13 import org.codehaus.aspectwerkz.expression.ast.ExpressionParser; 14 import org.codehaus.aspectwerkz.expression.ast.SimpleNode; 15 import org.codehaus.aspectwerkz.expression.ast.Node; 16 import org.codehaus.aspectwerkz.expression.regexp.Pattern; 17 import org.codehaus.aspectwerkz.util.SequencedHashMap; 18 import org.codehaus.aspectwerkz.util.ContextClassLoader; 19 import org.codehaus.aspectwerkz.joinpoint.JoinPoint; 20 import org.codehaus.aspectwerkz.joinpoint.StaticJoinPoint; 21 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper; 22 import org.codehaus.aspectwerkz.reflect.ClassInfo; 23 import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo; 24 import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo; 25 import org.codehaus.aspectwerkz.cflow.CflowAspectExpressionVisitor; 26 27 import java.util.Map ; 28 import java.util.Set ; 29 import java.util.List ; 30 import java.util.ArrayList ; 31 32 42 public class ExpressionInfo { 43 44 public final static String JOINPOINT_CLASS_NAME = JoinPoint.class.getName(); 45 public final static String STATIC_JOINPOINT_CLASS_NAME = StaticJoinPoint.class.getName(); 46 public final static String JOINPOINT_ABBREVIATION = "JoinPoint"; 47 public final static String STATIC_JOINPOINT_ABBREVIATION = "StaticJoinPoint"; 48 public final static String RTTI_ABBREVIATION = "Rtti"; 49 50 53 private static final ExpressionParser s_parser = new ExpressionParser(System.in); 54 55 private final ExpressionVisitor m_expression; 56 57 private final AdvisedClassFilterExpressionVisitor m_advisedClassFilterExpression; 58 59 private final CflowAspectExpressionVisitor m_cflowAspectExpression; 60 61 64 private Map m_argsTypeByName = new SequencedHashMap(); 65 66 75 private List m_possibleArguments = null; 76 77 80 private String m_specialArgumentName = null; 81 82 88 public ExpressionInfo(final String expression, final String namespace) { 89 try { 90 Node root = s_parser.parse(expression); 91 m_expression = new ExpressionVisitor(this, expression, namespace, root); 92 m_advisedClassFilterExpression = 93 new AdvisedClassFilterExpressionVisitor(this, expression, namespace, root); 94 m_cflowAspectExpression = new CflowAspectExpressionVisitor(this, root, namespace); 95 } catch (Throwable e) { 96 throw new DefinitionException("expression is not well-formed [" + expression + "]: " + e.getMessage(), e); 97 } 98 } 99 100 110 public ExpressionInfo(final Node subExpression, final String namespace) { 111 try { 112 m_expression = new ExpressionVisitor(this, "N/A", namespace, subExpression); 113 m_advisedClassFilterExpression = 114 new AdvisedClassFilterExpressionVisitor(this, "N/A", namespace, subExpression); 115 m_cflowAspectExpression = new CflowAspectExpressionVisitor(this, subExpression, namespace); 116 } catch (Throwable e) { 117 throw new DefinitionException("sub expression is not well-formed from [" + subExpression+ "]: " + e.getMessage(), e); 118 } 119 } 120 121 126 public ExpressionVisitor getExpression() { 127 return m_expression; 128 } 129 130 135 public String getNamespace() { 136 return m_expression.m_namespace; 137 } 138 139 144 public CflowAspectExpressionVisitor getCflowAspectExpression() { 145 return m_cflowAspectExpression; 146 } 147 148 153 public AdvisedClassFilterExpressionVisitor getAdvisedClassFilterExpression() { 154 return m_advisedClassFilterExpression; 155 } 156 157 162 public static ExpressionParser getParser() { 163 return s_parser; 164 } 165 166 171 public String toString() { 172 return m_expression.toString(); 173 } 174 175 184 public void addArgument(final String name, final String className, final ClassLoader loader) { 185 String expression = toString(); 188 if (expression.indexOf('(') > 0) { 190 if (!isJoinPointOrRtti(className, loader)) { 192 if (toString().indexOf(name) < 0) { 193 throw new DefinitionException( 194 "pointcut expression is missing a parameter that has been encountered in the advice: '" 195 + toString() + "' - '" + name + "' of type '" + className + 196 "' missing in '" + 197 getExpression().m_namespace + 198 "'" 199 ); 200 } else { 201 if (m_possibleArguments == null) { 203 m_possibleArguments = new ArrayList (); 204 new ExpressionValidateVisitor(toString(), getNamespace(), getExpression().m_root) 205 .populate(m_possibleArguments); 206 } 207 if (!m_possibleArguments.contains(name)) { 208 throw new DefinitionException( 209 "pointcut expression is missing a parameter that has been encountered in the advice: '" 210 + toString() + "' - '" + name + "' of type '" + 211 className + 212 "' missing in '" + 213 getExpression().m_namespace + 214 "'" 215 ); 216 } 217 } 218 } 219 } 220 m_argsTypeByName.put(name, className); 221 } 222 223 228 public void setSpecialArgumentName(String specialArgumentName) { 229 m_specialArgumentName = specialArgumentName; 230 } 231 232 237 public String getSpecialArgumentName() { 238 return m_specialArgumentName; 239 } 240 241 247 public String getArgumentType(final String parameterName) { 248 return (String ) m_argsTypeByName.get(parameterName); 249 } 250 251 257 public int getArgumentIndex(final String parameterName) { 258 if (m_argsTypeByName.containsKey(parameterName)) { 259 return ((SequencedHashMap) m_argsTypeByName).indexOf(parameterName); 260 } else { 261 return -1; 262 } 263 } 264 265 271 public String getArgumentNameAtIndex(final int index) { 272 if (index >= m_argsTypeByName.size()) { 273 throw new ArrayIndexOutOfBoundsException ( 274 "cannot get argument at index " + 275 index + " in " + m_expression.toString() 276 ); 277 } 278 return (String ) m_argsTypeByName.keySet().toArray()[index]; 279 } 280 281 286 public Set getArgumentNames() { 287 return m_argsTypeByName.keySet(); 288 } 289 290 299 private boolean isJoinPointOrRtti(String className, final ClassLoader loader) { 300 if (JOINPOINT_CLASS_NAME.equals(className) 301 || STATIC_JOINPOINT_CLASS_NAME.equals(className) 302 || JOINPOINT_ABBREVIATION.equals(className) 303 || STATIC_JOINPOINT_ABBREVIATION.equals(className) 304 || RTTI_ABBREVIATION.equals(className)) { 305 return true; 306 } 307 if (className.equals("int") || 308 className.equals("long") || 309 className.equals("short") || 310 className.equals("float") || 311 className.equals("double") || 312 className.equals("boolean") || 313 className.equals("byte") || 314 className.equals("char") || 315 className.endsWith("]") || 316 className.startsWith("java.")) { 317 return false; 318 } 319 try { 320 String fullClassName = (String ) Pattern.ABBREVIATIONS.get(className); 321 if (fullClassName != null) { 322 className = fullClassName; 323 } 324 if (className.startsWith("java.")) { 325 return false; 326 } 327 ClassInfo classInfo = AsmClassInfo.getClassInfo(className, loader); 328 if (ClassInfoHelper.implementsInterface(classInfo, JOINPOINT_CLASS_NAME) || 329 ClassInfoHelper.implementsInterface(classInfo, STATIC_JOINPOINT_CLASS_NAME)) { 330 return true; 331 } 332 } catch (Throwable e) { 333 throw new WrappedRuntimeException(e); 334 } 335 return false; 336 } 337 338 public void inheritPossibleArgumentFrom(ExpressionInfo expressionInfo) { 339 m_specialArgumentName = expressionInfo.m_specialArgumentName; 340 m_possibleArguments = expressionInfo.m_possibleArguments; 341 m_argsTypeByName = expressionInfo.m_argsTypeByName; 342 } 343 } 344 345 | Popular Tags |