Using Merlin

Tutorial Overview

This tutorial takes you though the creation of a very simple component, the declaration of a component type descriptor, and the declaration of a block containing the component.

Resources (sample code and build files) supporting this tutorial are included in the Merlin distribution under the tutorials/hello directory.

Creating a component

The following code is a minimal component. It simply log a message during the initialization stage. We will progressively extend this component to do more creative things as we proceed through this tutorial.

package tutorial;

import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.activity.Initializable;

/**
 * A sample component.  This component implements a number 
 * of lifecycle interface.  Each lifecycle interface is a stage
 * that is processed by a container during the deployment of 
 * the component.  The lifecycle stages demonstrated here include
 * LogEnabled (association of a logging channel), Initializable
 * (initialization of the component), Executable (component
 * execution), and Disposable (componet disposal).  PLease note 
 * that all lifecycle stages are optional.
 *
 * @avalon.component version="1.0" name="hello"
 */
public class HelloComponent 
  implements LogEnabled, Initializable, Executable, Disposable
{

   /**
    * Internal reference to the logging channel supplied to us 
    * by the container. 
    */
    private Logger m_logger;

   /**
    * Supply of a logging channel by the container.
    *
    * @param logger the logging channel for this component
    */
    public void enableLogging( final Logger logger )
    {
        m_logger = logger;
        getLogger().info( "logging stage" );
    }

   /**
    * Initialization of the component by the container.
    * @exception Exception if an initialization error occurs
    */
    public void initialize() throws Exception
    {
        getLogger().info( "initialization stage" );
    }

   /**
    * Component execution trigger by the container following 
    * completion of the initialization stage.
    */
    public void execute()
    {
        getLogger().info( "execution stage" );
    } 

   /**
    * Component disposal trigger by the container during which
    * the component will release consumed resources.
    */
    public void dispose()
    {
        getLogger().info( "disposal stage" );
        m_logger = null;
    } 

   /**
    * Return the logging channel assigned to us by the container.
    * @return the logging channel
    */
    private Logger getLogger()
    {
        return m_logger;
    }

}

Creating a Type Descriptor

In order for Merlin to recognize this class as a component, we need to generate a <classname>.xinfo file. However, this can be done automatically by including a pre-goal as shown below into the maven.xml file.

<preGoal name="java:compile">
  <attainGoal name="avalon:meta"/>
</preGoal>

The avalon:meta plugin looks for @avalon tags in the source code, to generate the correct Type Descriptor. In the above example it will find the @avalon.component tag in the class level javadocs and generate component the descriptors for us (see below).

Generated Type Descriptor

The following text is an example of a component type definition. It contains the declaration of the component name and the component implementation version. From the example above ( @avalon.component version="1.0" name="hello" ) the generated Type Descriptor would look something like this.

<type>
  <info>
    <name>hello</name>
    <version>1.0.0</version>
    <lifestyle>transient</lifestyle>
  </info>
</type>

Creating a block

A block is the definition of a composite component. It represents an application made up of a set of components and the supporting resources. In our example the block will contain the single HelloComponent component. Based on this information Merlin will create a container and deploy the hello component on startup.

<container name="tutorial">

   <classloader>
     <classpath>
       <repository>
         <resource id="avalon-framework:avalon-framework-impl" version="4.1.5"/>
       </repository>
     </classpath>
   </classloader>

   <component name="hello" class="tutorial.HelloComponent"/>

</container>

Execution

The next tutorial - titled Running Hello covers deployment of the component using the Merlin runtime platform.