Introduction

The aim of this guide is to explain to the novice user how to invoke the default services offered by the Raccoon Core modules.

Currently the Raccoon Core module offers the following services:

  • Log: an easy to use logging service. The default implementation is the Log4j package, but you can also switch to the log service offered by the JDK 1.4
  • Config: an easy to use configuration service. The default implementation is the standard java properties file.

My first application

The code of this application is located in the package raccoon.core.sample.MyFirstApp of the core-sample release. The source code of this simple application is located here in an HTML format.

Step 1: Setting up the environnement

The minimal work that is to be done is to place the following jars in the java classpath:

  • Raccoon Core jar file: currently this file is named raccoon-0.5.5.jar
  • Castor Xml jar file: currently this file is named castor-0.9.3.19-xml.jar
  • Apache Xerces parser: currently this file is named xerces-1.2.3.jar
  • Log4j jar file: currently this file is named log4j-1.1.3.jar
Additionnaly you may add the sample configuration file called raccoon.properties to the path. This is necessary if you wish to customise the behaviour of the Core Modules, this isn't compulsory but we will do it in this tutorial.

The contents of the file raccoon.properties are:

          
raccoon.service.manager.mapping = data.services.xml
raccoon.service.manager.service = core_components.xml
          
        

We will change the value of raccoon.service.manager.service later on in the tutorial.

Step 2: Writing my first log statement

This step corresponds to the code found in the method writeLog().

Using the log service is a very simple matter of invoking the getLog() method of the CoreHelper

          
          LogBase log = CoreHelper.getLog();

          log.debug("My first debug string");
          
        

If the debug level is enabled, which it is in the default distribution for the Raccoon Core, you should see the following line (amongst others) in the file named raccoon-core.log:

          
10 [main] DEBUG sample.MyFirstApp  - My first debug string
          
        

If not, you then you should refer to the section [] to configure the Log4j component debug level to be enabled.

The easiest thing to do is to edit the configuration file used by log4j: raccoon.core.service.log.log.properties

Step 3: Reading my first configuration element

This step corresponds to the code found in the first part of the method readConfig().

Using the configuration service is a very simple matter of invoking the getConfig() method of the CoreHelper and invoking the desired method to read the right type of element: getString(), getLong(), ....

          
          LogBase config = CoreHelper.getConfig();

          String componentFile = config.getString("raccoon.service.manager.service");
          System.out.println("The configuration file is currently : \"" + componentFile + "\"");
          
        

The invocation of the method getConfig() returns a configuration instance that contains the contents of the default property file for the Raccoon Core. In the default distribution of the Raccoon Core the file is named raccoon.properties and should be located in the classpath.

When you execute the above code you should get the following output:

          
The configuration file is currently : "core_components.xml"
          
        

If not, you then you should refer to the section [] to check if your Config component is configured correctly or if your default property file (raccoon.properties) contains: raccoon.service.manager.service = core_components.xml

Step 4: Customizing the Core Module Config

This step corresponds to the code found in the second part of the method readConfig().

As you've seen in the previous step the CoreHelper will load components defined in a file called core_components.xml located in the package raccoon.core.manager. However one might be tempted to use a configuration file other than raccoon.properties, say for example: sample.properties.

So the first thing to do is to create a configuration file, say my_components.xml, and to copy the contents of the file core_components.xml into it. The next thing to do is to add the following element within this file:

          
          <Component ComponentName="myConfig" ComponentClass="raccoon.core.service.config.StdConfig">
            <PropertyDefaultValues PropertyName="propertyFileName" PropertyType="string" PropertyValue="sample" />
          </Component>
          
        

Where sample refers to a file called sample.properties that is located in the current classpath.

Don't forget to change the file raccoon.properties so that the core will load your custom component definition. The line to change is this one: raccoon.service.manager.service = my_components.xml

Reading the contents of that file (sample.properties) is as simple as executing the code shown below. You should get The message found in the properties file is : "Hello World from the sample application.".

          
          ConfigBase config = CoreHelper.getConfig("myConfig");
          System.out.println("The message found in the properties file is : \"" + config.getString("message") + "\"");
          
        

The string myConfig refers to the component defined in the previous xml configuration file.

My first Component

A component is in essence a java class that is managed by the Component Manager of the Raccoon Core Framework. It is special in the sense that it complies to the IOC principles

Step 1: Selecting the behaviour

The first thing to do is to choose the different behaviours your component requires. Currently the following behaviours are available:

  • Configurable: if the component requires a configuration service that implements the ConfigBase interface.
  • Initialisable: if the component requires an invocation of the load method before it is used and an invocation to the load method before it is disposed of.
  • Loggable: if the component requires a logging service that implements the LogBase interface.

