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 :)