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); } }