Easyconf library 0.9.0 API

The purpose of easyconf is to provide an easy to use and centralized library to configure software components from XML and properties configuration files.

See:
          Description

Packages
com.germinus.easyconf  
com.germinus.easyconf.jmx  
com.germinus.easyconf.servlet  
com.germinus.easyconf.struts  
com.germinus.easyconf.taglib  

 

The purpose of easyconf is to provide an easy to use and centralized library to configure software components from XML and properties configuration files. Easyconf simplifies the management of different configuration of an application in different environments (preproduction, production, etc. or for different deployments). The purpose of easyconf is to provide an easy to use and centralized library to access documentation. Its main features are:

  1. Support for both properties and XML files (or a mix of both)
  2. Support for changing the configuration for different environments and subprojects
  3. Support for accessing properties from JSP files
  4. Support for several configuration modules (called components) to allow different software components running in the same JVM to use separate configuration files.

Quick start

Easyconf consist of a central component (ConfReader) that returns the configuration of a given component. This class has a static method called getConfiguration which must be given the name of a component. The name of the component can be any String which can be used to identify it within easyconf.

Reading the configuration from Java

Following is an example of how to use this class:

ComponentConfiguration conf = ConfReader.getConfiguration("my-component");

The result is an object with the configuration of the given component. The component configuration contains a properties based configuration and a XML based configuration. Let's start with the first one. Note that we'll asume from now on that we'll be working with the configuration of a component called my-component.
The properties are read from a file named after the component name. In our example the properties would be read from the file my-component.properties (later you'll see that other files will also be read to allow a property value to be overridden in different environments). This simple convention hides the name of the file from the program code.
Once you have the ComponentConfiguration you can just read the property values which are automatically converted to integers, booleans, lists, etc. Following are two examples of how to read typed properties:
  List portlets = conf.getProperties().getList("static.portlets");
  boolean disable = conf.getProperties().getBoolean("registration.disable");
On the other hand the XML configuration can be converted to any object by filling a digester rules file. The XML configuration of the previous example will be read from a file named my-component.xml and its digester rules from my-component.digesterRules.xml. The XML parsing converts the configuration to a set of user defined object classes. For example imagine that we want to configure some databases specifying it's tables and types of tables. We define two classes: DatabaseConf and Table. Then we write the XML configuration in my-component.xml, for example:
<database>
  <tables>
    <table tableType="type1"/>
  </tables>
</database>

Next we write the Digester rules in my-component.digesterRules.xml:
<!DOCTYPE digester-rules PUBLIC
   "-//Jakarta Apache //DTD digester-rules XML V1.0//EN"
   "digester-rules.dtd">
<digester-rules>
  <pattern value="database">
    <object-create-rule classname="com.foo.bar.DatabaseConf"/>
    <pattern value="tables/table">
      <object-create-rule classname="com.foo.bar.Table"/>
      <set-properties-rule/>
      <set-next-rule methodname="addTable" paramtype="com.foo.bar.Table"/>
    </pattern>
  </pattern>
</digester-rules>
Finally, just one line of code is necesary to obtain the objects which have resulted from parsing the configuration. Easyconf calls the result an object graph because it returns one object which can contain other objects inside, which can contain even more objects, etc. Here is an example of code of retrieving and using the object graph of the previous XML configuration:
    DatabaseConf dbconf = (DatabaseConf) conf.getConfigurationObject();
    Table firstTable = dbconf.getTables().get(0);
    String tableType = firstTable.getTableType();

For more information about how to write the rules files check the digester xml rules documentation A variant of this example is using properties from the properties based configuration in the XML file. For example:

<database>
  <tables>
    <table tableType="${table.type1}"/>
  </tables>
</database>
Where table.type1 is defined in a properties file as:
table.type1=type1
This allows to change this value for different environments.

In a next section is a more detailed description of a component configurations.

Reading the configuration from a JSP page

EasyConf provides a taglib to make it very easy to read the configuration of a component from a JSP. It is limited to properties because that's what is most commonly needed in this situations. Herea is a self explaining example:
    <%@ taglib uri="/WEB-INF/tld/easyconf.tld" prefix="easyconf" %>

        <easyconf:property id="static_portlets"
                   component="xpression-ui"
                   property="static.portlets"
                   type="java.util.List"/>
        <logic:iterate id="item" name="static_portlets">
           <bean:write name="item"/>
        </logic:iterate>

        <easyconf:property id="registration_disabled"
                   component="my-component"
                   property="registration.disabled"/>
        <logic:equal name="registration_disabled" value="true">
           <bean:message key="registration.disabled"/>
        </logic:equal>
Los valores soportados en el parametro type son: java.util.List, java.lang.Integer , java.lang.String java.lang.Double, java.lang.Float, java.lang.Byte java.math.BigDecimal, java.lang.BigInteger, java.lang.Boolean java.lang.Short y java.lang.Long.

Structure of a component configuration

The configuration is an instance of ComponentConfiguration which is composed of:

XML based configuration

The XML configuration of a component is read using Digester from Jakarta and is converted to objects using the information of two files: The result of reading this configuration is a graph of regular Java objects (POJOs) which can be used without limitations by the software component. A nice additional feature of the XML based configuration is that the values of any of its elements or attributes can contain variables whose values are defined in the properties based configuration. The variable should be of the form ${variableName}. For example, the following XML fragment can be used:

<welcome-msg> Bienvenido a ${server.name} </welcome-msg>

As long as there is a property named server.name as explained next.

Properties based configuration

The properties configuration of a module is obtained from a composition of the following files:
  1. ${componentName}.properties
  2. global-configuration.properties
In case of collision the values of global-configuration.properties will override the ones in the specific properties file. Furthermore, any of this files can include other files which contain overridden values for any of its properties. This is done with a special property whose key is include-and-override. This property is multivaluated so that several files can be included. In case of collision of values among the included files the ones specified last will override the previous ones. A usual pattern is to include the following properties in global-configuration.properties:

include-and-override=global-configuration-env.properties include-and-override=global-configuration-prj.properties

Which allows any property in any component to be redefined for a especific environment and for a specific project. Note that if the specified file does not exist it will be ignored silently.

Access to system properties

EasyConf makes available all system properties as variables that can be used in the values of the properties files. For example, if the application is run using the following command:

java ......... -Dinstallation-dir=/opt/application

You can use the variable ${installation-dir} in a properties file. For example:

readme.file.path=${installation-dir}/README

Support for environment configuration

The support for environment configuration is based on the access to system properties and the special include-and-override property. Using a system property you can set the name of the current environment. For example:

java ......... -Dconfiguration-environment=production

Then in global-configuration.properties you can set the following property:

include-and-override=global-configuration-${configuration-environment}.properties

Which in the previous example will cause EasyConf to load the file global-configuration-production.properties. Using this pattern you can have an application EAR, WAR or JAR which contains the configuration for all the environments and then set a system property when running the application to select which configuration should be used. As usual, the referenced files that do not exist they will be silently ignored. If the JVM property is not defined no file will be loaded.

Properties format

The format of the properties files is the same as the standard Java properties with the following additions: For more information about the format of the properties read: Note that not all the funcionalities of Commons Configuration are available in easyconf, particularly the way to read XML as EasyConf provides a more powerful mechanism.



Copyright © 2005 EasyConf team. All Rights Reserved.