I want to create something that resembles an extendable Enum (understanding extending Enums isn’t possible in Java 6).
Here is what im trying to do:
I have many “Model” classes and each of these classes have a set of Fields that are to be associated with it. These Fields are used to index into Maps that contain representations of the data.
I need to be able to access the Fields from an Class OR instance obj as follows:
MyModel.Fields.SOME_FIELD #=> has string value of "diff-from-field-name"
or
myModel.Fields.SOME_FIELD #=> has string value of "diff-from-field-name"
I also need to be able to get a list of ALL the fields for Model
MyModel.Fields.getKeys() #=> List<String> of all the string values ("diff-from-field name")
When defining the “Fields” class for each Model, I would like to be able to keep the definition in the same file as the Model.
public class MyModel {
public static final Fields extends BaseFields {
public static final String SOME_FIELD = "diff-from-field-name";
public static final String FOO = "bar";
}
public Fields Fields = new Fields();
// Implement MyModel logic
}
I also want to have OtherModel extends MyModel and beable to inherit the Fields from MyModel.Fields and then add its own Fields on top if it ..
public class OtherModel extends MyModel {
public static final class Fields extends MyModel.Fields {
public static final String CAT = "feline";
....
Which woulds allow
OtherModel.Fields.CAT #=> feline
OtherModel.Fields.SOME_FIELD #=> diff-from-field-name
OtherModel.Fields.FOO #=> bar
OtherModel.Fields.getKeys() #=> 3 ["feline", "diff-from-field-name", "bar"]
I am trying to make the definition of the “Fields” in the models as clean and simple as possible as a variety of developers will be building out these “Model” objects.
Thanks
I was able to come up with a solution using reflection that seems to work — I haven’t gone through the full gamut of testing, this was more me just fooling around seeing what possible options I have.
ActiveField : Java Class which all other “Fields” Classes (which will be inner classes in my Model classes) will extend. This has a non-static method “getKeys()” which looks at “this’s” class, and pulled a list of all the Fields from it. It then checks a few things like Modifiers, Field Type and Casing, to ensure that it only looks at Fields that match my convention: all “field keys” must be “public static final” of type String, and the field name must be all UPPERCASE.
Then in my “Model” classes (which are fancy wrappers around a Map, which can be indexed using the Fields fields)
public class ActiveResource {
/**
* Base fields for modeling ActiveResource objs – All classes that inherit from
* ActiveResource should have these fields/values (unless overridden)
*/
public static class Fields extends ActiveField {
public static final String CREATED_AT = “node:created”;
public static final String LAST_MODIFIED_AT = “node:lastModified”;
}
}
I can then make a class Foo which extends my ActiveResource class
Now, I can do the following:
I can also access the Fields as a static field off my Model objects
So far this looks like a pretty nice solution, that will require minimal instruction for building out new Models.