Inherit interface annotation for interception

327 views
Skip to first unread message

BradBeck

unread,
Jul 19, 2007, 4:07:21 PM7/19/07
to google-guice
Suppose I have an interface...

public interface MedicalService {
@AllowedRole("None")
public void doNotCallMe();

@AllowedRole("All")
public void everyoneCallMe();

@AllowedRole("Doctor")
public void doctorCallMe()

@AllowedRole({"Nurse", "Doctor"})
public void medicalStaffCallMe();
}

I'd like be able to intercept the implementations of this interface
without having to repeat the annotations in each implementation.

Is this possible?

Robbie Vanbrabant

unread,
Jul 19, 2007, 5:18:51 PM7/19/07
to google...@googlegroups.com
Well for what it's worth, that's possible. I haven't used the Guice AOP support that much, but there's a matcher for subclasses. So you could match all subclasses of MedicalService, and retrieve the correct Method annotation for a method from the interceptor you configure, after which you can execute your logic depending on that data. That's probably not the only way to do that, but I guess it should work.
 
Robbie
 

Dhanji R. Prasanna

unread,
Jul 19, 2007, 6:42:03 PM7/19/07
to google...@googlegroups.com

Are you talking about intercepting any invocation of these methods (on subclass impls) or direct invocation of the subclass impl?

If the former then that is what the interceptors do. If the latter you're out of luck without bringing the annotations down. The latter would imply subverting the interface contract anyway so Im not even sure why you'd want that.

Dhanji.

Gregory Kick

unread,
Jul 19, 2007, 7:47:53 PM7/19/07
to google...@googlegroups.com
Wait a sec, why would this work? Even if the @AllowedRole annotation
uses @Inherited, it "only causes annotations to be inherited from
superclasses; annotations on implemented interfaces have no effect."
Without some crazy call to getInterfaces() and some method matching,
the annotatedWith matcher (which just uses getAnnotation()) will never
pick it up... right?


--
Gregory Kick
http://kickstyle.net/

Gregory Kick

unread,
Jul 19, 2007, 8:05:23 PM7/19/07
to google...@googlegroups.com
Actually, now that I reread this, I think that I might have just
misread the question. If you're trying to bind the interceptor to all
invocations of the methods defined in the interface and get the
annotation information with
bindInterceptor(Matchers.subclassesOf(...), Matchers.any(), ...), then
Robbie was right. If you're trying to match methods in that interface
that are annotated with @AllowedRole using
bindInterceptor(Matchers.subclassesOf(...),
Matchers.annotatedWith(...), ...) that won't work.

Personally, I wouldn't be particularly comfortable using the first
approach because it would either have to assume that the method is
annotated or check that it is each time. I'd rather just move the
annotations down to the implementations so that I could use the
annotatedWith matcher and not have to risk the NPE if somebody drops
an annotation somewhere. It's probably not a big deal for this case,
but probably not a best practice either...

BradBeck

unread,
Jul 20, 2007, 12:17:47 PM7/20/07
to google-guice
I was hoping to be able to do

bindInterceptor(Matchers.any(), Matchers.annotatedWith(...), ...)

And in the interceptor be able to get the information contained in the
annotation about what roles should be allowed, i.e.

methodInvocation.getMethod().getAnnotation(AllowedRole.class)

BradBeck

unread,
Jul 20, 2007, 2:15:06 PM7/20/07
to google-guice
I should mention that the interface may also contain methods that are
not annotated, e.g.

public interface MedicalService {
@AllowedRole("None")
public void doNotCallMe();

@AllowedRole("All")
public void everyoneCallMe();

@AllowedRole("Doctor")
public void doctorCallMe()

@AllowedRole({"Nurse", "Doctor"})
public void medicalStaffCallMe();

public void unrestrictedCallMe();
}

And the interceptor should not be called for non-annotated methods.

BradBeck

unread,
Jul 20, 2007, 2:23:31 PM7/20/07
to google-guice
I ran across the following article with appears to be a step in the
direction of what I'm looking for...

Inherited Annotations in Java, by Mikhail Milonov
http://www.codeguru.com/java/article.php/c13793/

Robbie Vanbrabant

unread,
Jul 20, 2007, 2:53:26 PM7/20/07
to google...@googlegroups.com
I guess we can conclude that it's not possible to achieve exactly what you want with Guice's current out of the box AOP support.
- A custom Matcher is probably the best technical solution
- I don't think that putting the annotations on the implementations is a bad idea if you don't have 3+ implementations.
- You could try to live with some interception you don't need (my initial suggestion). In most cases, it's a performance loss that's acceptable.
 
Robbie
 
On 7/20/07, BradBeck <bradle...@gmail.com> wrote:

BradBeck

unread,
Jul 20, 2007, 3:55:29 PM7/20/07
to google-guice
I pretty much came to the same conclusion. My current approach is to
bind the interceptor based on the subClassesOf(...) as you suggested.
But in my interceptor implementation I need to walk up the Class/
Interface hierarchy in order to get the annotations and the data
(roles) they contain and to weed out the methods that are not
annotated.

Thanks,
-Brad

On Jul 20, 1:53 pm, "Robbie Vanbrabant" <robbie.vanbrab...@gmail.com>
wrote:


> I guess we can conclude that it's not possible to achieve exactly what you
> want with Guice's current out of the box AOP support.
> - A custom Matcher is probably the best technical solution
> - I don't think that putting the annotations on the implementations is a bad
> idea if you don't have 3+ implementations.
> - You could try to live with some interception you don't need (my initial
> suggestion). In most cases, it's a performance loss that's acceptable.
>
> Robbie
>

Reply all
Reply to author
Forward
0 new messages