001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.aspectwerkz.joinpoint.management;
005:
006: import com.tc.asm.Type;
007:
008: import com.tc.aspectwerkz.aspect.AdviceInfo;
009: import com.tc.aspectwerkz.aspect.AdviceType;
010: import com.tc.aspectwerkz.definition.AdviceDefinition;
011: import com.tc.aspectwerkz.definition.AspectDefinition;
012: import com.tc.aspectwerkz.definition.SystemDefinition;
013: import com.tc.aspectwerkz.definition.SystemDefinitionContainer;
014: import com.tc.aspectwerkz.definition.Virtual;
015: import com.tc.aspectwerkz.joinpoint.JoinPoint;
016: import com.tc.aspectwerkz.joinpoint.StaticJoinPoint;
017: import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
018: import com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo;
019: import com.tc.aspectwerkz.reflect.ClassInfo;
020: import com.tc.aspectwerkz.reflect.ReflectionInfo;
021: import com.tc.aspectwerkz.reflect.MethodInfo;
022: import com.tc.aspectwerkz.reflect.ClassInfoHelper;
023: import com.tc.aspectwerkz.transform.TransformationConstants;
024: import com.tc.aspectwerkz.transform.inlining.AsmHelper;
025: import com.tc.aspectwerkz.transform.inlining.AspectModelManager;
026: import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint;
027: import com.tc.aspectwerkz.transform.inlining.compiler.CompilationInfo;
028: import com.tc.aspectwerkz.transform.inlining.compiler.CompilerHelper;
029: import com.tc.aspectwerkz.transform.inlining.spi.AspectModel;
030: import com.tc.aspectwerkz.util.ContextClassLoader;
031: import com.tc.aspectwerkz.util.Strings;
032: import com.tc.aspectwerkz.expression.PointcutType;
033: import com.tc.aspectwerkz.expression.ExpressionContext;
034: import com.tc.aspectwerkz.expression.ExpressionInfo;
035: import com.tc.aspectwerkz.expression.ArgsIndexVisitor;
036:
037: import java.util.ArrayList;
038: import java.util.Collection;
039: import java.util.HashSet;
040: import java.util.Iterator;
041: import java.util.List;
042: import java.util.Set;
043:
044: /**
045: * Manages the join point compilation, loading and instantiation for the target classes. This implementation relies on
046: * the SystemDefinitionContainer.
047: *
048: * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
049: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
050: */
051: public class JoinPointManager {
052:
053: /**
054: * Used to eagerly load the join point compilation. Ensures that the specific joinPoint class for the given target
055: * class and joinPoint info is generated. This call is added to the weaved class as a "clinit" block.
056: *
057: * @param joinPointType
058: * @param callerClass
059: * @param callerMethodName
060: * @param callerMethodDesc
061: * @param callerMethodModifiers
062: * @param calleeClassName
063: * @param calleeMemberName
064: * @param calleeMemberDesc
065: * @param calleeMemberModifiers
066: * @param joinPointHash
067: * @param joinPointClassName
068: * @param systemDef optional system definition that will override the existing one
069: */
070: public static void loadJoinPoint(final int joinPointType,
071: final Class callerClass, final String callerMethodName,
072: final String callerMethodDesc,
073: final int callerMethodModifiers,
074: final String calleeClassName,
075: final String calleeMemberName,
076: final String calleeMemberDesc,
077: final int calleeMemberModifiers, final int joinPointHash,
078: final String joinPointClassName,
079: final SystemDefinition systemDef) {
080: Class calleeClass = null;
081: try {
082: if (calleeClassName != null) {
083: calleeClass = Class.forName(calleeClassName.replace(
084: '/', '.'), false, callerClass.getClassLoader());
085: }
086: } catch (ClassNotFoundException calleeNotFound) {
087: throw new RuntimeException("callee class ["
088: + calleeClassName
089: + "] can not be found in class loader ["
090: + callerClass.getClassLoader() + "]");
091: }
092:
093: // check if the JP is already loaded
094: // this can occurs if user packaged its JIT classes, or if we are using multiweaving
095: final ClassLoader classLoader = callerClass.getClassLoader();
096: boolean generateJoinPoint = false;
097: try {
098: if (calleeClass == null) {
099: throw new RuntimeException("callee class ["
100: + calleeClassName + "] is NULL");
101: }
102: ContextClassLoader.forName(classLoader, joinPointClassName
103: .replace('/', '.'));
104: } catch (ClassNotFoundException e) {
105: generateJoinPoint = true;
106: }
107: if (!generateJoinPoint) {
108: return;
109: }
110:
111: final CompiledJoinPoint compiledJoinPoint = compileJoinPoint(
112: joinPointType, callerClass, callerMethodName,
113: callerMethodDesc, callerMethodModifiers,
114: calleeClassName, calleeMemberName, calleeMemberDesc,
115: calleeMemberModifiers, joinPointHash,
116: joinPointClassName, calleeClass, classLoader, systemDef);
117:
118: Class jpClass = CompilerHelper.attachToClassLoader(
119: joinPointClassName, classLoader,
120: compiledJoinPoint.bytecode);
121: CompilerHelper.addCompilationInfo(jpClass,
122: compiledJoinPoint.compilationInfo);
123: }
124:
125: /**
126: * Ensures that the specific joinPoint class for the given target class and joinPoint info is generated. This call is
127: * added to the weaved class as a "clinit" block
128: *
129: * @param joinPointType
130: * @param callerClass
131: * @param callerMethodName
132: * @param callerMethodDesc
133: * @param callerMethodModifiers
134: * @param calleeClassName
135: * @param calleeMemberName
136: * @param calleeMemberDesc
137: * @param calleeMemberModifiers
138: * @param joinPointHash
139: * @param joinPointClassName
140: */
141: public static void loadJoinPoint(final int joinPointType,
142: final Class callerClass, final String callerMethodName,
143: final String callerMethodDesc,
144: final int callerMethodModifiers,
145: final String calleeClassName,
146: final String calleeMemberName,
147: final String calleeMemberDesc,
148: final int calleeMemberModifiers, final int joinPointHash,
149: final String joinPointClassName) {
150: loadJoinPoint(joinPointType, callerClass, callerMethodName,
151: callerMethodDesc, callerMethodModifiers,
152: calleeClassName, calleeMemberName, calleeMemberDesc,
153: calleeMemberModifiers, joinPointHash,
154: joinPointClassName, null);
155: }
156:
157: /**
158: * Compile a new joinpoint
159: *
160: * @param joinPointType
161: * @param callerClass
162: * @param callerMethodName
163: * @param callerMethodDesc
164: * @param callerMethodModifiers
165: * @param calleeClassName
166: * @param calleeMemberName
167: * @param calleeMemberDesc
168: * @param calleeMemberModifiers
169: * @param joinPointHash
170: * @param joinPointClassName
171: * @param calleeClass
172: * @param loader the loader that hosts the definitions, and from where caller, callee and aspect are visible. At
173: * runtime it is exactly callerClass.getClassLoader() but in offline mode and genjp, it can happen to be
174: * different when weaved class also exists in the compilation classpath.
175: * @param systemDef (can be null)
176: * @return the compiled join point
177: */
178: public static CompiledJoinPoint compileJoinPoint(
179: final int joinPointType, final Class callerClass,
180: final String callerMethodName,
181: final String callerMethodDesc,
182: final int callerMethodModifiers,
183: final String calleeClassName,
184: final String calleeMemberName,
185: final String calleeMemberDesc,
186: final int calleeMemberModifiers, final int joinPointHash,
187: final String joinPointClassName, final Class calleeClass,
188: final ClassLoader loader, final SystemDefinition systemDef) {
189:
190: ClassInfo calleeClassInfo = JavaClassInfo
191: .getClassInfo(calleeClass);
192:
193: // create the callee info
194: final ReflectionInfo reflectionInfo;
195: final PointcutType pointcutType;
196: switch (joinPointType) {
197: case JoinPointType.STATIC_INITIALIZATION_INT:
198: reflectionInfo = calleeClassInfo.staticInitializer();
199: pointcutType = PointcutType.STATIC_INITIALIZATION;
200: break;
201: case JoinPointType.METHOD_EXECUTION_INT:
202: reflectionInfo = calleeClassInfo.getMethod(joinPointHash);
203: pointcutType = PointcutType.EXECUTION;
204: break;
205: case JoinPointType.METHOD_CALL_INT:
206: reflectionInfo = calleeClassInfo.getMethod(joinPointHash);
207: pointcutType = PointcutType.CALL;
208: break;
209: case JoinPointType.FIELD_GET_INT:
210: reflectionInfo = calleeClassInfo.getField(joinPointHash);
211: pointcutType = PointcutType.GET;
212: break;
213: case JoinPointType.FIELD_SET_INT:
214: reflectionInfo = calleeClassInfo.getField(joinPointHash);
215: pointcutType = PointcutType.SET;
216: break;
217: case JoinPointType.CONSTRUCTOR_EXECUTION_INT:
218: reflectionInfo = calleeClassInfo
219: .getConstructor(joinPointHash);
220: pointcutType = PointcutType.EXECUTION;
221: break;
222: case JoinPointType.CONSTRUCTOR_CALL_INT:
223: reflectionInfo = calleeClassInfo
224: .getConstructor(joinPointHash);
225: pointcutType = PointcutType.CALL;
226: break;
227: case JoinPointType.HANDLER_INT:
228: reflectionInfo = calleeClassInfo;
229: pointcutType = PointcutType.HANDLER;
230: break;
231: default:
232: throw new RuntimeException("Joinpoint type not supported: "
233: + joinPointType);
234: }
235:
236: // create the caller info
237: final ClassInfo callerClassInfo = JavaClassInfo
238: .getClassInfo(callerClass);
239: final ReflectionInfo withinInfo;
240: if (TransformationConstants.CLINIT_METHOD_NAME
241: .equals(callerMethodName)) {
242: withinInfo = callerClassInfo.staticInitializer();
243: } else if (TransformationConstants.INIT_METHOD_NAME
244: .equals(callerMethodName)) {
245: withinInfo = callerClassInfo.getConstructor(AsmHelper
246: .calculateConstructorHash(callerMethodDesc));
247: } else {
248: withinInfo = callerClassInfo.getMethod(AsmHelper
249: .calculateMethodHash(callerMethodName,
250: callerMethodDesc));
251: }
252:
253: // getDefault the compilation model
254: final ExpressionContext ctx = new ExpressionContext(
255: pointcutType, reflectionInfo, withinInfo);
256: final AdviceInfoContainer adviceContainer = getAdviceInfoContainerForJoinPoint(
257: ctx, loader, systemDef);
258: final EmittedJoinPoint emittedJoinPoint = new EmittedJoinPoint(
259: joinPointType, callerClass.getName(), callerMethodName,
260: callerMethodDesc, callerMethodModifiers, calleeClass
261: .getName(), calleeMemberName, calleeMemberDesc,
262: calleeMemberModifiers, joinPointHash,
263: joinPointClassName, EmittedJoinPoint.NO_LINE_NUMBER);
264: final CompilationInfo.Model compilationModel = new CompilationInfo.Model(
265: emittedJoinPoint, adviceContainer, callerClassInfo);
266:
267: return new CompiledJoinPoint(compilationModel);
268: }
269:
270: /**
271: * A compiled joinpoint is tied to a compilation model at a given time
272: */
273: public static class CompiledJoinPoint {
274: public byte[] bytecode;
275: public CompilationInfo compilationInfo;
276:
277: public CompiledJoinPoint(CompilationInfo.Model model) {
278: bytecode = CompilerHelper.compileJoinPoint(model);
279: compilationInfo = new CompilationInfo(model);
280: }
281: }
282:
283: /**
284: * Retrieves the advice info wrapped up in a struct.
285: *
286: * @param expressionContext
287: * @param loader
288: * @param systemDef (can be null)
289: * @return the advice info
290: */
291: public static AdviceInfoContainer getAdviceInfoContainerForJoinPoint(
292: final ExpressionContext expressionContext,
293: final ClassLoader loader, final SystemDefinition systemDef) {
294: final List beforeAdvices = new ArrayList();
295: final List aroundAdvices = new ArrayList();
296: final List afterFinallyAdvices = new ArrayList();
297: final List afterReturningAdvices = new ArrayList();
298: final List afterThrowingAdvices = new ArrayList();
299:
300: final Set systemDefinitions;
301: if (systemDef == null) {
302: systemDefinitions = SystemDefinitionContainer
303: .getDefinitionsFor(loader);
304: } else {
305: systemDefinitions = new HashSet();
306: systemDefinitions.add(systemDef);
307: }
308: // FIXME these two lines are needed to weave in other aspects on the classpath etc. - now causes verify error
309: // for (Iterator it = SystemDefinitionContainer.getDefinitionsFor(loader).iterator(); it.hasNext();) {
310: // definitions.add(it.next());
311: // }
312:
313: for (Iterator iterator = systemDefinitions.iterator(); iterator
314: .hasNext();) {
315: SystemDefinition systemDefinition = (SystemDefinition) iterator
316: .next();
317: Collection aspects = systemDefinition
318: .getAspectDefinitions();
319: for (Iterator iterator1 = aspects.iterator(); iterator1
320: .hasNext();) {
321: AspectDefinition aspectDefinition = (AspectDefinition) iterator1
322: .next();
323: if (aspectDefinition.getName().equals(
324: Virtual.class.getName())) {
325: continue;
326: }
327:
328: // TODO - do we care about non bounded pointcut ?
329: for (Iterator iterator2 = aspectDefinition
330: .getAdviceDefinitions().iterator(); iterator2
331: .hasNext();) {
332: AdviceDefinition adviceDefinition = (AdviceDefinition) iterator2
333: .next();
334: final ExpressionInfo expressionInfo = adviceDefinition
335: .getExpressionInfo();
336: if (expressionInfo == null) {
337: continue;
338: }
339: try {
340: if (expressionInfo.getExpression().match(
341: expressionContext)) {
342: // compute the target method to advice method arguments map, and grab information about this
343: // and target bindings
344: expressionContext.resetRuntimeState();
345: ArgsIndexVisitor
346: .updateContextForRuntimeInformation(
347: expressionInfo,
348: expressionContext, loader);
349: // Note that the expressionContext dynamic information updated here should only be used
350: // in the scope of this code block, since at the next iteration, the data will be
351: // updated for another advice binding
352: // [hence see setMethodArgumentIndexes below]
353:
354: // create a lightweight representation of the bounded advices to pass to the compiler
355: final MethodInfo adviceMethodInfo = adviceDefinition
356: .getMethodInfo();
357: final AdviceInfo adviceInfo = new AdviceInfo(
358: aspectDefinition.getQualifiedName(),
359: aspectDefinition.getClassName(),
360: aspectDefinition
361: .getDeploymentModel(),
362: adviceMethodInfo.getName(),
363: AsmHelper
364: .getMethodDescriptor(adviceMethodInfo),
365: AsmHelper
366: .getArgumentTypes(adviceMethodInfo),
367: adviceDefinition.getType(),
368: adviceDefinition
369: .getSpecialArgumentType(),
370: adviceDefinition.getName(),
371: expressionContext.m_targetWithRuntimeCheck,
372: expressionInfo, expressionContext,
373: adviceDefinition);
374:
375: setMethodArgumentIndexes(expressionInfo,
376: expressionContext, adviceInfo,
377: loader);
378:
379: if (AdviceType.BEFORE
380: .equals(adviceDefinition.getType())) {
381: beforeAdvices.add(adviceInfo);
382: } else if (AdviceType.AROUND
383: .equals(adviceDefinition.getType())) {
384: aroundAdvices.add(adviceInfo);
385: } else if (AdviceType.AFTER_FINALLY
386: .equals(adviceDefinition.getType())) {
387: afterFinallyAdvices.add(adviceInfo);
388: } else if (AdviceType.AFTER_RETURNING
389: .equals(adviceDefinition.getType())) {
390: afterReturningAdvices.add(adviceInfo);
391: } else if (AdviceType.AFTER_THROWING
392: .equals(adviceDefinition.getType())) {
393: afterThrowingAdvices.add(adviceInfo);
394: } else if (AdviceType.AFTER
395: .equals(adviceDefinition.getType())) {
396: afterFinallyAdvices.add(adviceInfo);// special case for "after only"
397: }
398: }
399: } catch (NullPointerException e) {
400: System.out
401: .println("-------------------------> NPE: Expression - "
402: + expressionInfo
403: .getExpressionString());
404: System.out
405: .println("-------------------------> NPE: Context - "
406: + expressionContext
407: .getDebugString());
408: throw e;
409: }
410: }
411: }
412: }
413:
414: final AdviceInfoContainer adviceInfoContainer = new AdviceInfoContainer(
415: aroundAdvices, beforeAdvices, afterFinallyAdvices,
416: afterReturningAdvices, afterThrowingAdvices);
417: return adviceInfoContainer;
418: }
419:
420: /**
421: * Get the parameter names from a "method declaration" signature like pc(type a, type2 b) => 0:a, 1:b
422: *
423: * @param adviceName
424: * @return the parameter names
425: */
426: public static String[] getParameterNames(final String adviceName) {
427: int paren = adviceName.indexOf('(');
428: List paramNames = new ArrayList();
429: if (paren > 0) {
430: String params = adviceName.substring(paren + 1,
431: adviceName.lastIndexOf(')')).trim();
432: String[] javaParameters = Strings.splitString(params, ",");
433: for (int i = 0; i < javaParameters.length; i++) {
434: String javaParameter = Strings.replaceSubString(
435: javaParameters[i], " ", " ").trim();
436: String[] paramInfo = Strings.splitString(javaParameter,
437: " ");
438: // handles XML def where name is optional
439: if (paramInfo.length == 2) {
440: paramNames.add(paramInfo[1]);
441: } else {
442: paramNames.add("anonymous_" + i);
443: }
444: }
445: }
446: String[] paramNamesArray = new String[paramNames.size()];
447: int index = 0;
448: for (Iterator it = paramNames.iterator(); it.hasNext(); index++) {
449: paramNamesArray[index] = (String) it.next();
450: }
451: return paramNamesArray;
452: }
453:
454: /**
455: * Sets the advice argument indexes map. <p/> Each advice arg is mapped to wether a system entity like
456: * StaticJoinPoint, Rtti, this, target etc thru a specific index (see AdviceInfo), or to one of the advised member
457: * arguments (thru args(..) binding).
458: *
459: * @param expressionInfo
460: * @param ctx
461: * @param adviceInfo
462: * @param loader
463: */
464: private static void setMethodArgumentIndexes(
465: final ExpressionInfo expressionInfo,
466: final ExpressionContext ctx, final AdviceInfo adviceInfo,
467: final ClassLoader loader) {
468: // grab the parameters names
469: String[] adviceArgNames = getParameterNames(adviceInfo
470: .getName());
471:
472: // map them from the ctx info
473: int[] adviceToTargetArgs = new int[adviceInfo
474: .getMethodParameterTypes().length];
475: for (int k = 0; k < adviceArgNames.length; k++) {
476: String adviceArgName = adviceArgNames[k];
477: int exprArgIndex = expressionInfo
478: .getArgumentIndex(adviceArgName);
479: if (exprArgIndex >= 0
480: && ctx.m_exprIndexToTargetIndex
481: .containsKey(adviceArgName)) {
482: adviceToTargetArgs[k] = ((Integer) ctx.m_exprIndexToTargetIndex
483: .get(adviceArgName)).intValue();
484: } else {
485: // does not appears to be an argument of the advised target
486: // It can be StaticJP / JP / This binding / Target binding
487: final Type type = adviceInfo.getMethodParameterTypes()[k];
488: if (isJoinPoint(type)) {
489: adviceToTargetArgs[k] = AdviceInfo.JOINPOINT_ARG;
490: } else if (isStaticJoinPoint(type)) {
491: adviceToTargetArgs[k] = AdviceInfo.STATIC_JOINPOINT_ARG;
492: } else if (isTarget(adviceArgName, ctx)) {
493: adviceToTargetArgs[k] = AdviceInfo.TARGET_ARG;
494: } else if (isThis(adviceArgName, ctx)) {
495: adviceToTargetArgs[k] = AdviceInfo.THIS_ARG;
496: } else if (isSpecialArgument(adviceArgName,
497: expressionInfo)) {
498: adviceToTargetArgs[k] = AdviceInfo.SPECIAL_ARGUMENT;
499: } else if (isCustomJointPoint(type, loader)) {
500: adviceToTargetArgs[k] = AdviceInfo.CUSTOM_JOIN_POINT_ARG;
501: } else {
502: throw new Error(
503: "Unbound advice parameter at index " + k
504: + " in "
505: + adviceInfo.getMethodName()
506: + adviceInfo.getMethodSignature()
507: + " named " + adviceArgName);
508: }
509: }
510: }
511:
512: // support for old style advices in XML whose name does not contain the call signature
513: if (adviceArgNames.length == 0) {
514: AspectDefinition aspectDef = adviceInfo
515: .getAdviceDefinition().getAspectDefinition();
516: Type[] adviceArgTypes = adviceInfo
517: .getMethodParameterTypes();
518: for (int i = 0; i < adviceArgTypes.length; i++) {
519:
520: if (aspectDef.isAspectWerkzAspect()) {
521: if (isJoinPoint(adviceArgTypes[i])) {
522: adviceToTargetArgs[i] = AdviceInfo.JOINPOINT_ARG;
523: } else if (isStaticJoinPoint(adviceArgTypes[i])) {
524: adviceToTargetArgs[i] = AdviceInfo.STATIC_JOINPOINT_ARG;
525: } else {
526: throw new Error(
527: "Unbound unnamed advice parameter at index "
528: + i
529: + " in "
530: + adviceInfo
531: .getMethodSignature());
532: }
533: } else {
534: // handles other models
535: // custom proceed won't be recognized here but will be in the first block
536: // logic (mandatory arg type declaration).
537: // TODO refactor models or def to not use getAroundClosureClassInfo
538: final AspectModel aspectModel = AspectModelManager
539: .getModelFor(aspectDef.getAspectModel());
540: final String super ClassName = aspectModel
541: .getAroundClosureClassInfo()
542: .getSuperClassName();
543: final String[] interfaces = aspectModel
544: .getAroundClosureClassInfo()
545: .getInterfaceNames();
546: final String[] classNames = new String[interfaces.length + 1];
547: classNames[0] = super ClassName;
548: for (int j = 1; j < interfaces.length + 1; j++) {
549: classNames[j] = interfaces[j - 1];
550: }
551:
552: final Type argType = adviceArgTypes[i];
553: if (isValidAroundClosureType(argType, classNames)) {
554: adviceToTargetArgs[i] = AdviceInfo.VALID_NON_AW_AROUND_CLOSURE_TYPE;
555: } else if (isSpecialArgumentType(argType,
556: adviceInfo)) {
557: adviceToTargetArgs[i] = AdviceInfo.SPECIAL_ARGUMENT;
558: }
559: }
560: }
561: }
562:
563: adviceInfo.setMethodToArgIndexes(adviceToTargetArgs);
564: }
565:
566: private static boolean isSpecialArgumentType(final Type argType,
567: final AdviceInfo adviceInfo) {
568: final String specialArgumentTypeDesc = adviceInfo
569: .getSpecialArgumentTypeDesc();
570: return specialArgumentTypeDesc != null
571: && specialArgumentTypeDesc.equals(argType
572: .getDescriptor());
573: }
574:
575: private static boolean isValidAroundClosureType(final Type argType,
576: final String[] closureTypeNames) {
577: for (int i = 0; i < closureTypeNames.length; i++) {
578: final String closureTypeName = closureTypeNames[i];
579: if (closureTypeName != null
580: && closureTypeName
581: .equals(argType.getInternalName())) {
582: return true;
583: }
584: }
585: return false;
586: }
587:
588: private static boolean isJoinPoint(final Type type) {
589: return Type.getType(JoinPoint.class).getDescriptor().equals(
590: type.getDescriptor());
591: }
592:
593: private static boolean isStaticJoinPoint(final Type type) {
594: return Type.getType(StaticJoinPoint.class).getDescriptor()
595: .equals(type.getDescriptor());
596: }
597:
598: private static boolean isTarget(final String adviceArgName,
599: final ExpressionContext ctx) {
600: return adviceArgName.equals(ctx.m_targetBoundedName);
601: }
602:
603: private static boolean isThis(final String adviceArgName,
604: final ExpressionContext ctx) {
605: return adviceArgName.equals(ctx.m_this BoundedName);
606: }
607:
608: private static boolean isSpecialArgument(
609: final String adviceArgName,
610: final ExpressionInfo expressionInfo) {
611: return adviceArgName.equals(expressionInfo
612: .getSpecialArgumentName());
613: }
614:
615: private static boolean isCustomJointPoint(final Type type,
616: final ClassLoader loader) {
617: ClassInfo classInfo = AsmClassInfo.getClassInfo(type
618: .getClassName(), loader);
619: return ClassInfoHelper.implementsInterface(classInfo,
620: ExpressionInfo.JOINPOINT_CLASS_NAME)
621: || ClassInfoHelper.implementsInterface(classInfo,
622: ExpressionInfo.STATIC_JOINPOINT_CLASS_NAME);
623: }
624: }
|