summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraclement <aclement>2008-10-21 22:50:52 +0000
committeraclement <aclement>2008-10-21 22:50:52 +0000
commit471db173df94e16aeca5edaa0a5f2948bcf3c50e (patch)
tree1338a04b65e25f5263aaff828dcce7aaf4bb78bb
parentc6d17d523c24fa884b61f27c171514e4d55a011b (diff)
downloadaspectj-471db173df94e16aeca5edaa0a5f2948bcf3c50e.tar.gz
aspectj-471db173df94e16aeca5edaa0a5f2948bcf3c50e.zip
246125: c16
-rw-r--r--weaver/src/org/aspectj/weaver/WeakClassLoaderReference.java8
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelWeakClassLoaderReference.java49
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelWorld.java5
-rw-r--r--weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java5
-rw-r--r--weaver/src/org/aspectj/weaver/tools/PointcutParser.java942
5 files changed, 519 insertions, 490 deletions
diff --git a/weaver/src/org/aspectj/weaver/WeakClassLoaderReference.java b/weaver/src/org/aspectj/weaver/WeakClassLoaderReference.java
index 3f0bdb8bd..bcf650286 100644
--- a/weaver/src/org/aspectj/weaver/WeakClassLoaderReference.java
+++ b/weaver/src/org/aspectj/weaver/WeakClassLoaderReference.java
@@ -13,8 +13,6 @@ package org.aspectj.weaver;
import java.lang.ref.WeakReference;
-import org.aspectj.apache.bcel.util.ClassLoaderReference;
-
/**
* Wraps a reference to a classloader inside a WeakReference. This should be used where we do not want the existence of a
* classloader reference to prevent garbage collection of that classloader (and possibly an associated weaver instance in the case
@@ -34,11 +32,11 @@ import org.aspectj.apache.bcel.util.ClassLoaderReference;
*
* @author Andy Clement
*/
-public class WeakClassLoaderReference implements ClassLoaderReference {
+public class WeakClassLoaderReference {
- private int hashcode;
+ protected final int hashcode;
- private WeakReference loaderRef;
+ private final WeakReference loaderRef;
public WeakClassLoaderReference(ClassLoader loader) {
loaderRef = new WeakReference(loader);
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeakClassLoaderReference.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeakClassLoaderReference.java
new file mode 100644
index 000000000..aac294fa4
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeakClassLoaderReference.java
@@ -0,0 +1,49 @@
+/* *******************************************************************
+ * Copyright (c) 2008 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.bcel;
+
+import org.aspectj.apache.bcel.util.ClassLoaderReference;
+import org.aspectj.weaver.WeakClassLoaderReference;
+
+/**
+ * Wraps a reference to a classloader inside a WeakReference. This should be used where we do not want the existence of a
+ * classloader reference to prevent garbage collection of that classloader (and possibly an associated weaver instance in the case
+ * of load time weaving).
+ * <p>
+ * In more detail:<br>
+ * When load time weaving, the class Aj maintains a WeakHashMap from the classloader instance to a weaver instance. The aim is that
+ * the weaver is around as long as the classloader is and should the classloader be dereferenced then the weaver can also be garbage
+ * collected. The problem is that if there are many references to the classloader from within the weaver, these are considered hard
+ * references and cause the classloader to be long lived - even if the user of the classloader has dereferenced it in their code.
+ * The solution is that the weaver should use instances of WeakClassLoaderReference objects - so that when the users hard reference
+ * to the classloader goes, nothing in the weaver will cause it to hang around. There is a big assertion here that the
+ * WeakClassLoaderReference instances will not 'lose' their ClassLoader references until the top level ClassLoader reference is
+ * null'd. This means there is no need to check for the null case on get() in this WeakReference logic below, because we shouldn't
+ * be using this weaver if its associated ClassLoader has been collected. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=210470
+ *
+ *
+ * @author Andy Clement
+ */
+public class BcelWeakClassLoaderReference extends WeakClassLoaderReference implements ClassLoaderReference {
+
+ public BcelWeakClassLoaderReference(ClassLoader loader) {
+ super(loader);
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof BcelWeakClassLoaderReference))
+ return false;
+ BcelWeakClassLoaderReference other = (BcelWeakClassLoaderReference) obj;
+ return (other.hashcode == hashcode);
+ }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
index 2453765bc..47f15a22c 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
@@ -66,7 +66,6 @@ import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.UnresolvedType;
-import org.aspectj.weaver.WeakClassLoaderReference;
import org.aspectj.weaver.World;
import org.aspectj.weaver.model.AsmRelationshipProvider;
import org.aspectj.weaver.patterns.DeclareAnnotation;
@@ -78,7 +77,7 @@ public class BcelWorld extends World implements Repository {
private final ClassPathManager classPath;
protected Repository delegate;
- private WeakClassLoaderReference loaderRef;
+ private BcelWeakClassLoaderReference loaderRef;
private final BcelWeavingSupport bcelWeavingSupport = new BcelWeavingSupport();
private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWorld.class);
@@ -286,7 +285,7 @@ public class BcelWorld extends World implements Repository {
*/
public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) {
classPath = null;
- loaderRef = new WeakClassLoaderReference(loader);
+ loaderRef = new BcelWeakClassLoaderReference(loader);
setMessageHandler(handler);
setCrossReferenceHandler(xrefHandler);
// Tell BCEL to use us for resolving any classes
diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java
index 24b098e3c..4f14303d6 100644
--- a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java
+++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java
@@ -25,9 +25,8 @@ import org.aspectj.weaver.WeakClassLoaderReference;
import org.aspectj.weaver.World;
/**
- * A ReflectionWorld is used solely for purposes of type resolution based on the
- * runtime classpath (java.lang.reflect). It does not support weaving operations
- * (creation of mungers etc..).
+ * A ReflectionWorld is used solely for purposes of type resolution based on the runtime classpath (java.lang.reflect). It does not
+ * support weaving operations (creation of mungers etc..).
*
*/
public class ReflectionWorld extends World implements IReflectionWorld {
diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
index 3e651f0ca..13841b71d 100644
--- a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
+++ b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java
@@ -51,494 +51,478 @@ import org.aspectj.weaver.reflect.PointcutParameterImpl;
import org.aspectj.weaver.reflect.ReflectionWorld;
/**
- * A PointcutParser can be used to build PointcutExpressions for a
- * user-defined subset of AspectJ's pointcut language
+ * A PointcutParser can be used to build PointcutExpressions for a user-defined subset of AspectJ's pointcut language
*/
public class PointcutParser {
-
+
private ReflectionWorld world;
private WeakClassLoaderReference classLoaderReference;
- private Set supportedPrimitives;
- private Set pointcutDesignators = new HashSet();
-
- /**
- * @return a Set containing every PointcutPrimitive except
- * if, cflow, and cflowbelow (useful for passing to
- * PointcutParser constructor).
- */
- public static Set getAllSupportedPointcutPrimitives() {
- Set primitives = new HashSet();
- primitives.add(PointcutPrimitive.ADVICE_EXECUTION);
- primitives.add(PointcutPrimitive.ARGS);
- primitives.add(PointcutPrimitive.CALL);
- primitives.add(PointcutPrimitive.EXECUTION);
- primitives.add(PointcutPrimitive.GET);
- primitives.add(PointcutPrimitive.HANDLER);
- primitives.add(PointcutPrimitive.INITIALIZATION);
- primitives.add(PointcutPrimitive.PRE_INITIALIZATION);
- primitives.add(PointcutPrimitive.SET);
- primitives.add(PointcutPrimitive.STATIC_INITIALIZATION);
- primitives.add(PointcutPrimitive.TARGET);
- primitives.add(PointcutPrimitive.THIS);
- primitives.add(PointcutPrimitive.WITHIN);
- primitives.add(PointcutPrimitive.WITHIN_CODE);
- primitives.add(PointcutPrimitive.AT_ANNOTATION);
- primitives.add(PointcutPrimitive.AT_THIS);
- primitives.add(PointcutPrimitive.AT_TARGET);
- primitives.add(PointcutPrimitive.AT_ARGS);
- primitives.add(PointcutPrimitive.AT_WITHIN);
- primitives.add(PointcutPrimitive.AT_WITHINCODE);
- primitives.add(PointcutPrimitive.REFERENCE);
-
- return primitives;
- }
-
- /**
- * Returns a pointcut parser that can parse the full AspectJ pointcut
- * language with the following exceptions:
- * <ul>
- * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
- * <li>Pointcut expressions must be self-contained :- they cannot contain references
- * to other named pointcuts
- * <li>The pointcut expression must be anonymous with no formals allowed.
- * </ul>
- * <p>When resolving types in pointcut expressions, the context classloader is used to find types.</p>
- */
- public static PointcutParser getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution() {
- PointcutParser p = new PointcutParser();
- p.setClassLoader(Thread.currentThread().getContextClassLoader());
- return p;
- }
-
- /**
- * Returns a pointcut parser that can parse pointcut expressions built
- * from a user-defined subset of AspectJ's supported pointcut primitives.
- * The following restrictions apply:
- * <ul>
- * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
- * <li>Pointcut expressions must be self-contained :- they cannot contain references
- * to other named pointcuts
- * <li>The pointcut expression must be anonymous with no formals allowed.
- * </ul>
- * <p>When resolving types in pointcut expressions, the context classloader is used to find types.</p>
- * @param supportedPointcutKinds a set of PointcutPrimitives this parser
- * should support
- * @throws UnsupportedOperationException if the set contains if, cflow, or
- * cflow below
- */
- public static PointcutParser getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(Set supportedPointcutKinds) {
- PointcutParser p = new PointcutParser(supportedPointcutKinds);
- p.setClassLoader(Thread.currentThread().getContextClassLoader());
- return p;
- }
-
- /**
- * Returns a pointcut parser that can parse the full AspectJ pointcut
- * language with the following exceptions:
- * <ul>
- * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
- * <li>Pointcut expressions must be self-contained :- they cannot contain references
- * to other named pointcuts
- * <li>The pointcut expression must be anonymous with no formals allowed.
- * </ul>
- * <p>When resolving types in pointcut expressions, the given classloader is used to find types.</p>
- */
- public static PointcutParser getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(ClassLoader classLoader) {
- PointcutParser p = new PointcutParser();
+ private final Set supportedPrimitives;
+ private final Set pointcutDesignators = new HashSet();
+
+ /**
+ * @return a Set containing every PointcutPrimitive except if, cflow, and cflowbelow (useful for passing to PointcutParser
+ * constructor).
+ */
+ public static Set getAllSupportedPointcutPrimitives() {
+ Set primitives = new HashSet();
+ primitives.add(PointcutPrimitive.ADVICE_EXECUTION);
+ primitives.add(PointcutPrimitive.ARGS);
+ primitives.add(PointcutPrimitive.CALL);
+ primitives.add(PointcutPrimitive.EXECUTION);
+ primitives.add(PointcutPrimitive.GET);
+ primitives.add(PointcutPrimitive.HANDLER);
+ primitives.add(PointcutPrimitive.INITIALIZATION);
+ primitives.add(PointcutPrimitive.PRE_INITIALIZATION);
+ primitives.add(PointcutPrimitive.SET);
+ primitives.add(PointcutPrimitive.STATIC_INITIALIZATION);
+ primitives.add(PointcutPrimitive.TARGET);
+ primitives.add(PointcutPrimitive.THIS);
+ primitives.add(PointcutPrimitive.WITHIN);
+ primitives.add(PointcutPrimitive.WITHIN_CODE);
+ primitives.add(PointcutPrimitive.AT_ANNOTATION);
+ primitives.add(PointcutPrimitive.AT_THIS);
+ primitives.add(PointcutPrimitive.AT_TARGET);
+ primitives.add(PointcutPrimitive.AT_ARGS);
+ primitives.add(PointcutPrimitive.AT_WITHIN);
+ primitives.add(PointcutPrimitive.AT_WITHINCODE);
+ primitives.add(PointcutPrimitive.REFERENCE);
+
+ return primitives;
+ }
+
+ /**
+ * Returns a pointcut parser that can parse the full AspectJ pointcut language with the following exceptions:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ * <p>
+ * When resolving types in pointcut expressions, the context classloader is used to find types.
+ * </p>
+ */
+ public static PointcutParser getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution() {
+ PointcutParser p = new PointcutParser();
+ p.setClassLoader(Thread.currentThread().getContextClassLoader());
+ return p;
+ }
+
+ /**
+ * Returns a pointcut parser that can parse pointcut expressions built from a user-defined subset of AspectJ's supported
+ * pointcut primitives. The following restrictions apply:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ * <p>
+ * When resolving types in pointcut expressions, the context classloader is used to find types.
+ * </p>
+ *
+ * @param supportedPointcutKinds a set of PointcutPrimitives this parser should support
+ * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below
+ */
+ public static PointcutParser getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(
+ Set supportedPointcutKinds) {
+ PointcutParser p = new PointcutParser(supportedPointcutKinds);
+ p.setClassLoader(Thread.currentThread().getContextClassLoader());
+ return p;
+ }
+
+ /**
+ * Returns a pointcut parser that can parse the full AspectJ pointcut language with the following exceptions:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ * <p>
+ * When resolving types in pointcut expressions, the given classloader is used to find types.
+ * </p>
+ */
+ public static PointcutParser getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(
+ ClassLoader classLoader) {
+ PointcutParser p = new PointcutParser();
p.setClassLoader(classLoader);
return p;
- }
-
-
- /**
- * Returns a pointcut parser that can parse pointcut expressions built
- * from a user-defined subset of AspectJ's supported pointcut primitives.
- * The following restrictions apply:
- * <ul>
- * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
- * <li>Pointcut expressions must be self-contained :- they cannot contain references
- * to other named pointcuts
- * <li>The pointcut expression must be anonymous with no formals allowed.
- * </ul>
- * <p>When resolving types in pointcut expressions, the given classloader is used to find types.</p>
- * @param supportedPointcutKinds a set of PointcutPrimitives this parser
- * should support
- * @throws UnsupportedOperationException if the set contains if, cflow, or
- * cflow below
- */
- public static PointcutParser getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(Set supportedPointcutKinds, ClassLoader classLoader) {
- PointcutParser p = new PointcutParser(supportedPointcutKinds);
+ }
+
+ /**
+ * Returns a pointcut parser that can parse pointcut expressions built from a user-defined subset of AspectJ's supported
+ * pointcut primitives. The following restrictions apply:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ * <p>
+ * When resolving types in pointcut expressions, the given classloader is used to find types.
+ * </p>
+ *
+ * @param supportedPointcutKinds a set of PointcutPrimitives this parser should support
+ * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below
+ */
+ public static PointcutParser getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
+ Set supportedPointcutKinds, ClassLoader classLoader) {
+ PointcutParser p = new PointcutParser(supportedPointcutKinds);
p.setClassLoader(classLoader);
- return p;
- }
-
- /**
- * Create a pointcut parser that can parse the full AspectJ pointcut
- * language with the following exceptions:
- * <ul>
- * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
- * <li>Pointcut expressions must be self-contained :- they cannot contain references
- * to other named pointcuts
- * <li>The pointcut expression must be anonymous with no formals allowed.
- * </ul>
- */
- protected PointcutParser() {
- supportedPrimitives = getAllSupportedPointcutPrimitives();
- setClassLoader(PointcutParser.class.getClassLoader());
- }
-
- /**
- * Create a pointcut parser that can parse pointcut expressions built
- * from a user-defined subset of AspectJ's supported pointcut primitives.
- * The following restrictions apply:
- * <ul>
- * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
- * <li>Pointcut expressions must be self-contained :- they cannot contain references
- * to other named pointcuts
- * <li>The pointcut expression must be anonymous with no formals allowed.
- * </ul>
- * @param supportedPointcutKinds a set of PointcutPrimitives this parser
- * should support
- * @throws UnsupportedOperationException if the set contains if, cflow, or
- * cflow below
- */
- private PointcutParser(Set/*<PointcutPrimitives>*/ supportedPointcutKinds) {
- supportedPrimitives = supportedPointcutKinds;
- for (Iterator iter = supportedPointcutKinds.iterator(); iter.hasNext();) {
- PointcutPrimitive element = (PointcutPrimitive) iter.next();
- if ((element == PointcutPrimitive.IF) ||
- (element == PointcutPrimitive.CFLOW) ||
- (element == PointcutPrimitive.CFLOW_BELOW)) {
- throw new UnsupportedOperationException("Cannot handle if, cflow, and cflowbelow primitives");
- }
- }
- setClassLoader(PointcutParser.class.getClassLoader());
- }
-
- protected void setWorld(ReflectionWorld aWorld) {
- this.world = aWorld;
- }
-
- /**
- * Set the classloader that this parser should use for
- * type resolution.
- * @param aLoader
- */
- protected void setClassLoader(ClassLoader aLoader) {
- this.classLoaderReference = new WeakClassLoaderReference(aLoader);
- world = new ReflectionWorld(this.classLoaderReference.getClassLoader());
- }
-
- /**
- * Set the lint properties for this parser from the
- * given resource on the classpath.
- * @param resourcePath path to a file containing aspectj
- * lint properties
- */
- public void setLintProperties(String resourcePath)throws IOException {
- URL url = this.classLoaderReference.getClassLoader().getResource(resourcePath);
- InputStream is = url.openStream();
- Properties p = new Properties();
+ return p;
+ }
+
+ /**
+ * Create a pointcut parser that can parse the full AspectJ pointcut language with the following exceptions:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ */
+ protected PointcutParser() {
+ supportedPrimitives = getAllSupportedPointcutPrimitives();
+ setClassLoader(PointcutParser.class.getClassLoader());
+ }
+
+ /**
+ * Create a pointcut parser that can parse pointcut expressions built from a user-defined subset of AspectJ's supported pointcut
+ * primitives. The following restrictions apply:
+ * <ul>
+ * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+ * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+ * <li>The pointcut expression must be anonymous with no formals allowed.
+ * </ul>
+ *
+ * @param supportedPointcutKinds a set of PointcutPrimitives this parser should support
+ * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below
+ */
+ private PointcutParser(Set/* <PointcutPrimitives> */supportedPointcutKinds) {
+ supportedPrimitives = supportedPointcutKinds;
+ for (Iterator iter = supportedPointcutKinds.iterator(); iter.hasNext();) {
+ PointcutPrimitive element = (PointcutPrimitive) iter.next();
+ if ((element == PointcutPrimitive.IF) || (element == PointcutPrimitive.CFLOW)
+ || (element == PointcutPrimitive.CFLOW_BELOW)) {
+ throw new UnsupportedOperationException("Cannot handle if, cflow, and cflowbelow primitives");
+ }
+ }
+ setClassLoader(PointcutParser.class.getClassLoader());
+ }
+
+ protected void setWorld(ReflectionWorld aWorld) {
+ this.world = aWorld;
+ }
+
+ /**
+ * Set the classloader that this parser should use for type resolution.
+ *
+ * @param aLoader
+ */
+ protected void setClassLoader(ClassLoader aLoader) {
+ this.classLoaderReference = new WeakClassLoaderReference(aLoader);
+ world = new ReflectionWorld(this.classLoaderReference.getClassLoader());
+ }
+
+ /**
+ * Set the lint properties for this parser from the given resource on the classpath.
+ *
+ * @param resourcePath path to a file containing aspectj lint properties
+ */
+ public void setLintProperties(String resourcePath) throws IOException {
+ URL url = this.classLoaderReference.getClassLoader().getResource(resourcePath);
+ InputStream is = url.openStream();
+ Properties p = new Properties();
p.load(is);
setLintProperties(p);
- }
-
- /**
- * Set the lint properties for this parser from the
- * given properties set.
- * @param properties
- */
- public void setLintProperties(Properties properties) {
- getWorld().getLint().setFromProperties(properties);
- }
-
- /**
- * Register a new pointcut designator handler with this parser.
- * This provides an extension mechansim for the integration of
- * domain-specific pointcut designators with the AspectJ
- * pointcut language.
- * @param designatorHandler
- */
- public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) {
- this.pointcutDesignators.add(designatorHandler);
- if (world != null) world.registerPointcutHandler(designatorHandler);
- }
-
- /**
- * Create a pointcut parameter of the given name and type.
- * @param name
- * @param type
- * @return
- */
- public PointcutParameter createPointcutParameter(String name, Class type) {
- return new PointcutParameterImpl(name,type);
- }
-
- /**
- * Parse the given pointcut expression.
- * A global scope is assumed for resolving any type references, and the pointcut
- * must contain no formals (variables to be bound).
- * @throws UnsupportedPointcutPrimitiveException if the parser encounters a
- * primitive pointcut expression of a kind not supported by this PointcutParser.
- * @throws IllegalArgumentException if the expression is not a well-formed
- * pointcut expression
- */
- public PointcutExpression parsePointcutExpression(String expression)
- throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
- return parsePointcutExpression(expression,null,new PointcutParameter[0]);
- }
-
- /**
- * Parse the given pointcut expression.
- * The pointcut is resolved as if it had been declared inside the inScope class
- * (this allows the pointcut to contain unqualified references to other pointcuts
- * declared in the same type for example).
- * The pointcut may contain zero or more formal parameters to be bound at matched
- * join points.
- * @throws UnsupportedPointcutPrimitiveException if the parser encounters a
- * primitive pointcut expression of a kind not supported by this PointcutParser.
- * @throws IllegalArgumentException if the expression is not a well-formed
- * pointcut expression
- */
- public PointcutExpression parsePointcutExpression(
- String expression,
- Class inScope,
- PointcutParameter[] formalParameters)
- throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
- PointcutExpressionImpl pcExpr = null;
- try {
- Pointcut pc = resolvePointcutExpression(expression,inScope,formalParameters);
- pc = concretizePointcutExpression(pc,inScope,formalParameters);
- validateAgainstSupportedPrimitives(pc,expression); // again, because we have now followed any ref'd pcuts
- pcExpr = new PointcutExpressionImpl(pc,expression,formalParameters,getWorld());
- } catch (ParserException pEx) {
- throw new IllegalArgumentException(buildUserMessageFromParserException(expression,pEx));
- } catch (ReflectionWorld.ReflectionWorldException rwEx) {
- throw new IllegalArgumentException(rwEx.getMessage());
- }
- return pcExpr;
- }
-
- protected Pointcut resolvePointcutExpression(
- String expression,
- Class inScope,
- PointcutParameter[] formalParameters) {
- try {
- PatternParser parser = new PatternParser(expression);
- parser.setPointcutDesignatorHandlers(pointcutDesignators, world);
- Pointcut pc = parser.parsePointcut();
- validateAgainstSupportedPrimitives(pc,expression);
- IScope resolutionScope = buildResolutionScope((inScope == null ? Object.class : inScope),formalParameters);
- pc = pc.resolve(resolutionScope);
- return pc;
- } catch (ParserException pEx) {
- throw new IllegalArgumentException(buildUserMessageFromParserException(expression,pEx));
- }
- }
-
- protected Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) {
- ResolvedType declaringTypeForResolution = null;
- if (inScope != null) {
- declaringTypeForResolution = getWorld().resolve(inScope.getName());
- } else {
- declaringTypeForResolution = ResolvedType.OBJECT.resolve(getWorld());
- }
- IntMap arity = new IntMap(formalParameters.length);
- for (int i = 0; i < formalParameters.length; i++) {
- arity.put(i, i);
- }
- return pc.concretize(declaringTypeForResolution, declaringTypeForResolution, arity);
- }
-
- /**
- * Parse the given aspectj type pattern, and return a
- * matcher that can be used to match types using it.
- * @param typePattern an aspectj type pattern
- * @return a type pattern matcher that matches using the given
- * pattern
- * @throws IllegalArgumentException if the type pattern cannot
- * be successfully parsed.
- */
- public TypePatternMatcher parseTypePattern(String typePattern)
- throws IllegalArgumentException {
- try {
- TypePattern tp = new PatternParser(typePattern).parseTypePattern();
- tp.resolve(world);
- return new TypePatternMatcherImpl(tp,world);
- } catch (ParserException pEx) {
- throw new IllegalArgumentException(buildUserMessageFromParserException(typePattern,pEx));
- } catch (ReflectionWorld.ReflectionWorldException rwEx) {
- throw new IllegalArgumentException(rwEx.getMessage());
- }
- }
-
- private World getWorld() {
- return world;
- }
-
- /* for testing */
- Set getSupportedPrimitives() {
- return supportedPrimitives;
- }
-
- /* for testing */
- IMessageHandler setCustomMessageHandler(IMessageHandler aHandler) {
- IMessageHandler current = getWorld().getMessageHandler();
- getWorld().setMessageHandler(aHandler);
- return current;
- }
-
- private IScope buildResolutionScope(Class inScope, PointcutParameter[] formalParameters) {
- if (formalParameters == null) formalParameters = new PointcutParameter[0];
- FormalBinding[] formalBindings = new FormalBinding[formalParameters.length];
- for (int i = 0; i < formalBindings.length; i++) {
- formalBindings[i] = new FormalBinding(toUnresolvedType(formalParameters[i].getType()),formalParameters[i].getName(),i);
+ }
+
+ /**
+ * Set the lint properties for this parser from the given properties set.
+ *
+ * @param properties
+ */
+ public void setLintProperties(Properties properties) {
+ getWorld().getLint().setFromProperties(properties);
+ }
+
+ /**
+ * Register a new pointcut designator handler with this parser. This provides an extension mechansim for the integration of
+ * domain-specific pointcut designators with the AspectJ pointcut language.
+ *
+ * @param designatorHandler
+ */
+ public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) {
+ this.pointcutDesignators.add(designatorHandler);
+ if (world != null)
+ world.registerPointcutHandler(designatorHandler);
+ }
+
+ /**
+ * Create a pointcut parameter of the given name and type.
+ *
+ * @param name
+ * @param type
+ * @return
+ */
+ public PointcutParameter createPointcutParameter(String name, Class type) {
+ return new PointcutParameterImpl(name, type);
+ }
+
+ /**
+ * Parse the given pointcut expression. A global scope is assumed for resolving any type references, and the pointcut must
+ * contain no formals (variables to be bound).
+ *
+ * @throws UnsupportedPointcutPrimitiveException if the parser encounters a primitive pointcut expression of a kind not
+ * supported by this PointcutParser.
+ * @throws IllegalArgumentException if the expression is not a well-formed pointcut expression
+ */
+ public PointcutExpression parsePointcutExpression(String expression) throws UnsupportedPointcutPrimitiveException,
+ IllegalArgumentException {
+ return parsePointcutExpression(expression, null, new PointcutParameter[0]);
+ }
+
+ /**
+ * Parse the given pointcut expression. The pointcut is resolved as if it had been declared inside the inScope class (this
+ * allows the pointcut to contain unqualified references to other pointcuts declared in the same type for example). The pointcut
+ * may contain zero or more formal parameters to be bound at matched join points.
+ *
+ * @throws UnsupportedPointcutPrimitiveException if the parser encounters a primitive pointcut expression of a kind not
+ * supported by this PointcutParser.
+ * @throws IllegalArgumentException if the expression is not a well-formed pointcut expression
+ */
+ public PointcutExpression parsePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters)
+ throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
+ PointcutExpressionImpl pcExpr = null;
+ try {
+ Pointcut pc = resolvePointcutExpression(expression, inScope, formalParameters);
+ pc = concretizePointcutExpression(pc, inScope, formalParameters);
+ validateAgainstSupportedPrimitives(pc, expression); // again, because we have now followed any ref'd pcuts
+ pcExpr = new PointcutExpressionImpl(pc, expression, formalParameters, getWorld());
+ } catch (ParserException pEx) {
+ throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx));
+ } catch (ReflectionWorld.ReflectionWorldException rwEx) {
+ throw new IllegalArgumentException(rwEx.getMessage());
}
- if (inScope == null) {
- return new SimpleScope(getWorld(),formalBindings);
- } else {
- ResolvedType inType = getWorld().resolve(inScope.getName());
- ISourceContext sourceContext = new ISourceContext() {
- public ISourceLocation makeSourceLocation(IHasPosition position) {
- return new SourceLocation(new File(""),0);
- }
- public ISourceLocation makeSourceLocation(int line, int offset) {
- return new SourceLocation(new File(""),line);
- }
- public int getOffset() {
- return 0;
- }
- public void tidy() {}
- };
- return new BindingScope(inType,sourceContext,formalBindings);
- }
- }
-
- private UnresolvedType toUnresolvedType(Class clazz) {
- if (clazz.isArray()) {
- return UnresolvedType.forSignature(clazz.getName().replace('.','/'));
- } else {
- return UnresolvedType.forName(clazz.getName());
- }
- }
-
- private void validateAgainstSupportedPrimitives(Pointcut pc, String expression) {
- switch(pc.getPointcutKind()) {
- case Pointcut.AND:
- validateAgainstSupportedPrimitives(((AndPointcut)pc).getLeft(),expression);
- validateAgainstSupportedPrimitives(((AndPointcut)pc).getRight(),expression);
- break;
- case Pointcut.ARGS:
- if (!supportedPrimitives.contains(PointcutPrimitive.ARGS))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ARGS);
- break;
- case Pointcut.CFLOW:
- CflowPointcut cfp = (CflowPointcut) pc;
- if (cfp.isCflowBelow()) {
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW_BELOW);
- } else {
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW);
- }
- case Pointcut.HANDLER:
- if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.HANDLER);
- break;
- case Pointcut.IF:
- case Pointcut.IF_FALSE:
- case Pointcut.IF_TRUE:
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.IF);
- case Pointcut.KINDED:
- validateKindedPointcut(((KindedPointcut)pc),expression);
- break;
- case Pointcut.NOT:
- validateAgainstSupportedPrimitives(((NotPointcut)pc).getNegatedPointcut(),expression);
- break;
- case Pointcut.OR:
- validateAgainstSupportedPrimitives(((OrPointcut)pc).getLeft(),expression);
- validateAgainstSupportedPrimitives(((OrPointcut)pc).getRight(),expression);
- break;
- case Pointcut.THIS_OR_TARGET:
- boolean isThis = ((ThisOrTargetPointcut)pc).isThis();
- if (isThis && !supportedPrimitives.contains(PointcutPrimitive.THIS)) {
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.THIS);
- } else if (!supportedPrimitives.contains(PointcutPrimitive.TARGET)) {
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.TARGET);
- }
- break;
- case Pointcut.WITHIN:
- if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN);
- break;
- case Pointcut.WITHINCODE:
- if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN_CODE);
- break;
- case Pointcut.ATTHIS_OR_TARGET:
- isThis = ((ThisOrTargetAnnotationPointcut)pc).isThis();
- if (isThis && !supportedPrimitives.contains(PointcutPrimitive.AT_THIS)) {
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_THIS);
- } else if (!supportedPrimitives.contains(PointcutPrimitive.AT_TARGET)) {
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_TARGET);
- }
- break;
- case Pointcut.ATARGS:
- if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ARGS);
- break;
- case Pointcut.ANNOTATION:
- if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ANNOTATION);
- break;
- case Pointcut.ATWITHIN:
- if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHIN);
- break;
- case Pointcut.ATWITHINCODE:
- if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHINCODE);
- break;
- case Pointcut.REFERENCE:
- if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE);
- break;
- case Pointcut.USER_EXTENSION:
- // always ok...
- break;
- case Pointcut.NONE: // deliberate fall-through
- default:
- throw new IllegalArgumentException("Unknown pointcut kind: " + pc.getPointcutKind());
- }
- }
-
- private void validateKindedPointcut(KindedPointcut pc, String expression) {
- Shadow.Kind kind = pc.getKind();
- if ((kind == Shadow.MethodCall) || (kind == Shadow.ConstructorCall)) {
- if (!supportedPrimitives.contains(PointcutPrimitive.CALL))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CALL);
- } else if ((kind == Shadow.MethodExecution) || (kind == Shadow.ConstructorExecution)) {
- if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.EXECUTION);
- } else if (kind == Shadow.AdviceExecution) {
- if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ADVICE_EXECUTION);
- } else if (kind == Shadow.FieldGet) {
- if (!supportedPrimitives.contains(PointcutPrimitive.GET))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.GET);
- } else if (kind == Shadow.FieldSet) {
- if (!supportedPrimitives.contains(PointcutPrimitive.SET))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.SET);
- } else if (kind == Shadow.Initialization) {
- if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.INITIALIZATION);
- } else if (kind == Shadow.PreInitialization) {
- if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.PRE_INITIALIZATION);
- } else if (kind == Shadow.StaticInitialization) {
- if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION))
- throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.STATIC_INITIALIZATION);
- }
- }
-
+ return pcExpr;
+ }
+
+ protected Pointcut resolvePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters) {
+ try {
+ PatternParser parser = new PatternParser(expression);
+ parser.setPointcutDesignatorHandlers(pointcutDesignators, world);
+ Pointcut pc = parser.parsePointcut();
+ validateAgainstSupportedPrimitives(pc, expression);
+ IScope resolutionScope = buildResolutionScope((inScope == null ? Object.class : inScope), formalParameters);
+ pc = pc.resolve(resolutionScope);
+ return pc;
+ } catch (ParserException pEx) {
+ throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx));
+ }
+ }
+
+ protected Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) {
+ ResolvedType declaringTypeForResolution = null;
+ if (inScope != null) {
+ declaringTypeForResolution = getWorld().resolve(inScope.getName());
+ } else {
+ declaringTypeForResolution = ResolvedType.OBJECT.resolve(getWorld());
+ }
+ IntMap arity = new IntMap(formalParameters.length);
+ for (int i = 0; i < formalParameters.length; i++) {
+ arity.put(i, i);
+ }
+ return pc.concretize(declaringTypeForResolution, declaringTypeForResolution, arity);
+ }
+
+ /**
+ * Parse the given aspectj type pattern, and return a matcher that can be used to match types using it.
+ *
+ * @param typePattern an aspectj type pattern
+ * @return a type pattern matcher that matches using the given pattern
+ * @throws IllegalArgumentException if the type pattern cannot be successfully parsed.
+ */
+ public TypePatternMatcher parseTypePattern(String typePattern) throws IllegalArgumentException {
+ try {
+ TypePattern tp = new PatternParser(typePattern).parseTypePattern();
+ tp.resolve(world);
+ return new TypePatternMatcherImpl(tp, world);
+ } catch (ParserException pEx) {
+ throw new IllegalArgumentException(buildUserMessageFromParserException(typePattern, pEx));
+ } catch (ReflectionWorld.ReflectionWorldException rwEx) {
+ throw new IllegalArgumentException(rwEx.getMessage());
+ }
+ }
+
+ private World getWorld() {
+ return world;
+ }
+
+ /* for testing */
+ Set getSupportedPrimitives() {
+ return supportedPrimitives;
+ }
+
+ /* for testing */
+ IMessageHandler setCustomMessageHandler(IMessageHandler aHandler) {
+ IMessageHandler current = getWorld().getMessageHandler();
+ getWorld().setMessageHandler(aHandler);
+ return current;
+ }
+
+ private IScope buildResolutionScope(Class inScope, PointcutParameter[] formalParameters) {
+ if (formalParameters == null)
+ formalParameters = new PointcutParameter[0];
+ FormalBinding[] formalBindings = new FormalBinding[formalParameters.length];
+ for (int i = 0; i < formalBindings.length; i++) {
+ formalBindings[i] = new FormalBinding(toUnresolvedType(formalParameters[i].getType()), formalParameters[i].getName(), i);
+ }
+ if (inScope == null) {
+ return new SimpleScope(getWorld(), formalBindings);
+ } else {
+ ResolvedType inType = getWorld().resolve(inScope.getName());
+ ISourceContext sourceContext = new ISourceContext() {
+ public ISourceLocation makeSourceLocation(IHasPosition position) {
+ return new SourceLocation(new File(""), 0);
+ }
+
+ public ISourceLocation makeSourceLocation(int line, int offset) {
+ return new SourceLocation(new File(""), line);
+ }
+
+ public int getOffset() {
+ return 0;
+ }
+
+ public void tidy() {
+ }
+ };
+ return new BindingScope(inType, sourceContext, formalBindings);
+ }
+ }
+
+ private UnresolvedType toUnresolvedType(Class clazz) {
+ if (clazz.isArray()) {
+ return UnresolvedType.forSignature(clazz.getName().replace('.', '/'));
+ } else {
+ return UnresolvedType.forName(clazz.getName());
+ }
+ }
+
+ private void validateAgainstSupportedPrimitives(Pointcut pc, String expression) {
+ switch (pc.getPointcutKind()) {
+ case Pointcut.AND:
+ validateAgainstSupportedPrimitives(((AndPointcut) pc).getLeft(), expression);
+ validateAgainstSupportedPrimitives(((AndPointcut) pc).getRight(), expression);
+ break;
+ case Pointcut.ARGS:
+ if (!supportedPrimitives.contains(PointcutPrimitive.ARGS))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ARGS);
+ break;
+ case Pointcut.CFLOW:
+ CflowPointcut cfp = (CflowPointcut) pc;
+ if (cfp.isCflowBelow()) {
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW_BELOW);
+ } else {
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW);
+ }
+ case Pointcut.HANDLER:
+ if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.HANDLER);
+ break;
+ case Pointcut.IF:
+ case Pointcut.IF_FALSE:
+ case Pointcut.IF_TRUE:
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.IF);
+ case Pointcut.KINDED:
+ validateKindedPointcut(((KindedPointcut) pc), expression);
+ break;
+ case Pointcut.NOT:
+ validateAgainstSupportedPrimitives(((NotPointcut) pc).getNegatedPointcut(), expression);
+ break;
+ case Pointcut.OR:
+ validateAgainstSupportedPrimitives(((OrPointcut) pc).getLeft(), expression);
+ validateAgainstSupportedPrimitives(((OrPointcut) pc).getRight(), expression);
+ break;
+ case Pointcut.THIS_OR_TARGET:
+ boolean isThis = ((ThisOrTargetPointcut) pc).isThis();
+ if (isThis && !supportedPrimitives.contains(PointcutPrimitive.THIS)) {
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.THIS);
+ } else if (!supportedPrimitives.contains(PointcutPrimitive.TARGET)) {
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.TARGET);
+ }
+ break;
+ case Pointcut.WITHIN:
+ if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN);
+ break;
+ case Pointcut.WITHINCODE:
+ if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN_CODE);
+ break;
+ case Pointcut.ATTHIS_OR_TARGET:
+ isThis = ((ThisOrTargetAnnotationPointcut) pc).isThis();
+ if (isThis && !supportedPrimitives.contains(PointcutPrimitive.AT_THIS)) {
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_THIS);
+ } else if (!supportedPrimitives.contains(PointcutPrimitive.AT_TARGET)) {
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_TARGET);
+ }
+ break;
+ case Pointcut.ATARGS:
+ if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ARGS);
+ break;
+ case Pointcut.ANNOTATION:
+ if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ANNOTATION);
+ break;
+ case Pointcut.ATWITHIN:
+ if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHIN);
+ break;
+ case Pointcut.ATWITHINCODE:
+ if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHINCODE);
+ break;
+ case Pointcut.REFERENCE:
+ if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE);
+ break;
+ case Pointcut.USER_EXTENSION:
+ // always ok...
+ break;
+ case Pointcut.NONE: // deliberate fall-through
+ default:
+ throw new IllegalArgumentException("Unknown pointcut kind: " + pc.getPointcutKind());
+ }
+ }
+
+ private void validateKindedPointcut(KindedPointcut pc, String expression) {
+ Shadow.Kind kind = pc.getKind();
+ if ((kind == Shadow.MethodCall) || (kind == Shadow.ConstructorCall)) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.CALL))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CALL);
+ } else if ((kind == Shadow.MethodExecution) || (kind == Shadow.ConstructorExecution)) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.EXECUTION);
+ } else if (kind == Shadow.AdviceExecution) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ADVICE_EXECUTION);
+ } else if (kind == Shadow.FieldGet) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.GET))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.GET);
+ } else if (kind == Shadow.FieldSet) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.SET))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.SET);
+ } else if (kind == Shadow.Initialization) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.INITIALIZATION);
+ } else if (kind == Shadow.PreInitialization) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.PRE_INITIALIZATION);
+ } else if (kind == Shadow.StaticInitialization) {
+ if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION))
+ throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.STATIC_INITIALIZATION);
+ }
+ }
+
private String buildUserMessageFromParserException(String pc, ParserException ex) {
StringBuffer msg = new StringBuffer();
msg.append("Pointcut is not well-formed: expecting '");
@@ -553,7 +537,7 @@ public class PointcutParser {
for (int i = 0; i < location.getStart(); i++) {
msg.append(" ");
}
- for (int j=location.getStart(); j <= location.getEnd(); j++) {
+ for (int j = location.getStart(); j <= location.getEnd(); j++) {
msg.append("^");
}
msg.append("\n");