2929import  org .aopalliance .intercept .MethodInvocation ;
3030import  org .aspectj .lang .JoinPoint ;
3131import  org .aspectj .lang .ProceedingJoinPoint ;
32+ import  org .aspectj .runtime .internal .AroundClosure ;
3233import  org .aspectj .weaver .tools .JoinPointMatch ;
3334import  org .aspectj .weaver .tools .PointcutParameter ;
3435
5758 * @author Adrian Colyer 
5859 * @author Juergen Hoeller 
5960 * @author Ramnivas Laddad 
61+  * @author Joshua Chen 
6062 * @since 2.0 
6163 */ 
6264@ SuppressWarnings ("serial" )
@@ -145,6 +147,12 @@ public static JoinPoint currentJoinPoint() {
145147	 */ 
146148	private  int  joinPointStaticPartArgumentIndex  = -1 ;
147149
150+ 	/** 
151+ 	 * Index for around closure argument (currently only 
152+ 	 * supported at index 0 if present at all). 
153+ 	 */ 
154+ 	private  int  aroundClosureArgumentIndex  = -1 ;
155+ 
148156	@ Nullable 
149157	private  Map <String , Integer > argumentBindings ;
150158
@@ -271,7 +279,7 @@ public void setArgumentNamesFromStringArray(String... argumentNames) {
271279			if  (!isVariableName (this .argumentNames [i ])) {
272280				throw  new  IllegalArgumentException (
273281						"'argumentNames' property of AbstractAspectJAdvice contains an argument name '"  +
274- 						this .argumentNames [i ] + "' that is not a valid Java identifier" );
282+ 								 this .argumentNames [i ] + "' that is not a valid Java identifier" );
275283			}
276284		}
277285		if  (this .aspectJAdviceMethod .getParameterCount () == this .argumentNames .length  + 1 ) {
@@ -284,7 +292,7 @@ public void setArgumentNamesFromStringArray(String... argumentNames) {
284292					String [] oldNames  = this .argumentNames ;
285293					this .argumentNames  = new  String [oldNames .length  + 1 ];
286294					System .arraycopy (oldNames , 0 , this .argumentNames , 0 , i );
287- 					this .argumentNames [i ] = "THIS_JOIN_POINT " ;
295+ 					this .argumentNames [i ] = "thisJoinPoint " ;
288296					System .arraycopy (oldNames , i , this .argumentNames , i  + 1 , oldNames .length  - i );
289297					break ;
290298				}
@@ -383,9 +391,14 @@ public final void calculateArgumentBindings() {
383391
384392		int  numUnboundArgs  = this .parameterTypes .length ;
385393		Class <?>[] parameterTypes  = this .aspectJAdviceMethod .getParameterTypes ();
386- 		if  (maybeBindJoinPoint (parameterTypes [0 ]) || maybeBindProceedingJoinPoint (parameterTypes [0 ]) ||
387- 				maybeBindJoinPointStaticPart (parameterTypes [0 ])) {
388- 			numUnboundArgs --;
394+ 		for  (int  i  = 0 ; i  < parameterTypes .length ; i ++) {
395+ 			if  (maybeBindJoinPoint (parameterTypes [i ], i ) ||
396+ 					maybeBindProceedingJoinPoint (parameterTypes [i ], i ) ||
397+ 					maybeBindJoinPointStaticPart (parameterTypes [i ], i ) ||
398+ 					maybeBindAroundClosure (parameterTypes [i ], i )
399+ 			) {
400+ 				numUnboundArgs --;
401+ 			}
389402		}
390403
391404		if  (numUnboundArgs  > 0 ) {
@@ -396,22 +409,22 @@ public final void calculateArgumentBindings() {
396409		this .argumentsIntrospected  = true ;
397410	}
398411
399- 	private  boolean  maybeBindJoinPoint (Class <?> candidateParameterType ) {
412+ 	private  boolean  maybeBindJoinPoint (Class <?> candidateParameterType ,  int   index ) {
400413		if  (JoinPoint .class  == candidateParameterType ) {
401- 			this .joinPointArgumentIndex  = 0 ;
414+ 			this .joinPointArgumentIndex  = index ;
402415			return  true ;
403416		}
404417		else  {
405418			return  false ;
406419		}
407420	}
408421
409- 	private  boolean  maybeBindProceedingJoinPoint (Class <?> candidateParameterType ) {
422+ 	private  boolean  maybeBindProceedingJoinPoint (Class <?> candidateParameterType ,  int   index ) {
410423		if  (ProceedingJoinPoint .class  == candidateParameterType ) {
411424			if  (!supportsProceedingJoinPoint ()) {
412425				throw  new  IllegalArgumentException ("ProceedingJoinPoint is only supported for around advice" );
413426			}
414- 			this .joinPointArgumentIndex  = 0 ;
427+ 			this .joinPointArgumentIndex  = index ;
415428			return  true ;
416429		}
417430		else  {
@@ -423,9 +436,19 @@ protected boolean supportsProceedingJoinPoint() {
423436		return  false ;
424437	}
425438
426- 	private  boolean  maybeBindJoinPointStaticPart (Class <?> candidateParameterType ) {
439+ 	private  boolean  maybeBindJoinPointStaticPart (Class <?> candidateParameterType ,  int   index ) {
427440		if  (JoinPoint .StaticPart .class  == candidateParameterType ) {
428- 			this .joinPointStaticPartArgumentIndex  = 0 ;
441+ 			this .joinPointStaticPartArgumentIndex  = index ;
442+ 			return  true ;
443+ 		}
444+ 		else  {
445+ 			return  false ;
446+ 		}
447+ 	}
448+ 
449+ 	private  boolean  maybeBindAroundClosure (Class <?> candidateParameterType , int  index ) {
450+ 		if  (AroundClosure .class  == candidateParameterType ) {
451+ 			this .aroundClosureArgumentIndex  = index ;
429452			return  true ;
430453		}
431454		else  {
@@ -480,7 +503,22 @@ private void bindExplicitArguments(int numArgumentsLeftToBind) {
480503
481504		// So we match in number... 
482505		int  argumentIndexOffset  = this .parameterTypes .length  - numArgumentsLeftToBind ;
483- 		for  (int  i  = argumentIndexOffset ; i  < this .argumentNames .length ; i ++) {
506+ 		if  (this .joinPointStaticPartArgumentIndex  > -1 ) {
507+ 			argumentIndexOffset --;
508+ 		}
509+ 		if  (this .joinPointArgumentIndex  > -1 ) {
510+ 			argumentIndexOffset --;
511+ 		}
512+ 		if  (this .aroundClosureArgumentIndex  > -1 ) {
513+ 			argumentIndexOffset --;
514+ 		}
515+ 		for  (int  i  = 0 ; i  < this .argumentNames .length ; i ++) {
516+ 			if  (this .joinPointStaticPartArgumentIndex  > -1  && i  == this .joinPointStaticPartArgumentIndex ) {
517+ 				continue ;
518+ 			}
519+ 			if  (this .joinPointArgumentIndex  > -1  && i  == this .joinPointArgumentIndex ) {
520+ 				continue ;
521+ 			}
484522			this .argumentBindings .put (this .argumentNames [i ], i );
485523		}
486524
@@ -525,17 +563,34 @@ private void configurePointcutParameters(String[] argumentNames, int argumentInd
525563		if  (this .throwingName  != null ) {
526564			numParametersToRemove ++;
527565		}
566+ 		if  (this .joinPointStaticPartArgumentIndex  > -1 ) {
567+ 			numParametersToRemove ++;
568+ 		}
569+ 		if  (this .joinPointArgumentIndex  > -1 ) {
570+ 			numParametersToRemove ++;
571+ 		}
572+ 		if  (this .aroundClosureArgumentIndex  > -1 ) {
573+ 			numParametersToRemove ++;
574+ 		}
575+ 
528576		String [] pointcutParameterNames  = new  String [argumentNames .length  - numParametersToRemove ];
529577		Class <?>[] pointcutParameterTypes  = new  Class <?>[pointcutParameterNames .length ];
530578		Class <?>[] methodParameterTypes  = this .aspectJAdviceMethod .getParameterTypes ();
531579
532580		int  index  = 0 ;
533581		for  (int  i  = 0 ; i  < argumentNames .length ; i ++) {
534- 			if  (i  < argumentIndexOffset ) {
582+ 			if  (this .aroundClosureArgumentIndex  > -1  && i  == this .aroundClosureArgumentIndex ) {
583+ 				continue ;
584+ 			}
585+ 
586+ 			if  (this .joinPointStaticPartArgumentIndex  > -1  && i  == this .joinPointStaticPartArgumentIndex ) {
587+ 				continue ;
588+ 			}
589+ 			if  (this .joinPointArgumentIndex  > -1  && i  == this .joinPointArgumentIndex ) {
535590				continue ;
536591			}
537592			if  (argumentNames [i ].equals (this .returningName ) ||
538- 				argumentNames [i ].equals (this .throwingName )) {
593+ 					 argumentNames [i ].equals (this .throwingName )) {
539594				continue ;
540595			}
541596			pointcutParameterNames [index ] = argumentNames [i ];
@@ -600,7 +655,9 @@ else if (this.joinPointStaticPartArgumentIndex != -1) {
600655			}
601656		}
602657
603- 		if  (numBound  != this .parameterTypes .length ) {
658+ 		// if jp is a ProceedingJoinPoint, can ignore numBound check, 
659+ 		// because use the ProceedingJoinPoint.proceed() method in aj 
660+ 		if  (!(jp  instanceof  ProceedingJoinPoint ) && numBound  != this .parameterTypes .length ) {
604661			throw  new  IllegalStateException ("Required to bind "  + this .parameterTypes .length  +
605662					" arguments, but only bound "  + numBound  + " (JoinPointMatch "  +
606663					(jpMatch  == null  ? "was NOT"  : "WAS" ) + " bound in invocation)" );
0 commit comments