1 4 package com.tc.aspectwerkz.transform.inlining.deployer; 5 6 import java.util.Iterator ; 7 import java.util.HashSet ; 8 import java.util.Set ; 9 10 import com.tc.aspectwerkz.DeploymentModel; 11 import com.tc.aspectwerkz.expression.ExpressionInfo; 12 import com.tc.aspectwerkz.annotation.AspectAnnotationParser; 13 import com.tc.aspectwerkz.definition.AdviceDefinition; 14 import com.tc.aspectwerkz.definition.AspectDefinition; 15 import com.tc.aspectwerkz.definition.DeploymentScope; 16 import com.tc.aspectwerkz.definition.DocumentParser; 17 import com.tc.aspectwerkz.definition.SystemDefinition; 18 import com.tc.aspectwerkz.definition.SystemDefinitionContainer; 19 import com.tc.aspectwerkz.joinpoint.management.AdviceInfoContainer; 20 import com.tc.aspectwerkz.joinpoint.management.JoinPointManager; 21 import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo; 22 import com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo; 23 import com.tc.aspectwerkz.reflect.ClassInfo; 24 import com.tc.aspectwerkz.transform.inlining.AspectModelManager; 25 import com.tc.aspectwerkz.transform.inlining.compiler.CompilationInfo; 26 import com.tc.aspectwerkz.transform.inlining.compiler.CompilerHelper; 27 import com.tc.aspectwerkz.transform.inlining.compiler.MatchingJoinPointInfo; 28 29 36 public class Deployer { 37 38 50 public static DeploymentHandle deploy(final Class aspect) { 51 return deploy(aspect, DeploymentScope.MATCH_ALL); 52 } 53 54 66 public static DeploymentHandle deploy(final String aspectClassName) { 67 return deploy(aspectClassName, DeploymentScope.MATCH_ALL); 68 } 69 70 83 public static DeploymentHandle deploy(final Class aspect, final ClassLoader deployLoader) { 84 return deploy(aspect, DeploymentScope.MATCH_ALL, deployLoader); 85 } 86 87 100 public static DeploymentHandle deploy(final String aspectClassName, final ClassLoader deployLoader) { 101 return deploy(aspectClassName, DeploymentScope.MATCH_ALL, deployLoader); 102 } 103 104 113 public static DeploymentHandle deploy(final Class aspect, final DeploymentScope deploymentScope) { 114 return deploy(aspect, deploymentScope, Thread.currentThread().getContextClassLoader()); 115 } 116 117 126 public static DeploymentHandle deploy(final String aspectClassName, final DeploymentScope deploymentScope) { 127 return deploy(aspectClassName, deploymentScope, Thread.currentThread().getContextClassLoader()); 128 } 129 130 142 public static DeploymentHandle deploy(final Class aspect, 143 final DeploymentScope deploymentScope, 144 final ClassLoader deployLoader) { 145 if (aspect == null) { 146 throw new IllegalArgumentException ("aspect to deploy can not be null"); 147 } 148 if (deploymentScope == null) { 149 throw new IllegalArgumentException ("prepared pointcut can not be null"); 150 } 151 if (deployLoader == null) { 152 throw new IllegalArgumentException ("class loader to deploy aspect in can not be null"); 153 } 154 155 final String className = aspect.getName(); 156 return deploy(className, deploymentScope, deployLoader); 157 158 } 159 160 170 public synchronized static DeploymentHandle deploy(final String className, 171 final DeploymentScope deploymentScope, 172 final ClassLoader deployLoader) { 173 logDeployment(className, deployLoader); 174 175 Class aspectClass = null; 176 try { 177 aspectClass = Class.forName(className, false, deployLoader); 178 } catch (ClassNotFoundException e) { 179 throw new RuntimeException ( 180 "could not load class [" + className + "] in class loader [" + deployLoader + "]" 181 ); 182 } 183 184 final DeploymentHandle deploymentHandle = new DeploymentHandle(aspectClass, deployLoader); 185 186 final ClassInfo aspectClassInfo = JavaClassInfo.getClassInfo(aspectClass); 187 188 final SystemDefinition systemDef = SystemDefinitionContainer.getVirtualDefinitionFor(deployLoader); 190 final AspectDefinition newAspectDef = new AspectDefinition(className, aspectClassInfo, systemDef); 191 final Set newExpressions = getNewExpressionsForAspect( 192 aspectClass, newAspectDef, systemDef, deploymentScope, deploymentHandle 193 ); 194 195 redefine(newExpressions); 196 return deploymentHandle; 197 } 198 199 211 public static DeploymentHandle deploy(final Class aspect, final String xmlDef) { 212 return deploy(aspect, xmlDef, DeploymentScope.MATCH_ALL); 213 } 214 215 228 public static DeploymentHandle deploy(final Class aspect, 229 final String xmlDef, 230 final DeploymentScope deploymentScope) { 231 return deploy(aspect, xmlDef, deploymentScope, aspect.getClassLoader()); 232 } 233 234 247 public static DeploymentHandle deploy(final Class aspect, final String xmlDef, final ClassLoader deployLoader) { 248 return deploy(aspect, xmlDef, DeploymentScope.MATCH_ALL, deployLoader); 249 } 250 251 267 public synchronized static DeploymentHandle deploy(final Class aspect, 268 final String xmlDef, 269 final DeploymentScope deploymentScope, 270 final ClassLoader deployLoader) { 271 if (aspect == null) { 272 throw new IllegalArgumentException ("aspect to deploy can not be null"); 273 } 274 if (deploymentScope == null) { 275 throw new IllegalArgumentException ("prepared pointcut can not be null"); 276 } 277 if (xmlDef == null) { 278 throw new IllegalArgumentException ("xml definition can not be null"); 279 } 280 if (deployLoader == null) { 281 throw new IllegalArgumentException ("class loader to deploy aspect in can not be null"); 282 } 283 final String className = aspect.getName(); 284 logDeployment(className, deployLoader); 285 286 final DeploymentHandle deploymentHandle = new DeploymentHandle(aspect, deployLoader); 287 288 final SystemDefinition systemDef = SystemDefinitionContainer.getVirtualDefinitionFor(deployLoader); 289 290 final AspectDefinition newAspectDef = DocumentParser.parseAspectDefinition(xmlDef, systemDef, aspect); 291 systemDef.addAspect(newAspectDef); 292 final Set newExpressions = getNewExpressionsForAspect(aspect, newAspectDef, systemDef, deploymentScope, 293 deploymentHandle); 294 redefine(newExpressions); 295 return deploymentHandle; 296 } 297 298 303 public static void undeploy(final Class aspect) { 304 undeploy(aspect, aspect.getClassLoader()); 305 } 306 307 313 public static void undeploy(final Class aspect, final ClassLoader loader) { 314 if (aspect == null) { 315 throw new IllegalArgumentException ("aspect to undeploy can not be null"); 316 } 317 if (loader == null) { 318 throw new IllegalArgumentException ("loader to undeploy aspect from can not be null"); 319 } 320 undeploy(aspect.getName(), loader); 321 } 322 323 329 public static void undeploy(final String className, final ClassLoader loader) { 330 logUndeployment(className, loader); 331 332 334 Set systemDefs = SystemDefinitionContainer.getAllDefinitionsFor(loader); 337 338 for (Iterator it = systemDefs.iterator(); it.hasNext();) { 339 SystemDefinition systemDef = (SystemDefinition) it.next(); 340 final AspectDefinition aspectDef = systemDef.getAspectDefinition(className); 341 if (aspectDef != null) { 342 343 final Set newExpressions = new HashSet (); 344 for (Iterator it2 = aspectDef.getAdviceDefinitions().iterator(); it2.hasNext();) { 345 AdviceDefinition adviceDef = (AdviceDefinition) it2.next(); 346 ExpressionInfo oldExpression = adviceDef.getExpressionInfo(); 347 if (oldExpression == null) { continue; 349 } 350 adviceDef.setExpressionInfo(null); 351 newExpressions.add(oldExpression); 352 } 353 redefine(newExpressions); 354 } 355 } 356 } 357 358 364 public static void undeploy(final DeploymentHandle deploymentHandle) { 365 if (deploymentHandle == null) { 366 throw new IllegalArgumentException ("deployment handle can not be null"); 367 } 368 369 deploymentHandle.revertChanges(); 370 371 final Class aspectClass = deploymentHandle.getAspectClass(); 372 if (aspectClass == null) { 373 return; } 375 undeploy(aspectClass); 376 } 377 378 383 private static void redefine(final Set expressions) { 384 final Set allMatchingJoinPoints = new HashSet (); 385 for (Iterator itExpr = expressions.iterator(); itExpr.hasNext();) { 386 ExpressionInfo expression = (ExpressionInfo) itExpr.next(); 387 Set matchingJoinPoints = CompilerHelper.getJoinPointsMatching(expression); 388 allMatchingJoinPoints.addAll(matchingJoinPoints); 389 } 390 391 final ChangeSet changeSet = new ChangeSet(); 392 for (Iterator it = allMatchingJoinPoints.iterator(); it.hasNext();) { 393 final MatchingJoinPointInfo joinPointInfo = (MatchingJoinPointInfo) it.next(); 394 395 final CompilationInfo compilationInfo = joinPointInfo.getCompilationInfo(); 396 compilationInfo.incrementRedefinitionCounter(); 397 398 changeSet.addElement(new ChangeSet.Element(compilationInfo, joinPointInfo)); 399 } 400 401 doRedefine(changeSet); 402 } 403 404 409 private static void doRedefine(final ChangeSet changeSet) { 410 for (Iterator it = changeSet.getElements().iterator(); it.hasNext();) { 411 compileNewJoinPoint((ChangeSet.Element) it.next()); 412 } 413 redefineInitialJoinPoints(changeSet); 414 } 415 416 421 private static void compileNewJoinPoint(final ChangeSet.Element changeSetElement) { 422 final CompilationInfo compilationInfo = changeSetElement.getCompilationInfo(); 423 final MatchingJoinPointInfo joinPointInfo = changeSetElement.getJoinPointInfo(); 424 final ClassLoader loader = joinPointInfo.getJoinPointClass().getClassLoader(); 425 final AdviceInfoContainer newAdviceContainer = JoinPointManager.getAdviceInfoContainerForJoinPoint( 426 joinPointInfo.getExpressionContext(), loader, null 427 ); 428 final CompilationInfo.Model redefinedModel = new CompilationInfo.Model( 429 compilationInfo.getInitialModel().getEmittedJoinPoint(), newAdviceContainer, 431 compilationInfo.getRedefinitionCounter(), 432 compilationInfo.getInitialModel().getThisClassInfo() 433 ); 434 CompilerHelper.compileJoinPointAndAttachToClassLoader(redefinedModel, loader); 435 436 compilationInfo.setRedefinedModel(redefinedModel); 437 CompilerHelper.addCompilationInfo(joinPointInfo.getJoinPointClass(), compilationInfo); 438 } 439 440 446 private static void redefineInitialJoinPoints(final ChangeSet changeSet) { 447 RedefinerFactory.newRedefiner(RedefinerFactory.Type.HOTSWAP).redefine(changeSet); 449 } 450 451 461 private static Set getNewExpressionsForAspect(final Class aspectClass, 462 final AspectDefinition newAspectDef, 463 final SystemDefinition systemDef, 464 final DeploymentScope deploymentScope, 465 final DeploymentHandle deploymentHandle) { 466 final ClassLoader aspectLoader = aspectClass.getClassLoader(); 467 final String aspectName = aspectClass.getName(); 468 469 String keptContainerClassName = newAspectDef.getContainerClassName(); 471 DeploymentModel keptModel = newAspectDef.getDeploymentModel(); 472 473 final ClassInfo classInfo = AsmClassInfo.getClassInfo(aspectName, aspectLoader); 474 AspectModelManager.defineAspect(classInfo, newAspectDef, aspectLoader); 475 AspectAnnotationParser.parse(classInfo, newAspectDef, aspectLoader); 476 477 AspectDefinition aspectDef = systemDef.getAspectDefinition(aspectName); 478 if (aspectDef != null) { 479 newAspectDef.setContainerClassName(keptContainerClassName); newAspectDef.setDeploymentModel(keptModel); } 484 485 systemDef.addAspectOverwriteIfExists(newAspectDef); 486 487 final Set newExpressions = new HashSet (); 488 for (Iterator it2 = newAspectDef.getAdviceDefinitions().iterator(); it2.hasNext();) { 489 AdviceDefinition adviceDef = (AdviceDefinition) it2.next(); 490 ExpressionInfo oldExpression = adviceDef.getExpressionInfo(); 491 if (oldExpression == null) { 492 continue; 493 } 494 deploymentHandle.registerDefinitionChange(adviceDef, oldExpression); 495 496 final ExpressionInfo newExpression = deploymentScope.newExpressionInfo(oldExpression); 497 adviceDef.setExpressionInfo(newExpression); 498 newExpressions.add(newExpression); 499 } 500 return newExpressions; 501 } 502 503 509 552 560 private static void logUndeployment(final String className, final ClassLoader loader) { 561 System.out.println( 562 new StringBuffer ().append("Deployer::INFO - undeploying aspect ["). 563 append(className).append("] from class loader ["). 564 append(loader).append(']').toString() 565 ); 566 } 567 568 576 private static void logDeployment(final String className, final ClassLoader loader) { 577 System.out.println( 578 new StringBuffer ().append("Deployer::INFO - deploying aspect ["). 579 append(className).append("] in class loader ["). 580 append(loader).append(']').toString() 581 ); 582 } 583 } 584 | Popular Tags |