Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to support "Extendable enums" in annotations?

In my library there is a concept of "user levels". I have provided several default levels but for various reasons want to give the user the option of using their own levels.

Currently this is implemented as

public interface AdminLevel {
    public void name();
}

public enum StandardAdminLevels implements AdminLevel {
    ADMIN,
    ANONYMOUS
}

The problem is that the user is usually going to be passing their required user level in an annotation. Things I have tried and failed:

  • Using AdminLevel as the type - Fails with "invalid type for annotation member"
  • Using String as the type but setting the value with StandardAdminLevels.ADMIN.name() - Fails with "attribute value must be constant"
  • Making StandardAdminLevels a final class that doesn't implement anything with public static final field's for each of the levels (essentially an enum) - Fails with "invalid type for annotation member"

Is there any other way I can't think of to have extendable enums in annotations? I'm trying to stick with enums due to their clarity and basic protection against invalid values, but the only other way I can think of is String constants. The problem I have is that would require verification at every single point user levels are used, potentially even in client code

Any ideas?

like image 955
TheLQ Avatar asked Jun 06 '13 01:06

TheLQ


Video Answer


1 Answers

One idea: every possible AdminLevel is its own class. Pass the Class of that class to the annotation.

public final class Admin implements AdminLevel { ... }
public final class Anonymous implements AdminLevel { ... }

@Requires(Admin.class) public void protectedMethod() { ... }

@interface Requires {
  Class<? extends AdminLevel> value();
}
like image 172
Sebastian Redl Avatar answered Oct 12 '22 16:10

Sebastian Redl