Configuration Engine

The configuration engine provides a hierarchical storage for configuration properties. It allows to override default parameters with user-specific settings, and uses the distributed cache to avoid database lookups.

A configuration parameter is characterized by the following properties:

A parameter is defined using one of the ParameterFactory methods. The parameter interface uses Java generics to provide typesafe manipulation of the configuration values, for example it is not possible (using the configuration APIs) to store a String value in an Integer parameter. Let's start with declaring a configuration parameter of type Integer:

public static final Parameter<Integer> INT_PARAM =
        Integer.class,       /* value class */
        "/config/test",      /* path */
        "param1"             /* key */,
        21                   /* default value */

Our new parameter has user scope, which (by definition) uses the application configuration as a fallback. This means we can now store values both in the application and user configuration (and because the fallback scopes of application are also used, also in the division configuration). Of course, unless we are logged in as a global supervisor, we cannot update the application configuration, but any user can update his or her own configuration. By default, the configuration engine uses the "least shared" scope, in our case the user scope. The following call puts a value in the configuration of the calling user and displays the new value:

EJBLookup.getConfigurationEngine().put(INT_PARAM, 123456);

System.out.println("User parameter value: " + EJBLookup.getConfigurationEngine().get(INT_PARAM));

Having global supervisor privileges (e.g. in a run-once script) we can also update the fallback value using the division configuration engine (which has the same interface as the configuration engine, but always uses division scope):

EJBLookup.getDivisionConfigurationEngine().put(INT_PARAM, 123456);

The configuration engine supports generic value types through serialization to XML with XStream. The ParameterFactory methods return optimized parameter implementations for most primitive values (e.g. Integer, Long or String), and uses the XStream-based implementation for everything else. For example, the following code declares and uses a parameter for values of type java.awt.Point:

// declare parameter
final Parameter<Point> POINT_PARAM = ParameterFactory.newInstance(Point.class,
                            "/config/test",         /* path */
                            "pointParam",           /* key */
                            new Point(10, 20)       /* default value */);

// store Point value
EJBLookup.getConfigurationEngine().put(POINT_PARAM, new Point(3, 4));

// retrieve stored value
System.out.println("Point parameter: " + EJBLookup.getConfigurationEngine().get(POINT_PARAM));