Sometimes it is nice to be able to access properties from a properties file in the same way as enums are accessed within Java. By this I mean that you can simply use the '.' (dot) notation and you get exactly what you expect.
for example with this enum
enum Colours {
BLUE(1), GREEN(2), RED(3);
private int num;
Colours( final int i ) {
num = i;
}
int getValue() {
return num;
}
}
you can expect that
int iCol = Colours.GREEN.getValue();
will not only compile but also give the correct number to iCol.
Now imagine that the colour blue is no longer to be represented by the number 1 but the number 7 instead, you would need to re-compile you enum in order to get the correct number.
Very Simple Solution
now take this code
enum KFType {
type( "type", ConversionType.INT ),
words( "words", ConversionType.STRING ),
//example in overriding the getter
special( "special", ConversionType.INT ) {
@SuppressWarnings( "unchecked" )
@Override
T getValue() {
Integer t = super.getValue();
return (T) Integer.valueOf( t.intValue() + 10 );
}
};
private ConversionType c;
private String tag;
private static final Properties keyFile = new Properties();
static {
try {
keyFile.load( new FileInputStream( "path to props" ) );
} catch ( IOException ioe ) {
ioe.printStackTrace();
}
}
KFType( final String t, final ConversionType con ) {
c = con;
tag = t;
}
T getValue() {
return c.convert( keyFile.get( tag ) );
}
}
@SuppressWarnings( "unchecked" )
enum ConversionType {
INT {
Integer convert( Object o ) {
return Integer.valueOf( o.toString() );
}
},
STRING {
String convert( Object o ) {
return o.toString();
}
};
abstract T convert( Object o );
}
The disadvantage here is that in order to get any changed values from the properties file the jvm will need to reload the enumerated type which normally means a restart (I think). The big advantage here is that you can now use properties from properties file, or an xml file as if they were code.
I have also shown that you can perform some sort of transformation to the values read from the properties file, here I simply add 10 to the number read but there is no reason why we couldn't wrap text in an http url or something similar.
Look at the output of this
@Test
public void testEnum() {
System.out.println( ((Integer)KFType.type.getValue()) + 10 );
System.out.println( ((Integer)KFType.special.getValue()) + 10 );
System.out.println( KFType.words.getValue() );
System.out.println( KFType.special.getValue().getClass() );
System.out.println( KFType.words.getValue().getClass() );
}
12355
120
these are words
class java.lang.Integer
class java.lang.String
this is when I use the following properties
type=12345
words=these are words
special=100
That's really helpful and far neater than the other way that I was going to load my properties.
ReplyDeleteI have also been able to keep my class under 100 lines with this enum methodology which should please Mr Arno :)