Getting started with Kilim: the WebLog example

Abstract

The goal of this tutorial is to present the various Kilim concepts in a hands-on, no-nonsense way, through building and configuring an example.

The example chosen here is a web application acting as a classical web log. The purpose of this application is to add and display some text entries. This example will, hopefully, demonstrate the intrinsic power of Kilim as well as its better side-effects such as making the application architecture more explicit.

Presentation of the WebLog application.

At the heart of WebLog is a servlet, called WebLog with a lot of originality. This servlet is to be deployed under Tomcat 4.0.3. The servlet will first only read some text and print it on screen. The reading backend is separate.

Optional functionalities will be added through this tutorial, such as several kinds of data storage (non-persistent, persistent via flat files or a database), an authentication module, as well as extending the functionality.

Note:

WebLog 1.0: introducing atoms, assemblages, implicit factories and aliases.

All WebLog 1.0 files are available for download.

In this example we want to take advantage from the dynamic aspects of Kilim, so WebLog uses two Kilim Configuration Files: a bootstrap kcf (Startup.kcf) and a runtime kcf (runtime.kcf).

Bootstrap Configuration File

Here is our bootstrap kcf (Startup.kcf).

<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE Configuration SYSTEM "configuration.dtd">
<CONFIGURATION bootstrap="org.objectweb.jonathan.libs.kernel.helpers.Kernel" generated="weblog.Startup">
  <ELEM name="runtime configuration file">
    <PROPERTY type="String" value="weblog.kcf"/>
  </ELEM>
</CONFIGURATION>

Runtime Configuration File

Here is our runtime kcf: weblog.kcf.

In this kcf, one can see two major constructs: an ATOM and an ASSEMBALGE. In the Kilim terminology, these represent the two ways to specify an object instance.

For more information, please check the Kilim configuration DTD.

Back to our example. The servlet accesses the configuration by getting the Log Handler element defined through the use of an ASSEMBLAGE element.

In the example, the factory is an IMPLICIT_FACTORY. As we mentioned earlier on, an IMPLICIT_FACTORY is made of ALTERNATIVE(s), each ALTERNATIVE is identified by its ID.

The alternative attribute of the ASSEMBLAGE element is set to "0", that means that at runtime, the assemblage will be created using the ALTERNATIVE for which the id attribute is "0".

With the ALTERNATIVE's class attribute and the ARGUMENTs sub-elements, Kilim is able to retrieve the class and the constructor it needs to instantiate the object.

The required parameters are provided by the ASSEMBLAGE's configuration (MY_CONFIGURATION), and identified by their names.

Implicit factory description:
...
<IMPLICIT_FACTORY>
  <ALTERNATIVE id="0" name="log handler" class="weblog.LogHandler">
    <ARGUMENT type="weblog.business.apis.EntriesReader" name="entries reader"/>
  </ALTERNATIVE>
</IMPLICIT_FACTORY>
...
			    

Assemblage description:
...
<ASSEMBLAGE alternative="0">
  <MY_FACTORY>
    ...
  </MY_FACTORY>
  <MY_CONFIGURATION>
    <CONFIGURATION>
      <ELEM name="entries reader">
        ...
      </ELEM>
    </CONFIGURATION>
  </MY_CONFIGURATION>
</ASSEMBLAGE>
...
			    

Note how the entries reader element in the assemblage's configuration matches the factory's argument.

It is not necessarily such a great idea to define in an ad hoc manner an ASSEMBLAGE's factory and configuration. Indeed, if one wants a component to be shared among two or more assemblages, we need a proper referencing semantic.

In Kilim, component crossreferencing is done through the use of ALIASes. An ALIAS is simply a symbolic link to an arbitrarily placed element in the configuration; much in the manner similar constructs in filesystems (soft links, shortcuts, aliases, depending on your system of choice).

ALIAS constructs are also useful when striving to have a simpler, more readable structure for your kcfs since they help keeping the number of nesting levels down.

In our case, we use an ALIAS in the previously defined ASSEMBLAGE's configuration, to reference the entries reader we decide to use:

...
<ELEM name="entries reader">
  <ALIAS name="/Entries/memory entries reader"/>
