Tweety: educational avalon container

A Phoenix is an ancient mythical bird with many magical powers; it is
also a very powerful container for avalon components. A tweety is a
sweet yellow canary; it will also be the simplest possible container for
avalon components.

Some sketchy thoughts follow. I’d like some input, after which I’ll
implement the stuff and put it in excalibur scratchpad (unless someone
beats me to it).

Furthermore, I’ll be archiving and discussion on all this and intend to
document that process as well, as it migh be a good example of the
typical steps involved in developing something using avalon.

Background

Talking about the complexity of avalon and its associated learning curve
made me draw a parallel with the complexity of unix. An approach that
has worked there: “Want to learn how to program unix? Start with it’s
tiny brother – minix.”

I think it’d be a good idea if we provide a minimalist container
explicitly designed around educational value.

Goals

  • be well documented
  • provide full support for the avalon framework interfaces
  • provide support for nothing else
  • use default framework implementations where possible
  • sacrifice flexibility for readable code wherever possible
  • sacrifice reusability for readable code wherever possible
  • use the most simple configuration possible
  • support only minimal metainfo (for example, no dependency mapping)
  • no security
  • minimal thread management
  • no classloader management
  • separation of engine and (mainable) embeddor

Use Case

An example of an avalon container for simple components, to use in
teaching avalon concepts.

Configuration

Configuration will be handled in standard java .properties files, or
simpler formats. The standard java CLASSPATH will be used for loading
all resources. Resources required for components will be as closely
coupled as possible.

########################################################################
# sample tweety.properties file
########################################################################
#
# Use this file to configure tweety internals. It is optional (ie
# there are default values).

# setup internals
tweety.logger = org.apache.logkit.Logger
tweety.loglevel = DEBUG

# find role definitions file
tweety.components = tweety.components

########################################################################
# sample tweety.components file
########################################################################
#
# Use this file to specify which components you want tweety to manage,
# and under what role they should be put in the ComponentManager.
# FORMAT: <role> = <javaclassname>

HelloWorldServer = org.apache.avalon.demos.HelloWorldServerImpl
HelloWorldClient = org.apache.avalon.demos.HelloWorldClientImpl

########################################################################
# sample of a <ClassName>.tweety file.
########################################################################
#
# This file lives in the same directory as <ClassName>, and specifies
# the resources tweety will use to take the component through its
# lifecycle (ie Configuration, Context, Parameters). If none of these
# are required, this file is not used.
#
# This one is for a HelloWorldServer that implements Configurable,
# Contextualizable and Parameterizable.

configuration.file = HelloWorldServer.config.xml
# configuration.class = HelloWorldServerConfiguration

context.class = HelloWorldServerContext

parameters.file = HelloWorldServer.properties

Interface

package org.apache.avalon.excalibur.tweety;

import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Stoppable;

public interface Tweety
extends Parameterizable, Startable, Initializable, Stoppable
{
/**
* Supply the configuration parameters for tweety. Used
* values include:
*
* tweety.logger: the logging implementation to use
* (default = org.apache.logkit.Logger)
* tweety.loglevel: the verbosity of the log messages
* generated by tweety
* (default = DEBUG)
* tweety.components: the filename that specifies which
* components to load and run
* (default = tweety.components)
*
*/
public void parameterize( Parameters parameters );
}

Classes

1) Tweety

package org.apache.avalon.excalibur.tweety.impl;

import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.excalibur.tweety.Tweety;

public class TweetyImpl implements Tweety
{
private Parameters m_parameters;

public TweetyImpl() {}

public void parameters( Parameters parameters )
{
m_parameters = parameters;
}
public void initialize()
{
/* @todo implement this */
throw new OperationNotSupportedException();

// create logger
// load components file
// create global component manager and service manager
// put all components into component manager and
// service manager
// create containerkit stuff, like a lifecycle helper
// create Parameters, Contexts, Configuration as
// specified in <ClassName>.tweety
}
public void start()
{
/* @todo implement this */
throw new OperationNotSupportedException();

// create a single new thread that runs
// all components up to start(), then waits
// for stop()
}
public void stop()
{
/* @todo implement this */
throw new OperationNotSupportedException();

// run all components up to dispose()
// set all references to everything to null
}
}

2) TweetyRunner

package org.apache.avalon.excalibur.tweety.impl;

import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.excalibur.tweety.Tweety;

/**
* This class creates tweety if it isn't running yet and starts
* it.
*/
public class TweetyRunner
{
/**
* Runs the Tweety container. You can supply a properties
* file for tweety as a command-line argument.
*
* @param args an array of <code>String</code> for config.
*/
public static void main( String[] args )
{
/* @todo implement this */
throw new OperationNotSupportedException();

// check with RMI registry tweety is not running
Tweety tweety = new TweetyImpl();

// parse arguments, create parameters
tweety.parameterize( parameters );
tweety.initialize();
tweety.start();

// export tweety to RMI registry (create if necessary)
// exit
}
}

3) TweetyStopper

package org.apache.avalon.excalibur.tweety.impl;

/**
* This class stops tweety if it is running.
*/
public class TweetyStopper
{
/**
* Stops the Tweety container.
*/
public static void main( String[] args )
{
/* @todo implement this */
throw new OperationNotSupportedException();

// lookup tweety in RMI registry
tweety.stop();

// remove tweety from registry
// exit
}
}

(archived email sent June 19, 2002 to the apache avalon mailing list, led to the creation of the Avalon Tweety Inversion-of-Control container)