mcconnell 2003/08/28 10:26:40
Added: merlin/merlin-platform/tutorials/dependencies/auto
.cvsignore README.txt project.xml
merlin/merlin-platform/tutorials/dependencies/auto/conf
block.xml
merlin/merlin-platform/tutorials/dependencies/auto/src/java/tutorial
HelloComponent.java HelloComponent.xinfo
RandomGenerator.java RandomGeneratorProvider.java
RandomGeneratorProvider.xinfo
merlin/merlin-platform/tutorials/dependencies/manual
.cvsignore README.txt project.xml
merlin/merlin-platform/tutorials/dependencies/manual/conf
block.xml
merlin/merlin-platform/tutorials/dependencies/manual/src/java/tutorial
HelloComponent.java Identifiable.java
IdentifiableComponent.java
Removed: merlin/merlin-platform/tutorials/dependencies .cvsignore
README.txt project.xml
merlin/merlin-platform/tutorials/dependencies/conf block.xml
merlin/merlin-platform/tutorials/dependencies/src/java/tutorial
HelloComponent.java HelloComponent.xinfo
RandomGenerator.java RandomGeneratorProvider.java
RandomGeneratorProvider.xinfo
Log:
Addition of a manual deps resolution tutorial.
Revision Changes Path
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/.cvsignore
Index: .cvsignore
===================================================================
maven.log
velocity.log
build.xml
build.properties
target
maven.log
working
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/README.txt
Index: README.txt
===================================================================
Dependency Management
=====================
Overview
--------
The dependencies tutorial covers the declaration of service dependencies
that a component has, the resolution of dependecies by the container, and
the application of dependent service by the container to the component
via a ServiceManager.
Service dependecies are declared in the component sources using the javadoc
tag:
@avalon.dependency type="org.somewhere.MyInterface"
Components that provide services declare the service export using the
tag @avalon.service. Merlin build and validates a dependency graph before
component initialization, and ensures that componets are actived in the
correct order. Consumers are always activated after suppliers and
deactivated before deactivation of respective suppliers.
Build instructions
------------------
$ maven
Runtime
-------
$ merlin target\classes -execute
[INFO ] (tutorial.random): initialization
[INFO ] (tutorial.hello): initialization
[INFO ] (tutorial.random): processing request
[INFO ] (tutorial.hello): received random value: -1591330260
[INFO ] (tutorial.hello): disposal
[INFO ] (tutorial.random): disposal
Summary
-------
The purpose of this demonstration is to show the following:
1. usage of @avalon.dependency tags
2. usage of @avalon.service tags
3. functionality of the container in handling automated
assembly
4. orderly commissioning and decommissioning provided
by the container
While the demonstration deals with the very simple case of a
single supplier and a single consumer component, Merlin provides
complete support for n-to-n relationships across arbitarily deep
dependency graphs. Using the Merlin plugin for Maven, you can
validate deployment scenarios by simulating deployment as part
of a componet suite test and validation phase. The following
command demonstrates Maven based deployment using the Merlin
plugin.
$ maven merlin:simulate
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/project.xml
Index: project.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<project>
<extend>${basedir}/../../project.xml</extend>
<id>merlin-tutorial-auto-dependencies</id>
<name>Merlin Automated Assembly Tutorial</name>
<package>tutorial</package>
<currentVersion>1.0</currentVersion>
<inceptionYear>2003</inceptionYear>
<shortDescription>Merlin Dependencies Tutorial.</shortDescription>
<dependencies>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
<version>SNAPSHOT</version>
</dependency>
</dependencies>
</project>
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/conf/block.xml
Index: block.xml
===================================================================
<container name="tutorial">
<classloader>
<classpath>
<repository>
<resource id="avalon-framework:avalon-framework-api" version="SNAPSHOT"/>
<resource id="avalon-framework:avalon-framework-impl" version="SNAPSHOT"/>
</repository>
</classpath>
</classloader>
<component name="hello" class="tutorial.HelloComponent" activation="startup"/>
</container>
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/src/java/tutorial/HelloComponent.java
Index: HelloComponent.java
===================================================================
package tutorial;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
/**
* The HelloComponent is dependent on a RandomGenerator service.
* @avalon.component version="1.0" name="simple" lifestyle="singleton"
*/
public class HelloComponent extends AbstractLogEnabled
implements Initializable, Serviceable, Disposable
{
RandomGenerator m_random = null;
/**
* Servicing of the component by the container during
* which service dependencies declared under the component
* can be resolved using the supplied service manager.
*
* @param manager the service manager
* @avalon.dependency type="tutorial.RandomGenerator:1.0"
* key="random"
*/
public void service( ServiceManager manager )
throws ServiceException
{
m_random = (RandomGenerator) manager.lookup( "random" );
}
public void initialize()
{
getLogger().info( "initialization" );
getLogger().info( "received random value: " + m_random.getRandom() );
}
public void dispose()
{
getLogger().info( "disposal" );
}
}
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/src/java/tutorial/HelloComponent.xinfo
Index: HelloComponent.xinfo
===================================================================
<?xml version="1.0"?>
<!DOCTYPE type
PUBLIC "-//AVALON/Type DTD Version 1.0//EN"
"http://avalon.apache.org/dtds/meta/type_1_1.dtd" >
<type>
<info>
<name>hello</name>
<version>1.0</version>
</info>
<dependencies>
<dependency key="random" type="tutorial.RandomGenerator"/>
</dependencies>
</type>
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/src/java/tutorial/RandomGenerator.java
Index: RandomGenerator.java
===================================================================
package tutorial;
/**
* A service that provides access to a random number.
*/
public interface RandomGenerator
{
/**
* Return a random integer
* @return the random number
*/
int getRandom();
}
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/src/java/tutorial/RandomGeneratorProvider.java
Index: RandomGeneratorProvider.java
===================================================================
package tutorial;
import java.util.Random;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
/**
* An implementation of a random number generator.
*
* @avalon.component version="1.0" name="random" lifestyle="singleton"
* @avalon.service type="tutorial.RandomGenerator" version="1.0"
*/
public class RandomGeneratorProvider extends AbstractLogEnabled
implements Initializable, RandomGenerator, Disposable
{
private Random m_random = new Random();
public void initialize()
{
getLogger().info( "initialization" );
}
/**
* Return a random integer
* @return the random number
*/
public int getRandom()
{
getLogger().info( "processing request" );
return m_random.nextInt();
}
public void dispose()
{
getLogger().info( "disposal" );
}
}
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/auto/src/java/tutorial/RandomGeneratorProvider.xinfo
Index: RandomGeneratorProvider.xinfo
===================================================================
<?xml version="1.0"?>
<!DOCTYPE type
PUBLIC "-//AVALON/Type DTD Version 1.0//EN"
"http://avalon.apache.org/dtds/meta/type_1_1.dtd" >
<type>
<info>
<name>random-provider</name>
<version>1.0</version>
</info>
<services>
<service type="tutorial.RandomGenerator"/>
</services>
</type>
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/.cvsignore
Index: .cvsignore
===================================================================
maven.log
velocity.log
build.xml
build.properties
target
maven.log
working
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/README.txt
Index: README.txt
===================================================================
Dependency Management
=====================
Overview
--------
The manual dependencies tutorial covers additional information dealing
with the explict control over dependency binding. In this example we
have HelloComponent with a dependency on to services of the same type. If we
depended on class merlin auto-assembly we would not necessarily get the
desired result. In such a situation, Merlin provides support for
overriding the auto assembly process though explicit dependency directives
included inside a <component/> tag.
In the block.xml we have three component direectives:
<component name="gloria" class="tutorial.IdentifiableComponent"/>
<component name="nancy" class="tutorial.IdentifiableComponent"/>
<component name="hello" class="tutorial.HelloComponent">
<dependencies>
<dependency key="primary" source="gloria"/>
<dependency key="secondary" source="nancy"/>
</dependencies>
</component>
The "hello" component has been manually wired together using named components
references under a set of <dependency/> directives, thereby overriding Merlin
auto-assembly huristics.
Build instructions
------------------
$ maven
Runtime
-------
$ merlin target\classes -execute
[INFO ] (tutorial.nancy): contextualize
[INFO ] (tutorial.gloria): contextualize
[INFO ] (tutorial.hello): initialization
[INFO ] (tutorial.hello): assigned primary: /tutorial/gloria
[INFO ] (tutorial.hello): assigned secondary: /tutorial/nancy
Summary
-------
The purpose of this demonstration is to show the following:
1. ability to override assembly using <dependency/> directives
(i.e. your still in control)
2. provide an example of dealing with multiple dependencies of
the same type
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/project.xml
Index: project.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<project>
<extend>${basedir}/../../project.xml</extend>
<id>merlin-tutorial-manual-dependencies</id>
<name>Merlin Explicit Dependencies Tutorial</name>
<package>tutorial</package>
<currentVersion>1.0</currentVersion>
<inceptionYear>2003</inceptionYear>
<shortDescription>Merlin Dependencies Tutorial.</shortDescription>
<dependencies>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
<version>SNAPSHOT</version>
</dependency>
</dependencies>
</project>
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/conf/block.xml
Index: block.xml
===================================================================
<container name="tutorial">
<classloader>
<classpath>
<repository>
<resource id="avalon-framework:avalon-framework-api" version="SNAPSHOT"/>
<resource id="avalon-framework:avalon-framework-impl" version="SNAPSHOT"/>
</repository>
</classpath>
</classloader>
<component name="gloria" class="tutorial.IdentifiableComponent"/>
<component name="nancy" class="tutorial.IdentifiableComponent"/>
<component name="hello" class="tutorial.HelloComponent">
<dependencies>
<dependency key="primary" source="gloria"/>
<dependency key="secondary" source="nancy"/>
</dependencies>
</component>
</container>
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/src/java/tutorial/HelloComponent.java
Index: HelloComponent.java
===================================================================
package tutorial;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
/**
* The HelloComponent is dependent on a RandomGenerator service.
* @avalon.component version="1.0" name="simple" lifestyle="singleton"
*/
public class HelloComponent extends AbstractLogEnabled
implements Initializable, Serviceable
{
Identifiable m_primary = null;
Identifiable m_secondary = null;
/**
* Servicing of the component by the container during
* which service dependencies declared under the component
* can be resolved using the supplied service manager.
*
* @param manager the service manager
* @avalon.dependency type="tutorial.Identifiable"
* key="primary"
* @avalon.dependency type="tutorial.Identifiable"
* key="secondary"
*/
public void service( ServiceManager manager )
throws ServiceException
{
m_primary = (Identifiable) manager.lookup( "primary" );
m_secondary = (Identifiable) manager.lookup( "secondary" );
}
public void initialize()
{
getLogger().info( "initialization" );
getLogger().info( "assigned primary: " + m_primary.getIdentity() );
getLogger().info( "assigned secondary: " + m_secondary.getIdentity() );
}
}
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/src/java/tutorial/Identifiable.java
Index: Identifiable.java
===================================================================
package tutorial;
/**
* A service that provides access to a component identity.
*/
public interface Identifiable
{
/**
* Return a message indicating the component identify.
* @return the identity
*/
String getIdentity();
}
1.1
avalon-sandbox/merlin/merlin-platform/tutorials/dependencies/manual/src/java/tutorial/IdentifiableComponent.java
Index: IdentifiableComponent.java
===================================================================
package tutorial;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
/**
* The IdentifiableComponent implements Identifiable.
*
* @avalon.component version="1.0" name="simple" lifestyle="singleton"
* @avalon.service type="tutorial.Identifiable"
*/
public class IdentifiableComponent extends AbstractLogEnabled
implements Identifiable, Contextualizable
{
private String m_identity = null;
/**
* Contextualization of the component during which we
* establish the component identity.
*
* @param context the component context
* @avalon.entry key="urn:avalon:name"
* @avalon.entry key="urn:avalon:partition"
*/
public void contextualize( Context context )
throws ContextException
{
getLogger().info( "contextualize" );
String name = (String) context.get( "urn:avalon:name" );
String partition = (String) context.get( "urn:avalon:partition" );
m_identity = partition + name;
}
public String getIdentity()
{
return m_identity;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]