[jboss-cvs] JBossAS SVN: r59246 - in projects/aop/trunk/aop/src/main/org/jboss/aop: advice advice/annotation instrument
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Dec 29 18:52:30 EST 2006
Author: flavia.rainone
Date: 2006-12-29 18:52:03 -0500 (Fri, 29 Dec 2006)
New Revision: 59246
Modified:
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/AdviceMethodProperties.java
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceInfo.java
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceMethodFactory.java
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AnnotatedParameterAdviceInfo.java
projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParameterAnnotationRule.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByConJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByMethodJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructionJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructorJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/FieldJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/JoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByConJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByMethodJoinPointGenerator.java
projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodJoinPointGenerator.java
Log:
[JBAOP-326] Target parameter support implemented
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/AdviceMethodProperties.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/AdviceMethodProperties.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/AdviceMethodProperties.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -46,15 +46,20 @@
public static final CtClass[] EMPTY_PARAMETERS = {};
+ public static enum Context {STATIC, TARGET_AVAILABLE, CALLER_AVAILABLE,
+ TARGET_CALLER_AVAILABLE}
+
//find properties
private Class aspectClass;
private String adviceName;
private Class infoType;
private Class invocationType;
+ private Class target;
private Class joinpointReturnType;
private Class[] joinpointParameters;
private Class[] joinpointExceptions;
-
+ private Context context;
+
//found properties
private Method adviceMethod;
private int[] args;
@@ -66,7 +71,9 @@
Class invocationType,
Class joinpointReturnType,
Class[] joinpointParameters,
- Class[] joinpointExceptions)
+ Class[] joinpointExceptions,
+ Class target,
+ Context context)
{
this.aspectClass = aspectClass;
this.adviceName = adviceName;
@@ -75,6 +82,8 @@
this.joinpointReturnType = joinpointReturnType;
this.joinpointParameters = joinpointParameters;
this.joinpointExceptions = joinpointExceptions;
+ this.target = target;
+ this.context = context;
}
public void setFoundProperties(Method adviceMethod, int[] args)
@@ -139,4 +148,13 @@
return args;
}
-}
+ public Class getTargetType()
+ {
+ return this.target;
+ }
+
+ public Context getContext()
+ {
+ return this.context;
+ }
+}
\ No newline at end of file
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceInfo.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceInfo.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceInfo.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -246,25 +246,29 @@
* contained in <code>properties</code>.
*
* @param properties contains information about the queried method
- * @param mutuallyExclusive a list of mutually exclusive rules
* @param returnType the expected return type
* @return <code>true</code> only if this advice is valid
*/
public abstract boolean validate(AdviceMethodProperties properties,
- int[][] mutuallyExclusive, ReturnType returnType);
+ ReturnType returnType);
/**
* Returns the distance in hierarchy between the annotated parameter identified by
* <code>annotationIndex</code>, and the expected type of this parameter.
*
* @param annotationIndex identifies a parameter annotation rule
+ * @param isContextRule is <code>true</code>, <code>annotationIndex</code>
+ * refers to a context rule, instead of a factory rule
+ * (context rules include target, caller, arg, etc;
+ * factory rule are dependent on the advice factory,
+ * and include join point, throwable, return and others)
* @param properties contains information about the queried advice method
* @return the assignability degree if there is a parameter with the
* annotation identified by <code>typeIndex</code>;
* {@link AdviceMethodFactory#NOT_ASSIGNABLE_DEGREE} otherwise.
*/
public abstract short getAssignabilityDegree(int annotationIndex,
- AdviceMethodProperties properties);
+ boolean isContextRule, AdviceMethodProperties properties);
/**
* Assign information of this advice to <code>properties</code>.
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceMethodFactory.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceMethodFactory.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AdviceMethodFactory.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -36,7 +36,7 @@
import org.jboss.aop.util.ReflectUtils;
/**
- * Utility class to figure out which advice method to use for a given joinpoint
+ * Utility class to select an advice method for a given joinpoint.
*
* @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
* @author Flavia Rainone
@@ -53,23 +53,20 @@
* Factory that selects advice methods for <i>before</i> interception.
*/
public static final AdviceMethodFactory BEFORE = new AdviceMethodFactory (null,
- new ParameterAnnotationRule[]{ParameterAnnotationRule.JOIN_POINT,
- ParameterAnnotationRule.ARGS, ParameterAnnotationRule.ARG},
- new int[][]{{1,2}}, ReturnType.VOID);
+ new ParameterAnnotationRule[]{ParameterAnnotationRule.JOIN_POINT},
+ ReturnType.VOID);
/**
* Factory that selects advice methods for <i>after</i> interception.
*/
public static final AdviceMethodFactory AFTER = new AdviceMethodFactory (null,
new ParameterAnnotationRule[]{ParameterAnnotationRule.JOIN_POINT,
- ParameterAnnotationRule.RETURN, ParameterAnnotationRule.ARGS,
- ParameterAnnotationRule.ARG}, new int[][]{{2, 3}}, ReturnType.ANY);
+ ParameterAnnotationRule.RETURN}, ReturnType.ANY);
/**
* Factory that selects advice methods for <i>throwing</i> interception.
*/
public static final AdviceMethodFactory THROWING = new AdviceMethodFactory (null,
new ParameterAnnotationRule[]{ParameterAnnotationRule.JOIN_POINT,
- ParameterAnnotationRule.THROWABLE, ParameterAnnotationRule.ARGS,
- ParameterAnnotationRule.ARG}, new int[][]{{2, 3}}, ReturnType.VOID);
+ ParameterAnnotationRule.THROWABLE}, ReturnType.VOID);
/**
* Factory that selects advice methods for <i>aroung</i> interception.
*/
@@ -131,7 +128,7 @@
return new AdviceInfo(method, 500)
{
public boolean validate(AdviceMethodProperties properties,
- int[][] mutuallyExclusive, ReturnType adviceReturn)
+ ReturnType adviceReturn)
{
if(parameterTypes[0].isAssignableFrom(properties.getInvocationType()))
{
@@ -148,7 +145,7 @@
}
public short getAssignabilityDegree(int typeIndex,
- AdviceMethodProperties properties)
+ boolean isContextRule, AdviceMethodProperties properties)
{
return getAssignabilityDegree(parameterTypes[0], properties.getInvocationType());
}
@@ -161,15 +158,36 @@
};
}
},
- new ParameterAnnotationRule[]{ParameterAnnotationRule.INVOCATION,
- ParameterAnnotationRule.ARGS, ParameterAnnotationRule.ARG},
- new int[][]{{1, 2}}, ReturnType.NOT_VOID);
+ new ParameterAnnotationRule[]{ParameterAnnotationRule.INVOCATION},
+ ReturnType.NOT_VOID);
- static StringBuffer adviceMatchingMessage;
static final short NOT_ASSIGNABLE_DEGREE = Short.MAX_VALUE;
static final short MAX_DEGREE = NOT_ASSIGNABLE_DEGREE - 1;
+ static final ParameterAnnotationRule[] FULLY_STATIC =
+ new ParameterAnnotationRule[] {ParameterAnnotationRule.ARGS,
+ ParameterAnnotationRule.ARG};
+ static final int[][] FS_INCOMPATIBILITY = new int[][]{{0, 1}};
+ static final ParameterAnnotationRule[] CALLER_AVAILABLE =
+ new ParameterAnnotationRule[] {ParameterAnnotationRule.CALLER,
+ ParameterAnnotationRule.ARGS, ParameterAnnotationRule.ARG};
+ static final int[][] CA_INCOMPATIBILITY = new int[][]{{1, 2}};
+
+ static final ParameterAnnotationRule[] TARGET_AVAILABLE =
+ new ParameterAnnotationRule[] {ParameterAnnotationRule.TARGET,
+ ParameterAnnotationRule.ARGS, ParameterAnnotationRule.ARG};
+ static final int[][] TA_INCOMPATIBILITY = CA_INCOMPATIBILITY;
+
+ static final ParameterAnnotationRule[] TARGET_CALLER_AVAILABLE =
+ new ParameterAnnotationRule[] {ParameterAnnotationRule.TARGET,
+ ParameterAnnotationRule.CALLER,
+ ParameterAnnotationRule.ARGS, ParameterAnnotationRule.ARG};
+ static final int[][] TCA_INCOMPATIBILITY = new int[][]{{2, 3}};
+
+ /** Stores advice matching failure messages on verbose mode. */
+ static StringBuffer adviceMatchingMessage;
+
/**
* Method that returns log information about the last matching process executed.
* Should be called only if <code>Aspect.verbose</code> is <code>true</code>.
@@ -185,9 +203,8 @@
private ReturnType returnType;
private AdviceSignatureRule adviceSignatureRule;
private ParameterAnnotationRule[] rules;
- private int[][] mutuallyExclusive;
-
+
/**
* Creates an advice method factory.
*
@@ -200,12 +217,12 @@
* a value to overwrite the join point execution result.
*/
private AdviceMethodFactory(AdviceSignatureRule adviceSignatureRule,
- ParameterAnnotationRule[] rules, int[][] mutuallyExclusive,
+ ParameterAnnotationRule[] rules,/*, int[][] mutuallyExclusive,*/
ReturnType returnType)
{
this.adviceSignatureRule = adviceSignatureRule;
this.rules = rules;
- this.mutuallyExclusive = mutuallyExclusive;
+ //this.mutuallyExclusive = mutuallyExclusive;
this.returnType = returnType;
}
@@ -238,6 +255,32 @@
return null;
}
+ ParameterAnnotationRule[] contextRules = null;
+ int[][] mutuallyExclusive = null;
+ switch(properties.getContext())
+ {
+ case STATIC:
+ contextRules = FULLY_STATIC;
+ mutuallyExclusive = FS_INCOMPATIBILITY;
+ break;
+ case TARGET_AVAILABLE:
+ contextRules = TARGET_AVAILABLE;
+ mutuallyExclusive = TA_INCOMPATIBILITY;
+ break;
+ case CALLER_AVAILABLE:
+ contextRules = CALLER_AVAILABLE;
+ mutuallyExclusive = CA_INCOMPATIBILITY;
+ break;
+ case TARGET_CALLER_AVAILABLE:
+ contextRules = TARGET_CALLER_AVAILABLE;
+ mutuallyExclusive = TCA_INCOMPATIBILITY;
+ break;
+ default:
+ throw new RuntimeException("Unexpected Context Type " +
+ properties.getContext());
+ }
+
+
LinkedList<AdviceInfo> rankedAdvices = new LinkedList<AdviceInfo>();
for (int i = 0; i < methods.length; i++)
{
@@ -252,7 +295,8 @@
try
{
// advice applies to annotated parameter rules
- rankedAdvices.add(new AnnotatedParameterAdviceInfo(methods[i], rules));
+ rankedAdvices.add(new AnnotatedParameterAdviceInfo(methods[i], rules,
+ contextRules, mutuallyExclusive));
}catch (ParameterAnnotationRuleException pare)
{
// no need to print messages -> exception prints automatically on verbose
@@ -267,7 +311,8 @@
// sort according to rank
Collections.sort(rankedAdvices);
// validate and retrive best match
- AdviceInfo bestAdvice = bestValidAdvice(rankedAdvices, properties);
+ AdviceInfo bestAdvice = bestValidAdvice(rankedAdvices, properties,
+ contextRules);
if (bestAdvice == null)
{
return null;
@@ -282,17 +327,19 @@
*
* @param rankedAdvices a sorted collection of advice infos
* @param properties contains information about the queried advice method
+ * @param contextRules the parameter annotation rules that are dependent on the
+ * join point context
* @return information about the best advice method match
*/
private AdviceInfo bestValidAdvice(LinkedList<AdviceInfo> rankedAdvices,
- AdviceMethodProperties properties)
+ AdviceMethodProperties properties, ParameterAnnotationRule[] contextRules)
{
AdviceInfo bestAdvice = null;
ListIterator<AdviceInfo> iterator = rankedAdvices.listIterator();
while (iterator.hasNext())
{
AdviceInfo advice = iterator.next();
- if (advice.validate(properties, mutuallyExclusive, returnType))
+ if (advice.validate(properties, returnType))
{
bestAdvice = advice;
break;
@@ -318,7 +365,7 @@
AdviceInfo advice = iterator.next();
if (advice.getRank() == bestAdvice.getRank())
{
- if (!advice.validate(properties, mutuallyExclusive, returnType))
+ if (!advice.validate(properties, returnType))
{
iterator.remove();
}
@@ -338,13 +385,12 @@
// if not, retrive the list of all valid advices with the highest rank
List<AdviceInfo> bestAdvices =
rankedAdvices.subList(0, iterator.nextIndex());
- Class returnType = properties.getJoinpointReturnType();
// deep process these advices to find the best match
- return bestMatch(bestAdvices, properties);
+ return bestMatch(bestAdvices, properties, contextRules);
}
/**
- * Return the best advice method among the advices contained in <code>greatestRank
+ * Returns the best advice method among the advices contained in <code>greatestRank
* </code>. The criteria used is the specificness of annotated parameters type,
* i.e., the more specific type <code>MethodInvocation</code> is better than
* <code>Invocation</code>.
@@ -352,22 +398,79 @@
* @param greatestRank contains information about all valid advice methods with the
* highest rank
* @param properties information about the queried advice method
+ * @param contextRules the context annotation rules (depend on the join point
+ * context)
* @return information about the best advice method match
*/
AdviceInfo bestMatch(Collection<AdviceInfo> greatestRank,
- AdviceMethodProperties properties)
+ AdviceMethodProperties properties, ParameterAnnotationRule[] contextRules)
{
+
+ // select the closest match according to assignability degree of parameters
+ // like Invocation, JoinPoint, Return, etc
+ AdviceInfo bestAdvice = selectBestRuleMatch(greatestRank, properties,
+ rules.length, false);
+ if (bestAdvice != null)
+ {
+ return bestAdvice;
+ }
+ // context rules are second priority
+ bestAdvice = selectBestRuleMatch(greatestRank, properties, contextRules.length,
+ true);
+ if (bestAdvice != null)
+ {
+ return bestAdvice;
+ }
short bestDegree = NOT_ASSIGNABLE_DEGREE;
+ if (returnType == ReturnType.ANY || returnType == ReturnType.NOT_VOID)
+ {
+ for (AdviceInfo currentAdvice: greatestRank)
+ {
+ short currentDegree = currentAdvice.getReturnAssignabilityDegree(properties);
+ if (currentDegree < bestDegree)
+ {
+ bestAdvice = currentAdvice;
+ bestDegree = currentDegree;
+ }
+ }
+ //in case of two or more advices with the same match degree, pick any one of them
+ return bestAdvice;
+ }
+ // we have more than one best advice; return any one of them
+ return greatestRank.iterator().next();
+ }
+
+ /**
+ * Returns the best advice method among the advices contained in <code>greatestRank
+ * </code>. The criteria used in the assignability degree of parameters
+ * that follow a set of rules (defined by <code>useContextRules</code>).
+ *
+ * @param greatestRank contains information about all valid advice methods with
+ * the highest rank
+ * @param properties information about the queried advice method
+ * @param totalRules the total number of rules that will be used on matching
+ * @param useContextRules if <code>true</code>, context rules are used instead
+ * of factory rules
+ * @return the best match. If there is more than one match, returns
+ * <code>null</code>
+ */
+ private AdviceInfo selectBestRuleMatch(Collection<AdviceInfo> greatestRank,
+ AdviceMethodProperties properties, int totalRules,
+ boolean isContextRule)
+ {
+ short bestDegree = NOT_ASSIGNABLE_DEGREE;
AdviceInfo bestAdvice = null;
Collection<AdviceInfo> removeList = new ArrayList<AdviceInfo>();
+
// rule i is more important than rule i + 1
- for (int i = 0; i < rules.length; i++)
+ for (int i = 0; i < totalRules; i++)
{
for (Iterator<AdviceInfo> iterator = greatestRank.iterator();
iterator.hasNext();)
{
AdviceInfo currentAdvice = iterator.next();
- short currentDegree = currentAdvice.getAssignabilityDegree(i, properties);
+ short currentDegree = currentAdvice.getAssignabilityDegree(i,
+ isContextRule, properties);
if (currentDegree < bestDegree)
{
if (bestAdvice != null)
@@ -393,22 +496,7 @@
bestAdvice = null;
bestDegree = NOT_ASSIGNABLE_DEGREE;
}
- if (returnType == ReturnType.ANY || returnType == ReturnType.NOT_VOID)
- {
- for (AdviceInfo currentAdvice: greatestRank)
- {
- short currentDegree = currentAdvice.getReturnAssignabilityDegree(properties);
- if (currentDegree < bestDegree)
- {
- bestAdvice = currentAdvice;
- bestDegree = currentDegree;
- }
- }
- //in case of two or more advices with the same match degree, pick any one of them
- return bestAdvice;
- }
- // we have more than one best advice; return any one of them
- return greatestRank.iterator().next();
+ return null;
}
/**
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AnnotatedParameterAdviceInfo.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AnnotatedParameterAdviceInfo.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/AnnotatedParameterAdviceInfo.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -2,11 +2,6 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
import org.jboss.aop.AspectManager;
import org.jboss.aop.advice.AdviceMethodProperties;
@@ -22,109 +17,52 @@
{
// the annotated parameter types
private ParameterAnnotationType paramTypes[];
+ // the context dependent annotated parameter types
+ private ParameterAnnotationType contextParamTypes[];
+ // muttually exclusive context parameter rules
+ private int[][] mutuallyExclusive;
/**
* Creates an annotated parameter advice info.
*
- * @param method the advice method
- * @param rules the annnotated parameter rules this method should comply with
+ * @param method the advice method
+ * @param rules the annnotated parameter rules this method should
+ * comply with
+ * @param contextRules second priority rules this method should comply with
+ * @param mutuallyExclusive a list of mutually exclusive context parameter rules
*
* @throws ParameterAnnotationRuleException thrown when the advice method does not
* comply with a parameter annotation rule.
*/
- public AnnotatedParameterAdviceInfo(Method method, ParameterAnnotationRule[] rules)
+ public AnnotatedParameterAdviceInfo(Method method, ParameterAnnotationRule[] rules,
+ ParameterAnnotationRule[] contextRules, int[][] mutuallyExclusive)
throws ParameterAnnotationRuleException
{
- this(rules, method);
+ super(method, 0);
+ this.paramTypes = createParameterAnnotationTypes(rules);
+ this.contextParamTypes = createParameterAnnotationTypes(contextRules);
+ this.mutuallyExclusive = mutuallyExclusive;
this.applyRules();
}
-
- /**
- * Private constructor. Called only internally, does not apply the parameter annotation
- * rules to the advice method parameters.
- *
- * @param rules the parameter annotation rules this method should comply with
- * @param method the advice method
- */
- private AnnotatedParameterAdviceInfo(ParameterAnnotationRule[] rules, Method method)
+
+ public boolean validate(AdviceMethodProperties properties, ReturnType returnType)
{
- super(method, 0);
- this.paramTypes = new ParameterAnnotationType[rules.length];
- // create appropriate annotated parameter types for each AP rule
- for (int i = 0; i < rules.length; i++)
+ for (ParameterAnnotationType paramType: paramTypes)
{
- if (rules[i].isSingleEnforced())
+ if (!paramType.validate(properties))
{
- this.paramTypes[i] = new SingleParameterType(rules[i]);
+ return false;
}
- else
- {
- this.paramTypes[i] = new MultipleParameterType(rules[i],
- method.getParameterTypes().length);
- }
}
- }
-
- /**
- * Creates all advice info instances necessary for representing the multi-annotated
- * parameters of <code>method</code>.
- * <p>Should be invoked when the constructor of <code>AnnotatedParamereAdviceInfo
- * </code> throws a <code>MultipleAdviceInfoException</code>.
- *
- * @param method the method that contains parameters with more than one
- * valid annotations
- * @param rules the parameter annotation rules
- * @param totalInstances the total number of instances that must be created
- * @param annotations the list of annotated parameter indexes
- * @return all advice info instances representing <code>method</code>.
- */
- public static List<AnnotatedParameterAdviceInfo> createAllAdviceInfo(
- Method method, ParameterAnnotationRule[] rules, int totalInstances,
- int[][]annotations)
- {
- List<AnnotatedParameterAdviceInfo> allAdvices =
- new LinkedList<AnnotatedParameterAdviceInfo>();
- Set<AnnotatedParameterAdviceInfo> removeAdvices =
- new HashSet<AnnotatedParameterAdviceInfo>();
- // create instances
- for (int i = 0; i < totalInstances; i++)
+
+ for (ParameterAnnotationType paramType: contextParamTypes)
{
- allAdvices.add(new AnnotatedParameterAdviceInfo(rules, method));
- }
- // set all the possible combinations of parameter annotations to the instances
- for (int i = 0; i < annotations.length; i++)
- {
- for (Iterator<AnnotatedParameterAdviceInfo> iterator = allAdvices.iterator();
- iterator.hasNext();)
- {
- for (int j = 0; j < annotations[i].length; j++)
- {
- AnnotatedParameterAdviceInfo adviceInfo = iterator.next();
- try
- {
- adviceInfo.paramTypes[annotations[i][j]].setIndex(i);
- } catch (ParameterAnnotationRuleException maoe)
- {
- removeAdvices.add(adviceInfo);
- }
- }
- }
- }
- // remove all combinations that resulted in multiple annotation exception
- allAdvices.removeAll(removeAdvices);
- return allAdvices;
- }
-
- public boolean validate(AdviceMethodProperties properties,
- int[][] mutuallyExclusive, ReturnType returnType)
- {
- for (ParameterAnnotationType paramType: paramTypes)
- {
if (!paramType.validate(properties))
{
return false;
}
}
+
switch (returnType)
{
case ANY:
@@ -155,16 +93,16 @@
int found = -1;
for (int j = 0; j < exclusiveParamTypes.length; j++)
{
- if (paramTypes[exclusiveParamTypes[j]].isSet())
+ if (contextParamTypes[exclusiveParamTypes[j]].isSet())
{
if (found != -1)
{
if (AspectManager.verbose)
{
AdviceMethodFactory.adviceMatchingMessage.append("\n[warn] - the use of parameter annotations ");
- AdviceMethodFactory.adviceMatchingMessage.append(paramTypes[exclusiveParamTypes[found]].rule.getAnnotation());
+ AdviceMethodFactory.adviceMatchingMessage.append(contextParamTypes[exclusiveParamTypes[found]].rule.getAnnotation());
AdviceMethodFactory.adviceMatchingMessage.append(" and ");
- AdviceMethodFactory.adviceMatchingMessage.append(paramTypes[exclusiveParamTypes[j]].rule.getAnnotation());
+ AdviceMethodFactory.adviceMatchingMessage.append(contextParamTypes[exclusiveParamTypes[j]].rule.getAnnotation());
AdviceMethodFactory.adviceMatchingMessage.append(" is mutually exclusive");
}
return false;
@@ -176,9 +114,13 @@
return true;
}
- public short getAssignabilityDegree(int annotationIndex,
+ public short getAssignabilityDegree(int annotationIndex, boolean isContextRule,
AdviceMethodProperties properties)
{
+ if (isContextRule)
+ {
+ return contextParamTypes[annotationIndex].getAssignabilityDegree(properties);
+ }
return paramTypes[annotationIndex].getAssignabilityDegree(properties);
}
@@ -189,10 +131,42 @@
{
paramTypes[i].assignParameterInfo(args);
}
+ for (int i = 0; i < contextParamTypes.length; i++)
+ {
+ contextParamTypes[i].assignParameterInfo(args);
+ }
properties.setFoundProperties(this.method, args);
}
/**
+ * Creates a parameter annotation type array correpondent to the parameter
+ * annotation rules contained in <code>rules</code>.
+ *
+ * @param rules the parameter annotation rules
+ *
+ * @return a parameter annotation type array correspondent to <code>rules</code>
+ */
+ private final ParameterAnnotationType[] createParameterAnnotationTypes(
+ ParameterAnnotationRule[] rules)
+ {
+ ParameterAnnotationType[] types = new ParameterAnnotationType[rules.length];
+ // create appropriate annotated parameter types for each AP rule
+ for (int i = 0; i < rules.length; i++)
+ {
+ if (rules[i].isSingleEnforced())
+ {
+ types[i] = new SingleParameterType(rules[i]);
+ }
+ else
+ {
+ types[i] = new MultipleParameterType(rules[i],
+ method.getParameterTypes().length);
+ }
+ }
+ return types;
+ }
+
+ /**
* Applies all parameter annotation rules to the advice method parameters.
*
* @throws ParameterAnnotationRuleException thrown when the advice method does not
@@ -201,86 +175,102 @@
private void applyRules() throws ParameterAnnotationRuleException
{
Annotation[][] paramAnnotations = method.getParameterAnnotations();
- boolean annotated;
+ boolean ruleFound;
for (int i = 0; i < paramAnnotations.length; i++)
{
- annotated = false;
+ ruleFound = false;
for (Annotation annotation: paramAnnotations[i])
{
// no valid annotation found for parameter i yet
- if (!annotated)
- for (int j = 0; j < paramTypes.length; j++)
+ if (!ruleFound)
{
- // found
- if (paramTypes[j].applies(annotation, i))
- {
- annotated = true;
- break;
- }
+ ruleFound = findAnnotationRule(annotation, i);
}
else
{
- // look for an extra annotation
- for (int j = 0; j < paramTypes.length; j++)
+ if (findAnnotationRule(annotation, i))
{
- if (paramTypes[j].applies(annotation))
+ if (AspectManager.verbose)
{
- throwMultiAnnotationFoundException(i);
+ throw new ParameterAnnotationRuleException("\n[warn] -parameter " + i +
+ " of method " + method + " contains more than one valid annotation");
}
+ else
+ {
+ throw new ParameterAnnotationRuleException(null);
+ }
}
}
}
- if (!annotated)
+ if (!ruleFound)
{
- throwAnnotationNotFoundException(i);
+ if (AspectManager.verbose)
+ {
+ if (paramAnnotations[i].length == 0)
+ {
+ throw new ParameterAnnotationRuleException("\n[warn] -parameter "
+ + i + " of method " + method + " is not annotated");
+ }
+ throw new ParameterAnnotationRuleException("\n[warn] -parameter "
+ + i + " of method " + method + " is not annotated correctly" +
+ "\n[warn] Expecting one of: " + getDescription(paramTypes) +
+ getDescription(contextParamTypes));
+ }
+ // no need to say the reason a rule's been broken
+ throw new ParameterAnnotationRuleException(null);
}
- }
-
+ }
}
-
- /**
- * Throws an exception indicating the ith parameter of this advice contains
- * multiple valid annotations.
- *
- * @param i the index of the not annotated parameter.
- *
- * @throws ParameterAnnotationRuleException
- */
- private final void throwMultiAnnotationFoundException(int i)
- throws ParameterAnnotationRuleException
+
+ private String getDescription(ParameterAnnotationType[] types)
{
- if (AspectManager.verbose)
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 1; i < types.length; i++)
{
- throw new ParameterAnnotationRuleException("\n[warn] -parameter " + i +
- " of method " + method + " contains more than one valid annotation");
+ buffer.append("\n ");
+ buffer.append(types[i]);
}
- else
- {
- throw new ParameterAnnotationRuleException(null);
- }
+ return buffer.toString();
}
-
+
/**
- * Throws an exception indicating the ith parameter of this advice is not annotated.
+ * Searches for an annotation <code>Annotation</code> on parameter annotation
+ * rules.
*
- * @param i the index of the not annotated parameter.
+ * @param annotation the parameter annotation to be searched on the parameter
+ * annotation rules
+ * @param i the number of the advice parameter that is annotated with
+ * <code>annotation</code>
*
- * @throws ParameterAnnotationRuleException
+ * @return <code>true</code> if there is a rule correspondent to
+ * <code>annotation</code>
+ *
+ * @throws ParameterAnnotationRuleException if a parameter annotation is found
+ * more than once and the annotation rule forbides multiple occurences
*/
- private final void throwAnnotationNotFoundException(int i)
+ private final boolean findAnnotationRule(Annotation annotation, int i)
throws ParameterAnnotationRuleException
{
- if (AspectManager.verbose)
+
+ for (int j = 0; j < paramTypes.length; j++)
{
- throw new ParameterAnnotationRuleException("\n[warn] -parameter " + i +
- " of method " + method + " is not annotated");
+ // found
+ if (paramTypes[j].applies(annotation, i))
+ {
+ return true;
+ }
}
- else
+ for (int j = 0; j < contextParamTypes.length; j++)
{
- throw new ParameterAnnotationRuleException(null);
+ // found
+ if (contextParamTypes[j].applies(annotation, i))
+ {
+ return true;
+ }
}
+ return false;
}
-
+
/**
* Contains validation data concerning a parameter annotation rule.
*/
@@ -348,6 +338,10 @@
return internalValidate(properties);
}
+ public String toString()
+ {
+ return rule.getAnnotation().toString();
+ }
/**
* Records that the parameter identified by <code>paramterIndex</code> is of this
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParameterAnnotationRule.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParameterAnnotationRule.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParameterAnnotationRule.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -56,24 +56,30 @@
return properties.getJoinpointReturnType();
}
},
-
+
/**
- * Rule for parameter annotation {@link Callee}.
- */
- CALLEE (
- Callee.class, null, AdviceMethodProperties.CALLEE_ARG, 45, false, true),
-
- /**
* Rule for parameter annotation {@link Caller}.
*/
CALLER (
- Caller.class, null, AdviceMethodProperties.CALLER_ARG, 45, false, true),
+ Caller.class, null, AdviceMethodProperties.CALLER_ARG, 45, false, true)
+ {
+ public Object getAssignableFrom(AdviceMethodProperties properties)
+ {
+ return null; // TODO caller
+ }
+ },
/**
* Rule for parameter annotation {@link Target}.
*/
TARGET (
- Target.class, null, AdviceMethodProperties.TARGET_ARG, 90, false, true),
+ Target.class, null, AdviceMethodProperties.TARGET_ARG, 90, false, true)
+ {
+ public Object getAssignableFrom(AdviceMethodProperties properties)
+ {
+ return properties.getTargetType();
+ }
+ },
/**
* Rule for parameter annotation {@link Arg}.
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByConJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByConJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByConJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -37,6 +37,7 @@
import org.jboss.aop.GeneratedClassAdvisor;
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.ConstructorCalledByConstructorInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -120,7 +121,9 @@
INVOCATION_TYPE,
ctor.getDeclaringClass(),
ctor.getParameterTypes(),
- ctor.getExceptionTypes());
+ ctor.getExceptionTypes(),
+ null,
+ Context.CALLER_AVAILABLE);
}
protected boolean isCaller()
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByMethodJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByMethodJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConByMethodJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -37,6 +37,7 @@
import org.jboss.aop.GeneratedClassAdvisor;
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.ConstructorCalledByMethodInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -128,7 +129,9 @@
INVOCATION_TYPE,
ctor.getDeclaringClass(),
ctor.getParameterTypes(),
- ctor.getExceptionTypes());
+ ctor.getExceptionTypes(),
+ null,
+ hasCallingObject()? Context.CALLER_AVAILABLE: Context.STATIC);
}
protected boolean isCaller()
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructionJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructionJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructionJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -38,6 +38,7 @@
import org.jboss.aop.GeneratedClassAdvisor;
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.ConstructionInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -113,7 +114,9 @@
INVOCATION_TYPE,
ctor.getDeclaringClass(),
ctor.getParameterTypes(),
- ctor.getExceptionTypes());
+ ctor.getExceptionTypes(),
+ ctor.getDeclaringClass(),
+ Context.TARGET_AVAILABLE);
}
protected boolean hasTargetObject()
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructorJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructorJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/ConstructorJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -38,6 +38,7 @@
import org.jboss.aop.GeneratedClassAdvisor;
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.ConstructorInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -114,7 +115,9 @@
INVOCATION_TYPE,
ctor.getDeclaringClass(),
ctor.getParameterTypes(),
- ctor.getExceptionTypes());
+ ctor.getExceptionTypes(),
+ null,
+ Context.STATIC);
}
protected boolean hasTargetObject()
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/FieldJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/FieldJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/FieldJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -37,6 +37,7 @@
import org.jboss.aop.GeneratedClassAdvisor;
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.FieldReadInvocation;
import org.jboss.aop.joinpoint.FieldWriteInvocation;
import org.jboss.aop.util.JavassistToReflect;
@@ -122,6 +123,19 @@
protected AdviceMethodProperties getAdviceMethodProperties(AdviceSetup setup)
{
Field field = ((FieldInfo)info).getAdvisedField();
+ if (hasTargetObject())
+ {
+ return new AdviceMethodProperties(
+ setup.getAspectClass(),
+ setup.getAdviceName(),
+ info.getClass(),
+ (read()) ? READ_INVOCATION_TYPE : WRITE_INVOCATION_TYPE,
+ (read()) ? getReturnType() : Void.TYPE,
+ (read()) ? new Class[] {} : new Class[] {field.getType()},
+ null,
+ field.getDeclaringClass(),
+ Context.TARGET_AVAILABLE);
+ }
return new AdviceMethodProperties(
setup.getAspectClass(),
setup.getAdviceName(),
@@ -129,7 +143,9 @@
(read()) ? READ_INVOCATION_TYPE : WRITE_INVOCATION_TYPE,
(read()) ? getReturnType() : Void.TYPE,
(read()) ? new Class[] {} : new Class[] {field.getType()},
- null);
+ null,
+ null,
+ Context.STATIC);
}
protected CtClass[] getJoinpointParameters() throws NotFoundException
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/JoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/JoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/JoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -64,13 +64,7 @@
{
// TODO replace by enum
protected static class JoinPointParameters {
- public static final JoinPointParameters ONLY_ARGS = new JoinPointParameters(false, -1, false, -1, 0, "")
- {
- /*public String declareArgsArray(int argsSize)
- {
- return "Object[] " + ARGUMENTS + " = new Object[]{$$};";
- }*/
- };
+ public static final JoinPointParameters ONLY_ARGS = new JoinPointParameters(false, -1, false, -1, 0, "");
public static final JoinPointParameters TARGET_ARGS = new JoinPointParameters(true, 1, false, -1, 1, "$1");
public static final JoinPointParameters CALLER_ARGS = new JoinPointParameters(false, -1, true, 1, 1, "$1");
public static final JoinPointParameters TARGET_CALLER_ARGS = new JoinPointParameters(true, 1, true, 2, 2, "$1, $2");
@@ -1674,15 +1668,7 @@
code.append(");");
return argsFound;
}
- /**
- * @param code
- * @param isAround
- * @param args
- * @param adviceParams
- * @param argsFound
- * @param i
- * @return
- */
+
private final boolean appendParameters(StringBuffer code, final int arg,
final Class adviceParam, boolean isAround, JoinPointGenerator generator)
{
@@ -1704,6 +1690,16 @@
case AdviceMethodProperties.THROWABLE_ARG:
code.append(THROWABLE);
break;
+ case AdviceMethodProperties.TARGET_ARG:
+ if (isAround)
+ {
+ code.append(TARGET_FIELD);
+ }
+ else
+ {
+ code.append("$1");
+ }
+ return true;
case AdviceMethodProperties.ARGS_ARG:
code.append(ARGUMENTS);
return true;
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByConJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByConJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByConJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -37,6 +37,7 @@
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.MethodByConInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.MethodCalledByConstructorInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -116,6 +117,19 @@
protected AdviceMethodProperties getAdviceMethodProperties(AdviceSetup setup)
{
Method method = ((MethodByConInfo)info).getMethod();
+ if (hasTargetObject())
+ {
+ return new AdviceMethodProperties(
+ setup.getAspectClass(),
+ setup.getAdviceName(),
+ info.getClass(),
+ INVOCATION_TYPE,
+ method.getReturnType(),
+ method.getParameterTypes(),
+ method.getExceptionTypes(),
+ method.getDeclaringClass(),
+ Context.TARGET_AVAILABLE);
+ }
return new AdviceMethodProperties(
setup.getAspectClass(),
setup.getAdviceName(),
@@ -123,7 +137,9 @@
INVOCATION_TYPE,
method.getReturnType(),
method.getParameterTypes(),
- method.getExceptionTypes());
+ method.getExceptionTypes(),
+ null,
+ Context.STATIC);
}
protected boolean isCaller()
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByMethodJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByMethodJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodByMethodJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -37,6 +37,7 @@
import org.jboss.aop.JoinPointInfo;
import org.jboss.aop.MethodByMethodInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.MethodCalledByMethodInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -123,6 +124,21 @@
protected AdviceMethodProperties getAdviceMethodProperties(AdviceSetup setup)
{
Method method = ((MethodByMethodInfo)info).getMethod();
+ if (hasTargetObject())
+ {
+ return new AdviceMethodProperties(
+ setup.getAspectClass(),
+ setup.getAdviceName(),
+ info.getClass(),
+ INVOCATION_TYPE,
+ method.getReturnType(),
+ method.getParameterTypes(),
+ method.getExceptionTypes(),
+ method.getDeclaringClass(),
+ hasCallingObject()?
+ Context.TARGET_CALLER_AVAILABLE:
+ Context.TARGET_AVAILABLE);
+ }
return new AdviceMethodProperties(
setup.getAspectClass(),
setup.getAdviceName(),
@@ -130,7 +146,9 @@
INVOCATION_TYPE,
method.getReturnType(),
method.getParameterTypes(),
- method.getExceptionTypes());
+ method.getExceptionTypes(),
+ null,
+ hasCallingObject()? Context.CALLER_AVAILABLE: Context.STATIC);
}
protected boolean isCaller()
Modified: projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodJoinPointGenerator.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodJoinPointGenerator.java 2006-12-29 17:08:21 UTC (rev 59245)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/instrument/MethodJoinPointGenerator.java 2006-12-29 23:52:03 UTC (rev 59246)
@@ -36,6 +36,7 @@
import org.jboss.aop.GeneratedClassAdvisor;
import org.jboss.aop.MethodInfo;
import org.jboss.aop.advice.AdviceMethodProperties;
+import org.jboss.aop.advice.AdviceMethodProperties.Context;
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.aop.util.ReflectToJavassist;
@@ -109,6 +110,19 @@
protected AdviceMethodProperties getAdviceMethodProperties(AdviceSetup setup)
{
Method method = ((MethodInfo)info).getAdvisedMethod();
+ if (hasTargetObject())
+ {
+ return new AdviceMethodProperties(
+ setup.getAspectClass(),
+ setup.getAdviceName(),
+ info.getClass(),
+ INVOCATION_TYPE,
+ method.getReturnType(),
+ method.getParameterTypes(),
+ method.getExceptionTypes(),
+ method.getDeclaringClass(),
+ Context.TARGET_AVAILABLE);
+ }
return new AdviceMethodProperties(
setup.getAspectClass(),
setup.getAdviceName(),
@@ -116,7 +130,9 @@
INVOCATION_TYPE,
method.getReturnType(),
method.getParameterTypes(),
- method.getExceptionTypes());
+ method.getExceptionTypes(),
+ null,
+ Context.STATIC);
}
More information about the jboss-cvs-commits
mailing list