Enum value matching using AspectJ
September 25, 2008 2 Comments
I wrote an Aspect to advise a particular constant-specific method.
What is a constant-specific method ?
The J2SE 5 documentation explains it.
“You can declare the method abstract in the enum type and override it with a concrete method in each constant. Such methods are known as constant-specific methods.”
There is an example here.
The enum is
package com.test.generics;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public enum TestEnum {
Value1{
public <T> List<T> getValue(){ return null; }
public <T> List<T> getSameValue(){ return null; }
},
Value2{
public <T> Set <T>getValue(){ return null; }
public <T> List<T> getSameValue(){ return null; }
};
abstract <T> Collection<T> getValue();
abstract <T> Collection<T> getSameValue();
public static void main(String[] args) {
System.out.println( Value1.getSameValue() );
System.out.println( Value2.getSameValue() );
}
}
package com.test;
import java.util.List;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import com.test.generics.TestEnum;
@Aspect()
public class EnumAspect {
/*
Matches a particular method of all enum values
*/
@Pointcut(
"execution(List<T> getValue())" )
public void testPointcut(){};
@Before("testPointcut()")
public void test() {
System.out.println( "Generics aspect" );
}
/*
Matches a method of a particular enum values
*/
@Pointcut(
"execution(List<T> getSameValue()) && target(testEnum) && if()")
public static boolean testPointcut1( TestEnum testEnum ){
return testEnum == TestEnum.Value2;
}
@Before("testPointcut1(testEnum)")
public void test1( TestEnum testEnum ) {
System.out.println( "Generics aspect [" + testEnum.ordinal() + "]" );
}
}
The if() pointcut expression with an empty body is used and the testPointcut1 method tests for the value of the enum. There does not seem to be a JoinPoint matching pattern to pick out certain enum values automatically. It looks like a pattern would be useful.
Update : Raised an enhancement request.
Update : 26 Oct 2020
One of the contributors who has commented here pointed out that this aspect works. I am not sure if this would have worked 12 years back when I raised the request. At that time I thought it was a missing feature.
@Aspect
public class EnumAspect {
@Pointcut("execution(java.util.Collection+ getValue()) && target(testEnum) && if()")
public static boolean testPointcut1(TestEnum testEnum) {
return testEnum == TestEnum.Value1;
}
@Before("testPointcut1(testEnum)")
public void test1(JoinPoint joinPoint, TestEnum testEnum) {
System.out.println(joinPoint + " -> " + testEnum);
}
@Pointcut("execution(java.util.Collection+ getValue()) && target(testEnum) && if()")
public static boolean testPointcut2(TestEnum testEnum) {
return testEnum == TestEnum.Value2;
}
@Before("testPointcut2(testEnum)")
public void test2(JoinPoint joinPoint, TestEnum testEnum) {
System.out.println(joinPoint + " -> " + testEnum);
}
}