1 4 package com.tc.aspectwerkz.definition; 5 6 7 import com.tc.aspectwerkz.DeploymentModel; 8 import com.tc.aspectwerkz.reflect.ClassInfo; 9 import com.tc.aspectwerkz.reflect.MethodInfo; 10 import com.tc.aspectwerkz.reflect.ClassInfoHelper; 11 import com.tc.aspectwerkz.aspect.AdviceType; 12 import com.tc.aspectwerkz.exception.DefinitionException; 13 import com.tc.aspectwerkz.expression.regexp.Pattern; 14 import com.tc.aspectwerkz.expression.ExpressionInfo; 15 import com.tc.aspectwerkz.expression.ExpressionNamespace; 16 import com.tc.aspectwerkz.transform.TransformationConstants; 17 import com.tc.aspectwerkz.util.Strings; 18 19 import java.util.Iterator ; 20 import java.util.Collection ; 21 import java.util.List ; 22 23 29 public class DefinitionParserHelper { 30 public static final String EXPRESSION_PREFIX = "AW_"; 31 32 39 public static void createAndAddPointcutDefToAspectDef(final String name, 40 final String expression, 41 final AspectDefinition aspectDef) { 42 PointcutDefinition pointcutDef = new PointcutDefinition(expression); 43 aspectDef.addPointcutDefinition(pointcutDef); 44 45 String pointcutName = name; 50 String pointcutCallSignature = null; 51 if (name.indexOf("(") > 0) { 52 pointcutName = name.substring(0, name.indexOf("(")); 53 pointcutCallSignature = name.substring(name.indexOf("(") + 1, name.lastIndexOf(")")); 54 } 55 56 ExpressionNamespace namespace = ExpressionNamespace.getNamespace(aspectDef.getQualifiedName()); 60 ExpressionInfo info = namespace.getExpressionInfoOrNull(pointcutName); 61 if (info == null) { 62 info = new ExpressionInfo(expression, aspectDef.getQualifiedName()); 63 if (pointcutCallSignature != null) { 65 String [] parameters = Strings.splitString(pointcutCallSignature, ","); 66 for (int i = 0; i < parameters.length; i++) { 67 String [] parameterInfo = Strings.splitString( 68 Strings.replaceSubString(parameters[i].trim(), " ", " "), 69 " " 70 ); 71 info.addArgument(parameterInfo[1], parameterInfo[0], aspectDef.getClassInfo().getClassLoader()); 72 } 73 } 74 } 75 ExpressionNamespace.getNamespace(aspectDef.getQualifiedName()).addExpressionInfo(pointcutName, info); 76 } 77 78 85 public static void createAndAddDeploymentScopeDef(final String name, final String expression, 87 final SystemDefinition systemDef) { 88 AspectDefinition aspectDef = systemDef.getAspectDefinition(Virtual.class.getName()); 89 aspectDef.addPointcutDefinition(new PointcutDefinition(expression)); 90 systemDef.addDeploymentScope(new DeploymentScope(name, expression)); 91 } 92 93 99 public static void createAndAddAdvisableDef(final String expression, final SystemDefinition systemDef) { 100 AspectDefinition virtualAspectDef = systemDef.getAspectDefinition(Virtual.class.getName()); 101 virtualAspectDef.addPointcutDefinition(new PointcutDefinition(expression)); 102 103 AdviceDefinition virtualAdviceDef = (AdviceDefinition) virtualAspectDef.getBeforeAdviceDefinitions().get(0); 104 ExpressionInfo oldExpressionInfo = virtualAdviceDef.getExpressionInfo(); 105 String newExpression; 106 if (oldExpressionInfo != null) { 107 String oldExpression = oldExpressionInfo.toString(); 108 newExpression = oldExpression + " || " + expression; 109 } else { 110 newExpression = expression; 111 } 112 113 virtualAdviceDef.setExpressionInfo( 114 new ExpressionInfo( 115 newExpression, 116 virtualAspectDef.getQualifiedName() 117 ) 118 ); 119 } 120 121 126 public static void attachDeploymentScopeDefsToVirtualAdvice(final SystemDefinition systemDef) { 127 final AspectDefinition virtualAspectDef = systemDef.getAspectDefinition(Virtual.class.getName()); 128 final AdviceDefinition virtualAdviceDef = (AdviceDefinition) virtualAspectDef.getBeforeAdviceDefinitions().get( 129 0 130 ); 131 132 final StringBuffer newExpression = new StringBuffer (); 133 final ExpressionInfo oldExpressionInfo = virtualAdviceDef.getExpressionInfo(); 134 if (oldExpressionInfo != null) { 135 String oldExpression = oldExpressionInfo.toString(); 136 newExpression.append(oldExpression); 137 } 138 final Collection deploymentScopes = systemDef.getDeploymentScopes(); 139 if (deploymentScopes.size() != 0 && oldExpressionInfo != null) { 140 newExpression.append(" || "); 141 } 142 for (Iterator it = deploymentScopes.iterator(); it.hasNext();) { 143 DeploymentScope deploymentScope = (DeploymentScope) it.next(); 144 newExpression.append(deploymentScope.getExpression()); 145 if (it.hasNext()) { 146 newExpression.append(" || "); 147 } 148 } 149 if (newExpression.length() != 0) { 150 virtualAdviceDef.setExpressionInfo( 151 new ExpressionInfo( 152 newExpression.toString(), 153 virtualAspectDef.getQualifiedName() 154 ) 155 ); 156 } 157 } 158 159 169 public static MixinDefinition createAndAddMixinDefToSystemDef(final ClassInfo mixinClassInfo, 170 final String expression, 171 final DeploymentModel deploymentModel, 172 final boolean isTransient, 173 final SystemDefinition systemDef) { 174 final MixinDefinition mixinDef = createMixinDefinition( 175 mixinClassInfo, 176 expression, 177 deploymentModel, 178 isTransient, 179 systemDef 180 ); 181 182 MixinDefinition doublon = null; 184 for (Iterator intros = systemDef.getMixinDefinitions().iterator(); intros.hasNext();) { 185 MixinDefinition intro = (MixinDefinition) intros.next(); 186 if (intro.getMixinImpl().getName().equals(mixinDef.getMixinImpl().getName())) { 187 doublon = intro; 188 intro.addExpressionInfos(mixinDef.getExpressionInfos()); 189 break; 190 } 191 } 192 if (doublon == null) { 193 systemDef.addMixinDefinition(mixinDef); 194 } 195 return mixinDef; 196 } 197 198 206 public static void createAndAddInterfaceIntroductionDefToAspectDef(final String expression, 207 final String introductionName, 208 final String interfaceClassName, 209 final AspectDefinition aspectDef) { 210 InterfaceIntroductionDefinition introDef = createInterfaceIntroductionDefinition( 212 introductionName, 213 expression, 214 interfaceClassName, 215 aspectDef 216 ); 217 aspectDef.addInterfaceIntroductionDefinition(introDef); 218 } 219 220 233 public static AdviceDefinition createAdviceDefinition(final String adviceName, 234 final AdviceType adviceType, 235 final String expression, 236 final String specialArgumentType, 237 final String aspectName, 238 final String aspectClassName, 239 final MethodInfo methodInfo, 240 final AspectDefinition aspectDef) { 241 ExpressionInfo expressionInfo = new ExpressionInfo( 242 expression, 243 aspectDef.getQualifiedName() 244 ); 245 246 String adviceCallSignature = null; 248 String resolvedSpecialArgumentType = specialArgumentType; 249 if (adviceName.indexOf('(') > 0) { 250 adviceCallSignature = adviceName.substring(adviceName.indexOf('(') + 1, adviceName.lastIndexOf(')')); 251 String [] parameters = Strings.splitString(adviceCallSignature, ","); 252 for (int i = 0; i < parameters.length; i++) { 253 String [] parameterInfo = Strings.splitString( 254 Strings.replaceSubString(parameters[i].trim(), " ", " "), 255 " " 256 ); 257 String paramName, paramType = null; 261 if (parameterInfo.length == 2) { 262 paramName = parameterInfo[1]; 263 paramType = parameterInfo[0]; 264 } else { 265 paramName = "anonymous_" + i; 266 paramType = (String ) Pattern.ABBREVIATIONS.get(parameterInfo[0]); 267 } 268 if (paramName.equals(specialArgumentType)) { 270 resolvedSpecialArgumentType = paramType; 271 expressionInfo.setSpecialArgumentName(paramName); 272 } else { 273 expressionInfo.addArgument(paramName, paramType, aspectDef.getClassInfo().getClassLoader()); 274 } 275 } 276 } 277 278 if (adviceType.equals(AdviceType.AROUND)) { 280 if (!"java.lang.Object".equals(methodInfo.getReturnType().getName())) { 281 throw new DefinitionException( 282 "around advice must return java.lang.Object : " + aspectClassName + "." + methodInfo.getName() 283 ); 284 } 285 } 286 287 final AdviceDefinition adviceDef = new AdviceDefinition( 288 adviceName, 289 adviceType, 290 resolvedSpecialArgumentType, 291 aspectName, 292 aspectClassName, 293 expressionInfo, 294 methodInfo, 295 aspectDef 296 ); 297 return adviceDef; 298 } 299 300 310 public static MixinDefinition createMixinDefinition(final ClassInfo mixinClassInfo, 311 final String expression, 312 final DeploymentModel deploymentModel, 313 final boolean isTransient, 314 final SystemDefinition systemDef) { 315 final MixinDefinition mixinDef = new MixinDefinition(mixinClassInfo, deploymentModel, isTransient, systemDef); 316 if (expression != null) { 317 ExpressionInfo expressionInfo = new ExpressionInfo(expression, systemDef.getUuid()); 318 319 ExpressionNamespace.getNamespace(systemDef.getUuid()).addExpressionInfo( 321 EXPRESSION_PREFIX + expression.hashCode(), 322 expressionInfo 323 ); 324 mixinDef.addExpressionInfo(expressionInfo); 325 } 326 return mixinDef; 327 } 328 329 338 public static InterfaceIntroductionDefinition createInterfaceIntroductionDefinition(final String introductionName, 339 final String expression, 340 final String interfaceClassName, 341 final AspectDefinition aspectDef) { 342 final InterfaceIntroductionDefinition introDef = new InterfaceIntroductionDefinition( 343 introductionName, interfaceClassName 344 ); 345 if (expression != null) { 346 ExpressionInfo expressionInfo = new ExpressionInfo(expression, aspectDef.getQualifiedName()); 347 348 ExpressionNamespace.getNamespace(aspectDef.getQualifiedName()).addExpressionInfo( 350 EXPRESSION_PREFIX + expression.hashCode(), 351 expressionInfo 352 ); 353 introDef.addExpressionInfo(expressionInfo); 354 } 355 return introDef; 356 } 357 358 367 public static void createAndAddAdviceDefsToAspectDef(final String type, 368 final String bindTo, 369 final String name, 370 final MethodInfo method, 371 final AspectDefinition aspectDef) { 372 try { 373 if (type.equalsIgnoreCase("around")) { 374 final String aspectName = aspectDef.getName(); 375 AdviceDefinition adviceDef = createAdviceDefinition( 376 name, 377 AdviceType.AROUND, 378 bindTo, 379 null, 380 aspectName, 381 aspectDef.getClassName(), 382 method, 383 aspectDef 384 ); 385 aspectDef.addAroundAdviceDefinition(adviceDef); 386 387 } else if (type.equalsIgnoreCase("before")) { 388 final String aspectName = aspectDef.getName(); 389 AdviceDefinition adviceDef = createAdviceDefinition( 390 name, 391 AdviceType.BEFORE, 392 bindTo, 393 null, 394 aspectName, 395 aspectDef.getClassName(), 396 method, 397 aspectDef 398 ); 399 aspectDef.addBeforeAdviceDefinition(adviceDef); 400 401 } else if (type.startsWith("after")) { 402 String specialArgumentType = null; 403 AdviceType adviceType = AdviceType.AFTER; 404 if (type.startsWith("after returning(")) { 405 adviceType = AdviceType.AFTER_RETURNING; 406 int start = type.indexOf('('); 407 int end = type.indexOf(')'); 408 specialArgumentType = type.substring(start + 1, end).trim(); 409 } else if (type.startsWith("after throwing(")) { 410 adviceType = AdviceType.AFTER_THROWING; 411 int start = type.indexOf('('); 412 int end = type.indexOf(')'); 413 specialArgumentType = type.substring(start + 1, end).trim(); 414 } else if (type.startsWith("after returning")) { 415 adviceType = AdviceType.AFTER_RETURNING; 416 } else if (type.startsWith("after throwing")) { 417 adviceType = AdviceType.AFTER_THROWING; 418 } else if (type.startsWith("after")) { 419 adviceType = AdviceType.AFTER_FINALLY; 420 } else if (type.startsWith("after finally")) { 421 adviceType = AdviceType.AFTER_FINALLY; 422 } 423 if (specialArgumentType != null && specialArgumentType.indexOf(' ') > 0) { 424 throw new DefinitionException( 425 "argument to after (returning/throwing) can only be a type (parameter name binding should be done using args(..))" 426 ); 427 } 428 final String aspectName = aspectDef.getName(); 429 AdviceDefinition adviceDef = createAdviceDefinition( 430 name, 431 adviceType, 432 bindTo, 433 specialArgumentType, 434 aspectName, 435 aspectDef.getClassName(), 436 method, 437 aspectDef 438 ); 439 440 aspectDef.addAfterAdviceDefinition(adviceDef); 441 } else { 442 throw new DefinitionException("Unkonw type for advice : " + type); 443 } 444 } catch (DefinitionException e) { 445 System.err.println( 446 "WARNING: unable to register advice " + aspectDef.getName() + "." + name + 447 " at pointcut [" + bindTo + "] due to: " + e.getMessage() 448 ); 449 } 451 } 452 453 public static MethodInfo createMethodInfoForAdviceFQN(final String name, 454 final AspectDefinition aspectDef, 455 final ClassInfo aspectClassInfo) { 456 List adviceMethodList = ClassInfoHelper.createMethodList(aspectClassInfo); 457 MethodInfo method = null; 458 for (Iterator it3 = adviceMethodList.iterator(); it3.hasNext();) { 459 MethodInfo methodCurrent = (MethodInfo) it3.next(); 460 if (aspectDef.isAspectWerkzAspect()) { 461 if (matchMethodAsAdvice(methodCurrent, name)) { 462 method = methodCurrent; 463 break; 464 } 465 } else { 466 if (methodCurrent.getName().equals(name)) { 473 method = methodCurrent; 474 break; 475 } 476 } 477 } 478 if (method == null) { 479 throw new DefinitionException( 480 "could not find advice method [" + name + "] in [" + aspectClassInfo.getName() + 481 "] (are you using a compiler extension that you have not registered?)" + 482 " (are you using XML defined advice, with StaticJoinPoint bindings without specifying the full" + 483 "source like signature?)" 484 ); 485 } 486 return method; 487 } 488 489 499 private static boolean matchMethodAsAdvice(MethodInfo method, String adviceSignature) { 500 String [] signatureElements = Strings.extractMethodSignature(adviceSignature); 503 504 if (!method.getName().equals(signatureElements[0])) { 506 return false; 507 } 508 if (method.getParameterTypes().length * 2 != signatureElements.length - 1) { 510 if (signatureElements.length == 1 && 513 method.getParameterTypes().length == 1 && 514 (method.getParameterTypes()[0].getName().equals(TransformationConstants.JOIN_POINT_JAVA_CLASS_NAME) 515 || method.getParameterTypes()[0].getName().equals(TransformationConstants.STATIC_JOIN_POINT_JAVA_CLASS_NAME))) 516 { 517 return true; 518 } else { 519 return false; 520 } 521 } 522 int argIndex = 0; 523 for (int i = 1; i < signatureElements.length; i++) { 524 String paramType = signatureElements[i++]; 525 String methodParamType = method.getParameterTypes()[argIndex++].getName(); 526 String paramTypeResolved = (String ) Pattern.ABBREVIATIONS.get(paramType); 528 if (methodParamType.equals(paramType) || methodParamType.equals(paramTypeResolved)) { 529 continue; 530 } else { 531 return false; 532 } 533 } 534 return true; 535 } 536 } | Popular Tags |