Mind you, if annotation content is static, it can however be rather complicated.
indeed, annotation content can be
- string
- enum
- Number
- another annotation
- or even an array
Which lead to some kind of annotation hell (I'm thinking, as an example, about JPA named queries).
Furthermore, as what you are asking for reminds me strongly of EJB security model, I will take some more examples.
An EJB can be freely acessed by any user (using ... nothing, it's the default), or its access can be restricted to some roles, using the @RolesAllowed({"roleA", "roleB", "roleC"})
. Furthermore, as the strings used here are simply Java constants, they can be declared in a "constants interface", declaring only those roles
public interface Roles {
String ROLE_A = "roleA";
String ROLE_B = "roleB";
String ROLE_C = "roleC";
}
Then, my initial declaration becomes @RolesAllowed({Roles.ROLE_A, Roles.ROLE_B, Roles.ROLE_C})
. This is however do not detail how these roles are applied to users ... which lead us right into the JAAS hell (an hell in which I won't push you down to ... well, unless you want to get rid of your preprocessor idea - which sits in another circle of hell :-)).
Anyway, let me stand one point very clearly : annotations are simply declarative, and they can/should only contain declaration of intention, and not behaviour. You can of course do string parsing to detect content and operate the require behaviour, but it's specifically a bad idea. If you're absolutely convinced you need your preprocessor, please at least replace the string fragment by another annotation :
#define USER_HAS_ACCESS(userArg, permissions) @Allow(userName=userArg, granted=permissions)
But ... wait, I've declared an annotation to simplify that preprocessing ? Maybe is it beceause those two things are greatly overlaping :-) So much, in fact, that it's some common sense to have annotation declared in a superclass and applied to all its descendant classes ...