Setting class variables dynamically from a config file

J

Joel Gilmore

Hi all,

I'm writing a java program (an evolution simulator) that has a large
number (>50) of preferences that can be tweaked (e.g., foodAvailable,
mutationRate, etc). They are booleans, ints and doubles. At present,
these are variables in a class, and I'm trying to work out the best
way for the user to be able to set these variables. Some of the most
important ones I've put into a preference box, but for the others that
will only get changed rarely, I'm trying to find a more sustainable
solution.

I envision having a user-editable config file which would be loaded at
the start, either in XML format or simply

foodAvailable = 20
mutationRate = 0.01

I know I could code a massive if-then-else block to handle all the
different variables (if (key="foodAvailable") foodAvailable=value;),
but I would have to update that every time I add a new variable as the
program grows (prone to error, and just looks like bad code). Is there
a way that I could dynamically read in the variable name and attempt
to set it? It would also be very convenient to be able to do the
reverse and dynamically generate the config file from my class
(getting its variable names and their values).

I've heard about Reflection, but not certain if that's where I should
start. Another option would be to store the parameters not as
variables but in some sort of dictionary with String keys. However,
speed is an issue and I'm worried if I have to do a dictionary lookup
for every variable in my code it's going to slow things down
significantly (is that fear unfounded?). I could read them out of the
dictionary into the class variables, but that would again require hard
coding the variable names?

I don't know if enumerating the parameters instead of using them as
variables would make any difference?

Basically, I'm just not sure where to start looking in the Java help
files - so any suggested approaches would be much appreciated!

Cheers,
Joel
 
O

Owen Jacobson

Joel said:
Hi all,

I'm writing a java program (an evolution simulator) that has a large
number (>50) of preferences that can be tweaked (e.g., foodAvailable,
mutationRate, etc). They are booleans, ints and doubles. At present,
these are variables in a class, and I'm trying to work out the best
way for the user to be able to set these variables. Some of the most
important ones I've put into a preference box, but for the others that
will only get changed rarely, I'm trying to find a more sustainable
solution.

I envision having a user-editable config file which would be loaded at
the start, either in XML format or simply

foodAvailable = 20
mutationRate = 0.01

I know I could code a massive if-then-else block to handle all the
different variables (if (key="foodAvailable") foodAvailable=value;),
but I would have to update that every time I add a new variable as the
program grows (prone to error, and just looks like bad code). Is there
a way that I could dynamically read in the variable name and attempt
to set it? It would also be very convenient to be able to do the
reverse and dynamically generate the config file from my class
(getting its variable names and their values).

I've heard about Reflection, but not certain if that's where I should
start. Another option would be to store the parameters not as
variables but in some sort of dictionary with String keys. However,
speed is an issue and I'm worried if I have to do a dictionary lookup
for every variable in my code it's going to slow things down
significantly (is that fear unfounded?). I could read them out of the
dictionary into the class variables, but that would again require hard
coding the variable names?

Two approaches come to mind:

1. Use Spring or another similar project to handle the configuration
step - this will also enable some cool stuff for assembling objects at
startup. The downside is that the configuration format will be one
designed for some really general-purpose tasks: using Spring, you'd
get something like:

....
<bean id="core" class="com.example.SimulationCore">
<property name="foodAvailable">
<value>20</value>
</property>
</bean>
....

which might be a little verbose. There are other context
configurators available for it if you do a little digging, though.

2. There is a class in Commons Beanutils which adapts arbitrary
beans to the Map API, allowing you to access its properties by name.
You can do the same thing using the java Beans (java.beans) API
yourself, too. You can iterate through a java.util.Properties object
(easily loaded from a file of the format
key = value
) and apply each entry to a bean.

Both of these approaches rely on your code following the bean
conventions for property access: int getFoo()/void setFoo (int) for a
property named 'foo' of type int.

-o
 
L

Lew

Owen said:
Two approaches come to mind:

1. Use Spring or another similar project to handle the configuration
step - this will also enable some cool stuff for assembling objects at
startup. The downside is that the configuration format will be one
designed for some really general-purpose tasks: using Spring, you'd
get something like:

....
<bean id="core" class="com.example.SimulationCore">
<property name="foodAvailable">
<value>20</value>
</property>
</bean>
....

which might be a little verbose. There are other context
configurators available for it if you do a little digging, though.

2. There is a class in Commons Beanutils which adapts arbitrary
beans to the Map API, allowing you to access its properties by name.
You can do the same thing using the java Beans (java.beans) API
yourself, too. You can iterate through a java.util.Properties object
(easily loaded from a file of the format
key = value
) and apply each entry to a bean.

Both of these approaches rely on your code following the bean
conventions for property access: int getFoo()/void setFoo (int) for a
property named 'foo' of type int.

There is also java.util.Properties, which can load an instance from a text
file in "key=value" format or XML layout. You can retrieve the String
equivalent of your values directly from the key for each property, then
convert to the correct type. This lacks the power of, say, Spring, but has
the virtue of simplicity and using only the standard API.
 
D

Daniele Futtorovic

There is also java.util.Properties, which can load an instance from a
text file in "key=value" format or XML layout. You can retrieve the
String equivalent of your values directly from the key for each
property, then convert to the correct type. This lacks the power of,
say, Spring, but has the virtue of simplicity and using only the
standard API.

This would still require the OP to hardcode variable assignments -- the
very thing he tries to avoid, as far as I understood.

Reflection seems to only way to avoid this step -- whether used through
some preexistent framework or directly.

Tutorial on reflection here:
<http://java.sun.com/docs/books/tutorial/reflect/index.html>

df.
 
M

Mark Space

Joel said:
I envision having a user-editable config file which would be loaded at
the start, either in XML format or simply

This actually is a good case for using reflection. The only real issue
is that Java suffers an embarrassment of riches for serializing classes
to XML and back. Before rolling your own you should look at some
parsers that have already been written (and debugged).

You've already got some good advice. A Google search for "java xml
serialization" gets lots of good hits. You should browse those results
yourself to see if anything strikes you as a very good match for your
application.

Here's a couple of thoughts by me:
JAXB - Java XML Binding
Uses annotations to make the job of marshaling classes to XML and back.
<http://java.sun.com/javase/6/docs/technotes/guides/xml/jaxb/index.html>

XStream
Claims to be simple and easy, always a win in my book.
http://xstream.codehaus.org/

Simple
It looks like Simple also uses annotations but claims to be (guess!)
simpler to use than JAXB.
http://simple.sourceforge.net/

I haven't used any of these, so you might want to look around for some
articles and check the docs, see what might be the best match for you.
 
J

Joel Gilmore

Thanks heaps guys - XStream and its ilk seems to be exactly what I was
looking for.

Much appreciated!

Cheers,
Joel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,233
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top