mcconnell 2002/12/09 04:16:26 Modified: merlin build.xml kernel.xml merlin/src/etc demo.mf project.mf merlin/src/java/org/apache/avalon/merlin/block Block.java DefaultBlock.java merlin/src/java/org/apache/avalon/merlin/kernel DefaultKernel.java Added: merlin/src/test/config block.xml merlin/src/test/org/apache/avalon/merlin/kernel KernelTestCase.java merlin/src/test/org/apache/avalon/playground BasicComponent.java BasicComponent.xconfig BasicComponent.xinfo BasicComponent.xprofile BasicContext.java BasicContextInterface.java BasicService.java BasicService.xservice Removed: merlin/src/java/org/apache/avalon/merlin/block BlockFactory.java DefaultBlockFactory.java DefaultBlockFactory.xinfo Log: Incorporating block abstraction and supporting test-cases. Revision Changes Path 1.4 +23 -2 avalon-sandbox/merlin/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/build.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- build.xml 7 Dec 2002 09:47:26 -0000 1.3 +++ build.xml 9 Dec 2002 12:16:25 -0000 1.4 @@ -44,6 +44,12 @@ <pathelement location="${build.testclasses}"/> </path> + <path id="runtime.class.path"> + <pathelement location="${build.dir}/lib/${jar.name}"/> + <pathelement location="${build.dir}/lib/${demo.jar}"/> + <pathelement location="${build.testclasses}"/> + </path> + <target name="main" depends="jar,jar-playground" description="Build the project"/> <target name="rebuild" depends="clean,main" description="Rebuild the project"/> <target name="all" depends="rebuild,docs" description="Rebuild the project"/> @@ -367,6 +373,14 @@ </fileset> </copy> + <copy todir="${build.playground}" flatten="true"> + <fileset dir="${src.dir}/test/config" includes="block.xml"/> + </copy> + + <copy todir="${build.dir}/tests"> + <fileset dir="${basedir}" includes="kernel.xml"/> + </copy> + </target> @@ -380,6 +394,9 @@ <zipfileset dir="${build.conf}" prefix="META-INF/"> <include name="LICENSE.txt"/> </zipfileset> + <zipfileset dir="${build.playground}" prefix="BLOCK-INFO/"> + <include name="block.xml"/> + </zipfileset> </jar> </target> @@ -392,8 +409,12 @@ <junit fork="true" haltonfailure="${junit.failonerror}" printsummary="yes" - dir="${build.tests}"> - <classpath refid="test.class.path"/> + dir="${basedir}"> + <classpath> + <path refid="runtime.class.path"/> + <pathelement location="${build.test}"/> + </classpath> + <jvmarg value="-Djava.ext.dirs=common;lib"/> <formatter type="xml"/> <!-- xml reports for junitreport --> <formatter type="plain" usefile="false"/> <!-- text reports for humans --> 1.2 +8 -185 avalon-sandbox/merlin/kernel.xml Index: kernel.xml =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/kernel.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- kernel.xml 3 Dec 2002 07:09:47 -0000 1.1 +++ kernel.xml 9 Dec 2002 12:16:25 -0000 1.2 @@ -1,52 +1,6 @@ -<!-- -Merlin demonstration kernal configuration. - -This configuration assembles a set of component instance within a container -hierachy and is used as one of several validation points. The example includes -demonstration of some of the main Merlin features: - - a) automatic component assembly - b) multiple candidate resolution - c) lifestyle support - d) lifecycle extension - e) custom containers - f) dynamic component addition - g) context management - h) configuration management - i) use of explicit, packaged and implicit profiles - j) nested containers - ---> - <kernel> - <!-- - Declaration of the domain name that this kernel is operating within. - --> - - <system> - <host>localhost</host> - </system> - - <!-- - Optional logging catagory creation directive. The logging element declares - the application wide default logging priority. - A target element enables defintion of a logging file to which log entries will - be directed. The target name attribute is the name referenced by category elements - defined within the loggers element. - - The target defaults of "default" which corresponds to a internal default logging - target that issue messages to System.out (unless overriden by a target named default). - If the target is declared inside a catagory element, it must refer to a named target - element. The priority attribute may contain one of the values <code>DEBUG</code> - <code>INFO</code>, <code>WARN</code>, or <code>ERROR</code> and declares the system - wide default logging priority. - - The target must contain a single file element with the attribute <code>location</code> - the corresponds to the name of the logging file to which log entries shall be written. - --> - <logging priority="INFO" target="default"> <category name="/sys/logger" priority="WARN"/> <target name="kernel"> @@ -60,153 +14,22 @@ <engine> - <!-- - Declaration of installed extension directories and kernel level classpath. - In this demo we are referencing the Merlin classes in the embedded demo so - we need to include Merlin and its' extension depedencies in directory - referenced within the library element. - --> - <library dir="."> - <include name="extensions"/> + <include name="build/lib"/> </library> - <!-- - Defintion of the lifestyle manager. - The lifestyles class attribute must reference a class implementing the - interface org.apache.excalibur.merlin.resource.LifestyleManager. - --> - - <lifestyles class="org.apache.excalibur.merlin.resource.DefaultLifestyleManager"/> - - <!-- - Declaration of the root container. - --> - - </engine> - - <container name="root"> - - <!-- - A container has a number of internal logging catagories that you can modify to - see what's going on. In practice you will probably only declare categories under - components, however - the container level logging categories are presented here - for completness. - --> - - <categories priority="INFO"> - <category priority="WARN" name="loader" /> - <category priority="WARN" name="loader.services" /> - <category priority="WARN" name="loader.deployment" /> - <category priority="WARN" name="loader.lifecycle" /> - <category priority="WARN" name="loader.resource" /> - <category priority="WARN" name="loader.types" /> - </categories> - - <!-- - Declaration of the classpath for this container. - --> - <classpath> <fileset dir="build/lib"> - <include name="demo.jar"/> + <include name="avalon-merlin-demo-2.0.jar"/> </fileset> </classpath> - <!-- - Declaration of the services hosted by this container. Service container here - will be managed relative to other provider components at the same level and - may be serviced by components declared in parent container. - --> - - <component name="complex" class="org.apache.excalibur.playground.ComplexComponent" activation="startup"> - - <categories priority="DEBUG"> - <category name="init" priority="DEBUG" /> - </categories> - - <!-- - 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 key="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> - - <!-- - A containers declaration will cause the creation of a new registry holding the - child container instances. - --> - - <container name="custom" class="org.apache.excalibur.playground.CustomContainer"> - - <container name="demo"> - - <categories priority="INFO"> - <category priority="WARN" name="loader" /> - </categories> - - <!-- - Including the next entry demonstrates the resolution of a dependency via a profile - resolved from a parent container. SimpleComponent needs BasicService with is available - from either TerminalComponent or BasicComponent implicitly created in the parent - container path (due to a depenency declared by ComplexComponent). In addition, this - profile demonstrates the use of a cascading configuration. The configuration passed - to the instantiated component is based primarily on this configuration declared here - with defaults derived from SimpleComponent.xconfig. - --> - <component name="simple" - class="org.apache.excalibur.playground.SimpleComponent" - enabled="true" - activation="true"> - - <configuration> - <message>This is a custom message.</message> - </configuration> - - </component> - - </container> - - </container> - - <component name="basic-sample" class="org.apache.excalibur.playground.BasicComponent" activation="startup"> - - <categories priority="DEBUG"> - <category priority="WARN" name="loader" /> - </categories> - - <context class="org.apache.excalibur.playground.BasicContext"> - <entry key="location">My Place</entry> - <import name="avalon:home" key="home"/> - </context> - </component> + </engine> - </container> + <blocks> + <fileset dir="build/lib"> + <include name="avalon-merlin-demo-2.0.jar"/> + </fileset> + </blocks> </kernel> 1.2 +5 -15 avalon-sandbox/merlin/src/etc/demo.mf Index: demo.mf =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/etc/demo.mf,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- demo.mf 3 Dec 2002 07:08:02 -0000 1.1 +++ demo.mf 9 Dec 2002 12:16:25 -0000 1.2 @@ -1,18 +1,8 @@ Manifest-Version: 1.0 Created-By: Apache Avalon -Extension-List: framework meta lifecycle i18n -framework-Extension-Name: avalon-framework -framework-Specification-Version: 1.0 -framework-Implementation-Version: 4.1.2 -meta-Extension-Name: avalon-meta -meta-Specification-Version: 1.0 -lifecycle-Extension-Name: avalon-lifecycle -lifecycle-Specification-Version: 1.0 -assembly-Extension-Name: avalon-assembly -assembly-Specification-Version: 1.0 -configuration-Extension-Name: excalibur-configuration -configuration-Specification-Version: 1.0 -i18n-Extension-Name: excalibur-i18n -i18n-Specification-Version: 1.0 - +Extension-List: merlin +merlin-Extension-Name: avalon-merlin +merlin-Specification-Version: 2.0 +Name: Avalon-Block +Block-Name: demo 1.3 +0 -1 avalon-sandbox/merlin/src/etc/project.mf Index: project.mf =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/etc/project.mf,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- project.mf 7 Dec 2002 14:02:36 -0000 1.2 +++ project.mf 9 Dec 2002 12:16:25 -0000 1.3 @@ -25,4 +25,3 @@ Name: Avalon-Block Block-Name: Merlin -Kernel-Service: true \ No newline at end of file 1.2 +2 -6 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/Block.java Index: Block.java =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/Block.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Block.java 3 Dec 2002 07:08:02 -0000 1.1 +++ Block.java 9 Dec 2002 12:16:25 -0000 1.2 @@ -50,17 +50,13 @@ package org.apache.avalon.merlin.block; -import java.net.URL; - -import org.apache.avalon.assembly.appliance.Appliance; - /** * A block is a deployment model supporting composite components. * * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> * @version $Revision$ $Date$ */ -public interface Block extends Appliance +public interface Block { static final String AVALON_BLOCK_KEY = "Avalon-Block"; } 1.3 +61 -29 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/DefaultBlock.java Index: DefaultBlock.java =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/DefaultBlock.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DefaultBlock.java 7 Dec 2002 09:47:26 -0000 1.2 +++ DefaultBlock.java 9 Dec 2002 12:16:25 -0000 1.3 @@ -7,46 +7,78 @@ import java.net.URL; import java.util.jar.Attributes; import java.util.jar.Manifest; +import java.util.jar.JarFile; +import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.assembly.appliance.DefaultAppliance; +import org.apache.avalon.assembly.engine.EngineClassLoader; +import org.apache.avalon.framework.activity.Initializable; +import org.apache.avalon.framework.context.Context; +import org.apache.avalon.framework.context.Contextualizable; +import org.apache.avalon.framework.context.ContextException; -public class DefaultBlock extends DefaultAppliance implements Block +public class DefaultBlock extends AbstractLogEnabled implements Block, Contextualizable, Initializable { - public static final Attributes.Name BLOCK_NAME = new Attributes.Name( "Block-Name" ); + //============================================================== + // static + //============================================================== - private JarFile m_base; + public static final Attributes.Name BLOCK_NAME = new Attributes.Name( "Block-Name" ); - public String getName() + public static String getName( Manifest manifest ) { - try + Attributes attributes = manifest.getAttributes( Block.AVALON_BLOCK_KEY ); + if( attributes == null ) { - Manifest manifest = m_base.getManifest(); - if( manifest == null ) - { - throw new NullPointerException( "manifest" ); - } - - Attributes attributes = manifest.getAttributes( Block.AVALON_BLOCK_KEY ); - if( attributes == null ) - { - throw new NullPointerException( "attributes" ); - } - - if( attributes.containsKey( BLOCK_NAME ) ) - { - return (String) attributes.get( BLOCK_NAME ); - } - else - { - return "default"; - } + return null; } - catch( IOException ioe ) + if( attributes.containsKey( BLOCK_NAME ) ) { - final String error = - "Unexpected IO Exception while reading manifest on jarfile: " + m_base.getName(); - throw new RuntimeException( error ); + return (String) attributes.get( BLOCK_NAME ); } + return null; + } + + //============================================================== + // state + //============================================================== + + private EngineClassLoader m_engine; + + private Manifest m_manifest; + + //============================================================== + // Contextualizable + //============================================================== + + /** + * <p>Application of a runtime context to the lifestyle service. + * The context value will be passed directly to lifestyle handlers + * established by this service. + * @param context the runtime context + */ + public void contextualize( Context context ) throws ContextException + { + m_engine = (EngineClassLoader) context.get( "urn:assembly:classloader" ); + m_manifest = (Manifest) context.get( "urn:merlin:block.manifest" ); + } + + //============================================================== + // Initializable + //============================================================== + + public void initialize() throws Exception + { + getLogger().info( "initialization" ); + } + + //============================================================== + // Block + //============================================================== + + public String getName() + { + return getName( m_manifest ); } } 1.4 +82 -13 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/kernel/DefaultKernel.java Index: DefaultKernel.java =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/kernel/DefaultKernel.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- DefaultKernel.java 9 Dec 2002 03:05:55 -0000 1.3 +++ DefaultKernel.java 9 Dec 2002 12:16:25 -0000 1.4 @@ -54,10 +54,11 @@ import java.io.IOException; import java.io.FileInputStream; import java.io.InputStream; -import java.net.URLClassLoader; +import java.net.URL; import java.util.jar.JarFile; import java.util.jar.Attributes; import java.util.jar.Manifest; +import java.net.JarURLConnection; import org.apache.avalon.framework.CascadingException; import org.apache.avalon.framework.logger.Logger; @@ -82,7 +83,11 @@ import org.apache.avalon.assembly.logging.DefaultLoggingManager; import org.apache.avalon.assembly.engine.EngineClassLoader; import org.apache.avalon.assembly.engine.Engine; +import org.apache.avalon.assembly.engine.model.LibraryDescriptor; +import org.apache.avalon.assembly.engine.model.ClasspathDescriptor; import org.apache.avalon.assembly.util.ExceptionHelper; +import org.apache.avalon.merlin.block.Block; +import org.apache.avalon.merlin.block.DefaultBlock; /** * Default kernel implementation. The implementation provides support for @@ -243,7 +248,7 @@ if( getLogger().isDebugEnabled() ) { - getLogger().debug( "initialization" ); + getLogger().debug( "initialization: " + m_home ); } // @@ -259,7 +264,8 @@ catch( Throwable e ) { final String error = - "Bootstrap engine establishment error."; + "Bootstrap engine establishment error. Extension path: " + + System.getProperty("java.ext.dirs"); String log = ExceptionHelper.packException( error, e ); if( getLogger().isErrorEnabled() ) { @@ -274,10 +280,57 @@ if( getLogger().isDebugEnabled() ) { - getLogger().debug( "container assembly" ); + getLogger().debug( "commencing container assembly" ); + } + + ClasspathDescriptor blocks = + m_creator.createClasspathDescriptor( m_config.getChild( "blocks" ) ); + URL[] urls = ClasspathDescriptor.expand( m_home, blocks ); + + for( int i=0; i<urls.length; i++ ) + { + URL url = urls[i]; + try + { + installBlock( url ); + } + catch( Throwable e ) + { + final String error = + "Error during block deployment for url: " + url; + } } } + private Block installBlock( URL url ) throws Exception + { + Manifest manifest = getManifest( url ); + if( !isBlock( manifest ) ) + { + final String warning = + "Manifest does not declare a block on resource: " + url; + throw new IllegalArgumentException( warning ); + } + + String name = DefaultBlock.getName( manifest ); + if( name == null ) + { + final String error = "Missing name in block: " + url; + throw new IllegalArgumentException( error ); + } + + getLogger().debug( "installing block: " + name ); + DefaultBlock block = new DefaultBlock(); + block.enableLogging( getLogger().getChildLogger( name ) ); + DefaultContext context = new DefaultContext(); + context.put( "urn:assembly:classloader", m_engine ); + context.put( "urn:merlin:block.manifest", manifest ); + context.makeReadOnly(); + block.contextualize( context ); + block.initialize(); + return block; + } + //============================================================== // Startable //============================================================== @@ -398,6 +451,13 @@ getLogger().debug( "bootstrap engine" ); } + LibraryDescriptor extensions = + m_creator.createLibraryDescriptor( + config.getChild( "library" ) ); + + ClasspathDescriptor classpath = + m_creator.createClasspathDescriptor( config.getChild( "classpath" ) ); + try { EngineClassLoader engine = new EngineClassLoader(); @@ -406,6 +466,8 @@ DefaultContext context = new DefaultContext(); context.put( "urn:avalon:home", m_home ); context.put( "urn:assembly:engine.bootstrap", "true" ); + context.put( "urn:assembly:engine.extensions", extensions ); + context.put( "urn:assembly:engine.classpath", classpath ); context.makeReadOnly(); engine.contextualize( context ); DefaultServiceManager manager = new DefaultServiceManager(); @@ -427,24 +489,31 @@ return m_local; } - private boolean isBlock( JarFile jar ) + private boolean isBlock( Manifest manifest ) + { + if( manifest == null ) + { + return false; + } + return ( manifest.getAttributes( Block.AVALON_BLOCK_KEY ) != null ); + } + + private Manifest getManifest( URL url ) { try { - Manifest manifest = jar.getManifest(); - if( manifest == null ) - { - return false; - } - return ( manifest.getAttributes( Block.AVALON_BLOCK_KEY ) != null ); + JarURLConnection connection = (JarURLConnection) url.openConnection(); + JarFile jar = connection.getJarFile(); + return jar.getManifest(); } catch( IOException ioe ) { final String error = - "Unexpected IO Exception while reading manifest on jarfile: " + jar.getName(); + "Unexpected IO Exception while reading manifest on url: " + url; throw new RuntimeException( error ); } } + /** * Return a string representation of the kernel. 1.1 avalon-sandbox/merlin/src/test/config/block.xml Index: block.xml =================================================================== <!-- Merlin default kernel configuration. --> <block> <!-- Defintion of the default logging priorities. --> <categories priority="WARN"> <category priority="DEBUG" name="/sys" /> </categories> <!-- Configuration of the component management engine that will be supplied to the block during deployment. --> <engine> <!-- Declaration of supplimentary extension directories. --> <!-- <library dir="."> <include name="build/lib"/> </library> --> <!-- Declaration of the location of additional supporting jar files not accessible as extensions. --> <classpath> <fileset dir="build/lib"> <include name="avalon-merlin-demo-2.0.jar"/> </fileset> </classpath> </engine> <!-- Declaration the block implemetation. --> <container> <import/> <component name="basic" class="org.apache.excalibur.playground.BasicComponent" activation="startup"> <categories priority="DEBUG"/> <context class="org.apache.excalibur.playground.BasicContext"> <entry key="location">My Place</entry> <import name="avalon:home" key="home" /> </context> </component> <export> <reference type="org.apache.excalibur.playground.BasicService"/> </export> </container> <!-- Declaration of any subsidiary blocks. --> <blocks> <!-- <fileset dir="build/lib"> <include name="xxx.jar"/> </fileset> --> </blocks> </block> 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/merlin/kernel/KernelTestCase.java Index: KernelTestCase.java =================================================================== package org.apache.avalon.merlin.kernel; import java.io.File; import java.io.IOException; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.FileNotFoundException; import java.util.StringTokenizer; import java.util.Enumeration; import java.util.List; import java.util.Iterator; import java.util.jar.JarFile; import java.util.ArrayList; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.net.URLClassLoader; import java.net.URL; import java.util.zip.ZipEntry; import java.net.MalformedURLException; import java.net.JarURLConnection; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.DefaultContext; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.merlin.block.Block; import org.apache.avalon.merlin.block.DefaultBlock; import org.apache.avalon.merlin.kernel.DefaultKernel; import org.apache.avalon.merlin.kernel.KernelException; import org.apache.avalon.assembly.util.ExceptionHelper; import junit.framework.TestCase; public class KernelTestCase extends TestCase { private DefaultKernel m_kernel; public KernelTestCase( ) { this( "kernel" ); } public KernelTestCase( String name ) { super( name ); } public void testDefaultKernel() throws Exception { String[] args = new String[]{ "kernel.xml" }; m_kernel = new DefaultKernel(); try { Runtime.getRuntime().addShutdownHook( new Thread() { public void run() { try { m_kernel.stop(); } catch( Throwable e ) { // ignore it } finally { m_kernel.dispose(); } } } ); } catch( IllegalStateException ise ) { if( m_kernel != null ) { try { m_kernel.stop(); } catch( Throwable e ) { // ignore it } finally { m_kernel.dispose(); } } return; } File base = getWorkingDirectory(); DefaultContext context = new DefaultContext(); context.put( "urn:urn:avalon:home", base ); context.makeReadOnly(); File file = getConfigurationFile( base, args ); if( !file.exists() ) { final String error = "Missing kernel configuration: " + file; throw new RuntimeException( error ); } Configuration config; try { config = getConfiguration( file ); } catch( Throwable e ) { final String error = "Problem loading kernel configuration form file: " + file; throw new RuntimeException( error ); } try { m_kernel.configure( config ); m_kernel.contextualize( context ); m_kernel.initialize(); m_kernel.start(); } catch( KernelException e ) { // its already been logged } catch( Throwable e ) { final String error = "Controller deployment failure."; ExceptionHelper.printException( error, e, null, true ); m_kernel.dispose(); } } /** * Get the target configuration file. * @param args the command line arguments */ public File getConfigurationFile( File base, String[] args ) { String filename; if( args.length > 0 ) { filename = args[ 0 ]; } else { filename = "kernel.xml"; } return new File( base, filename ); } /** * Get the target configuration file. * @param args the command line arguments */ public File getWorkingDirectory( ) { return new File( System.getProperty( "user.dir" ) ); } private Configuration getConfiguration( final File file ) throws ConfigurationException { try { DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); InputStream is = new FileInputStream( file ); if( is == null ) { throw new ConfigurationException( "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 ConfigurationException( error, e ); } } } 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicComponent.java Index: BasicComponent.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.avalon.playground; import java.io.File; import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.activity.Startable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.Contextualizable; 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]">Avalon Development Team</a> */ public class BasicComponent extends AbstractLogEnabled implements Contextualizable, Configurable, Initializable, Startable, Disposable, BasicService { private String m_location; private String m_message; private File m_home; //======================================================================= // Contextualizable //======================================================================= /** * Supply of the the component context to the component type. * @param context the context value */ public void contextualize( Context context ) { BasicContextInterface c = (BasicContextInterface)context; m_location = c.getLocation(); m_home = c.getWorkingDirectory(); } //======================================================================= // Configurable //======================================================================= /** * Supply of the the component configuration to the type. * @param config the configuration value */ public void configure( Configuration config ) { getLogger().debug( "configure" ); m_message = config.getChild( "message" ).getValue( null ); } //======================================================================= // Initializable //======================================================================= /** * Initialization of the component type by its container. */ public void initialize() { getLogger().debug( "initialize" ); getLogger().debug( "location: " + m_location ); getLogger().debug( "home: " + m_home ); getLogger().debug( "message: " + m_message ); } //======================================================================= // Startable //======================================================================= /** * Start the component. */ public void start() { doPrimeObjective(); } /** * Stop the component. */ public void stop() { getLogger().info( "stopping" ); } /** * Dispose of the component. */ public void dispose() { getLogger().debug( "dispose" ); } //======================================================================= // BasicService //======================================================================= /** * Service interface implementation. */ public void doPrimeObjective() { getLogger().info( m_message + " from '" + m_location + "'." ); } } 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicComponent.xconfig Index: BasicComponent.xconfig =================================================================== <?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 Avalon Development Team @version 1.0 12/03/2001 --> <!-- The .xconfig file contains the default configuration for the component. --> <configuration> <message>Hello</message> </configuration> 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicComponent.xinfo Index: BasicComponent.xinfo =================================================================== <?xml version="1.0"?> <!DOCTYPE type PUBLIC "-//AVALON/Component Type DTD Version 1.0//EN" "http://jakarta.apache.org/avalon/dtds/meta/type_1_1.dtd" > <!-- 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 Avalon Development Team @version 1.0 12/03/2001 --> <type> <info> <name>basic</name> <!-- <attributes> <attribute key="urn:assembly:appliance.factory-service" value="org.apache.avalon.merlin.block.BlockFactory"/> <attribute key="urn:assembly:appliance.factory-version" value="1.0"/> </attributes> --> </info> <context type="org.apache.avalon.playground.BasicContextInterface"> <entry key="location"/> <entry key="home" type="java.io.File"/> </context> <services> <service> <reference type="org.apache.avalon.playground.BasicService" version="1.1"/> </service> </services> </type> 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicComponent.xprofile Index: BasicComponent.xprofile =================================================================== <?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 Avalon Development Team @version 1.0 12/03/2001 --> <profiles> <!-- A packaged profile is equivalent to a component declaration inside a container, except that it is provided by a component type. A PACKAGED profiles take priority over an IMPLICIT profile. An EXPLICIT profile declared inside a container definition will take priority over PACKAGED profiles. --> <component name="basic"> <context class="org.apache.avalon.playground.BasicContext"> <import name="urn:avalon:home" key="home" /> <entry key="location">Paris</entry> </context> </component> </profiles> 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicContext.java Index: BasicContext.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.avalon.playground; import java.io.File; import java.util.Map; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.DefaultContext; /** * This is example of a custom context class. It is used in the demonsteation * of a context management fraework to show how a context class can be * supplied to a component declaring a context interface criteria. * * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> */ public class BasicContext extends DefaultContext implements BasicContextInterface { /** * Creation of a new custom context instance. * @param map the context name/value map * @param parent a possibly parent context */ public BasicContext( Map map, Context parent ) { super( map, parent ); } /** * @return the location */ public String getLocation() { try { return (String)super.get( "location" ); } catch( Throwable e ) { return "Unknown"; } } /** * @return the working directory */ public File getWorkingDirectory() { try { return (File)super.get( "home" ); } catch( Throwable e ) { throw new RuntimeException( "context object does not provide required home entry." ); } } } 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicContextInterface.java Index: BasicContextInterface.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.avalon.playground; import java.io.File; import org.apache.avalon.framework.context.Context; /** * Simple non-standard Context interface to demonstration context * management at the level of different context types. * * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> */ public interface BasicContextInterface extends Context { /** * @return a string containing a location value */ String getLocation(); /** * @return a file representing the working directory */ File getWorkingDirectory(); } 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicService.java Index: BasicService.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software * itself, if and wherever such third-party acknowledgments * normally appear. * * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.avalon.playground; /** * The <code>BasicService</code> executes a prime objective. * * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> */ public interface BasicService { /** * Execute the prime objective of this services. */ void doPrimeObjective(); } 1.1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/BasicService.xservice Index: BasicService.xservice =================================================================== <?xml version="1.0"?> <!DOCTYPE type PUBLIC "-//AVALON/Component Type DTD Version 1.0//EN" "http://jakarta.apache.org/avalon/dtds/meta/type_1_1.dtd" > <!-- 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 Avalon Development Team @version 1.0 12/03/2001 --> <service> <version>1.1</version> <attributes> <attribute key="urn:avalon:service.name" value="basic"/> <attribute key="urn:avalon:service.description"> A demonstration service used within the scope of the Avalon playground package for educational and unit testing purposes. </attribute> </attributes> </service>
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>