[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[aspectj-users] Restricting visibility of a method via AspectJ
|
Hi,
I had the idea that it should be possible to use an annotation to declare custom visibility of a method that is really public. You could use this to annotate methods that have been made public for unit testing, or because you just need 1 particular class in another package to use it.
I just want to put down what I have got so far, maybe others can build on it or improve if they like the idea.
Idea #1: Restrict the calling of the public method to test code (assuming TestNG here)
1) Create an annotation called @TestingOnly and put that on any method that only should be called by testing code
2) The following aspect should do it:
public aspect IllegalTestOnlyMethodCallChecker {
declare error: testCallOutsideTestCode(): "Don't call test methods outside test code!";
pointcut clientCall() : call(@TestingOnly * *(..))
&& !within(@org.testng.annotations.Test *)
&& !withincode(@org.testng.annotations.Test * *(..))
;
}
Idea #2: Restrict the calling of a public method to only being called from an approved class
1) Create an annotation @RestrictedVisibility
@Retention(RetentionPolicy.RUNTIME)
public @interface RestrictedVisibility {
Class allowedClass();
}
2) Use the annotation like this:
public class DomainObject {
@RestrictedVisibility(allowedClass = TestService.class)
public void domainMethod() {
}
}
This would mean that only TestService is allowed to call the method 'domainMethod'
3) Use this aspect
public aspect RestrictedVisibilityAspect {
pointcut callToRestricted(Object targetObject, Object callingObject):call( @RestrictedVisibility * *(..) )
&& target(targetObject)
&& this(callingObject);
before(Object targetObject, Object callingObject) : callToRestricted(targetObject, callingObject)
{
System.out.println( thisJoinPointStaticPart.getSignature() );
System.out.println(targetObject);
System.out.println(callingObject);
Method m = ((MethodSignature)thisJoinPointStaticPart.getSignature()).getMethod();
RestrictedVisibility rv = m.getAnnotation(RestrictedVisibility.class);
if( rv.allowedClass().equals( callingObject.getClass() ))
{
System.out.println( "It is ok!");
}
else
{
System.out.println( "This call is not allowed!");
}
};
}
Note that I was not able to use declare error anymore due to the use of this() and target(). You should ofcourse throw a RunTimeException instead of just printing something like I did here.
Is it possible to avoid the reflection and casting?
Is anybody else using an Aspect simular to this?
regards,
Wim