Paul Stovell blogged about binding data to enums in C#. Here is how I would implement this technique in Java….
First, an annotation that I will use to bind data to my enum
@Target(Element.FIELD)
@Retention(RententionPolicy.RUNTIME)
public @interface Config {
String name();
String alias();
}
Then, here is my enum
public enum Role {
@Config(name="James Bond", alias = "Agent 007")
AGENT;
// static attribute that will allow us to
// config the enum only once.
private static boolean isConfigured = false;
static {
if(!isConfigured){
configureRole();
}
}
private RoleValue value;
Role(){
}
public RoleValue getValue(){
if(value == null){
throw new IllegalStateException();
}
return new RoleValue(value);
}
private static void configureRole(){
final Field[] declaredEnums = Role.class.getDeclaredFields();
for(Field eachField : declaredEnums){
final Config placedConfig = eachField.getAnnotation(Config.class);
final boolean isValuesField = eachField.getName().equals("$VALUES");
final boolean isRefreshedField = eachField.getName().equals("isConfigured");
final boolean isValueField = eachField.getName().equals("value");
// ... we want to igonore the VALUES, isConfigured, and value fields.
// ... we care only about the Role's enum instances.
if(isValuesField || isRefreshedField || isValueField){
continue;
}
final String name = placedConfig.name();
final String alias = placedConfig.alias();
final Enum<Role> actualEnum = valueOf(eachField.getName());
final RoleValue enumValue = new RoleValue(name, alias);
try {
final Field field = actualEnum.getDeclaringClass().getDeclaredField(
"value"
);
field.setAccessible(true);
field.set(actualEnum, enumValue);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
isConfigured = true;
}
}
/**
* a updatable value
*/
public static class RoleValue {
private final String name;
private final String alias;
public RoleValue(String name, String alias){
this.name = name;
this.alias = alias;
}
public RoleValue(RoleValue value){
this(value.getName(), value.getAlias());
}
public String getName(){
return name;
}
public String getAlias(){
return alias;
}
}
}
interesting way to play with Java 5.0′s enums…. cool :)