1 4 package com.tc.aspectwerkz.expression; 5 6 7 import com.tc.aspectwerkz.cflow.CflowAspectExpressionVisitor; 8 import com.tc.aspectwerkz.exception.DefinitionException; 9 import com.tc.aspectwerkz.exception.WrappedRuntimeException; 10 import com.tc.aspectwerkz.expression.ast.ExpressionParser; 11 import com.tc.aspectwerkz.expression.ast.Node; 12 import com.tc.aspectwerkz.expression.regexp.Pattern; 13 import com.tc.aspectwerkz.joinpoint.JoinPoint; 14 import com.tc.aspectwerkz.joinpoint.StaticJoinPoint; 15 import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo; 16 import com.tc.aspectwerkz.reflect.ClassInfoHelper; 17 import com.tc.aspectwerkz.reflect.ClassInfo; 18 import com.tc.aspectwerkz.util.SequencedHashMap; 19 20 import java.util.Map ; 21 import java.util.Set ; 22 import java.util.List ; 23 import java.util.ArrayList ; 24 25 35 public class ExpressionInfo { 36 37 public final static String JOINPOINT_CLASS_NAME = JoinPoint.class.getName(); 38 public final static String STATIC_JOINPOINT_CLASS_NAME = StaticJoinPoint.class.getName(); 39 public final static String JOINPOINT_ABBREVIATION = "JoinPoint"; 40 public final static String STATIC_JOINPOINT_ABBREVIATION = "StaticJoinPoint"; 41 public final static String RTTI_ABBREVIATION = "Rtti"; 42 43 46 private static final ExpressionParser s_parser = new ExpressionParser(System.in); 47 48 private final ExpressionVisitor m_expression; 49 50 private final AdvisedClassFilterExpressionVisitor m_advisedClassFilterExpression; 51 52 private final CflowAspectExpressionVisitor m_cflowAspectExpression; 53 54 57 private Map m_argsTypeByName = new SequencedHashMap(); 58 59 68 private List m_possibleArguments = null; 69 70 73 private String m_specialArgumentName = null; 74 75 81 public ExpressionInfo(final String expression, final String namespace) { 82 try { 83 Node root; 84 synchronized (s_parser) { 85 root = s_parser.parse(expression); 86 } 87 m_expression = new ExpressionVisitor(this, expression, namespace, root); 88 m_advisedClassFilterExpression = 89 new AdvisedClassFilterExpressionVisitor(this, expression, namespace, root); 90 m_cflowAspectExpression = new CflowAspectExpressionVisitor(this, root, namespace); 91 } catch (Throwable e) { 92 throw new DefinitionException("expression is not well-formed [" + expression + "]: " + e.getMessage(), e); 93 } 94 } 95 96 106 public ExpressionInfo(final Node subExpression, final String namespace) { 107 try { 108 m_expression = new ExpressionVisitor(this, "N/A", namespace, subExpression); 109 m_advisedClassFilterExpression = 110 new AdvisedClassFilterExpressionVisitor(this, "N/A", namespace, subExpression); 111 m_cflowAspectExpression = new CflowAspectExpressionVisitor(this, subExpression, namespace); 112 } catch (Throwable e) { 113 throw new DefinitionException("sub expression is not well-formed from [" + subExpression + "]: " + e.getMessage(), e); 114 } 115 } 116 117 122 public ExpressionVisitor getExpression() { 123 return m_expression; 124 } 125 126 131 public String getNamespace() { 132 return m_expression.m_namespace; 133 } 134 135 140 public CflowAspectExpressionVisitor getCflowAspectExpression() { 141 return m_cflowAspectExpression; 142 } 143 144 149 public AdvisedClassFilterExpressionVisitor getAdvisedClassFilterExpression() { 150 return m_advisedClassFilterExpression; 151 } 152 153 158 public String toString() { 159 return m_expression.toString(); 160 } 161 162 171 public void addArgument(final String name, final String className, final ClassLoader loader) { 172 String expression = toString(); 175 if (expression.indexOf('(') > 0) { 177 if (!isJoinPointOrRtti(className, loader)) { 179 if (toString().indexOf(name) < 0) { 180 throw new DefinitionException( 181 "pointcut expression is missing a parameter that has been encountered in the advice: '" 182 + toString() + "' - '" + name + "' of type '" + className + 183 "' missing in '" + 184 getExpression().m_namespace + 185 "'" 186 ); 187 } else { 188 if (m_possibleArguments == null) { 190 m_possibleArguments = new ArrayList (); 191 new ExpressionValidateVisitor(toString(), getNamespace(), getExpression().m_root) 192 .populate(m_possibleArguments); 193 } 194 if (!m_possibleArguments.contains(name)) { 195 throw new DefinitionException( 196 "pointcut expression is missing a parameter that has been encountered in the advice: '" 197 + toString() + "' - '" + name + "' of type '" + 198 className + 199 "' missing in '" + 200 getExpression().m_namespace + 201 "'" 202 ); 203 } 204 } 205 } 206 } 207 m_argsTypeByName.put(name, className); 208 } 209 210 215 public void setSpecialArgumentName(String specialArgumentName) { 216 m_specialArgumentName = specialArgumentName; 217 } 218 219 224 public String getSpecialArgumentName() { 225 return m_specialArgumentName; 226 } 227 228 234 public String getArgumentType(final String parameterName) { 235 return (String ) m_argsTypeByName.get(parameterName); 236 } 237 238 244 public int getArgumentIndex(final String parameterName) { 245 if (m_argsTypeByName.containsKey(parameterName)) { 246 return ((SequencedHashMap) m_argsTypeByName).indexOf(parameterName); 247 } else { 248 return -1; 249 } 250 } 251 252 258 public String getArgumentNameAtIndex(final int index) { 259 if (index >= m_argsTypeByName.size()) { 260 throw new ArrayIndexOutOfBoundsException ( 261 "cannot getDefault argument at index " + 262 index + " in " + m_expression.toString() 263 ); 264 } 265 return (String ) m_argsTypeByName.keySet().toArray()[index]; 266 } 267 268 273 public Set getArgumentNames() { 274 return m_argsTypeByName.keySet(); 275 } 276 277 286 private boolean isJoinPointOrRtti(String className, final ClassLoader loader) { 287 if (JOINPOINT_CLASS_NAME.equals(className) 288 || STATIC_JOINPOINT_CLASS_NAME.equals(className) 289 || JOINPOINT_ABBREVIATION.equals(className) 290 || STATIC_JOINPOINT_ABBREVIATION.equals(className) 291 || RTTI_ABBREVIATION.equals(className)) { 292 return true; 293 } 294 if (className.equals("int") || 295 className.equals("long") || 296 className.equals("short") || 297 className.equals("float") || 298 className.equals("double") || 299 className.equals("boolean") || 300 className.equals("byte") || 301 className.equals("char") || 302 className.endsWith("]") || 303 className.startsWith("java.")) { 304 return false; 305 } 306 try { 307 String fullClassName = (String ) Pattern.ABBREVIATIONS.get(className); 308 if (fullClassName != null) { 309 className = fullClassName; 310 } 311 if (className.startsWith("java.")) { 312 return false; 313 } 314 ClassInfo classInfo = AsmClassInfo.getClassInfo(className, loader); 315 if (ClassInfoHelper.implementsInterface(classInfo, JOINPOINT_CLASS_NAME) || 316 ClassInfoHelper.implementsInterface(classInfo, STATIC_JOINPOINT_CLASS_NAME)) { 317 return true; 318 } 319 } catch (Throwable e) { 320 throw new WrappedRuntimeException(e); 321 } 322 return false; 323 } 324 325 public void inheritPossibleArgumentFrom(ExpressionInfo expressionInfo) { 326 m_specialArgumentName = expressionInfo.m_specialArgumentName; 327 m_possibleArguments = expressionInfo.m_possibleArguments; 328 m_argsTypeByName = expressionInfo.m_argsTypeByName; 329 } 330 331 public static ExpressionParser getParser() { 332 return s_parser; 333 } 334 335 public String getExpressionString() { 336 return m_expression.toString(); 337 } 338 } 339 340 | Popular Tags |