mcconnell 2002/06/30 21:27:16
Added: assembly .cvsignore build.properties build.xml
assembly/demo/src/etc demo.mf
assembly/demo/src/java/org/apache/excalibur/playground
BasicComponent.java BasicComponent.xinfo
BasicService.java ComplexComponent.java
ComplexComponent.xinfo InvalidComponent.java
InvalidComponent.xinfo SimpleComponent.java
SimpleComponent.xinfo SimpleService.java
TerminalComponent.java TerminalComponent.xinfo
assembly/lib avalon-framework.jar
excalibur-configuration-1.0.jar
excalibur-containerkit-1.0.jar
excalibur-extension-1.0a.jar excalibur-i18n-1.0.jar
excalibur-io-1.1.jar excalibur-util-1.0.jar
logkit.jar
assembly/src .cvsignore
assembly/src/etc profile.xml project.mf
assembly/src/java/org/apache/excalibur/merlin/registry
AssemblyException.java
AssemblyRuntimeException.java
ComponentDefinition.java ComponentType.java
DefaultClassLoader.java DefaultProfile.java
DefaultRegistry.java DefaultRegistry.xinfo
Fileset.java Main.java Profile.java
ProfileException.java ProfileRuntimeException.java
Registry.java RegistryException.java
RegistryRuntimeException.java Resources.properties
Selector.java ServiceRegistry.java
UnresolvedProviderException.java package.html
assembly/src/java/org/apache/excalibur/merlin/registry/doc-files
registry.gif
Log:
first commit of the Merlin Registry service
Revision Changes Path
1.1 jakarta-avalon-excalibur/assembly/.cvsignore
Index: .cvsignore
===================================================================
local.properties
build
dist
checkstyle.cache
1.1 jakarta-avalon-excalibur/assembly/build.properties
Index: build.properties
===================================================================
#
# This file is read in by the build.xml file.
#
project.title=Merlin II
1.1 jakarta-avalon-excalibur/assembly/build.xml
Index: build.xml
===================================================================
<!--
Copyright 2001-2002 OSM SARL, All Rights Reserved.
-->
<project name="assembly" default="help" basedir=".">
<property file="local.properties"/>
<property file="build.properties"/>
<target name="help" >
<echo>
Description
-----------
${project.title}
General Targets:
----------------
all - clean, build and dist
build - invokes the general build target
javadoc - javadoc API generation
dist - executes build, javadoc and support file creation
clean - destroy the build directory
test - run the component
</echo>
</target>
<property name="VERSION" value="${MAJOR}.${MINOR}.${MICRO}"/>
<property name="apps.path" value="../../jakarta-avalon-apps" />
<property name="excalibur.path" value="../../jakarta-avalon-excalibur" />
<property name="containerkit.path" value="${excalibur.path}/containerkit" />
<property name="lib" value="lib" />
<property name="src" value="src" />
<property name="etc" value="${src}/etc" />
<property name="build" value="build" />
<property name="dist" value="dist" />
<property name="javadoc.root.path" value="${dist}/javadoc" />
<property name="avalon.href" value="http://jakarta.apache.org/avalon/api/"
/>
<property name="jdk.href" value="http://java.sun.com/j2se/1.4/docs/api/" />
<property name="containerkit.href"
value="${containerkit.path}/dist/docs/api" />
<property name="overview.html" value="${etc}/overview.html" />
<property name="project.manifest" value="project.mf" />
<!-- classpath -->
<path id="project.classpath">
<fileset dir="${lib}">
<include name="*.jar" />
</fileset>
</path>
<!-- MAIN TARGETS -->
<target name="all" depends="clean,dist,javadoc"/>
<target name="dist" depends="build"/>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
<!-- PREPARE -->
<target name="prepare" >
<mkdir dir="${build}" />
<mkdir dir="${build}" />
<mkdir dir="${dist}" />
</target>
<!-- BLOCK -->
<target name="context" depends="prepare">
<mkdir dir="dist"/>
<uptodate property="uptodate"
targetfile="${dist}/${ant.project.name}.jar">
<srcfiles dir="${src}/java">
<include name="**/*.*"/>
</srcfiles>
<srcfiles dir="${etc}">
<include name="${project.manifest}"/>
</srcfiles>
</uptodate>
</target>
<target name="build" depends="context,demo.build" unless="uptodate" >
<echo message="Building Block"/>
<mkdir dir="${build}/main"/>
<javac debug="off" destdir="${build}/main" deprecation="true">
<classpath>
<path refid="project.classpath" />
</classpath>
<src path="${src}/java" />
</javac>
<copy todir="${build}/main">
<fileset dir="${src}/java">
<include name="**/*.xinfo"/>
<include name="**/*.xml"/>
<include name="**/*.properties"/>
</fileset>
</copy>
<jar jarfile="${dist}/${ant.project.name}.jar" basedir="${build}/main"
manifest="${etc}/${project.manifest}"/>
</target>
<target name="demo.context" depends="prepare">
<mkdir dir="dist"/>
<uptodate property="demo.uptodate" targetfile="${dist}/demo.jar">
<srcfiles dir="demo/src/java">
<include name="**/*.*"/>
</srcfiles>
<srcfiles dir="demo/src/etc">
<include name="demo.mf"/>
</srcfiles>
</uptodate>
</target>
<target name="demo.build" depends="demo.context" unless="demo.uptodate" >
<echo message="Building Demo"/>
<mkdir dir="${build}/demo"/>
<javac debug="off" destdir="${build}/demo" deprecation="true">
<classpath>
<path refid="project.classpath" />
</classpath>
<src path="demo/src/java" />
</javac>
<copy todir="${build}/demo">
<fileset dir="demo/src/java">
<include name="**/*.xinfo"/>
<include name="**/*.xml"/>
<include name="**/*.properties"/>
</fileset>
</copy>
<jar jarfile="${dist}/demo.jar" basedir="${build}/demo"
manifest="demo/src/etc/demo.mf"/>
</target>
<!-- UTILITY TARGETS -->
<target name="support">
<copy todir="${dist}">
<fileset dir="${etc}">
<include name="LICENSE.TXT"/>
<include name="README.TXT"/>
</fileset>
</copy>
</target>
<target name="javadoc" depends="prepare" >
<echo message="path: ${javadoc.root.path}/${ant.project.name}"/>
<mkdir dir="${javadoc.root.path}/${ant.project.name}" />
<javadoc destdir="${javadoc.root.path}/${ant.project.name}"
doctitle="<h1>${project.title} ${VERSION}</h1>"
noindex="false" author="false"
use="true"
windowtitle="Assembly"
additionalparam="-breakiterator -J-Xmx128m"
packagenames="org.*,net.*"
>
<sourcepath path="${src}/java"/>
<classpath>
<path refid="project.classpath" />
<pathelement path="${dist}/${ant.project.name}.jar}" />
</classpath>
<link href="${jdk.href}" />
<link href="${avalon.href}" />
<link href="${containerkit.href}" />
</javadoc>
</target>
<target name="deploy" depends="build">
<mkdir dir="deploy"/>
<copy todir="deploy">
<fileset dir="${dist}">
<include name="assembly.jar"/>
</fileset>
<fileset dir="${lib}">
<include name="avalon-framework.jar"/>
<include name="logkit.jar"/>
<include name="excalibur-i18n-1.0.jar" />
<include name="excalibur-containerkit-1.0.jar" />
<include name="excalibur-extension-1.0a.jar" />
<include name="excalibur-configuration-1.0.jar" />
<include name="excalibur-io-1.1.jar" />
<include name="excalibur-util-1.0.jar" />
</fileset>
</copy>
</target>
<target name="kernel" depends="deploy">
<java jar="deploy/assembly.jar" fork="true">
<arg value="${src}/etc/profile.xml"/>
</java>
</target>
</project>
1.1 jakarta-avalon-excalibur/assembly/demo/src/etc/demo.mf
Index: demo.mf
===================================================================
Manifest-Version: 1.0
Created-By: OSM SARL
Extension-List: framework
framework-Extension-Name: avalon-framework
framework-Specification-Version: 1.0
framework-Implementation-Version: 4.1.2
Name: org/apache/excalibur/playground/SimpleComponent.class
Avalon-Block: true
Name: org/apache/excalibur/playground/TerminalComponent.class
Avalon-Block: true
Name: org/apache/excalibur/playground/BasicComponent.class
Avalon-Block: true
Name: org/apache/excalibur/playground/ComplexComponent.class
Avalon-Block: true
Name: org/apache/excalibur/playground/InvalidComponent.class
Avalon-Block: true
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicComponent.java
Index: BasicComponent.java
===================================================================
package org.apache.excalibur.playground;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* This is a minimal demonstration component that implements the
* <code>BasicService</code> interface and has no dependencies.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class BasicComponent extends AbstractLogEnabled
implements BasicService
{
//=======================================================================
// BasicService
//=======================================================================
public void doPrimeObjective()
{
getLogger().info("hello from BasicComponent");
}
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicComponent.xinfo
Index: BasicComponent.xinfo
===================================================================
<?xml version="1.0"?>
<component-info>
<component>
<!-- the component name -->
<name>basic-component</name>
</component>
<services>
<!-- services that this component provides -->
<service>
<service-ref type="org.apache.excalibur.playground.BasicService"/>
</service>
</services>
</component-info>
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicService.java
Index: BasicService.java
===================================================================
/*
*/
package org.apache.excalibur.playground;
/**
* The <code>BasicService</code> executes a prime objective.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public interface BasicService
{
static final String KEY = "org.apache.excalibur.playground.BasicService";
/**
* Execute the prime objective of this services.
*/
void doPrimeObjective();
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ComplexComponent.java
Index: ComplexComponent.java
===================================================================
/*
* ComplexComponent.java
*/
package org.apache.excalibur.playground;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
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;
/**
* This is a minimal demonstration component that declares no interface but
* has dependecies on two services. These include SimpleService and
* BasicService.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class ComplexComponent extends AbstractLogEnabled
implements Serviceable, Initializable, Executable, Disposable
{
private ServiceManager m_manager;
private SimpleService m_simple;
private BasicService m_basic;
//=================================================================
// Serviceable
//=================================================================
/**
* Pass the <code>ServiceManager</code> to the <code>Serviceable</code>.
* The <code>Serviceable</code> implementation uses the specified
* <code>ServiceManager</code> to acquire the services it needs for
* execution.
*
* @param manager The <code>ServiceManager</code> which this
* <code>Serviceable</code> uses.
*/
public void service( ServiceManager manager )
throws ServiceException
{
if( getLogger().isDebugEnabled() )
getLogger().debug("service");
m_manager = manager;
}
//=======================================================================
// Initializable
//=======================================================================
public void initialize()
throws Exception
{
if( getLogger().isDebugEnabled() )
getLogger().debug("initialize");
//
// verify current state
//
if( getLogger() == null ) throw new IllegalStateException(
"Logging channel has not been assigned.");
if( m_manager == null ) throw new IllegalStateException(
"Manager has not been declared.");
//
// lookup the primary service
//
m_simple = (SimpleService) m_manager.lookup( "simple" );
m_basic = (BasicService) m_manager.lookup( "basic" );
}
//=======================================================================
// Executable
//=======================================================================
public void execute()
{
getLogger().info("hello from ComplexComponent");
m_simple.doObjective();
m_basic.doPrimeObjective();
}
//=======================================================================
// Disposable
//=======================================================================
public void dispose()
{
if( getLogger().isDebugEnabled() )
getLogger().debug("dispose");
m_simple = null;
m_manager = null;
}
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ComplexComponent.xinfo
Index: ComplexComponent.xinfo
===================================================================
<?xml version="1.0"?>
<component-info>
<component>
<name>complex</name>
</component>
<dependencies>
<dependency>
<role>basic</role>
<service-ref type="org.apache.excalibur.playground.BasicService"/>
</dependency>
<dependency>
<role>simple</role>
<service-ref type="org.apache.excalibur.playground.SimpleService"/>
</dependency>
</dependencies>
</component-info>
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/InvalidComponent.java
Index: InvalidComponent.java
===================================================================
package org.apache.excalibur.playground;
/**
* This is a minimal demonstration component that is declared with an invalid
service dependency.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class InvalidComponent
{
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/InvalidComponent.xinfo
Index: InvalidComponent.xinfo
===================================================================
<?xml version="1.0"?>
<component-info>
<component>
<name>simple-component</name>
</component>
<dependencies>
<dependency>
<role>silly</role>
<service-ref type="org.apache.excalibur.playground.InvalidService"/>
</dependency>
</dependencies>
</component-info>
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.java
Index: SimpleComponent.java
===================================================================
package org.apache.excalibur.playground;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* This is a minimal demonstration component that a dependency on
* BasicService and provides SimpleService.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class SimpleComponent extends AbstractLogEnabled
implements SimpleService
{
//=======================================================================
// PrimaryService
//=======================================================================
public void doObjective()
{
getLogger().info("hello from SimpleComponent");
}
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.xinfo
Index: SimpleComponent.xinfo
===================================================================
<?xml version="1.0"?>
<component-info>
<component>
<name>simple-component</name>
</component>
<services>
<service>
<service-ref type="org.apache.excalibur.playground.SimpleService"/>
</service>
</services>
<dependencies>
<dependency>
<role>basic</role>
<service-ref type="org.apache.excalibur.playground.BasicService"/>
</dependency>
</dependencies>
</component-info>
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleService.java
Index: SimpleService.java
===================================================================
/*
*/
package org.apache.excalibur.playground;
/**
* The <code>SimpleService</code> executes an objective.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public interface SimpleService
{
static final String KEY = "org.apache.excalibur.playground.SimpleService";
/**
* Execute the prime objective of this services.
*/
void doObjective();
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/TerminalComponent.java
Index: TerminalComponent.java
===================================================================
package org.apache.excalibur.playground;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* This is a minimal demonstration component that provides BasicService
* and has no dependencies
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class TerminalComponent extends AbstractLogEnabled
implements BasicService
{
//=======================================================================
// BasicService
//=======================================================================
public void doPrimeObjective()
{
getLogger().info("hello from TerminalComponent");
}
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/TerminalComponent.xinfo
Index: TerminalComponent.xinfo
===================================================================
<?xml version="1.0"?>
<component-info>
<component>
<name>terminal-component</name>
</component>
<services>
<service>
<service-ref type="org.apache.excalibur.playground.BasicService"/>
</service>
</services>
</component-info>
1.1
jakarta-avalon-excalibur/assembly/lib/avalon-framework.jar
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/lib/excalibur-configuration-1.0.jar
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/lib/excalibur-containerkit-1.0.jar
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/lib/excalibur-extension-1.0a.jar
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/lib/excalibur-i18n-1.0.jar
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/lib/excalibur-io-1.1.jar
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/lib/excalibur-util-1.0.jar
<<Binary file>>
1.1 jakarta-avalon-excalibur/assembly/lib/logkit.jar
<<Binary file>>
1.1 jakarta-avalon-excalibur/assembly/src/.cvsignore
Index: .cvsignore
===================================================================
doc
1.1 jakarta-avalon-excalibur/assembly/src/etc/profile.xml
Index: profile.xml
===================================================================
<!--
Assemble a component instance.
-->
<kernel>
<!--
Declaration of the logging hierachy and constraints.
-->
<logger priority="DEBUG"/>
<!--
Location of installed extension directories.
-->
<extensions>
<dirset dir=".">
<include name="lib"/>
</dirset>
</extensions>
<!--
Definition of the registry of component types from which profiles can be
applied.
-->
<registry name="root">
<!--
The classpath available to all components in the registry and from which
component type descriptions will be created.
-->
<classpath>
<fileset dir="dist">
<include name="demo.jar"/>
</fileset>
</classpath>
<!--
The following is only used for testing - it is the classname of a
component
type to validate.
-->
<test class="org.apache.excalibur.playground.ComplexComponent"/>
<!--
The set of components declared within the scope of this application.
-->
<factories>
<component name="complex"
class="org.apache.excalibur.playground.ComplexComponent">
<!--
Include the following context value in the context supplied a
component using this
profile. Context entries are normally only required in the case
where the component
type declares a required context type and entry values. Generally
speaking, a component
will normally qualify it's instantiation criteria through a
configuration declaration.
Any context values defined at this level will override context
values supplied by the
container.
-->
<context>
<entry name="location" value="Paris"/>
</context>
<!--
Apply the following configuration when instantiating the component.
This configuration
will be applied as the primary configuration in a cascading
configuration chain. A
type may declare a default configuration under a "classname".xconfig
file that will be
used to dereference any configuration requests not resolvable by the
configuration
supplied here.
-->
<configuration>
<message value="Hello"/>
</configuration>
<!--
The parameterization criteria from this instance of the component
type.
-->
<parameters/>
</component>
</factories>
</registry>
</kernel>
1.1 jakarta-avalon-excalibur/assembly/src/etc/project.mf
Index: project.mf
===================================================================
Manifest-Version: 1.0
Created-By: OSM SARL
Extension-Name: Assembler
Specification-Vendor: Apache Software Foundation
Specification-Version: 1.0
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 0.1
Class-Path: avalon-framework.jar logkit.jar excalibur-i18n-1.0.jar
excalibur-configuration-1.0.jar excalibur-extension-1.0a.jar
excalibur-containerkit-1.0.jar
Main-Class: org.apache.excalibur.merlin.registry.Main
Name: org/apache/excalibur/merlin/registry/DefaultRegistry.class
Avalon-Block: true
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/AssemblyException.java
Index: AssemblyException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that there was an error Assembling a component model.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class AssemblyException
extends CascadingException
{
private static final Hashtable EMPTY_TABLE = new Hashtable();
private Dictionary m_errors;
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param message The detail message for this exception.
*/
public AssemblyException( final String message )
{
this( null, message, null );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
*/
public AssemblyException( final Dictionary errors, final String message )
{
this( errors, message, null );
}
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyException( final String message, final Throwable throwable
)
{
this( null, message, throwable );
}
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyException( final Dictionary errors, final String message,
final Throwable throwable )
{
super( message, throwable );
if( errors != null )
{
m_errors = errors;
}
else
{
m_errors = EMPTY_TABLE;
}
}
/**
* Return the table of supplimentary messages.
* @return the messages table
*/
public Dictionary getDictionary()
{
return m_errors;
}
/**
* Returns a stringified representation of the exception.
* @return the exception as a string.
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( super.toString() );
buffer.append( " Errors: " + m_errors.size() );
Enumeration keys = m_errors.keys();
while( keys.hasMoreElements() )
{
Object key = keys.nextElement();
buffer.append( "\n source: " + key.toString() + " cause: " +
m_errors.get( key ) );
}
return buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/AssemblyRuntimeException.java
Index: AssemblyRuntimeException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingRuntimeException;
/**
* Exception to indicate that there was an error during assembly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class AssemblyRuntimeException
extends CascadingRuntimeException
{
private static final Hashtable EMPTY_TABLE = new Hashtable();
private Dictionary m_errors;
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param message The detail message for this exception.
*/
public AssemblyRuntimeException( final String message )
{
this( null, message, null );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
*/
public AssemblyRuntimeException( final Dictionary errors, final String
message )
{
this( errors, message, null );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyRuntimeException( final String message, final Throwable
throwable )
{
this( null, message, throwable );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyRuntimeException( final Dictionary errors, final String
message,
final Throwable throwable )
{
super( message, throwable );
if( errors != null )
{
m_errors = errors;
}
else
{
m_errors = EMPTY_TABLE;
}
}
/**
* Return the table of supplimentary messages.
* @return the messages table
*/
public Dictionary getDictionary()
{
return m_errors;
}
/**
* Returns a stringified representation of the exception.
* @return the exception as a string.
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( super.toString() );
buffer.append( " Errors: " + m_errors.size() );
Enumeration keys = m_errors.keys();
while( keys.hasMoreElements() )
{
Object key = keys.nextElement();
buffer.append( "\n source: " + key.toString() + " cause: " +
m_errors.get( key ) );
}
return buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ComponentDefinition.java
Index: ComponentDefinition.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.net.URL;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.Version;
import org.apache.excalibur.containerkit.metainfo.ContextDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.verifier.ComponentVerifier;
import org.apache.excalibur.containerkit.verifier.VerifyException;
import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
import org.apache.excalibur.merlin.registry.Registry;
import org.apache.excalibur.merlin.registry.UnresolvedProviderException;
/**
* <p>Provides support for the navigation across
<code>ComponentDefinition</code> instances
* implied by service and dependency relationships.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
class ComponentDefinition extends AbstractLogEnabled implements ComponentType
{
//=======================================================================
// static
//=======================================================================
private static final Resources REZ =
ResourceManager.getPackageResources( ComponentDefinition.class );
private static final Profile[] EMPTY_PROFILES = new Profile[0];
//=======================================================================
// state
//=======================================================================
/**
* The registry against which dependecies can be resolved.
*/
private DefaultRegistry m_registry;
/**
* The compontent info instance backing the type defintion.
*/
private ComponentInfo m_component;
/**
* The set of factory profile criteria supplied for this type.
*/
private Configuration[] m_criteria;
/**
* The set of factory profiles derived from the supplied criteria.
*/
private Hashtable m_profiles = new Hashtable();
/**
* Interal flag indicating that profile initialization has been
* applied.
*/
private boolean m_init = false;
//=======================================================================
// constructor
//=======================================================================
/**
* Creation of a new ComponentDefinition.
* @param registry the component registry
* @param component a component info descriptor
* @param profiles a set of configuration fragments describing component
profiles
* declared for this component type
*/
public ComponentDefinition(
DefaultRegistry registry, ComponentInfo component, Configuration[]
profiles )
throws ConfigurationException
{
m_registry = registry;
m_component = component;
m_criteria = profiles;
}
//=======================================================================
// Initializable
//=======================================================================
/**
* Initialization of the component type during which the validation of
* type and integrity of dependecies is undertaken. Initialization
failure
* may occur is a dependecy cannot be resolved.
* @exception Initializable
*/
private void initialize() throws UnresolvedProviderException,
ConfigurationException
{
if( m_init ) return;
if( m_criteria.length == 0 )
{
// create an implicit profile
DefaultProfile profile = new DefaultProfile( m_registry, this );
m_profiles.put( profile.getName(), profile );
}
else
{
// use the explicit profiles
for( int i=0; i<m_criteria.length; i++ )
{
DefaultProfile profile = new DefaultProfile( m_registry,
this, m_criteria[i] );
m_profiles.put( profile.getName(), profile );
}
}
m_init = true;
}
//=======================================================================
// ComponentType
//=======================================================================
/**
* Convinience operation to construct an abstract name representing this
* component defintion.
* @return an abstract name
*/
public String getName()
{
return
getComponentInfo().getComponentDescriptor().getImplementationKey() + ":"
+ m_component.getComponentDescriptor().getVersion();
}
/**
* Returns the <code>ComponentInfo</code> instance describing the
meta-info structure
* for this component type.
*
* @return the meta-info set for the component type
*/
public ComponentInfo getComponentInfo()
{
return m_component;
}
/**
* Return the set of profiles for this component type.
* @return the set of profiles available for this component type
*/
public Profile[] getProfiles()
throws UnresolvedProviderException, ConfigurationException
{
initialize();
return (Profile[]) m_profiles.values().toArray( EMPTY_PROFILES );
}
/**
* Return a named profile for this component type.
* @return the named profile or null if the name doers not match a known
profile
*/
public Profile getProfile( String name )
throws UnresolvedProviderException, ConfigurationException
{
initialize();
return (Profile) m_profiles.get( name );
}
/**
* Returns a stringified representation of the component definition.
* @return string representation of the conponent type.
*/
public String toString()
{
return
getComponentInfo().getComponentDescriptor().getImplementationKey() + "/"
+ getComponentInfo().getComponentDescriptor().getVersion() + "/"
+ " (" + getComponentInfo().getComponentDescriptor().getName() +
")";
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ComponentType.java
Index: ComponentType.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.verifier.VerifyException;
import org.apache.excalibur.merlin.registry.UnresolvedProviderException;
import org.apache.avalon.framework.configuration.ConfigurationException;
/**
* Definition of a navigable meta information structure representing a
component type.
*
* @see org.apache.excalibur.merlin.registry.Registry
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public interface ComponentType
{
/**
* Returns the name of the component type.
* @return an abstract name
*/
String getName();
/**
* Returns the <code>ComponentInfo</code> instance describing the
meta-info structure
* for this component type.
*
* @return the meta-info set for the component type
*/
ComponentInfo getComponentInfo();
/**
* Return the set of profiles for this component type.
* @return the set of profiles available for this component type
*/
Profile[] getProfiles() throws UnresolvedProviderException,
ConfigurationException;
/**
* Return a named profile for this component type.
* @return the named profile or null if the name doers not match a known
profile
*/
public Profile getProfile( String name ) throws
UnresolvedProviderException, ConfigurationException;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultClassLoader.java
Index: DefaultClassLoader.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.io.File;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.LinkedList;
import java.net.URLClassLoader;
import java.net.URL;
import java.net.JarURLConnection;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.PackageManager;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.excalibur.merlin.registry.*;
/**
* Classloader for an assembly of components.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
class DefaultClassLoader extends URLClassLoader implements LogEnabled
{
//===================================================================
// static
//===================================================================
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultClassLoader.class );
//===================================================================
// state
//===================================================================
private File[] m_stack;
/**
* List of names of block implementation classes.
*/
private final List m_blocks = new LinkedList();
private PackageManager m_manager;
private Logger m_logger;
//===================================================================
// constructor
//===================================================================
DefaultClassLoader(
PackageRepository repository, ClassLoader parent, Configuration
classpath, Logger logger )
{
super( new URL[ 0 ], parent );
m_logger = logger;
m_manager = new PackageManager( repository );
addClasspath( classpath );
}
public void addClasspath( Configuration classpath )
{
try
{
URL[] urls = Fileset.expandClasspath( classpath );
for( int i = 0; i < urls.length; i++ )
{
addURL( urls[ i ] );
}
String[] path = Fileset.urlsToStrings( urls );
final File[] extensions = getOptionalPackagesFor( path );
for( int i = 0; i < extensions.length; i++ )
{
addURL( extensions[ i ].toURL() );
}
}
catch( Throwable e )
{
final String error = "Unexpected exception while creating
classloader";
throw new RegistryRuntimeException( error, e );
}
}
//===================================================================
// LogEnabled
//===================================================================
public void enableLogging( Logger logger )
{
m_logger = logger;
}
public Logger getLogger()
{
return m_logger;
}
//===================================================================
// ClassLoader
//===================================================================
/**
*
*/
protected void addURL( URL url )
{
try
{
super.addURL( url );
getLogger().debug("scanning: " + url );
String[] entries = getBlocksEntries( url );
for( int i=0; i<entries.length; i++ )
{
getLogger().debug("component: " + entries[i] );
m_blocks.add( entries[i] );
}
}
catch( Throwable e )
{
throw new CascadingRuntimeException(
"Unexpected error while attempting to add classloader URL: " +
url, e );
}
}
//===================================================================
// ClassLoader extensions
//===================================================================
/**
* Returns TRUE is the component classname is know by the classloader.
* @return a component availablity status
*/
public boolean hasComponent( String classname )
{
return m_blocks.contains( classname );
}
/**
* Return the array of component implementation class names within the
scope
* of the classloader.
* @return the block names array
*/
public String[] getComponentClassnames()
{
return (String[]) m_blocks.toArray( new String[0] );
}
//===================================================================
// internals
//===================================================================
/**
* Returns an array of <code>String</code>s corresponding to the set of
classnames
* where each classname is a declared block within the supplied jar file.
* @param file a jar file
* @exception RegistryRuntimeException if a general exception occurs
*/
private String[] getBlocksEntries( URL base )
throws RegistryRuntimeException
{
Vector vector = new Vector();
try
{
final URL url = new URL( "jar:" + base.toString() + "!/" );
final JarURLConnection jar =
(JarURLConnection)url.openConnection();
final Map map = jar.getManifest().getEntries();
final Iterator iterator = map.keySet().iterator();
while( iterator.hasNext() )
{
final String name = (String)iterator.next();
final Attributes attributes = (Attributes)map.get( name );
final Iterator it = attributes.keySet().iterator();
while( it.hasNext() )
{
final Object entry = it.next();
if( entry.toString().equals( "Avalon-Block" ) )
{
if( attributes.get( entry ).equals( "true" ) )
{
vector.add( name.substring( 0, name.indexOf(
".class" ) ) );
}
}
}
}
}
catch( IOException e )
{
final String error = "IO exception while attempt to read block
manifest.";
throw new RegistryRuntimeException( error, e );
}
catch( Throwable e )
{
final String error = "Unexpected exception while inspecting
manifest on file: ";
throw new RegistryRuntimeException( error + base, e );
}
finally
{
return (String[]) vector.toArray( new String[0] );
}
}
/**
* Retrieve the files for the optional packages required by
* the jars in ClassPath.
*
* @param classPath the Classpath array
* @return the files that need to be added to ClassLoader
*/
private File[] getOptionalPackagesFor( final String[] classPath )
throws Exception
{
final Manifest[] manifests = getManifests( classPath );
final Extension[] available = Extension.getAvailable( manifests );
final Extension[] required = Extension.getRequired( manifests );
//if( getLogger().isDebugEnabled() )
//{
// final String message1 =
// REZ.getString( "available-extensions",
// Arrays.asList( available ) );
// getLogger().debug( message1 );
// final String message2 =
// REZ.getString( "required-extensions",
// Arrays.asList( required ) );
// getLogger().debug( message2 );
//}
final ArrayList dependencies = new ArrayList();
final ArrayList unsatisfied = new ArrayList();
m_manager.scanDependencies( required,
available,
dependencies,
unsatisfied );
if( 0 != unsatisfied.size() )
{
final int size = unsatisfied.size();
for( int i = 0; i < size; i++ )
{
final Extension extension = (Extension)unsatisfied.get( i );
final Object[] params = new Object[]
{
extension.getExtensionName(),
extension.getSpecificationVendor(),
extension.getSpecificationVersion(),
extension.getImplementationVendor(),
extension.getImplementationVendorID(),
extension.getImplementationVersion(),
extension.getImplementationURL()
};
final String message = REZ.format( "missing.extension",
params );
getLogger().warn( message );
}
final String message =
REZ.getString( "unsatisfied.extensions", new Integer( size )
);
throw new Exception( message );
}
final OptionalPackage[] packages =
(OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ]
);
return OptionalPackage.toFiles( packages );
}
private Manifest[] getManifests( final String[] classPath )
throws Exception
{
final ArrayList manifests = new ArrayList();
for( int i = 0; i < classPath.length; i++ )
{
final String element = classPath[ i ];
if( element.endsWith( ".jar" ) )
{
try
{
final URL url = new URL( "jar:" + element + "!/" );
final JarURLConnection connection =
(JarURLConnection)url.openConnection();
final Manifest manifest = connection.getManifest();
manifests.add( manifest );
}
catch( final IOException ioe )
{
final String message = REZ.getString(
"bad-classpath-entry", element );
getLogger().warn( message );
throw new Exception( message );
}
}
}
return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultProfile.java
Index: DefaultProfile.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.Version;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
import org.apache.excalibur.merlin.registry.Registry;
import org.apache.excalibur.merlin.registry.UnresolvedProviderException;
import org.apache.excalibur.configuration.ContextFactory;
/**
* The default implementation of a profile under which configuration, context
* and parameterization criteria is associated against a component type
defintion.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
class DefaultProfile extends ComponentMetaData
implements Profile
{
private static String getAbstractName( Configuration profile )
{
return profile.getAttribute("name",null);
}
private static DependencyMetaData[] getDependencyMetaData(
final DefaultRegistry registry, final ComponentType type )
throws UnresolvedProviderException
{
Vector vector = new Vector();
DependencyDescriptor[] deps =
type.getComponentInfo().getDependencies();
for( int i=0; i<deps.length; i++ )
{
final String role = deps[i].getRole();
final Profile provider = registry.getCandidateProfile( deps[i] );
DependencyMetaData data = new DependencyMetaData(
role,
provider.getName()
);
vector.add( data );
}
return (DependencyMetaData[]) vector.toArray( new
DependencyMetaData[0] );
}
private final ComponentType m_type;
private final Configuration m_profile;
private final DefaultRegistry m_registry;
/**
* Creation of a default profile.
* @param type the component type that this profile is qualifying
*/
public DefaultProfile( final DefaultRegistry registry, final
ComponentType type )
throws ConfigurationException, UnresolvedProviderException
{
this( registry, type, new DefaultConfiguration("profile") );
}
/**
* Creation of a profile of a component type. The
* configuration is a profile instance containing criteria for for the
* profiles default configuration, parameters and content.
*
* @param type the component type that this profile is qualifying
* @param profile a configuration instance possibly containing a context,
* parameters and configuration element.
* @param name the profile name
*/
public DefaultProfile(
final DefaultRegistry registry, final ComponentType type, final
Configuration profile )
throws ConfigurationException, UnresolvedProviderException
{
super(
getAbstractName( profile ),
getDependencyMetaData( registry, type ),
Parameters.fromConfiguration( profile.getChild("paramerters") ),
profile.getChild("configuration"),
type.getComponentInfo()
);
m_type = type;
m_profile = profile;
m_registry = registry;
m_registry.install( this );
}
/**
* Returns the component type bound to the profile.
* @return the component type
*/
public ComponentType getComponentType()
{
return m_type;
}
/**
* Returns the context to be supplied to an instance of the profile
* @return the profile context object
*/
public Context getContext( Context parent )
{
try
{
Configuration criteria = m_profile.getChild("context");
return ContextFactory.createContextFromConfiguration( parent,
criteria );
}
catch( Throwable e )
{
throw new ProfileRuntimeException(
"Unexpected error while creating context.", e );
}
}
public String toString()
{
return "DefaultProfile name: '" + getName() + "' type: " +
getComponentType();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultRegistry.java
Index: DefaultRegistry.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.Enumeration;
import java.security.Policy;
import java.io.FileInputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
import org.apache.excalibur.containerkit.verifier.AssemblyVerifier;
import org.apache.excalibur.containerkit.verifier.MetaDataVerifier;
import org.apache.excalibur.containerkit.verifier.VerifyException;
import org.apache.excalibur.containerkit.dependency.DependencyMap;
import org.apache.log.Hierarchy;
import org.apache.log.Priority;
import org.apache.log.output.io.StreamTarget;
import org.apache.excalibur.merlin.registry.*;
import org.apache.excalibur.merlin.registry.Profile;
/**
* Provides support for the maintenance of a registry of
* component type definitions established within a classloader.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public class DefaultRegistry extends AbstractLogEnabled implements
Contextualizable, Serviceable, Configurable, Initializable, Executable,
Disposable, Registry
{
//=======================================================================
// static
//=======================================================================
private static final ComponentType[] EMPTY_DEFS = new ComponentType[0];
private static final Profile[] EMPTY_PROFILES = new Profile[0];
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultRegistry.class );
//=======================================================================
// state
//=======================================================================
/**
* The context argument supplied by the container.
*/
private Context m_context;
/**
* The list of all ComponentDefinition instances keyed by classname.
*/
private Hashtable m_componentRegistry = new Hashtable();
/**
* The list of all ComponentDefinition instances keyed by service
classname.
*/
private ServiceRegistry m_services;
private ClassLoader m_classloaderParent;
private DefaultClassLoader m_classloader;
/**
* List of the component classname recorded in the jar file manifests.
*/
private List m_classnames = new LinkedList();
/**
* The extensions repository (supplied by service manager).
*/
private PackageRepository m_repository;
private Configuration m_config;
private MetaDataVerifier m_verifier;
private AssemblyVerifier m_assemblyVerifier;
private Hashtable m_profileMapping = new Hashtable();
private Hashtable m_profiles = new Hashtable();
private ComponentMetaData[] m_appContext;
//=======================================================================
// LogEnabled
//=======================================================================
public void enableLogging( Logger logger )
{
super.enableLogging( logger );
}
//=======================================================================
// Contextualizable
//=======================================================================
/**
* Service context from which the registry classloader is resolved.
* @param context a context value containing the key 'classloader'
*/
public void contextualize( Context context ) throws ContextException
{
m_context = context;
m_classloaderParent = (ClassLoader) context.get( CLASSLOADER_KEY );
}
//=======================================================================
// Configure
//=======================================================================
/**
* Invoked by the container to establish the registry configuration.
* @param config a component configuration
*/
public void configure( Configuration config)
{
m_config = config;
}
//=======================================================================
// Service
//=======================================================================
/**
* Invoked by the container to establish services that this component
* is dependent on. The implementation receives the singelton extensions
* repository which will be used during initalization to construct the
* registry classloader.
*
* @param manager a component manager
* @exception ServiceException if a servicing error occurs
*/
public void service( ServiceManager manager ) throws ServiceException
{
m_repository = (PackageRepository) manager.lookup(
PackageRepository.ROLE );
}
//=======================================================================
// Initializable
//=======================================================================
/**
* Initalization of a <code>Registry</code> during which an application
* scoped classloader is created.
* @exception Exception if an error occurs during initialization.
*/
public void initialize() throws Exception
{
getLogger().debug("classloader creation");
m_classloader = new DefaultClassLoader(
m_repository,
m_classloaderParent,
m_config.getChild("classpath"),
getLogger().getChildLogger( "loader" )
);
//
// for all of the compoents declared under manifest jar block entries,
// register these as potential service providers with the service
repository
//
getLogger().debug("repository creation");
m_services = new ServiceRegistry( this, m_classloader,
m_config.getChild("factories") );
m_services.enableLogging( getLogger().getChildLogger("services") );
String[] blocks = m_classloader.getComponentClassnames();
try
{
//
// register all of the the componet providers implied by the
classpath
// manifest declarations
//
for( int i=0; i<blocks.length; i++ )
{
// initialize the component type defintions
final String classname = blocks[i].replace('/','.');
m_services.register( classname );
}
//
// for all of the components declared in the application profiles,
// install each one in the service repository - the side effect
of
// this is the buildup of the m_profiles table that will be used
to
// construct the application context
//
//getLogger().debug("profile:\n " + ConfigurationUtil.list(
m_config ));
Configuration factories = m_config.getChild("factories");
Configuration[] entries = factories.getChildren();
for( int i=0; i<entries.length; i++ )
{
final Configuration factory = entries[i];
getLogger().debug("factory: \n" + ConfigurationUtil.list(
factory ));
final String name = factory.getAttribute("name");
final String classname = factory.getAttribute("class");
final String mode = factory.getName();
if( mode.equals("component") )
{
m_services.install( classname, name );
}
else
{
// unrecognized declaration
getLogger().debug(
"bypassing unrecognized element "
+ ConfigurationUtil.list( factory ) );
}
}
}
catch( Throwable e )
{
final String error = "Internal registry initialization failure.";
throw new RegistryException( error, e );
}
}
//=======================================================================
// Executable
//=======================================================================
/**
* Executes composition of a target component assembly options relative to
a target
* component classname within the scope of a classpath declaration
containing jar file
* references (refer contextualize), and generate a report to the logging
channel.
*
* @exception Exception if an error occurs during execution
*/
public void execute() throws Exception
{
//
// the m_profiles table contain all of the profiles that
// have been selected to act as potential service provider for all of
the
// dependecies - from this point we need to buid the set of profiles
needed
// to execute the targets
//
Vector vector = new Vector();
DependencyMap map = new DependencyMap();
Profile[] profiles = m_services.getInstalledProfiles();
for( int i=0; i<profiles.length; i++ )
{
vector.add( profiles[i] );
getLogger().debug("profile: " + profiles[i] );
map.add( (ComponentMetaData) profiles[i] );
}
ComponentMetaData[] context = (ComponentMetaData[])
vector.toArray(new ComponentMetaData[0] );
verify( context );
//
// build the ordered sequence of dependecies
//
getLogger().debug("startup sequence");
ComponentMetaData[] startup = map.getStartupGraph();
for( int i=0; i<startup.length; i++ )
{
getLogger().debug("start: " + startup[i] );
}
getLogger().debug("shutdown sequence");
ComponentMetaData[] shutdown = map.getShutdownGraph();
for( int i=0; i<shutdown.length; i++ )
{
getLogger().debug("stop: " + shutdown[i] );
}
}
//=======================================================================
// Registry
//=======================================================================
/**
* Return the preferred profile for a depedency.
* @param dependency a consumer component dependecy declaration
* @return the preferred candidate supplier profile or null if not
candidates found
*/
public Profile getCandidateProfile( DependencyDescriptor dependency )
throws UnresolvedProviderException
{
return m_services.getCandidateProfile( dependency );
}
/**
* Returns an array of component profiles representing candidate component
types
* capable of acting as a service supplier relative to the supplied
dependecy descriptor.
* @param dependency the dependency descriptor to evaluate
* @return the set of profiles
*/
public Profile[] getCandidateProfiles( DependencyDescriptor dependency )
{
return m_services.getProfiles( dependency.getService() );
}
/**
* Method invoked by a DefaultProfile to declare itself within the
application scope.
* @param profile the Profile to include in application scope
*/
void install( Profile profile )
{
m_services.install( profile );
}
//=======================================================================
// implementation
//=======================================================================
/**
* Test if the registry can resolve a request for a component with the
supplied classname
* @param classname a component or service class name
* @return TRUE if the registry can service the request
*/
private boolean hasComponentDefinition( String classname )
{
return m_services.getComponentType( classname ) != null;
}
/**
* Returns an component defintion either through referdnce to an exiting
defintion
* or through defintion coreation if no exiting defintion is available
relative to
* the request classname key.
* @param classname the class name of the component defintion to locate or
create
* @return the corresponding component defintion
* @exception RegistryRuntimeException if an error occurs during the
* construction of a new component defintion
*/
private ComponentType getComponentDefinition( String classname )
{
return m_services.getComponentType( classname );
}
private void verify( ComponentMetaData[] assembly ) throws VerifyException
{
if( m_assemblyVerifier == null )
{
m_assemblyVerifier = new AssemblyVerifier();
m_assemblyVerifier.enableLogging(
getLogger().getChildLogger("verifier") );
}
m_assemblyVerifier.verifyAssembly( assembly );
}
/**
* Returns the component type implementation class.
* @param type the component type descriptor
* @return the class implementing the component type
*/
private Class getComponentClass( ComponentType type ) throws
RegistryException
{
if( null == type )
throw new NullPointerException("Illegal null component type
argument.");
final String classname =
type.getComponentInfo().getComponentDescriptor().getImplementationKey();
try
{
return m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error = "Could not load implementation class for
component type: "
+ classname;
throw new RegistryException( error, e );
}
}
/**
* Returns the service type implementation class.
* @param service the service type descriptor
* @return the class implementing the service type
*/
private Class getServiceClass( ServiceDescriptor service ) throws
RegistryException
{
final String classname =
service.getServiceDesignator().getClassname();
try
{
return m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error = "Could not load implementation class for
service type: "
+ classname;
throw new RegistryException( error, e );
}
}
//=======================================================================
// Disposable
//=======================================================================
/**
* Disposal of this component.
*/
public void dispose()
{
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultRegistry.xinfo
Index: DefaultRegistry.xinfo
===================================================================
<?xml version="1.0"?>
<!--
Copyright (C) The Apache Software Foundation. All rights reserved.
This software is published under the terms of the Apache Software License
version 1.1, a copy of which has been included with this distribution in
the LICENSE.txt file.
@author Stephen McConnell
@version 1.0 12/03/2001
-->
<blockinfo>
<block>
<name>registry</name>
<version>1.0</version>
</block>
<services>
<service name="org.apache.excalibur.merlin.registry.Registry"
version="1.0"/>
</services>
</blockinfo>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Fileset.java
Index: Fileset.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.avalon.framework.configuration.Configuration;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.File;
import java.util.Vector;
import java.util.StringTokenizer;
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
class Fileset
{
//=======================================================================
// static
//=======================================================================
public static File[] expandExtensions( Configuration conf )
{
Vector vector = new Vector();
Configuration[] dirsets = conf.getChildren("dirset");
for( int i=0; i<dirsets.length; i++ )
{
expandDirSetToVector( vector, dirsets[i] );
}
return (File[]) vector.toArray( new File[ vector.size() ] );
}
private static void expandDirSetToVector( Vector vector, Configuration
dirset )
{
File base = new File( dirset.getAttribute("dir",
System.getProperty("user.dir") ) );
if( !base.isDirectory() )
throw new IllegalArgumentException("Base dir does not refer to a
directory in path: " + base );
Configuration[] includes = dirset.getChildren("include");
for( int i=0; i<includes.length; i++ )
{
String name = includes[i].getAttribute("name", null );
if( name == null )
throw new IllegalArgumentException(
"Include does not contain the name attribute: " +
includes[i].getLocation() );
File file = new File( base, name );
if( file.isDirectory() )
{
vector.add( file );
}
else
{
throw new IllegalArgumentException(
"Include dir does not refer to a directory: " + file + ",
base: " + base );
}
}
}
public static URL[] expandClasspath( Configuration conf )
{
Vector vector = new Vector();
Configuration[] filesets = conf.getChildren("fileset");
for( int i=0; i<filesets.length; i++ )
{
expandFileSetToVector( vector, filesets[i] );
}
return (URL[]) vector.toArray( new URL[ vector.size() ] );
}
public static URL[] expandFileSet( Configuration conf )
{
Vector vector = new Vector();
expandFileSetToVector( vector, conf );
return (URL[]) vector.toArray( new URL[ vector.size() ] );
}
private static void expandFileSetToVector( Vector vector, Configuration
conf )
{
File base = new File( conf.getAttribute("dir",
System.getProperty("user.dir") ) );
if( !base.isDirectory() )
throw new IllegalArgumentException("Base dir does not refer to a
directory in path: " + base );
Configuration[] includes = conf.getChildren("include");
for( int i=0; i<includes.length; i++ )
{
String name = includes[i].getAttribute("name", null );
if( name == null )
throw new IllegalArgumentException(
"Include does not contain the name attribute: " +
includes[i].getLocation() );
File file = new File( base, name );
if( !file.exists() )
throw new IllegalArgumentException(
"Include references file that does not exist: " +
includes[i].getLocation() );
try
{
vector.add( file.toURL() );
}
catch( Throwable e )
{
throw new IllegalArgumentException(
"Could not convert include to a URL: " +
includes[i].getLocation() );
}
}
}
public static String[] splitPath( String path, String token )
{
StringTokenizer tokenizer = new StringTokenizer( path, token );
Vector vector = new Vector();
while( tokenizer.hasMoreElements() )
{
vector.add( tokenizer.nextToken() );
}
return (String[]) vector.toArray( new String[ vector.size() ] );
}
public static File[] expandPath( String[] path )
{
Vector vector = new Vector();
for( int i=0; i<path.length; i++ )
{
File file = new File( path[i] );
vector.add( file );
if( file.isDirectory() )
{
expandDirectory( vector, file );
}
}
return (File[]) vector.toArray( new File[ vector.size() ] );
}
private static void expandDirectory( Vector vector, File dir )
{
if( !dir.isDirectory() ) return;
final File[] files = dir.listFiles();
for( int i=0; i<files.length; i++ )
{
File file = files[i];
vector.add( file );
if( file.isDirectory() )
{
expandDirectory( vector, file );
}
}
}
public static String[] urlsToStrings( URL[] urls )
{
Vector vector = new Vector();
for( int i=0; i<urls.length; i++ )
{
vector.add( urls[i].toString() );
}
return (String[]) vector.toArray( new String[ vector.size() ] );
}
public static URL[] fileToURL( File[] files ) throws MalformedURLException
{
Vector vector = new Vector();
for( int i=0; i<files.length; i++ )
{
vector.add( files[i].toURL() );
}
return (URL[]) vector.toArray( new URL[ vector.size() ] );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Main.java
Index: Main.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import java.io.FileInputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.log.Hierarchy;
import org.apache.log.Priority;
import org.apache.log.output.io.StreamTarget;
/**
* Application bootstrap.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public class Main
{
//=======================================================================
// static
//=======================================================================
private static final ComponentType[] EMPTY_DEFS = new ComponentType[0];
private static final ServiceDescriptor[] EMPTY_SVCS = new
ServiceDescriptor[0];
private static final File[] EMPTY_FILES = new File[0];
private static final String DEFAULT_FORMAT =
"[%7.7{priority}] (%{category}): %{message}\\n%{throwable}";
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultRegistry.class );
/**
* Creation of a root type registry.
*/
public static void main( String[] args )
{
DefaultRegistry registry = new DefaultRegistry();
// create a configuration object containing the kernel profile
// from which we can establish the logger and extensions directory
String path = null;
Configuration config = null;
if( args.length > 0 )
path = args[0];
if( path == null )
{
// FIX ME
// the following does not make sense - we need at least a target
component
config = new DefaultConfiguration("merlin", null );
}
else
{
config = getProfile( new File( path ) );
}
// create a bootstrap logger - this needs to be replaced with
// the Avalon Exvalibur Logkit package
Logger logger = null;
Logger main = null;
try
{
// FIX ME
// logging setup should use the ECM logging setup model
// create an internal logger for the registry
final Hierarchy hierarchy = createHierarchy(
Priority.getPriorityForName(
config.getChild("logger").getAttribute("priority","INFO")
)
);
logger = new LogKitLogger( hierarchy.getLoggerFor( "" ) );
main = new LogKitLogger( hierarchy.getLoggerFor( "merlin" ) );
registry.enableLogging( logger.getChildLogger("registry") );
}
catch( Throwable e )
{
System.out.println("Unexpected error while supplying registry
logger.");
e.printStackTrace( );
System.exit(0);
}
// FIX ME - change this so that the DefaultRegistry uses the
// context classloader as a default value if none declared as a
context
// (i.e. make contextualization optional)
// supply a context object with the classloader
ClassLoader parent = Thread.currentThread().getContextClassLoader();
DefaultContext context = new DefaultContext();
context.put( DefaultRegistry.CLASSLOADER_KEY, parent );
try
{
registry.contextualize( context );
}
catch( Throwable e )
{
main.error("Unexpected error while supply registry context.", e);
System.exit(0);
}
// FIX ME - change this so that the DefaultRegistry creates an empty
// extensions repository if none supplied - also, move this to
// context and declare it as optional
// supply an service object with the type repository
PackageRepository extensions = new DefaultPackageRepository(
Fileset.expandExtensions( config.getChild("extensions") ) );
try
{
DefaultServiceManager manager = new DefaultServiceManager();
manager.put( PackageRepository.ROLE, extensions );
registry.service( manager );
}
catch( Throwable e )
{
main.error("Unexpected error while servicing the registry.", e );
System.exit(0);
}
// configure the registry
try
{
registry.configure( config.getChild("registry") );
}
catch( Throwable e )
{
main.error("Unexpected error while configuring the registry.", e
);
System.exit(0);
}
// initialize the registry
try
{
main.debug("initialization");
registry.initialize( );
}
catch( Throwable e )
{
main.error("Unexpected error during registry initialization.", e);
System.exit(0);
}
// type registry demo
try
{
main.debug("execution");
registry.execute();
}
catch( Throwable e )
{
final String error = "Execution error.";
main.error( ExceptionUtil.printStackTrace( e ) );
}
}
private static Hierarchy createHierarchy( Priority priority )
{
try
{
Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
hierarchy.setDefaultLogTarget(
new StreamTarget( System.out, new AvalonFormatter(
DEFAULT_FORMAT ) ) );
hierarchy.setDefaultPriority( priority );
return hierarchy;
}
catch( Throwable e )
{
final String error = "Unexpected exception while creating
bootstrap logger.";
throw new CascadingRuntimeException( error, e );
}
}
private static Configuration getProfile( final File file )
{
try
{
DefaultConfigurationBuilder builder = new
DefaultConfigurationBuilder();
InputStream is = new FileInputStream( file );
if( is == null )
{
throw new RuntimeException(
"Could not load the configuration resource \"" + file +
"\"" );
}
return builder.build( is );
}
catch( Throwable e )
{
final String error = "Unable to create configuration from file: "
+ file;
throw new CascadingRuntimeException( error, e );
}
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Profile.java
Index: Profile.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.Version;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
/**
* Interface that defines a set of constraints applied to a component type.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public interface Profile
{
/**
* Default role name for this interface.
*/
static final String ROLE = Profile.class.getName();
/**
* Returns the name of the component type profile.
* @return the profile name
*/
String getName();
/**
* Returns the component type that this profile constrains.
* @return the component type
*/
ComponentType getComponentType();
/**
* Returns the context to be supplied to an instance of the profile
* @return the profile context object
*/
Context getContext( Context parent );
/**
* Returns the configuration to be supplied to an instance of the profile
* @return the profile configuration object
*/
Configuration getConfiguration();
/**
* Returns the parameters to be supplied to an instance of the profile
* @return the profile parameter object
*/
Parameters getParameters();
/**
* Returns all dependency metadata for the profile.
* @return the dependency metadata array
*/
public DependencyMetaData[] getDependencies();
/**
* Returns dependency metadata for a name dependency.
* @return the dependency metadata
*/
public DependencyMetaData getDependency( String role );
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ProfileException.java
Index: ProfileException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that there was an error relating to a profile.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class ProfileException
extends CascadingException
{
private static final Hashtable EMPTY_TABLE = new Hashtable();
private Dictionary m_errors;
/**
* Construct a new <code>ProfileException</code> instance.
*
* @param message The detail message for this exception.
*/
public ProfileException( final String message )
{
this( null, message, null );
}
/**
* Construct a new <code>ProfileException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
*/
public ProfileException( final Dictionary errors, final String message )
{
this( errors, message, null );
}
/**
* Construct a new <code>ProfileException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public ProfileException( final String message, final Throwable throwable )
{
this( null, message, throwable );
}
/**
* Construct a new <code>ProfileException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public ProfileException( final Dictionary errors, final String message,
final Throwable throwable )
{
super( message, throwable );
if( errors != null )
{
m_errors = errors;
}
else
{
m_errors = EMPTY_TABLE;
}
}
/**
* Return the table of supplimentary messages.
* @return the messages table
*/
public Dictionary getDictionary()
{
return m_errors;
}
/**
* Returns a stringified representation of the exception.
* @return the exception as a string.
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( super.toString() );
buffer.append( " Errors: " + m_errors.size() );
Enumeration keys = m_errors.keys();
while( keys.hasMoreElements() )
{
Object key = keys.nextElement();
buffer.append( "\n source: " + key.toString() + " cause: " +
m_errors.get( key ) );
}
return buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ProfileRuntimeException.java
Index: ProfileRuntimeException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingRuntimeException;
/**
* Exception to indicate that there was an error during assembly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class ProfileRuntimeException
extends CascadingRuntimeException
{
private static final Hashtable EMPTY_TABLE = new Hashtable();
private Dictionary m_errors;
/**
* Construct a new <code>ProfileRuntimeException</code> instance.
*
* @param message The detail message for this exception.
*/
public ProfileRuntimeException( final String message )
{
this( null, message, null );
}
/**
* Construct a new <code>ProfileRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
*/
public ProfileRuntimeException( final Dictionary errors, final String
message )
{
this( errors, message, null );
}
/**
* Construct a new <code>ProfileRuntimeException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public ProfileRuntimeException( final String message, final Throwable
throwable )
{
this( null, message, throwable );
}
/**
* Construct a new <code>ProfileRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public ProfileRuntimeException( final Dictionary errors, final String
message,
final Throwable throwable )
{
super( message, throwable );
if( errors != null )
{
m_errors = errors;
}
else
{
m_errors = EMPTY_TABLE;
}
}
/**
* Return the table of supplimentary messages.
* @return the messages table
*/
public Dictionary getDictionary()
{
return m_errors;
}
/**
* Returns a stringified representation of the exception.
* @return the exception as a string.
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( super.toString() );
buffer.append( " Errors: " + m_errors.size() );
Enumeration keys = m_errors.keys();
while( keys.hasMoreElements() )
{
Object key = keys.nextElement();
buffer.append( "\n source: " + key.toString() + " cause: " +
m_errors.get( key ) );
}
return buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Registry.java
Index: Registry.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.merlin.registry.ComponentType;
import org.apache.excalibur.merlin.registry.Profile;
/**
* A service that provides support for location of components types.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public interface Registry
{
/**
* Default role.
*/
static final String ROLE = Registry.class.getName();
/**
* Returns an array of component profiles representing candidate component
types
* capable of acting as a service supplier relative to the supplied
dependecy descriptor.
* @param dependency the dependency descriptor to evaluate
* @return the set of profiles
*/
Profile[] getCandidateProfiles( DependencyDescriptor dependency );
/**
* Return a single preferred profile capable of supporting the supplied
dependency.
* @param dependency a consumer component dependecy declaration
* @return the preferred candidate supplier profile or null if not
candidates found
*/
Profile getCandidateProfile( DependencyDescriptor dependency )
throws UnresolvedProviderException;
/**
* Key value used to publish the application classloader.
*/
static final String CLASSLOADER_KEY = "classloader";
//public void register( Profile profile );
/**
* Test if the registry can resolve a request for a component with the
supplied classname
* @param classname a component or service class name
* @return TRUE if the registry can service the request
*/
//boolean hasComponentDefinition( String classname );
/**
* Returns an component defintion relative to the requested classname.
* @param classname the class name of the componet defintion to locate or
create
* @return the corresponding component defintion
* @exception AssemblyException if an error occurs during the construction
of a
* new component defintion
*/
//ComponentType getComponentDefinition( String classname ) throws
RegistryException;
/**
* Returns an array of component definitions capable of acting as a
service supplier
* relative to the supplied dependecy descriptor.
* @param dependency the dependency descriptor to evaluate
* @return the set of matching service descriptors capable of supporting
the dependency
*/
//public ComponentType[] getCandidateProviders( DependencyDescriptor
dependency );
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/RegistryException.java
Index: RegistryException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that there was a repository related error.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class RegistryException
extends CascadingException
{
/**
* Construct a new <code>RegistryException</code> instance.
*
* @param message The detail message for this exception.
*/
public RegistryException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public RegistryException( final String message, final Throwable throwable
)
{
super( message, throwable );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/RegistryRuntimeException.java
Index: RegistryRuntimeException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.avalon.framework.CascadingRuntimeException;
/**
* Exception to indicate that there was a repository related runtime error.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class RegistryRuntimeException
extends CascadingRuntimeException
{
/**
* Construct a new <code>RegistryRuntimeException</code> instance.
*
* @param message The detail message for this exception.
*/
public RegistryRuntimeException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>RegistryRuntimeException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public RegistryRuntimeException( final String message, final Throwable
throwable )
{
super( message, throwable );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Resources.properties
Index: Resources.properties
===================================================================
xinfo-load=Creating ComponentInfo from {0}.
xinfo-missing=XINFO resource unavailable for class "{0}".
xinfo-parse-error=Error occured while parsing xinfo resource "{0}".
xinfo-nocreate=Failed to create ComponentInfo from resource "{0}" (Reason:
{1}).
xinfo-props-error=Unable to construct attributes using key "{0}" (Reason:
{1}).
cinfo-nocreate=Failed to create ComponentDescriptor from resource "{0}"
(Reason: {1}).
cinfo-properties-error=Failed to create ComponentInfo attributes from
resource "{0}" (Reason: {1}).
sinfo-noname=Missing name attribute in service declaration from resource
"{0}".
sinfo-version=Bad service version in resource "(Reason: {0})".
sinfo-nocreate=Failed to create ServiceInfo from resource "{0}" (Reason: {1}).
dinfo-service-error="Could not create dependecy service delcaration (Reason:
{0}).
dinfo-nocreate="Could not create dependecy delcaration from resource "{0}"
(Reason: {1}).
missing.extension=Unable to locate an extension that is required by
application.\n Extension Name: {0}\n Specification Vendor: {1}\n
Specification Version: {2}\n Implementation Vendor: {3}\n Implementation
Vendor-Id: {4}\n Implementation Version: {5}\n Implementation URL: {6}
unsatisfied.extensions=Missing {0} extensions and thus can not build
ClassLoader for application.
bad-classpath-entry=There is a bad entry ("{0}") on classpath that made it
impossible to load a manifest.
available-extensions=Available extensions: {0}
required-extensions=The list of required extensions for application includes:
{0}
optional-packages-added=The list of "Optional Packages" added to the
application include: {0}
classpath-entries=The list of classpath entrys for the application include:
{0}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Selector.java
Index: Selector.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.excalibur.merlin.registry.Profile;
/**
* Interface implemented by selection services that can provide a sorted
* set of profiles for a paricular service type.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public interface Selector
{
/**
* Returns the preferred profile for an available selection of provider
profiles.
* @param profiles the set of profiles of potential service providers
* @return the preferred provider or null if no satisfactory provider can
be established
* from the supplied profiles.
*/
Profile select( Profile[] profiles ) throws UnresolvedProviderException;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ServiceRegistry.java
Index: ServiceRegistry.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Iterator;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.merlin.registry.ComponentType;
import org.apache.excalibur.merlin.registry.Profile;
import org.apache.excalibur.merlin.registry.ComponentDefinition;
import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
import org.apache.excalibur.containerkit.infobuilder.ComponentInfoBuilder;
import org.apache.excalibur.configuration.ConfigurationUtil;
/**
* Internal table that holds available component type keyed relative
* to the service it provides.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
final class ServiceRegistry extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
private ComponentInfoBuilder m_infoBuilder = new ComponentInfoBuilder();
private ClassLoader m_classloader;
private Configuration m_profiles;
private DefaultRegistry m_registry;
/**
* Component type lists keyed by service designator.
*/
private Hashtable m_services = new Hashtable();
/**
* Component types keyed by classname.
*/
private Hashtable m_types = new Hashtable();
/**
* The set of installed profiles keyed by profile name.
*/
private Hashtable m_installed = new Hashtable();
//=======================================================================
// constructor
//=======================================================================
/**
* Creation of a new service registry.
* @param registry the registry that will be supplied to new component
defintions
* @param loader the registry class loader
* @param profiles the configuration fragment containing explicit
component profiles
*/
public ServiceRegistry( DefaultRegistry registry, ClassLoader loader,
Configuration profiles )
{
m_classloader = loader;
m_profiles = profiles;
m_registry = registry;
}
//=======================================================================
// LogEnabled
//=======================================================================
/**
* Set the logging channel for the service registry.
* @param logger the logging channel
*/
public void enableLogging( Logger logger )
{
super.enableLogging( logger );
m_infoBuilder.enableLogging( logger.getChildLogger("builder") );
}
//=======================================================================
// ServiceRegistry
//=======================================================================
/**
* Register a potential supplier component type. The implementation will
* create a component type instance for the entry if not already known and
* return the existing or new instance to the invoking client.
*
* @param classname the component class name
* @return the component type
*/
public ComponentType register( String classname ) throws Exception
{
ComponentType type = getComponentType( classname );
if( type == null )
{
type = createComponentDefinition( classname );
register( type );
}
return type;
}
/**
* Install a provider and return the profile.
* @param classname the classname of the provider to install
* @param name the component profile to use for the provider
*/
public Profile install( String classname, String name ) throws Exception
{
return install( register( classname ).getProfile( name ) );
}
/**
* Install a provider and return the profile.
* @param classname the classname of the provider to install
* @param name the component profile to use for the provider
*/
public Profile install( Profile profile )
{
m_installed.put( profile.getName(), profile );
return profile;
}
/**
* Return the set of profiles representing the application scope.
* @return the installed profiles
*/
public Profile[] getInstalledProfiles()
{
return (Profile[]) m_installed.values().toArray( new Profile[0] );
}
/**
* Returns the set of component types know to the registry.
* @return the set of component types registered with the registry
*/
public ComponentType[] getTypes()
{
return (ComponentType[]) m_types.entrySet().toArray( new
ComponentType[0] );
}
/**
* Returns the set of component types know to the registry that are
capable of
* supporting the supplied service.
* @return the set of candidate component types
*/
public ComponentType[] getComponentTypes( ServiceDesignator service )
{
return (ComponentType[]) getList( service ).toArray( new
ComponentType[0] );
}
/**
* Returns a registered component type.
* @return the component type from the registry or null if the type is
unknown
*/
public ComponentType getComponentType( String classname ) throws
IllegalArgumentException
{
return (ComponentType) m_types.get( classname );
}
public Profile[] getProfiles( ServiceDesignator service )
{
Vector vector = new Vector();
ComponentType[] components = getComponentTypes( service );
for( int i=0; i<components.length; i++ )
{
try
{
Profile[] profiles = components[i].getProfiles();
for( int j=0; j<profiles.length; j++ )
{
vector.add( profiles[j] );
}
}
catch( Throwable e )
{
getLogger().warn("skipping type: " + components[i], e );
}
}
return (Profile[]) vector.toArray( new Profile[0] );
}
public Profile getCandidateProfile( DependencyDescriptor dependency )
throws UnresolvedProviderException
{
Profile[] profiles = getProfiles( dependency.getService() );
if( profiles.length == 0 )
{
throw new UnresolvedProviderException( "No candidates matching
dependency.", dependency );
}
else
{
Selector selector = getSelector( dependency );
if( selector == null )
{
return profiles[0];
}
else
{
return selector.select( profiles );
}
}
}
private void register( ComponentType type )
{
getLogger().debug("registering provider type: " +
getImplementationKey( type ) );
m_types.put( getImplementationKey( type ), type );
ServiceDescriptor[] services = type.getComponentInfo().getServices();
for( int i=0; i<services.length; i++ )
{
register( services[i].getServiceDesignator(), type );
}
}
private Selector getSelector( DependencyDescriptor dependency )
{
// if the dependency declares a selector class then use that,
// otherwise, look for a default service type selector
String selectorName =
dependency.getAttribute("avalon.service.selector");
if( selectorName == null )
selectorName = dependency.getService().getClassname() + "Selector";
try
{
Class clazz = m_classloader.loadClass( selectorName );
Selector selector = (Selector) clazz.newInstance();
if( selector instanceof LogEnabled )
{
((LogEnabled)selector).enableLogging(
getLogger().getChildLogger("selector") );
}
return selector;
}
catch( Throwable e )
{
return null;
}
}
private void register( ServiceDesignator service, ComponentType type )
{
List list = getList( service );
list.add( type );
}
private List getList( ServiceDesignator service )
{
List list = null;
Iterator iterator = m_services.keySet().iterator();
while( iterator.hasNext() )
{
ServiceDesignator singleton = (ServiceDesignator) iterator.next();
if( singleton.matches( service ) )
{
list = (List) m_services.get( singleton );
}
}
if( list == null )
{
getLogger().debug("registering service type: " + service );
list = new LinkedList();
m_services.put( service, list );
}
return list;
}
private String getImplementationKey( ComponentType type )
{
return
type.getComponentInfo().getComponentDescriptor().getImplementationKey();
}
/**
* Create a new ComponentDefintion instance.
* @param registry the component defintion registry
* @param classname the name of the component class
* @return the component info instance
* @exception AssemblyException if an assembly error occurs
*/
private ComponentDefinition createComponentDefinition( final String
classname )
throws RegistryException
{
if( classname == null )
throw new NullPointerException("classname");
if( classname.indexOf("/") > -1 )
throw new IllegalArgumentException( "invlaid classname" );
try
{
ComponentInfo info = m_infoBuilder.build( classname,
m_classloader );
final String name = info.getComponentDescriptor().getName();
Configuration[] profiles = ConfigurationUtil.match(
m_profiles, "component", "class", classname );
ComponentDefinition type = new ComponentDefinition( m_registry,
info, profiles );
type.enableLogging( getLogger().getChildLogger( name ) );
return type;
}
catch( Throwable e )
{
final String error = "Internal error while attempting to read
xinfo.";
throw new RegistryException( error, e );
}
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/UnresolvedProviderException.java
Index: UnresolvedProviderException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.registry;
import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that a service provider could not be found.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
*/
public final class UnresolvedProviderException
extends CascadingException
{
private DependencyDescriptor m_dependency;
/**
* Construct a new <code>UnresolvedProviderException</code> instance.
*
* @param dependency the unresolved dependency
*/
public UnresolvedProviderException( String message, DependencyDescriptor
dependency )
{
this( message, dependency, null );
}
/**
* Construct a new <code>UnresolvedProviderException</code> instance.
*
* @param dependency the unresolved dependency
* @param cause the causal exception
*/
public UnresolvedProviderException( String message, DependencyDescriptor
dependency, Throwable cause )
{
super( message, cause );
m_dependency = dependency;
}
public String getMessage()
{
return "Could not resolve provider for dependency "
+ m_dependency.getService()
+ " for role: " + m_dependency.getRole()
+ " due to " + super.getMessage();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/package.html
Index: package.html
===================================================================
<body>
<p>
A geneneric container supporting component lifecycle management. The
container serves as a repository for component types and provides support for a
type hierarchy based on an formal component type and profile model. The
repository enables resolution of component types based on a classloader,
extension directory set defintion, supplied classpath, and application
directives. Components are established based on the publication of components
within a jar file manifest together with explicit component profile directives
included within the repository configuration. Given a manifest declaration of a
component implementation class, a component type definition will be resolvable
providing the registry can resolve all type constraints (specifically the
validation of the dependecies of candidate supplier components).
</p>
<h3>Funtional Summary</h3>
<ul>
<li>Geneneric container supporting component lifecycle management.
<li>Hierachical container composition.
</ul>
<h3>Key Features</h3>
<p>A primary objective of this container is to provide simple deployment of
components with minimal administration overhead. In many cases, no component
assembly directives are required as the container will apply assembly logic
based on the meta-information association with component types that are either
explicity declared, or implicly located via a classpath and extension
directories.</p>
<ul>
<li>Stand-alone and embeddable deployment.
<li>Automatic component profile generation.
<li>Automatic assembly of components based on dependency and service
production declarations.
<li>Service provider selection plug-in architecture.
<li>Customization of application content.
<li>Support for multiple extension directories.
<li>Protected classloading.
</ul>
<h3>Object Model</h3>
<p>The container object model provides a simplified view of the
<code>containerkit</code> framework. The princincipal entry point is the
[EMAIL PROTECTED] org.apache.excalibur.merlin.registry.Registry} and the
associated default component based implementation [EMAIL PROTECTED]
org.apache.excalibur.merlin.registry.DefaultRegistry}. The registry acts as a
component type repository. Component types are exposed as instances of the
[EMAIL PROTECTED] org.apache.excalibur.merlin.registry.ComponentType}
interface. Each component type represents a concrete component implementation
class. For each component type, the container associates at least one
instantiation [EMAIL PROTECTED] org.apache.excalibur.merlin.registry.Profile}.
A profile is either a default profile generated by the container based on
meta-information derived from the type, or, an explicit profile declared by the
component user under the registry configuration. Multiple profile for a
particular component type can coexist in the same container.
<h3>Package Structure (UML)</h3>
<p><img src=doc-files/registry.gif border=0></p>
</body>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/doc-files/registry.gif
<<Binary file>>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>