Pergunta

I'm rolling my own IAuthorizationStrategy for Wicket 1.5.x I've setup type annotation for pages to use with isInstantiationAuthorized(). It works well and I'd like to use annotations for isActionAuthorized() as well. Ideally I'd like to be able annotate local variables and then check the annotations in my AuthStrategy. From what I've read Local variable Annotation doesn't work that way.

Is there any kind of known work around, maybe some sort of Compile time annotation processing to turn an annotated local variable into an "anonymous" subclass with the annotation as a type annotation?

For the record, the annotation I'm trying to use looks like this:

@Retention(RetentionPolicy.Runtime)
@Target(ElementType.Type, ElementType.LOCAL_VARIABLE)
public @interface AdminOnly
{
  int isVisible() default 0;
  int isEnabled() default 1;
}

UPDATE

So based on @Xavi López'es answer what I was hoping to do isn't exactly possible. Annotated LocalVariables should be available at compile time though. Is there some way maybe I could use them as a shortcut for boiler-plating the meta-data code examples that are available in Wicket Examples or the excellent Apache Wicket Cookbook?

Foi útil?

Solução

I've struggled with a similar issue some time ago with Wicket 1.3.x, and didn't find any way to achieve this with annotations. Annotations on local variables can't be retained at run-time, as explained in the JLS (9.6.3.2. @Retention):

An annotation on a local variable declaration is never retained in the binary representation.

In this related question: How can I create an annotation processor that processes a Local Variable? they talked about LAPT-javac, a patched javac version to allow this. On their site there's a link to the Type Annotations Specification (JSR 308), which will hopefully address this subject (JDK 8 ?).

I ended up defining a plain old interface with a related functionality code:

public interface RestrictedComponent {
    Integer getFunction();
}

The main problem with this approach is that it's not possible to make instant anonymous subclasses of a specific class implement other interfaces (such as Component c = new TextField() implements AdminOnly { }) , but you can always define Component extensions that just implement RestrictedComponent in a class:

public abstract class RestrictedTextField extends TextField implements RestrictedComponent { } 

Finally, I ended up implementing a RestrictedContainer that just subclassed WebMarkupContainer and put every secured component inside one, modelling it with a <wicket:container> in the markup.

public class RestrictedContainer extends WebMarkupContainer implements RestrictedComponent {
    private final Integer function;
    public RestrictedContainer(String id, IModel model, final Integer function) {
        super(id, model);
        this.function = function;
    }
    public RestrictedContainer(String id, final Integer funcionalitat) {
        super(id);
        this.function = function;
    }
    public Integer getFunction() {
        return function;
    }
}

And then in the Authorization Strategy checked for component instanceof RestrictedComponent and returned true or false depending on user permissions on the associated function.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top