Step 2: Creating your component

There are two ways to create your component:
  1. The foremost and easiest by far is to extend AbsComponent class. However this isn't always possible because in Java you can't extend two different classes ;o)
  2. The compulsory way is to implement the interface ComponentBase. This is the minimal thing to do but represents the greatest work ...
This tutorial will consider it possible to extend the AbsComponent class, the sample code can be found within the class MyFirstComponent. The html version of this code can be found here.

The first thing to do is to extend the AbsComponent and to implement the abstract methods of this class. We will consider in the first step that this component is neither: configurable, initialisable and loggable.

You should now have the smallest class possible for a component!

Step 3: Declaring your component

Once you've created your component you need to declare it so that it can be maintained by the Service Manager. To do this you need to edit the file my_components.xml (created in the section "My first application") and add the following lines:

        <Component ComponentName="myFirstComponent" ComponentClass="raccoon.core.sample.MyFirstComponent">

        </Component>
        
        

This is the smallest possible declaration of Component. To use this component all you need to do is write the following source code in some method:

        try {

          ComponentBase myCompo = CoreHelper.lookup("myFirstComponent", "myFirstComponent", null);
          System.out.println("Service Manager returned the following component: " + myCompo.getClass().getName());

        } catch (RaccoonException e) {
          e.printStackTrace();
        }
        
        

And you should get the following output:

Service Manager returned the following component: raccoon.core.sample.MyFirstComponent
        
        

Step 4: Defining default values for properties

Let's add a java property to MyFirstComponent called location, this should result in the following code:

        /** The java property named 'location' */
        private String mLocation = null;

        /**
         * Accessor to the java property 'location'
         * @return the location of this component instance
         */
        public String getLocation() {
          return mLocation;
        }

        /**
         * Accessor to the java property 'location'
         * @param pLocation the new location of this component instance
         */
        public void setLocation(String pLocation) {
          mLocation = pLocation;
        }
        
        

Supposing that the default value for location is Paris, France, then we have to add the following line in the file my_components.xml:

          <PropertyDefaultValues PropertyName="location" PropertyType="string" PropertyValue="Paris, France" />
          

This would give the following declaration:

        <Component ComponentName="myFirstComponent" ComponentClass="raccoon.core.sample.MyFirstComponent">
          <PropertyDefaultValues PropertyName="location" PropertyType="string" PropertyValue="Paris, France" />
        </Component>
        
        

Now if we add the following code to our previous code:

          if (myCompo instanceof MyFirstComponent) {
            MyFirstComponent myFirstComponent = (MyFirstComponent) myCompo;
            System.out.println("The value of location is \"" + myFirstComponent.getLocation() + "\"");
          }
        

We should get the following output:

          
The value of location is "Paris, France"
          
        

Step 5: Adding a component

Naturally a component may depend upon another component. In normal circumstances you would write: mySubCompo = new SomeComponent(); and then use the SomeComponent instance. If we apply the IOC principle we can't do this and besides it won't make your code easy to test ;o)

So if we suppose that your component needs a component of a type ConfigBase in order to retrieve some configuration information you need to add the following code to your component:

        /** The configuration service */
        private ConfigBase mData = null;

        public ConfigBase getData() {
          return mData;
        }

        public void setData(ConfigBase pData) {
          mData = pData;
        }
        

And the following line to the configuration file:

          <RequiredComponents ComponentName="myConfig" PropertyName="data"/>
        

Where the component myConfig was defined in the section "My first application". You should now have the following elements within your xml file:

          
        <Component ComponentName="myConfig" ComponentClass="raccoon.core.service.config.StdConfig">
          <PropertyDefaultValues PropertyName="propertyFileName" PropertyType="string" PropertyValue="sample" />
        </Component>

        <Component ComponentName="myFirstComponent" ComponentClass="raccoon.core.sample.MyFirstComponent">
          <PropertyDefaultValues PropertyName="location" PropertyType="string" PropertyValue="Paris, France" />
          <RequiredComponents ComponentName="myConfig" PropertyName="data"/>
        </Component>
        
        

Plus all the default elements to!

You can check that this works by adding the following code to your component:

        System.out.println("The message is \"" + myFirstComponent.getData().getString("message") + "\"");
        

You should get the following output:

The message is "Hello World from the sample application."
        

You now have seen the basic features of the Service Manager (or Component Manager), if you have any suggestions or questions please send an email to RaccoonUser