Commons Configuration
  1. Commons Configuration
  2. CONFIGURATION-186

[configuration] Provide support for declaring and creating objects

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

      Description

      A useful enhancement for the configuration API could be a way to create and
      initialize objects whose class and initialization parameters are defined in a
      configuration file.

      The idea is that both the class name and initialization parameters for an object
      are defined in a standard format. A createObject(String key) method (which might
      fit best in DataConfiguration?) would extract the class name from the specified
      property, create the object using reflection and then populate properties via
      [beanutils].

      For the concrete format for declaring objects in a configuration file there are
      many possibilities. We have to define a format which is easy to use, but
      although suports complex initialization parameters. A possible object
      declaration could look as follows (here in XML flavour, but other configuration
      sources are of course possible, too):

      <myobject>
      <class>package.ClassName</class>
      <args>
      <arg1>value1</arg1>
      <arg2>value2></arg2>
      ...
      </args>
      </myobject>

      We could even go a step further and define an interface
      public interface Configurable
      {
      void initialize(Configuration config);
      }

      If the newly created object implements this interface, its initialize() method
      will be called and a sub configuration will be passed that contains the content
      of the <args> section. This would allow for arbitrary complex and also
      hierarchical initialization parameters. It's a bit similar to what IoC
      frameworks do.

      Side note: If we add more features to the configuration definition files
      processed by ConfigurationFactory (e.g locators or declarations for reloading
      strategies) and use a XMLConfiguration to load these files, the proposed object
      creation facility may come in handy.

        Activity

        Hide
        Emmanuel Bourg added a comment -

        I'm a bit reluctant to follow this path, Commons Configuration is well suited
        for simple configuration purposes (i.e properties of simple types like int,
        String, float, Date, arrays...), but not for marshalling/unmarshalling complex
        objects. There is a ton of frameworks already adressing this issue (Castor,
        betwixt, digester, JAXB, JDK 1.4 XMLEncoder/Decoder...) and this is not a
        trivial problem, do we really want to solve it once again ?

        Show
        Emmanuel Bourg added a comment - I'm a bit reluctant to follow this path, Commons Configuration is well suited for simple configuration purposes (i.e properties of simple types like int, String, float, Date, arrays...), but not for marshalling/unmarshalling complex objects. There is a ton of frameworks already adressing this issue (Castor, betwixt, digester, JAXB, JDK 1.4 XMLEncoder/Decoder...) and this is not a trivial problem, do we really want to solve it once again ?
        Hide
        Oliver Heger added a comment -

        Sorry for not being precise. I don't want to implement a marshalling framework.

        What I suggest is a simple way to define objects and to set some properties on
        those. Such a feature has already been requested on the user list. I use a
        similar approach in some of my apps and find it quite convenient (especially
        that you can alter the application's behavior by simply changing the
        implementation class of an interface in the configuration file, e.g. for
        swapping between a "real" and a test implementation).

        And, as I pointed out, we could use this mechanism ourselves when redesigning
        ConfigurationFactory and the related stuff.

        Show
        Oliver Heger added a comment - Sorry for not being precise. I don't want to implement a marshalling framework. What I suggest is a simple way to define objects and to set some properties on those. Such a feature has already been requested on the user list. I use a similar approach in some of my apps and find it quite convenient (especially that you can alter the application's behavior by simply changing the implementation class of an interface in the configuration file, e.g. for swapping between a "real" and a test implementation). And, as I pointed out, we could use this mechanism ourselves when redesigning ConfigurationFactory and the related stuff.
        Hide
        Oliver Heger added a comment -

        I'm going to try something out, which I then want to use in ConfigurationFactory
        to support further configuration options, e.g. for reloading strategies.

        Show
        Oliver Heger added a comment - I'm going to try something out, which I then want to use in ConfigurationFactory to support further configuration options, e.g. for reloading strategies.
        Hide
        Oliver Heger added a comment -

        Some new code related to the features described in this ticket has been
        committed. Two new interfaces were introduced:

        • BeanFactory is responsible for creating new instances of specified classes.
        • BeanDeclaration specifies how a bean and its properties are defined in a
          configuration.

        Default implementations for these interfaces are provided. For creating a bean
        from a Configuration object the following steps are necessary:

        • A BeanDeclaration object must be created that can deal with the Configuration
          and the layout of the bean declaration.
        • With this object an utility method of the BeanHelper class (a class with
          static helper methods) can be called, which creates the object. In code (using
          the default implementation of the BeanDeclaration interface), this looks as follows:

        XMLConfiguration config = new XMLConfiguration("bean.xml");
        XMLBeanDeclaration decl = new XMLBeanDeclaration(config, "personBean");
        PersonBean person = (PersonBean) BeanHelper.createBean(decl);

        With bean.xml looking like that:

        <config>
        <personBean config-class="my.model.PersonBean"
        lastName="Doe" firstName="John">
        <address config-class="my.model.AddressBean"
        street="21st street 11" zip="1234"
        city="TestCity"/>
        </personBean>
        </config>

        Show
        Oliver Heger added a comment - Some new code related to the features described in this ticket has been committed. Two new interfaces were introduced: BeanFactory is responsible for creating new instances of specified classes. BeanDeclaration specifies how a bean and its properties are defined in a configuration. Default implementations for these interfaces are provided. For creating a bean from a Configuration object the following steps are necessary: A BeanDeclaration object must be created that can deal with the Configuration and the layout of the bean declaration. With this object an utility method of the BeanHelper class (a class with static helper methods) can be called, which creates the object. In code (using the default implementation of the BeanDeclaration interface), this looks as follows: XMLConfiguration config = new XMLConfiguration("bean.xml"); XMLBeanDeclaration decl = new XMLBeanDeclaration(config, "personBean"); PersonBean person = (PersonBean) BeanHelper.createBean(decl); With bean.xml looking like that: <config> <personBean config-class="my.model.PersonBean" lastName="Doe" firstName="John"> <address config-class="my.model.AddressBean" street="21st street 11" zip="1234" city="TestCity"/> </personBean> </config>
        Hide
        Oliver Heger added a comment -

        After the user guide was updated to cover the new features I am closing this
        ticket now.

        Maybe it makes sense to provide other BeanDeclaration implementations as well,
        e.g. one for properties files. If this is desired, new enhancement tickets can
        be created.

        Show
        Oliver Heger added a comment - After the user guide was updated to cover the new features I am closing this ticket now. Maybe it makes sense to provide other BeanDeclaration implementations as well, e.g. one for properties files. If this is desired, new enhancement tickets can be created.

          People

          • Assignee:
            Unassigned
            Reporter:
            Oliver Heger
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development