Setting class variables dynamically from a config file

Discussion in 'Java' started by Joel Gilmore, Feb 11, 2008.

  1. Joel Gilmore

    Joel Gilmore Guest

    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
     
    Joel Gilmore, Feb 11, 2008
    #1
    1. Advertising

  2. Joel Gilmore wrote:
    > 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
     
    Owen Jacobson, Feb 11, 2008
    #2
    1. Advertising

  3. Joel Gilmore

    Lew Guest

    Joel Gilmore wrote:
    >> 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).


    Owen Jacobson wrote:
    > 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.

    --
    Lew
     
    Lew, Feb 11, 2008
    #3
  4. On 2008-02-11 04:26 +0100, Lew allegedly wrote:
    > 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.
     
    Daniele Futtorovic, Feb 11, 2008
    #4
  5. Joel Gilmore

    Mark Space Guest

    Joel Gilmore wrote:

    > 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.
     
    Mark Space, Feb 11, 2008
    #5
  6. Joel Gilmore

    Joel Gilmore Guest

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

    Much appreciated!

    Cheers,
    Joel
     
    Joel Gilmore, Feb 12, 2008
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hardy Wang
    Replies:
    2
    Views:
    1,482
    Joe Fallon
    Jul 31, 2004
  2. CSharpner
    Replies:
    0
    Views:
    1,050
    CSharpner
    Apr 9, 2007
  3. leeanne
    Replies:
    0
    Views:
    1,877
    leeanne
    Sep 24, 2008
  4. Thijs De vries
    Replies:
    1
    Views:
    93
    Jesús Gabriel y Galán
    Oct 20, 2010
  5. kampy
    Replies:
    9
    Views:
    338
    Steven D'Aprano
    Oct 19, 2012
Loading...

Share This Page