diff options
18 files changed, 1290 insertions, 54 deletions
diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcPrivileged.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcPrivileged.java new file mode 100644 index 000000000..78ca43e05 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcPrivileged.java @@ -0,0 +1,27 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + + +/** + * @author colyer + * Marker annotation for privileged aspects. + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ajcPrivileged {} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java new file mode 100644 index 000000000..f29d93599 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import java.lang.reflect.Method; + +import org.aspectj.lang.annotation.AdviceName; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceType; + +/** + * @author colyer + * + */ +public class AdviceImpl implements Advice { + + private final AdviceType kind; + private final Method adviceMethod; + private String pointcutExpression; + + protected AdviceImpl(Method method, String pointcut, AdviceType type) { + this.kind = type; + this.adviceMethod = method; + this.pointcutExpression = pointcut; + } + + public AdviceType getKind() { + return kind; + } + + public String getName() { + String adviceName = adviceMethod.getName(); + if (adviceName.startsWith("ajc$")) { + adviceName = ""; + AdviceName name = adviceMethod.getAnnotation(AdviceName.class); + if (name != null) adviceName = name.value(); + } + return adviceName; + } + + public String getPointcutExpression() { + return pointcutExpression; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java index 4fc4ab5a7..09db33898 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java @@ -17,10 +17,23 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.aspectj.internal.lang.annotation.ajcPrivileged; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; import org.aspectj.lang.reflect.Advice; import org.aspectj.lang.reflect.AdviceType; import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; import org.aspectj.lang.reflect.DeclareAnnotation; import org.aspectj.lang.reflect.DeclareErrorOrWarning; import org.aspectj.lang.reflect.DeclareParents; @@ -29,16 +42,26 @@ import org.aspectj.lang.reflect.DeclareSoft; import org.aspectj.lang.reflect.InterTypeConstructorDeclaration; import org.aspectj.lang.reflect.InterTypeFieldDeclaration; import org.aspectj.lang.reflect.InterTypeMethodDeclaration; +import org.aspectj.lang.reflect.NoSuchAdviceException; +import org.aspectj.lang.reflect.NoSuchPointcutException; import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; import org.aspectj.lang.reflect.Pointcut; + /** * @author colyer * */ public class AjTypeImpl<T> implements AjType { + private static final String ajcMagic = "ajc$"; + private Class<T> clazz; + private Pointcut[] declaredPointcuts = null; + private Pointcut[] pointcuts = null; + private Advice[] declaredAdvice = null; + private Advice[] advice = null; public AjTypeImpl(Class<T> fromClass) { this.clazz = fromClass; @@ -117,7 +140,27 @@ public class AjTypeImpl<T> implements AjType { } public PerClause getPerClause() { - return null; + if (isAspect()) { + Aspect aspectAnn = clazz.getAnnotation(Aspect.class); + String perClause = aspectAnn.value(); + if (perClause.equals("")) { + return new PerClauseImpl(PerClauseKind.SINGLETON,""); + } else if (perClause.startsWith("perthis(")) { + return new PerClauseImpl(PerClauseKind.PERTHIS,perClause.substring("perthis(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("pertarget(")) { + return new PerClauseImpl(PerClauseKind.PERTARGET,perClause.substring("pertarget(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("percflow(")) { + return new PerClauseImpl(PerClauseKind.PERCFLOW,perClause.substring("percflow(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("percflowbelow(")) { + return new PerClauseImpl(PerClauseKind.PERCFLOWBELOW,perClause.substring("percflowbelow(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("pertypewithin")) { + return new PerClauseImpl(PerClauseKind.PERTYPEWITHIN,perClause.substring("pertypewithin(".length(),perClause.length() - 1)); + } else { + throw new IllegalStateException("Per-clause not recognized: " + perClause); + } + } else { + return null; + } } /* (non-Javadoc) @@ -201,106 +244,289 @@ public class AjTypeImpl<T> implements AjType { * @see org.aspectj.lang.reflect.AjType#getDeclaredField(java.lang.String) */ public Field getDeclaredField(String name) throws NoSuchFieldException { - return clazz.getDeclaredField(name); + Field f = clazz.getDeclaredField(name); + if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name); + return f; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredFields() */ public Field[] getDeclaredFields() { - return clazz.getDeclaredFields(); + Field[] fields = clazz.getDeclaredFields(); + List<Field> filteredFields = new ArrayList<Field>(); + for (Field field : fields) + if (!field.getName().startsWith(ajcMagic)) filteredFields.add(field); + Field[] ret = new Field[filteredFields.size()]; + filteredFields.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getField(java.lang.String) */ public Field getField(String name) throws NoSuchFieldException { - return clazz.getField(name); + Field f = clazz.getDeclaredField(name); + if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name); + return f; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getFields() */ public Field[] getFields() { - return clazz.getFields(); + Field[] fields = clazz.getFields(); + List<Field> filteredFields = new ArrayList<Field>(); + for (Field field : fields) + if (!field.getName().startsWith(ajcMagic)) filteredFields.add(field); + Field[] ret = new Field[filteredFields.size()]; + filteredFields.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredMethod(java.lang.String, java.lang.Class...) */ public Method getDeclaredMethod(String name, Class... parameterTypes) throws NoSuchMethodException { - return clazz.getDeclaredMethod(name,parameterTypes); + Method m = clazz.getDeclaredMethod(name,parameterTypes); + if (!isReallyAMethod(m)) throw new NoSuchMethodException(name); + return m; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getMethod(java.lang.String, java.lang.Class...) */ public Method getMethod(String name, Class... parameterTypes) throws NoSuchMethodException { - return clazz.getMethod(name,parameterTypes); + Method m = clazz.getMethod(name,parameterTypes); + if (!isReallyAMethod(m)) throw new NoSuchMethodException(name); + return m; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredMethods() */ public Method[] getDeclaredMethods() { - return clazz.getDeclaredMethods(); + Method[] methods = clazz.getDeclaredMethods(); + List<Method> filteredMethods = new ArrayList<Method>(); + for (Method method : methods) { + if (isReallyAMethod(method)) filteredMethods.add(method); + } + Method[] ret = new Method[filteredMethods.size()]; + filteredMethods.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getMethods() */ public Method[] getMethods() { - return clazz.getMethods(); + Method[] methods = clazz.getMethods(); + List<Method> filteredMethods = new ArrayList<Method>(); + for (Method method : methods) { + if (isReallyAMethod(method)) filteredMethods.add(method); + } + Method[] ret = new Method[filteredMethods.size()]; + filteredMethods.toArray(ret); + return ret; } + private boolean isReallyAMethod(Method method) { + if (method.getName().startsWith(ajcMagic)) return false; + if (method.isAnnotationPresent(org.aspectj.lang.annotation.Pointcut.class)) return false; + if (method.isAnnotationPresent(Before.class)) return false; + if (method.isAnnotationPresent(After.class)) return false; + if (method.isAnnotationPresent(AfterReturning.class)) return false; + if (method.isAnnotationPresent(AfterThrowing.class)) return false; + if (method.isAnnotationPresent(Around.class)) return false; + return true; + } + /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredPointcut(java.lang.String) */ - public Pointcut getDeclaredPointcut(String name) { - // TODO Auto-generated method stub - return null; + public Pointcut getDeclaredPointcut(String name) throws NoSuchPointcutException { + Pointcut[] pcs = getDeclaredPointcuts(); + for (Pointcut pc : pcs) + if (pc.getName().equals(name)) return pc; + throw new NoSuchPointcutException(name); } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getPointcut(java.lang.String) */ - public Pointcut getPointcut(String name) { - // TODO Auto-generated method stub - return null; + public Pointcut getPointcut(String name) throws NoSuchPointcutException { + Pointcut[] pcs = getDeclaredPointcuts(); + for (Pointcut pc : pcs) + if (pc.getName().equals(name)) return pc; + throw new NoSuchPointcutException(name); } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredPointcuts() */ public Pointcut[] getDeclaredPointcuts() { - // TODO Auto-generated method stub - return null; + if (declaredPointcuts != null) return declaredPointcuts; + List<Pointcut> pointcuts = new ArrayList<Pointcut>(); + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + Pointcut pc = asPointcut(method); + if (pc != null) pointcuts.add(pc); + } + Pointcut[] ret = new Pointcut[pointcuts.size()]; + pointcuts.toArray(ret); + declaredPointcuts = ret; + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getPointcuts() */ public Pointcut[] getPointcuts() { - // TODO Auto-generated method stub - return null; + if (pointcuts != null) return pointcuts; + List<Pointcut> pcuts = new ArrayList<Pointcut>(); + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + Pointcut pc = asPointcut(method); + if (pc != null) pcuts.add(pc); + } + Pointcut[] ret = new Pointcut[pcuts.size()]; + pcuts.toArray(ret); + pointcuts = ret; + return ret; + } + + private Pointcut asPointcut(Method method) { + org.aspectj.lang.annotation.Pointcut pcAnn = method.getAnnotation(org.aspectj.lang.annotation.Pointcut.class); + if (pcAnn != null) { + String name = method.getName(); + if (name.startsWith(ajcMagic)) { + // extract real name + int nameStart = name.indexOf("$$"); + name = name.substring(nameStart +2,name.length()); + int nextDollar = name.indexOf("$"); + if (nextDollar != -1) name = name.substring(0,nextDollar); + } + return new PointcutImpl(name,pcAnn.value(),method,AjTypeSystem.getAjType(method.getDeclaringClass())); + } else { + return null; + } + } + + + public Advice[] getDeclaredAdvice(AdviceType... ofType) { + Set<AdviceType> types; + if (ofType.length == 0) { + types = EnumSet.allOf(AdviceType.class); + } else { + types = EnumSet.noneOf(AdviceType.class); + types.addAll(Arrays.asList(ofType)); + } + return getDeclaredAdvice(types); + } + + public Advice[] getAdvice(AdviceType... ofType) { + Set<AdviceType> types; + if (ofType.length == 0) { + types = EnumSet.allOf(AdviceType.class); + } else { + types = EnumSet.noneOf(AdviceType.class); + types.addAll(Arrays.asList(ofType)); + } + return getAdvice(types); } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredAdvice(org.aspectj.lang.reflect.AdviceType) */ - public Advice[] getDeclaredAdvice(AdviceType adviceType) { - // TODO Auto-generated method stub - return null; + private Advice[] getDeclaredAdvice(Set ofAdviceTypes) { + if (declaredAdvice == null) initDeclaredAdvice(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Advice a : declaredAdvice) { + if (ofAdviceTypes.contains(a.getKind())) adviceList.add(a); + } + Advice[] ret = new Advice[adviceList.size()]; + adviceList.toArray(ret); + return ret; + } + + private void initDeclaredAdvice() { + Method[] methods = clazz.getDeclaredMethods(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Method method : methods) { + Advice advice = asAdvice(method); + if (advice != null) adviceList.add(advice); + } + declaredAdvice = new Advice[adviceList.size()]; + adviceList.toArray(declaredAdvice); } /* (non-Javadoc) - * @see org.aspectj.lang.reflect.AjType#getAdvice(org.aspectj.lang.reflect.AdviceType) + * @see org.aspectj.lang.reflect.AjType#getDeclaredAdvice(org.aspectj.lang.reflect.AdviceType) */ - public Advice[] getAdvice(AdviceType adviceType) { - // TODO Auto-generated method stub - return null; + private Advice[] getAdvice(Set ofAdviceTypes) { + if (advice == null) initAdvice(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Advice a : advice) { + if (ofAdviceTypes.contains(a.getKind())) adviceList.add(a); + } + Advice[] ret = new Advice[adviceList.size()]; + adviceList.toArray(ret); + return ret; } + private void initAdvice() { + Method[] methods = clazz.getDeclaredMethods(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Method method : methods) { + Advice advice = asAdvice(method); + if (advice != null) adviceList.add(advice); + } + advice = new Advice[adviceList.size()]; + adviceList.toArray(advice); + } + + + public Advice getAdvice(String name) throws NoSuchAdviceException { + if (name.equals("")) throw new IllegalArgumentException("use getAdvice(AdviceType...) instead for un-named advice"); + if (advice == null) initAdvice(); + for (Advice a : advice) { + if (a.getName().equals(name)) return a; + } + throw new NoSuchAdviceException(name); + } + + public Advice getDeclaredAdvice(String name) throws NoSuchAdviceException { + if (name.equals("")) throw new IllegalArgumentException("use getAdvice(AdviceType...) instead for un-named advice"); + if (declaredAdvice == null) initDeclaredAdvice(); + for (Advice a : declaredAdvice) { + if (a.getName().equals(name)) return a; + } + throw new NoSuchAdviceException(name); + } + + private Advice asAdvice(Method method) { + if (method.getAnnotations().length == 0) return null; + Before beforeAnn = method.getAnnotation(Before.class); + if (beforeAnn != null) return new AdviceImpl(method,beforeAnn.value(),AdviceType.BEFORE); + After afterAnn = method.getAnnotation(After.class); + if (afterAnn != null) return new AdviceImpl(method,afterAnn.value(),AdviceType.AFTER); + AfterReturning afterReturningAnn = method.getAnnotation(AfterReturning.class); + if (afterReturningAnn != null) { + String pcExpr = afterReturningAnn.pointcut(); + if (pcExpr.equals("")) pcExpr = afterReturningAnn.value(); + return new AdviceImpl(method,pcExpr,AdviceType.AFTER_RETURNING); + } + AfterThrowing afterThrowingAnn = method.getAnnotation(AfterThrowing.class); + if (afterThrowingAnn != null) { + String pcExpr = afterThrowingAnn.pointcut(); + if (pcExpr == null) pcExpr = afterThrowingAnn.value(); + return new AdviceImpl(method,pcExpr,AdviceType.AFTER_THROWING); + } + Around aroundAnn = method.getAnnotation(Around.class); + if (aroundAnn != null) return new AdviceImpl(method,aroundAnn.value(),AdviceType.AROUND); + return null; + } + /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredITDMethod(java.lang.String, java.lang.Class, java.lang.Class...) */ @@ -509,12 +735,7 @@ public class AjTypeImpl<T> implements AjType { * @see org.aspectj.lang.reflect.AjType#isAspect() */ public boolean isAspect() { - // 2 tests we could use today... presence of aspectOf method (but what if user defines one in - // a class), and presence of @Aspect annotation (@AspectJ style only). - // Is the solution to put the @Aspect annotation on a code-style aspect too during weaving? - // Or should we generate some private structure with all the reflection info in it, including the aspect - // info? - return false; + return clazz.getAnnotation(Aspect.class) != null; } /* (non-Javadoc) @@ -524,4 +745,20 @@ public class AjTypeImpl<T> implements AjType { return clazz.isMemberClass() && isAspect(); } + public boolean isPrivileged() { + return isAspect() && clazz.isAnnotationPresent(ajcPrivileged.class); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AjTypeImpl)) return false; + AjTypeImpl other = (AjTypeImpl) obj; + return other.clazz.equals(clazz); + } + + @Override + public int hashCode() { + return clazz.hashCode(); + } + } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java new file mode 100644 index 000000000..a589f79dc --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; + +/** + * @author colyer + * + */ +public class PerClauseImpl implements PerClause { + + private final PerClauseKind kind; + private final String pointcutExpression; + + protected PerClauseImpl(PerClauseKind kind, String pointcutExpression) { + this.kind = kind; + this.pointcutExpression = pointcutExpression; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.PerClause#getKind() + */ + public PerClauseKind getKind() { + return kind; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.PerClause#getPointcutExpression() + */ + public String getPointcutExpression() { + return pointcutExpression; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java new file mode 100644 index 000000000..adc1e9510 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java @@ -0,0 +1,60 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import java.lang.reflect.Method; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.Pointcut; + +/** + * @author colyer + * + */ +public class PointcutImpl implements Pointcut { + + private final String name; + private final String pc; + private final Method baseMethod; + private final AjType declaringType; + + protected PointcutImpl(String name, String pc, Method method, AjType declaringType) { + this.name = name; + this.pc = pc; + this.baseMethod = method; + this.declaringType = declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.Pointcut#getPointcutExpression() + */ + public String getPointcutExpression() { + return pc; + } + + public String getName() { + return name; + } + + public int getModifiers() { + return baseMethod.getModifiers(); + } + + public Class<?>[] getParameterTypes() { + return baseMethod.getParameterTypes(); + } + + public AjType getDeclaringType() { + return declaringType; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/annotation/AdviceName.java b/aspectj5rt/java5-src/org/aspectj/lang/annotation/AdviceName.java new file mode 100644 index 000000000..4e3ec7f9e --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/annotation/AdviceName.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2005 Contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer initial implementation + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * Used to annotated code-style advice to name it + * Name is used by reflection api if present, may in future be used in adviceexecution() pcd. + * It is an error to use the @AdviceName annotation on an annotation-style advice declaration. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface AdviceName { + + /** + * The name of the advice + */ + String value(); +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java index b31f94b6e..3fbc668cd 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java @@ -13,4 +13,9 @@ package org.aspectj.lang.reflect; public interface Advice { + AdviceType getKind(); + + String getName(); + + String getPointcutExpression(); } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java index 74f4b32db..19a30aa48 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java @@ -11,12 +11,13 @@ * ******************************************************************/ package org.aspectj.lang.reflect; -import java.lang.reflect.Method; +import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; -import java.lang.annotation.Annotation; +import java.util.Set; /** * The runtime representation of a type (Aspect, Class, Interface, Annotation, Enum, or Array) in an AspectJ @@ -96,9 +97,9 @@ public interface AjType<T> extends Type { // pointcuts - public Pointcut getDeclaredPointcut(String name); + public Pointcut getDeclaredPointcut(String name) throws NoSuchPointcutException; - public Pointcut getPointcut(String name); + public Pointcut getPointcut(String name) throws NoSuchPointcutException; public Pointcut[] getDeclaredPointcuts(); @@ -106,9 +107,13 @@ public interface AjType<T> extends Type { // advice - public Advice[] getDeclaredAdvice(AdviceType adviceType); + public Advice[] getDeclaredAdvice(AdviceType... ofTypes); + + public Advice[] getAdvice(AdviceType... ofTypes); + + public Advice getAdvice(String name) throws NoSuchAdviceException; - public Advice[] getAdvice(AdviceType adviceType); + public Advice getDeclaredAdvice(String name) throws NoSuchAdviceException; // inter-type declarations @@ -172,16 +177,6 @@ public interface AjType<T> extends Type { public boolean isMemberAspect(); + public boolean isPrivileged(); + } - - -// implementation notes: - -// additional runtime info we need: -// whether or not a class is an aspect -// pointcuts in a type (+ name, parameter types, parameter names, expression) -// itds in a type (is there enough in the class file already?) -// advice in a type (should be enough in the class file already?) -// declares in an aspect (+ associated info) - -// anchor in a generated static member on the type: ajc$reflectionInfo ? or use annotations??
\ No newline at end of file diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java index e47fe6d8b..42d207804 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java @@ -11,6 +11,8 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import org.aspectj.internal.lang.reflect.AjTypeImpl; + /** * @author colyer * @@ -18,6 +20,6 @@ package org.aspectj.lang.reflect; public class AjTypeSystem { public static AjType getAjType(Class fromClass) { - return null; + return new AjTypeImpl(fromClass); } } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchAdviceException.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchAdviceException.java new file mode 100644 index 000000000..e14dfb7d3 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchAdviceException.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.lang.reflect; + +/** + * @author colyer + * + */ +public class NoSuchAdviceException extends Exception { + + private static final long serialVersionUID = 3256444698657634352L; + private String name; + + public NoSuchAdviceException(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchPointcutException.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchPointcutException.java new file mode 100644 index 000000000..df1bf9189 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchPointcutException.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.lang.reflect; + +/** + * @author colyer + * + */ +public class NoSuchPointcutException extends Exception { + + private static final long serialVersionUID = 3256444698657634352L; + private String name; + + public NoSuchPointcutException(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java index eab0b811e..7416ac09d 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java @@ -16,5 +16,6 @@ package org.aspectj.lang.reflect; * */ public interface PerClause { - + PerClauseKind getKind(); + String getPointcutExpression(); } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClauseKind.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClauseKind.java new file mode 100644 index 000000000..03313d8c5 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClauseKind.java @@ -0,0 +1,25 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.lang.reflect; + +/** + * @author colyer + * The different perclauses (aspect instantiation models) + */ +public enum PerClauseKind { + SINGLETON, + PERTHIS, + PERTARGET, + PERCFLOW, + PERCFLOWBELOW, + PERTYPEWITHIN; +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java index 398729ca4..0802db410 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java @@ -13,4 +13,13 @@ package org.aspectj.lang.reflect; public interface Pointcut { + String getPointcutExpression(); + + String getName(); + + int getModifiers(); + + Class<?>[] getParameterTypes(); + + AjType getDeclaringType(); } diff --git a/aspectj5rt/testsrc/Aspectj5rtModuleTests.java b/aspectj5rt/testsrc/Aspectj5rtModuleTests.java index 065df5479..ff1e30a2f 100644 --- a/aspectj5rt/testsrc/Aspectj5rtModuleTests.java +++ b/aspectj5rt/testsrc/Aspectj5rtModuleTests.java @@ -12,12 +12,19 @@ // default package -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.aspectj.internal.lang.reflect.AjTypeTests; +import org.aspectj.internal.lang.reflect.AjTypeTestsWithAspects; public class Aspectj5rtModuleTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite("Aspectj5rt module tests"); + suite.addTestSuite(AjTypeTests.class); + suite.addTestSuite(AjTypeTestsWithAspects.class); return suite; } diff --git a/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTests.java b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTests.java new file mode 100644 index 000000000..bae481e72 --- /dev/null +++ b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTests.java @@ -0,0 +1,304 @@ +package org.aspectj.internal.lang.reflect; + +import java.io.Serializable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +import junit.framework.TestCase; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; + +public class AjTypeTests extends TestCase { + + private AjType stringType; + + @Override + protected void setUp() throws Exception { + super.setUp(); + stringType = AjTypeSystem.getAjType(String.class); + } + + public void testCreateAjType() { + assertNotNull("should find type",stringType); + } + + public void testGetName() { + assertEquals(String.class.getName(),stringType.getName()); + } + + public void testGetPackage() { + assertEquals(String.class.getPackage(),stringType.getPackage()); + } + + public void testGetInterfaces() { + Class[] i1 = String.class.getInterfaces(); + Class[] i2 = stringType.getInterfaces(); + assertEquals(i1.length,i2.length); + for (int i = 0; i < i1.length; i++) + assertEquals(i1[i],i2[i]); + } + + public void testGetModifiers() { + assertEquals(String.class.getModifiers(),stringType.getModifiers()); + } + + public void testGetSupertype() { + Class stringSuper = String.class.getSuperclass(); + AjType ajSuper = stringType.getSupertype(); + assertEquals(AjTypeSystem.getAjType(stringSuper),ajSuper); + } + + public void testGetGenericSupertype() { + Type t = AjTypeSystem.getAjType(Goo.class).getGenericSupertype(); + assertEquals(Foo.class,t); + } + + public void testGetEnclosingMethod() { + new Goo().foo(); + } + + public void testGetEnclosingConstructor() { + new Goo(); + } + + public void testGetEnclosingType() { + AjType t = AjTypeSystem.getAjType(Foo.Z.class); + assertEquals("org.aspectj.internal.lang.reflect.Foo",t.getEnclosingType().getName()); + } + + public void testGetDeclaringType() { + AjType t = AjTypeSystem.getAjType(Foo.Z.class); + assertEquals("org.aspectj.internal.lang.reflect.Foo",t.getDeclaringType().getName()); + } + + public void testIsAnnotationPresent() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertTrue(foo.isAnnotationPresent(SomeAnn.class)); + assertFalse(goo.isAnnotationPresent(SomeAnn.class)); + } + + public void testGetAnnotation() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertNotNull(foo.getAnnotation(SomeAnn.class)); + assertNull(goo.getAnnotation(SomeAnn.class)); + } + + public void testGetAnnotations() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertEquals(1,foo.getAnnotations().length); + assertEquals(0,goo.getAnnotations().length); + } + + public void testGetDeclaredAnnotations() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertEquals(0,goo.getDeclaredAnnotations().length); + assertEquals(1,foo.getDeclaredAnnotations().length); + } + + public void testGetAjTypes() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType[] fooTypes = foo.getAjTypes(); + assertEquals(1,fooTypes.length); + assertEquals("org.aspectj.internal.lang.reflect.Foo$Z",fooTypes[0].getName()); + } + + public void testGetDeclaredAjTypes() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType[] fooTypes = foo.getDeclaredAjTypes(); + assertEquals(2,fooTypes.length); + assertEquals("org.aspectj.internal.lang.reflect.Foo$Z",fooTypes[0].getName()); + assertEquals("org.aspectj.internal.lang.reflect.Foo$XX",fooTypes[1].getName()); + } + + public void testGetConstructor() throws Exception { + Constructor c1 = String.class.getConstructor(String.class); + Constructor c2 = stringType.getConstructor(String.class); + assertEquals(c1,c2); + } + + public void testGetConstructors() { + Constructor[] c1 = String.class.getConstructors(); + Constructor[] c2 = stringType.getConstructors(); + assertEquals(c1.length,c2.length); + for (int i = 0; i < c1.length; i++) + assertEquals(c1[i],c2[i]); + } + + public void testGetDeclaredConstructor() throws Exception { + Constructor c1 = String.class.getDeclaredConstructor(String.class); + Constructor c2 = stringType.getDeclaredConstructor(String.class); + assertEquals(c1,c2); + } + + public void testGetDeclaredConstructors() { + Constructor[] c1 = String.class.getDeclaredConstructors(); + Constructor[] c2 = stringType.getDeclaredConstructors(); + assertEquals(c1.length,c2.length); + for (int i = 0; i < c1.length; i++) + assertEquals(c1[i],c2[i]); + } + + public void testGetDeclaredField() throws Exception { + Field f1 = String.class.getDeclaredField("value"); + Field f2 = stringType.getDeclaredField("value"); + assertEquals(f1,f2); + } + + public void testGetDeclaredFields() { + Field[] f1 = String.class.getDeclaredFields(); + Field[] f2 = stringType.getDeclaredFields(); + assertEquals(f1.length,f2.length); + for (int i = 0; i < f1.length; i++) + assertEquals(f1[i],f2[i]); + } + + public void testGetField() throws Exception { + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertEquals("g",goo.getField("g").getName()); + } + + public void testGetFields() { + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + Field[] fields = goo.getFields(); + assertEquals(1,fields.length); + assertEquals("g",fields[0].getName()); + + } + + public void testGetDeclaredMethod() throws Exception { + Method m1 = String.class.getDeclaredMethod("toUpperCase"); + Method m2 = stringType.getDeclaredMethod("toUpperCase"); + assertEquals(m1,m2); + } + + public void testGetMethod() throws Exception { + Method m1 = String.class.getMethod("toUpperCase"); + Method m2 = stringType.getMethod("toUpperCase"); + assertEquals(m1,m2); + } + + public void testGetDeclaredMethods() { + Method[] m1 = String.class.getDeclaredMethods(); + Method[] m2 = stringType.getDeclaredMethods(); + assertEquals(m1.length,m2.length); + for (int i = 0; i < m1.length; i++) + assertEquals(m1[i],m2[i]); + } + + public void testGetMethods() { + Method[] m1 = String.class.getMethods(); + Method[] m2 = stringType.getMethods(); + assertEquals(m1.length,m2.length); + for (int i = 0; i < m1.length; i++) + assertEquals(m1[i],m2[i]); + } + + public void testGetEnumConstants() { + AjType e = AjTypeSystem.getAjType(E.class); + Object[] consts = e.getEnumConstants(); + assertEquals(3,consts.length); + } + + public void testGetTypeParameters() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + TypeVariable<Class<Foo>>[] tvs = foo.getTypeParameters(); + assertEquals(1,tvs.length); + assertEquals("T",tvs[0].getName()); + } + + public void testIsEnum() { + assertFalse(stringType.isEnum()); + } + + public void testIsInstance() { + assertTrue(stringType.isInstance("I am")); + } + + public void testIsInterface() { + assertFalse(stringType.isInterface()); + assertTrue(AjTypeSystem.getAjType(Serializable.class).isInterface()); + } + + public void testIsLocalClass() { + assertFalse(stringType.isLocalClass()); + } + + public void testIsArray() { + assertFalse(stringType.isArray()); + assertTrue(AjTypeSystem.getAjType(Integer[].class).isArray()); + } + + public void testIsPrimitive() { + assertFalse(stringType.isPrimitive()); + assertTrue(AjTypeSystem.getAjType(boolean.class).isPrimitive()); + } + + public void testIsAspect() { + assertFalse(stringType.isAspect()); + } + + public void testIsMemberAspect() { + assertFalse(stringType.isMemberAspect()); + } + + public void testIsPrivileged() { + assertFalse(stringType.isPrivileged()); + } + + public void testEquals() { + AjType stringTypeTwo = AjTypeSystem.getAjType(String.class); + assertTrue(stringType.equals(stringTypeTwo)); + } + + public void testHashCode() { + AjType stringTypeTwo = AjTypeSystem.getAjType(String.class); + assertEquals(stringType.hashCode(),stringTypeTwo.hashCode()); + } + +} + +@Retention(RetentionPolicy.RUNTIME) +@interface SomeAnn {} + +@SomeAnn +class Foo<T> { + + public Foo() { + class Y { int y; } + AjType t = AjTypeSystem.getAjType(Y.class); + Constructor c = t.getEnclosingConstructor(); + if (!c.getName().equals("org.aspectj.internal.lang.reflect.Foo")) throw new RuntimeException("should have been Foo"); + } + public void foo() { + class X { int x; } + AjType t = AjTypeSystem.getAjType(X.class); + Method m = t.getEnclosingMethod(); + if (!m.getName().equals("foo")) throw new RuntimeException("should have been foo"); + } + public class Z { int z; } + class XX { int xx; } +} + +class Goo extends Foo { + @interface IX {} + + public Goo() { + super(); + } + + public int g; + int g2; + +} + +enum E { A,B,C; } diff --git a/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java new file mode 100644 index 000000000..0972a67f4 --- /dev/null +++ b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java @@ -0,0 +1,371 @@ +package org.aspectj.internal.lang.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.EnumSet; +import java.util.Set; + +import junit.framework.TestCase; + +import org.aspectj.internal.lang.annotation.ajcPrivileged; +import org.aspectj.lang.annotation.AdviceName; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceType; +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.NoSuchAdviceException; +import org.aspectj.lang.reflect.NoSuchPointcutException; +import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; +import org.aspectj.lang.reflect.Pointcut; + +public class AjTypeTestsWithAspects extends TestCase { + + private AjType sa; + + protected void setUp() throws Exception { + super.setUp(); + sa = AjTypeSystem.getAjType(SimpleAspect.class); + } + + public void testGetPerClause() { + AjType perThisA = AjTypeSystem.getAjType(PerThisAspect.class); + AjType perTargetA = AjTypeSystem.getAjType(PerTargetAspect.class); + AjType perCflowA = AjTypeSystem.getAjType(PerCflowAspect.class); + AjType perCflowbelowA = AjTypeSystem.getAjType(PerCflowbelowAspect.class); + AjType perTypeWithinA = AjTypeSystem.getAjType(PerTypeWithin.class); + + PerClause pc = perThisA.getPerClause(); + assertEquals(PerClauseKind.PERTHIS,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perTargetA.getPerClause(); + assertEquals(PerClauseKind.PERTARGET,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perCflowA.getPerClause(); + assertEquals(PerClauseKind.PERCFLOW,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perCflowbelowA.getPerClause(); + assertEquals(PerClauseKind.PERCFLOWBELOW,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perTypeWithinA.getPerClause(); + assertEquals(PerClauseKind.PERTYPEWITHIN,pc.getKind()); + assertEquals("org.aspectj..*",pc.getPointcutExpression()); + + } + + public void testGetDeclaredField() throws Exception{ + Field f = sa.getDeclaredField("s"); + try { + Field f2 = sa.getDeclaredField("ajc$xyz$s"); + fail("Expecting NoSuchFieldException"); + } catch (NoSuchFieldException nsf) {} + } + + public void testGetField() throws Exception { + Field f = sa.getField("s"); + try { + Field f2 = sa.getField("ajc$xyz$s"); + fail("Expecting NoSuchFieldException"); + } catch (NoSuchFieldException nsf) {} + } + + public void testGetDeclaredFields() { + Field[] fields = sa.getDeclaredFields(); + assertEquals(1,fields.length); + assertEquals("s",fields[0].getName()); + } + + public void testGetFields() { + Field[] fields = sa.getFields(); + assertEquals(1,fields.length); + assertEquals("s",fields[0].getName()); + } + + public void testGetDeclaredMethod() throws Exception { + Method m = sa.getDeclaredMethod("aMethod"); + try { + Method m2 = sa.getDeclaredMethod("logEntry"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + try { + Method m3 = sa.getDeclaredMethod("ajc$before$123"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + } + + public void testGetMethod() throws Exception { + Method m = sa.getMethod("aMethod"); + try { + Method m2 = sa.getMethod("logEntry"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + try { + Method m3 = sa.getMethod("ajc$before$123"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + } + + public void testGetDeclaredMethods() { + Method[] ms = sa.getDeclaredMethods(); + assertEquals(1,ms.length); + assertEquals("aMethod",ms[0].getName()); + } + + public void testGetMethods() { + Method[] ms = sa.getMethods(); + assertEquals(10,ms.length); + assertEquals("aMethod",ms[0].getName()); + } + + public void testGetDeclaredPointcut() throws Exception { + Pointcut p1 = sa.getDeclaredPointcut("simpleAspectMethodExecution"); + assertEquals("simpleAspectMethodExecution",p1.getName()); + assertEquals("execution(* SimpleAspect.*(..))",p1.getPointcutExpression()); + assertEquals(sa,p1.getDeclaringType()); + assertEquals(0,p1.getParameterTypes().length); + assertTrue(Modifier.isPublic(p1.getModifiers())); + Pointcut p2 = sa.getDeclaredPointcut("simpleAspectCall"); + assertEquals("simpleAspectCall",p2.getName()); + assertEquals("call(* SimpleAspect.*(..))",p2.getPointcutExpression()); + assertEquals(sa,p2.getDeclaringType()); + assertEquals(1,p2.getParameterTypes().length); + assertTrue(Modifier.isPrivate(p2.getModifiers())); + try { + Pointcut p3 = sa.getDeclaredPointcut("sausages"); + fail("Expecting NoSuchPointcutExcetpion"); + } catch (NoSuchPointcutException ex) { + assertEquals("sausages",ex.getName()); + } + } + + public void testGetPointcut() throws Exception { + Pointcut p1 = sa.getPointcut("simpleAspectMethodExecution"); + assertEquals("simpleAspectMethodExecution",p1.getName()); + assertEquals("execution(* SimpleAspect.*(..))",p1.getPointcutExpression()); + assertEquals(sa,p1.getDeclaringType()); + assertEquals(0,p1.getParameterTypes().length); + assertTrue(Modifier.isPublic(p1.getModifiers())); + Pointcut p2 = sa.getPointcut("simpleAspectCall"); + assertEquals("simpleAspectCall",p2.getName()); + assertEquals("call(* SimpleAspect.*(..))",p2.getPointcutExpression()); + assertEquals(sa,p2.getDeclaringType()); + assertEquals(1,p2.getParameterTypes().length); + assertTrue(Modifier.isPrivate(p2.getModifiers())); + try { + Pointcut p3 = sa.getPointcut("sausages"); + fail("Expecting NoSuchPointcutExcetpion"); + } catch (NoSuchPointcutException ex) { + assertEquals("sausages",ex.getName()); + } + } + + public void testGetDeclaredPointcuts() { + Pointcut[] pcs = sa.getDeclaredPointcuts(); + assertEquals(2,pcs.length); + assertEquals("simpleAspectMethodExecution",pcs[0].getName()); + assertEquals("simpleAspectCall",pcs[1].getName()); + } + + public void testGetPointcuts() { + Pointcut[] pcs = sa.getPointcuts(); + assertEquals(1,pcs.length); + assertEquals("simpleAspectMethodExecution",pcs[0].getName()); + } + + public void testGetDeclaredAdvice() { + Advice[] advice = sa.getDeclaredAdvice(); + assertEquals(10,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_RETURNING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_THROWING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AROUND); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE,AdviceType.AFTER); + assertEquals(4,advice.length); + + advice = sa.getDeclaredAdvice(AdviceType.BEFORE); + assertEquals("execution(* SimpleAspect.*(..))",advice[0].getPointcutExpression()); + assertEquals("logEntry",advice[0].getName()); + assertEquals(AdviceType.BEFORE,advice[0].getKind()); + assertEquals("execution(* SimpleAspect.*(..))",advice[1].getPointcutExpression()); + assertEquals("",advice[1].getName()); + } + + public void testGetAdvice() { + Advice[] advice = sa.getDeclaredAdvice(); + assertEquals(10,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_RETURNING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_THROWING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AROUND); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE,AdviceType.AFTER); + assertEquals(4,advice.length); + } + + public void testGetNamedAdvice() throws Exception { + Advice a = sa.getAdvice("logItAll"); + assertEquals("logItAll",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + a = sa.getAdvice("whatGoesAround"); + assertEquals("whatGoesAround",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + try { + a = sa.getAdvice("ajc$after$123"); + fail("Expecting NoSuchAdviceException"); + } catch (NoSuchAdviceException ex) { + assertEquals("ajc$after$123",ex.getName()); + } + try { + a = sa.getAdvice(""); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + ; + } + } + + public void testGetNamedDeclaredAdvice() throws Exception { + Advice a = sa.getDeclaredAdvice("logItAll"); + assertEquals("logItAll",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + a = sa.getDeclaredAdvice("whatGoesAround"); + assertEquals("whatGoesAround",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + try { + a = sa.getDeclaredAdvice("ajc$after$123"); + fail("Expecting NoSuchAdviceException"); + } catch (NoSuchAdviceException ex) { + assertEquals("ajc$after$123",ex.getName()); + } + try { + a = sa.getDeclaredAdvice(""); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + ; + } + } + + public void testIsPrivileged() { + assertFalse(sa.isPrivileged()); + assertTrue(AjTypeSystem.getAjType(SimplePrivilegedAspect.class).isPrivileged()); + } + + public void testIsAspect() { + assertTrue(sa.isAspect()); + } + + public void testIsMemberAspect() { + assertFalse(AjTypeSystem.getAjType(SimplePrivilegedAspect.class).isMemberAspect()); + assertTrue(AjTypeSystem.getAjType(SimplePrivilegedAspect.MemberAspect.class).isMemberAspect()); + + } +} + + +@Aspect +class SimpleAspect { + + // regular field + public String s; + + // synthetic field + public String ajc$xyz$s; + + // regular method + public void aMethod() {} + + // advice method, annotation style + @Before("execution(* SimpleAspect.*(..))") + public void logEntry() {} + + // advice method, code style + @Before("execution(* SimpleAspect.*(..))") + public void ajc$before$123() {} + + // advice method, annotation style + @After("execution(* SimpleAspect.*(..))") + public void logFinally() {} + + // advice method, code style + @After("execution(* SimpleAspect.*(..))") + public void ajc$after$123() {} + + // advice method, annotation style + @AfterReturning("execution(* SimpleAspect.*(..))") + public void logExit() {} + + // advice method, code style + @AfterReturning("execution(* SimpleAspect.*(..))") + public void ajc$afterReturning$123() {} + + // advice method, annotation style + @AfterThrowing("execution(* SimpleAspect.*(..))") + public void logException() {} + + // advice method, code style + @AfterThrowing("execution(* SimpleAspect.*(..))") + public void ajc$afterThrowing$123() {} + + // advice method, annotation style + @Around("execution(* SimpleAspect.*(..))") + public void logItAll() {} + + // advice method, code style + @Around("execution(* SimpleAspect.*(..))") + @AdviceName("whatGoesAround") + public void ajc$around$123() {} + + // pointcut, annotation style + @org.aspectj.lang.annotation.Pointcut("execution(* SimpleAspect.*(..))") + public void simpleAspectMethodExecution() {}; + + // pointcut, code style + @org.aspectj.lang.annotation.Pointcut("call(* SimpleAspect.*(..))") + private void ajc$pointcut$$simpleAspectCall$123(SimpleAspect target) {}; + +} + +@Aspect +@ajcPrivileged +class SimplePrivilegedAspect { + + @Aspect + static class MemberAspect {} + +} + +@Aspect("perthis(pc())") +class PerThisAspect {} + +@Aspect("pertarget(pc())") +class PerTargetAspect {} + +@Aspect("percflow(pc())") +class PerCflowAspect {} + +@Aspect("percflowbelow(pc())") +class PerCflowbelowAspect {} + +@Aspect("pertypewithin(org.aspectj..*)") +class PerTypeWithin {} diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar Binary files differindex 105609e1e..8ee14c02c 100644 --- a/lib/test/aspectjrt.jar +++ b/lib/test/aspectjrt.jar |