Package de.uni_trier.wi2.procake.utils.composition

CAKE Composition Manager

The components of the system are mostly defined by Java interfaces. If a component needs access to another component, only the interfaces should be used and never an implementation. This makes it possible to change an implementation of a component without changing any other component. For example, if the logger should be realized with a database backend, only the implementation changed and not the interface. Consequently, no other component must be adapted to the new backend.

Factories

The factory classes are the connections between the interfaces and the implementations that should be used. If an object of an interfaces is needed a request to the corresponding factory is send which returns the object.

Beside the methods of the Factory interface contains each factory two kind of static methods:

get-methods
Each method that beginns with "get" reuses an existing object. Therefore, most of these methods beginning with "getDefault" to emphasis this issue.
new-methods
Each method that beginns with "new" creates a new object. In some factories it is necessary to specify the newly created object as the default object thus the new-method exist with a boolean parameter. The boolean parameter specifies if the newly created object should be set as the default object.

An example of the different kinds of method can be found in the data model factory, see ModelFactory.

Composition Manager

The task of the composition managers is to connect the factories with the concrete implementation. Which implementation should be used is defined in an XML file. For example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Composition SYSTEM "composition.dtd">

<Composition>
        <Factory name="logger" class="cake.logger.LoggerFactory">
                <Implementation class="cake.logger.log4j1_2_8Impl.Log4JLogger">
                        <Parameter name="configuration_file" value="etc/console.log4j"/>
                </Implementation>
        </Factory>        
        <Factory name="io_factory" class="cake.io.IOFactory">
                <Implementation class="cake.data.io.xml.xerces_saxImpl.ModelSaxParser" />
                <Implementation class="de.uni_trier.wi2.procake.data.io.xml.xerces_writerImpl.ModelWriterImpl />
                <Implementation class="cake.data.io.xml.xerces_saxImpl.ObjectSaxParser />
                <Implementation class="cake.data.io.xml.xerces_saxImpl.ObjectPoolSaxParser />
                <Implementation class="cake.data.io.xml.xerces_writerImpl.ObjectWriterImpl" />
                <Implementation class="cake.data.io.xml.xerces_writerImpl.ObjectPoolWriterImpl" />
        </Factory>        
</Composition> 

Each factory can get one or more implementations wich must implement the interface FactoryObjectImplementation and a special interface defined in the corresponding component, e.g., LoggerFactoryObject for the logger factory. Additionally, each implementation can get several parameter, e.g., the configuration file for the logger.

Of course, the composition manager should be called before anything else to build the system. A typical code fragment to build the system look like this:

 if (CompositionManager.isSystemBuild() == false) {
     CompositionManager cm = new CompositionManager();
     cm.setConfigurationFile("/etc/composition.xml");
     cm.build();
}