</ELEM>
...

The ALIAS points to another part of the kcf, namely:

...
<ELEM name="Entries">
  <CONFIGURATION>
    <ELEM name="memory entries reader">
      <ATOM class="weblog.business.libs.MemoryEntriesReader"/>
    </ELEM>
  </CONFIGURATION>
</ELEM>
...

WebLog 2.0

All WebLog 2.0 files are available for download.

From now, we want to add authentification to our weblog via a basic username / password scheme. Firstly we write the relevant class: weblog.business.libs.AuthenticationServiceImpl, then we have to make it appear in the configuration.

To do this, we simply add an ATOM to the runtime kcf (full version):

...
  <ELEM name="Authentication Service">
    <ATOM class="weblog.business.libs.AuthenticationServiceImpl"/>
  </ELEM>
...

The authentication service is very simple, since it does not require any parameter, it is defined by an ATOM.

In order to allow the use of WebLog without authentication, the servlet looks for an object named Authentication Service in the configuration. If none is found, then no authentication is expected from the user.

This behaviour is coded in the servlet's source:

...
Object $oAuth = initialContext.getValue("Authentication Service", (char)0);
if ($oAuth != Context.NO_VALUE) {
    auth = (AuthenticationService)$oAuth;
}
...
if (auth != null) {
...
}

WebLog 3.0: introducing sequences

All WebLog 3.0 files are available for download.

In this version, we would like to specify a level for each new weblog entry. Therefore, we add another ALTERNATIVE in our ASSEMBLAGE. This ALTERNATIVE needs an array of java.lang.String for second parameter.

...
          <ALTERNATIVE id="1" name="log handler" class="weblog.LogHandler">
            <ARGUMENT type="weblog.business.apis.EntriesReader" name="entries reader"/>
            <ARGUMENT type="java.lang.String[]" name="priority levels"/>
          </ALTERNATIVE>
...

Then, we set the ASSEMBLAGE's alternative attribute to "1".

In Kilim, arrays are represented by SEQUENCEs (full version):

...
          <ELEM name="priority levels">
            <SEQUENCE elements_type="String">
              <ELEM name="0"><PROPERTY type="String" value="Low"/></ELEM>
              <ELEM name="1"><PROPERTY type="String" value="Normal"/></ELEM>
              <ELEM name="2"><PROPERTY type="String" value="High"/></ELEM>
              <ELEM name="3"><PROPERTY type="String" value="Very High"/></ELEM>
            </SEQUENCE>
          </ELEM>
...

WebLog 4.0: introducing setters

All WebLog 4.0 files are available for download.

We mentioned in part one that implicit factories' ALTERNATIVEs could use setter methods as well as constructors. Now we will take advantage of this example.

Note: in Kilim a setter method is defined as any method with only one parameter.

We would like to add the date in front of each entry. The LogHandler class is modified to use a default date pattern which can be changed by invoking the setDatePattern method with a String parameter.

Another ALTERNATIVE is added to the WebLog runtime kcf (full version):

...
          <ALTERNATIVE id="2" name="log handler" class="weblog.LogHandler">
            <ARGUMENT type="weblog.business.apis.EntriesReader" name="entries reader"/>
            <ARGUMENT type="java.lang.String[]" name="priority levels"/>
            <SETTER name="setDatePattern"><ARGUMENT type="java.lang.String" name="pattern"/></SETTER>
          </ALTERNATIVE>
...

The new parameter appears as a PROPERTY in the configuration:

...
          <ELEM name="pattern"><PROPERTY type="String" value="MMM dd HH:mm:ss"/></ELEM>
...

(Note: the pattern syntax is specified in the java.text.SimpleDateFormat API).

Then, the alternative's attribute of the ASSEMBLAGE is set to "2".

Exercise

Modify the runtime kcf (weblog.kcf) in order to use a flat file data storage (weblog.business.libs.FlatFileEntriesReader class).

Here is the solution: weblog.kcf.


The difference between bootstrap and runtime configuration files is explained in An Introduction to Kilim Configuration Files.


Last updated: 2002-09-10

Sylvain Chambon and Bruno Michel