mcconnell    02/03/03 07:45:59

  Modified:    enterprise/tools/lib avalon-framework.jar
  Added:       enterprise/tools/etc overview.html
               enterprise/tools/lib .cvsignore merlin.jar
               enterprise/tools/src/etc LICENSE.HTML LICENSE.TXT README.TXT
                        demo.mf license.css loader.mf
               
enterprise/tools/src/java/org/apache/avalon/excalibur/configuration
                        CascadingConfiguration.java package.html
               enterprise/tools/src/java/org/apache/avalon/excalibur/service
                        DefaultServiceManager.java DependencyInfo.java
                        PipelineException.java
                        PipelineRuntimeException.java ServiceContext.java
                        ServiceFactory.java ServiceInfo.java
                        ServiceLoader.java ServiceLoaderContext.java
                        ServiceProvider.java ServiceRegistry.java
                        SingletonProvider.java TransientProvider.java
                        UnitInfo.java package.html
               enterprise/tools/src/java/org/apache/avalon/excalibur/service/ant
                        Load.java
               enterprise/tools/src/java/org/apache/avalon/phoenix
                        Block.java BlockContext.java
               enterprise/tools/src/java/org/apache/demo
                        DirectoryBlock.java DirectoryBlock.xinfo
                        DirectoryService.java ReferralBlock.java
                        ReferralBlock.xinfo ReferralService.java
  Log:
  addition of service management and service loading framework
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-apps/enterprise/tools/etc/overview.html
  
  Index: overview.html
  ===================================================================
    <body> 
    </body>
  
  
  
  1.2       +33 -28    
jakarta-avalon-apps/enterprise/tools/lib/avalon-framework.jar
  
        <<Binary file>>
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/lib/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  merlin.jar
  
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/lib/merlin.jar
  
        <<Binary file>>
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/src/etc/LICENSE.HTML
  
  Index: LICENSE.HTML
  ===================================================================
  <HTML>
  <HEAD>
        <LINK rel="stylesheet" type="text/css" href="license.css" title="index">
        <TITLE>Persistent State Service (PSS) License and Due Credits</TITLE>
        <META name="description" 
                content="Persistent State Service (PSS) Open Source License">
        <META name="keywords" content="pss, omg, apache, osm">
  </HEAD>
  
  <BODY BGCOLOR="#ffffff">
  
        <p class="title">Persistent State Service (PSS) <br>Disclaimers, 
Licenses and Due Credits</p>
  
        <hr>
  
  <p class="sub-title">The Apache Software License, Version 1.1</p>
  
  <pre class="pre">
  
   Copyright (C) 1997-2001 The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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", "Excalibur", "Avalon Framework" 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 (INCLU-
   DING, 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/>.
  </pre>
  
        <hr>
  
  Initial submissions of the service management utilities provided under the 
  Excalibur Service package together with cascading configuration utilities 
  have been provided by OSM <a href="http://www.osm.net";>http://www.osm.net</a>.
  
  </body>
  </html>
  
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/src/etc/LICENSE.TXT
  
  Index: LICENSE.TXT
  ===================================================================
  
  Disclaimers, Licenses and Due Credits
  
  
================================================================================
  The Apache Software License, Version 1.1
  
================================================================================
  
   Copyright (C) 1997-2001 The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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", "Excalibur", "Avalon Framework" 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 (INCLU-
   DING, 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/>.
  
  
================================================================================
  Due Credits
  
================================================================================
  
  Initial submissions of the service management utilities provided under the 
  Excalibur Service package together with cascading configuration utilities 
  have been provided by OSM http://www.osm.net.
  
  
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/src/etc/README.TXT
  
        <<Binary file>>
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/src/etc/demo.mf
  
  Index: demo.mf
  ===================================================================
  Manifest-Version: 1.0
  
  Name: org/apache/demo/DirectoryBlock.class
  Avalon-Block: true
  
  Name: org/apache/demo/ReferralBlock.class
  Avalon-Block: true
  
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/src/etc/license.css
  
  Index: license.css
  ===================================================================
  
  A:link {color: blue}
  A:visited {color: lightslategray}
  A:active {color: blue}
  
  H1 { 
        font-size: 12pt; color: black;  font-style: normal;  font-weight: 
normal;
        margin-left: 9px; margin-top: 20px; margin-bottom: 12px; font-family: 
serif;
        }
  
  .logo {
        position:absolute; 
        top:35px; left:0px;
        }
  
  .title { 
        font-size: 12pt; color: black;  
        margin-left: 9px; margin-top: 120px; margin-bottom: 12px;
        }
        
  .title2 { 
        font-size: 12pt; color: black;  
        margin-left: 9px; margin-top: 20px; margin-bottom: 12px;
        }
        
  .cover { 
        horizontal-align: center; text-align: center; 
        margin-left: 9px; margin-top: 3px; margin-bottom: 3px;
        }
        
  .sub-title { 
        font-size: 12pt; color: black; 
        margin-left: 9px; margin-top: 6px; margin-bottom: 12px;  
        }
  
  .pre { 
        margin-left: 37px;
       }
        
  .map { 
        horizontal-align: center; text-align: center; 
        margin: 3px; margin-top: 48px;
        }
        
  .picture { 
        horizontal-align: center; text-align: center; 
        margin: 9px;
        }
        
  .figure { 
        horizontal-align: center; text-align: center; font-style: italic; 
        margin: 36px;
        }
  
  .icon { 
        vertical-align: bottom; 
        margin-left: 3px; margin-top: 24px; margin-right 24px;
        }
        
  .note { 
        vertical-align: bottom; 
        margin-left: 24px; margin-top: 3px; margin-right: 60px;
        font-style: italic; 
        }
        
  .menu { 
        vertical-align: bottom; font-size: 10pt; font-style: italic; color: 
black; 
        margin-left: 9px; margin-top: 9px;  margin-bottom: 6px;
        }
        
  .menu2 { 
        vertical-align: bottom; font-size: 10pt; font-style: italic; color: 
black; 
        margin-left: 37px; margin-top: 3px;  margin-bottom: 3px;
        }
        
  .item { 
        vertical-align: bottom; font-size: 10pt; font-style: italic; color: 
black; 
        margin-left: 9px; margin-top: 9px; margin-bottom: 6px;
        }
        
  
  .body { 
        margin-left: 9px; font-size: 12pt; 
        }
  
  .legal { 
        vertical-align: bottom; font-size: 10pt; color: black; 
        margin-left: 9px;
        }
  
  
  
  1.1                  jakarta-avalon-apps/enterprise/tools/src/etc/loader.mf
  
  Index: loader.mf
  ===================================================================
  Manifest-Version: 1.0
  Main-Class: org.apache.avalon.excalibur.service.ServiceLoader
  Class-Path: avalon-framework.jar logkit-1.0.jar
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/configuration/CascadingConfiguration.java
  
  Index: CascadingConfiguration.java
  ===================================================================
  /**
   * File: CascadingConfiguration.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2001-2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.configuration;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  
  /**
   * The CascadingConfiguration is a classic Configuration backed by parent 
   * Configuration.  Operations such as getChild return a CascadingConfiguration
   * encapsulating both a primary and parent configuration.  Requests for 
attribute
   * values are resolved against the base configuration initially.  If the 
result
   * of the resolution is unsucessful, the request is applied against the parent
   * configuration.  As a parent may also be a CascadingConfiguration, the 
evaluation
   * will be applied until a value is resolved against a class parent 
Configuration.
   * @author Stephen McConnell <[EMAIL PROTECTED]>
   */
  public class CascadingConfiguration implements Configuration
  {
      
//=============================================================================
      // state
      
//=============================================================================
  
      private final Configuration m_base;
      private final Configuration m_parent;
  
      
//=============================================================================
      // constructors
      
//=============================================================================
  
      /**
       * Create a CascadingConfiguration with specified parent.  The base
       * configuration shall override a parent configuration on request for 
       * attribute values and configuration body values.  Unresolved request
       * are redirected up the parent chain until a classic configuration is
       * reached.  Request for child configurations will return a 
       * new CascadingConfiguration referencing the child of the base and 
       * the child of the primary (i.e. a child configuration chain).
       *
       * @param base the base Configuration
       * @param parent the parent Configuration 
       */
      public CascadingConfiguration( final Configuration base , final 
Configuration parent )
      {
          if( base == null ) 
          {
              m_base = new DefaultConfiguration( "-", null );
          }
          else
          {
              m_base = base;
          }
          if( parent == null ) 
          {
              m_parent = new DefaultConfiguration( "-", null );
          }
          else
          {
              m_parent = parent;
          }
      }
  
      
//=============================================================================
      // Configuration
      
//=============================================================================
  
      /**
       * Return the name of the base node.
       * @return name of the <code>Configuration</code> node.
       */
      public String getName()
      {
          return m_base.getName();
      }
  
      /**
       * Return a string describing location of the base Configuration.
       * Location can be different for different mediums (ie "file:line" for 
normal XML files or
       * "table:primary-key" for DB based configurations);
       *
       * @return a string describing location of Configuration
       */
      public String getLocation()
      {
          return m_base.getLocation();
      }
  
      /**
       * Returns the namespace the main Configuration node
       * belongs to.
       * @since 4.1
       * @return a Namespace identifying the namespace of this Configuration.
       */
      public String getNamespace() throws ConfigurationException
      {
          return m_base.getNamespace();
      }
  
      /**
       * Return a new <code>CascadingConfiguration</code> instance 
encapsulating the
       * specified child node of the base and parent node.
       *
       * @param child The name of the child node.
       * @return Configuration
       */
      public Configuration getChild( String child )
      {
          return new CascadingConfiguration( m_base.getChild( child ), 
m_parent.getChild( child ) );
      }
  
      /**
       * Return a <code>Configuration</code> instance encapsulating the 
specified
       * child node.
       *
       * @param child The name of the child node.
       * @param createNew If <code>true</code>, a new <code>Configuration</code>
       * will be created and returned if the specified child does not exist in 
either
       * the base or parent configuratioin. If <code>false</code>, 
<code>null</code> 
       * will be returned when the specified child doesn't exist in either the 
base or 
       * the parent.
       * @return Configuration
       */
      public Configuration getChild( String child, boolean createNew )
      {
          if( createNew ) return getChild( child );
          Configuration c = m_base.getChild( child, false );
          if( child != null ) return c;
          return m_parent.getChild( child, false );
      }
  
      /**
       * Return an <code>Array</code> of <code>Configuration</code>
       * elements containing all node children of both base and parent 
configurations. 
       * The array order will reflect the order in the source config file, 
commencing
       * with the base configuration.
       *
       * @return All child nodes 
       */
      public Configuration[] getChildren()
      {
          Configuration[] b = m_base.getChildren( );
          Configuration[] p = m_parent.getChildren( );
          Configuration[] result = new Configuration[ b.length + p.length ];
          System.arraycopy(b, 0, result, 0, b.length );
          System.arraycopy(p, 0, result, b.length, p.length );
          return result;
      }
  
      /**
       * Return an <code>Array</code> of <code>Configuration</code>
       * elements containing all node children with the specified name from 
       * both base and parent configurations. The array
       * order will reflect the order in the source config file commencing 
       * with the base configuration.
       *
       * @param name The name of the children to get.
       * @return The child nodes with name <code>name</code>
       */
      public Configuration[] getChildren( String name )
      {
          Configuration[] b = m_base.getChildren( name );
          Configuration[] p = m_parent.getChildren( name );
          Configuration[] result = new Configuration[ b.length + p.length ];
          System.arraycopy(b, 0, result, 0, b.length );
          System.arraycopy(p, 0, result, b.length, p.length );
          return result;
      }
  
      /**
       * Return an array of all attribute names in both base and parent.
       * <p>
       * <em>The order of attributes in this array can not be relied on.</em> As
       * with XML, a <code>Configuration</code>'s attributes are an
       * <em>unordered</em> set. If your code relies on order, eg
       * <tt>conf.getAttributeNames()[0]</tt>, then it is liable to break if a
       * different XML parser is used.
       * </p>
       */
      public String[] getAttributeNames()
      {
          java.util.Vector vector = new java.util.Vector();
          String[] names = m_base.getAttributeNames();
          String[] names2 = m_parent.getAttributeNames();
          for( int i=0; i<names.length; i++ )
          {
              vector.add( names[i] );
          }
          for( int i=0; i<names2.length; i++ )
          {
              if( vector.indexOf( names2[i] ) < 0 ) vector.add( names2[i] );
          }
          return (String[]) vector.toArray( new String[0] );
      }
  
      /**
       * Return the value of specified attribute.  If the base configuration
       * does not contain the attribute, the equivialent operation is applied 
to 
       * the parent configuration.
       *
       * @param paramName The name of the parameter you ask the value of.
       * @return String value of attribute.
       * @exception ConfigurationException If no attribute with that name 
exists.
       */
      public String getAttribute( String paramName ) throws 
ConfigurationException
      {
          try
          {
              return m_base.getAttribute( paramName );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttribute( paramName );
          }
      }
  
      /**
       * Return the <code>int</code> value of the specified attribute contained
       * in this node or the parent.
       * @param paramName The name of the parameter you ask the value of.
       * @return int value of attribute
       * @exception ConfigurationException If no parameter with that name 
exists.
       *                                   or if conversion to <code>int</code> 
fails.
       */
      public int getAttributeAsInteger( String paramName ) throws 
ConfigurationException
      {
          try
          {
              return m_base.getAttributeAsInteger( paramName );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsInteger( paramName );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>long</code>.
       *
       * @param paramName The name of the parameter you ask the value of.
       * @return long value of attribute
       * @exception ConfigurationException If no parameter with that name 
exists.
       *                                   or if conversion to 
<code>long</code> fails.
       */
      public long getAttributeAsLong( String name ) throws 
ConfigurationException
      {
          try
          {
              return m_base.getAttributeAsLong( name );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsLong( name );
          }
      }
  
  
      /**
       * Return the <code>float</code> value of the specified parameter 
contained
       * in this node.
       * @param paramName The name of the parameter you ask the value of.
       * @return float value of attribute
       * @exception ConfigurationException If no parameter with that name 
exists.
       *                                   or if conversion to 
<code>float</code> fails.
       */
      public float getAttributeAsFloat( String paramName ) throws 
ConfigurationException
      {
          try
          {
              return m_base.getAttributeAsFloat( paramName );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsFloat( paramName );
          }
      }
  
  
      /**
       * Return the <code>boolean</code> value of the specified parameter 
contained
       * in this node.<br>
       *
       * @param paramName The name of the parameter you ask the value of.
       * @return boolean value of attribute
       * @exception ConfigurationException If no parameter with that name 
exists.
       *                                   or if conversion to 
<code>boolean</code> fails.
       */
      public boolean getAttributeAsBoolean( String paramName ) throws 
ConfigurationException
      {
          try
          {
              return m_base.getAttributeAsBoolean( paramName );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsBoolean( paramName );
          }
      }
  
      /**
       * Return the <code>String</code> value of the node.
       *
       * @return the value of the node.
       */
      public String getValue() throws ConfigurationException
      {
          try
          {
              return m_base.getValue();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValue();
          }
      }
  
  
      /**
       * Return the <code>int</code> value of the node.
       *
       * @exception ConfigurationException If conversion to <code>int</code> 
fails.
       */
      public int getValueAsInteger() throws ConfigurationException
      {
          try
          {
              return m_base.getValueAsInteger();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsInteger();
          }
      }
  
      /**
       * Return the <code>float</code> value of the node.
       *
       * @return the value of the node.
       * @exception ConfigurationException If conversion to <code>float</code> 
fails.
       */
      public float getValueAsFloat() throws ConfigurationException
      {
          try
          {
              return m_base.getValueAsFloat();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsFloat();
          }
      }
  
      /**
       * Return the <code>boolean</code> value of the node.
       *
       * @return the value of the node.
       * @exception ConfigurationException If conversion to 
<code>boolean</code> fails.
       */
      public boolean getValueAsBoolean() throws ConfigurationException
      {
          try
          {
              return m_base.getValueAsBoolean();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsBoolean();
          }
      }
  
      /**
       * Return the <code>long</code> value of the node.<br>
       *
       * @return the value of the node.
       * @exception ConfigurationException If conversion to <code>long</code> 
fails.
       */
      public long getValueAsLong() throws ConfigurationException
      {
          try
          {
              return m_base.getValueAsLong();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsLong();
          }
      }
  
      /**
       * Returns the value of the configuration element as a 
<code>String</code>.
       * If the configuration value is not set, the default value will be
       * used.
       *
       * @param defaultValue The default value desired.
       * @return String value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      public String getValue( String defaultValue )
      {
          try
          {
              return m_base.getValue();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValue( defaultValue );
          }
      }
  
  
      /**
       * Returns the value of the configuration element as an <code>int</code>.
       * If the configuration value is not set, the default value will be
       * used.
       *
       * @param defaultValue The default value desired.
       * @return int value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      public int getValueAsInteger( int defaultValue )
      {
          try
          {
              return m_base.getValueAsInteger();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsInteger( defaultValue );
          }
      }
  
  
      /**
       * Returns the value of the configuration element as a <code>long</code>.
       * If the configuration value is not set, the default value will be
       * used.
       *
       * @param defaultValue The default value desired.
       * @return long value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      public long getValueAsLong( long defaultValue )
      {
          try
          {
              return m_base.getValueAsLong();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsLong( defaultValue );
          }
      }
  
  
      /**
       * Returns the value of the configuration element as a <code>float</code>.
       * If the configuration value is not set, the default value will be
       * used.
       *
       * @param defaultValue The default value desired.
       * @return float value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      public float getValueAsFloat( float defaultValue )
      {
          try
          {
              return m_base.getValueAsFloat();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsFloat( defaultValue );
          }
      }
  
  
      /**
       * Returns the value of the configuration element as a 
<code>boolean</code>.
       * If the configuration value is not set, the default value will be
       * used.
       *
       * @param defaultValue The default value desired.
       * @return boolean value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      public boolean getValueAsBoolean( boolean defaultValue )
      {
          try
          {
              return m_base.getValueAsBoolean();
          }
          catch( ConfigurationException e )
          {
              return m_parent.getValueAsBoolean( defaultValue );
          }
      }
  
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>String</code>, or the default value if no attribute by
       * that name exists or is empty.
       *
       * @param name The name of the attribute you ask the value of.
       * @param defaultValue The default value desired.
       * @return String value of attribute. It will return the default
       *         value if the named attribute does not exist, or if
       *         the value is not set.
       */
      public String getAttribute( String name, String defaultValue )
      {
          try
          {
              return m_base.getAttribute( name );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttribute( name, defaultValue );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>int</code>, or the default value if no attribute by
       * that name exists or is empty.
       *
       * @param name The name of the attribute you ask the value of.
       * @param defaultValue The default value desired.
       * @return int value of attribute. It will return the default
       *         value if the named attribute does not exist, or if
       *         the value is not set.
       */
      public int getAttributeAsInteger( String name, int defaultValue )
      {
          try
          {
              return m_base.getAttributeAsInteger( name );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsInteger( name, defaultValue );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>long</code>, or the default value if no attribute by
       * that name exists or is empty.
       *
       * @param name The name of the attribute you ask the value of.
       * @param defaultValue The default value desired.
       * @return long value of attribute. It will return the default
       *          value if the named attribute does not exist, or if
       *          the value is not set.
       */
      public long getAttributeAsLong( String name, long defaultValue )
      {
          try
          {
              return m_base.getAttributeAsLong( name );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsLong( name, defaultValue );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>float</code>, or the default value if no attribute by
       * that name exists or is empty.
       *
       * @param name The name of the attribute you ask the value of.
       * @param defaultValue The default value desired.
       * @return float value of attribute. It will return the default
       *          value if the named attribute does not exist, or if
       *          the value is not set.
       */
      public float getAttributeAsFloat( String name, float defaultValue )
      {
          try
          {
              return m_base.getAttributeAsFloat( name );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsFloat( name, defaultValue );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>boolean</code>, or the default value if no attribute by
       * that name exists or is empty.
       *
       * @param name The name of the attribute you ask the value of.
       * @param defaultValue The default value desired.
       * @return boolean value of attribute. It will return the default
       *         value if the named attribute does not exist, or if
       *         the value is not set.
       */
      public boolean getAttributeAsBoolean( String name, boolean defaultValue )
      {
          try
          {
              return m_base.getAttributeAsBoolean( name );
          }
          catch( ConfigurationException e )
          {
              return m_parent.getAttributeAsBoolean( name, defaultValue );
          }
      }
  }
  
  
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/configuration/package.html
  
  Index: package.html
  ===================================================================
  <body>
  <p>Resource supporting extended configuraiton management.</p>
  </body>
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DefaultServiceManager.java
  
  Index: DefaultServiceManager.java
  ===================================================================
  /*
   * File: DefaultServiceManager.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  
  
  /**
   * Internal helper class the implements the service manager interface and 
   * is supplied to dynamically crerated componets during service lifecyle
   * pipeline processing.
   */
  class DefaultServiceManager implements ServiceManager
  {
  
     /**
      * Hashtable containing service providers keyed by role name.  
      * The manager use the providers in this table to aquire services
      * in response to <code>lookup</code> invocations.  Provider 
      * types fall into one of the following three catagories:
      *
      * <table>
      * <tr><td><b>Policy</b></td><td><b>Description</b></td><tr>
      * <tr><td>SINGLETON_LIFETIME_POLICY</td><td>
      * Service of the type singleton are distinguished by the fact 
      * that they do not inherit from Pool or Transient.  The singleton
      * provider object is a reference to the singleton service and is 
      * return directly by the implemetation on invocation of lookup.
      * </td>
      * <tr><td>POOLED_LIFETIME_POLICY</td><td>
      * Pooled services implement the Pool interface.  The service
      * resolves lookup aquires the pooled service by invoking 
      * <code>checkout</code> on the pool implementation. Clients 
      * using pooled services are required to release services using
      * the manager <code>release</code> method.  The implemetation will
      * attempt to locate the issuing pool and release the object on 
      * behalf of the client. 
      * </td>
      * <tr><td>TRANSIENT_LIFETIME_POLICY</td><td>
      * A transient provider is factory from which new instances are 
      * created and pipelined following a invocation of <code>lookup</code>.
      * The invocing client is totally responsible for service disposal.
      * </td>
      */
      private Hashtable m_providers = new Hashtable();
  
      public DefaultServiceManager( Hashtable providers ) throws Exception
      {
          m_providers = providers;
      }
  
      public boolean hasService( String role )
      {
          return (m_providers.get( role ) != null );
      }
  
      public Object lookup( String role ) throws ServiceException
      {
          Object provider = m_providers.get( role );
          if( provider == null ) throw new ServiceException(
              "Could not locate a provider for the role: " + role );
  
          if( provider instanceof TransientProvider )
          {
              //
              // return a transient instance
              //
  
              return ((TransientProvider)provider).create( );
          }
  /*
          else if( provider instanceof PooledProvider )
          {
              //
              // return a pooled service
              //
  
              return ((PooledProvider)provider).checkout( );
          }
  */
          else
          {
              //
              // return a singleton service
              //
  
              return ((SingletonProvider)provider).provide( );
          }
      }
  
      public void release( Object object )
      {
          //
          // release a pooled service
          //
  /*
          Class c = object.getClass();
          Enumeration providers = m_providers.elements();
          while( providers.hasMoreElements()) 
          {
              Object provider = providers.nextElement();
              if( provider instanceof PooledProvider )
              {
                  PooledProvider pool = (PooledProvider) provider;
                  if( pool.getBaseClass().isAssignableFrom( c ) )
                  {
                      pool.release( object );
                      break;
                  }
              }
          }
  */
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DependencyInfo.java
  
  Index: DependencyInfo.java
  ===================================================================
  /*
   * File: DependencyInfo.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import org.apache.avalon.framework.configuration.Configuration;
  
  /**
   * Abstract meta-information that describes a single dependancy that a 
   * <code>Serviceable</code> object may have towards other 
   * components.
   */
  
  class DependencyInfo extends ServiceInfo
  {
      private String m_role;
  
     /**
      * Creation of a new <code<DependencyInfo</code> instance.
      * @param config a configuration corresponding to a &lt;depends&gt; 
statement
      */
      public DependencyInfo( final Configuration config ) throws Exception
      {
          super( config.getChild("service") );
          m_role = config.getChild("role").getValue();
      }
  
     /**
      * Returns the role name that the component uses to lookup a 
      * the dependency.
      * @return the dependecy role name
      * @see org.apache.avalon.framework.service.ServiceManager
      * @see org.apache.avalon.framework.service.Serviceable
      */
      public String getRole()
      {
          return m_role;
      }
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/PipelineException.java
  
  Index: PipelineException.java
  ===================================================================
  /*
   * File: PipelineException.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.StringWriter;
  import java.util.StringTokenizer;
  import java.io.PrintWriter;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Thrown by an Pipeline as a result of an unexpected error 
   * during execution.
   *
   * @author  mcconnell
   * @version 1.0
   */
  
  public class PipelineException extends CascadingException {
  
      /**
       * Construct a new <code>PipelineRuntimeException</code> instance with 
the 
       * supplied message parameter and a null value for the cause exception.
       *
       * @param message Message summarising the exception.
       */
  
      public PipelineException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>PipelineRuntimeException</code> instance with 
the 
       * supplied message parameter and a supplied cause exception.
       *
       * @param message The detail message for this exception.
       * @param cause the root cause of the exception
       */
  
      public PipelineException( final String message, final Throwable cause ) 
      {
          super( message, cause );
      }
  
      public String toString()
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( "\n=================================================" );
          sb.append( "\nException: " + this.getClass().getName() + ", " + 
getMessage());
          if( this.getCause() != null ) appendCause( sb, this.getCause() );
          sb.append( "\n=================================================" );
          return sb.toString();
      }
  
      private void appendCause( StringBuffer buffer, Throwable cause )
      {
          if( cause == null ) return;
          buffer.append( "\nCause: " + cause.getClass().getName() 
            + ", " + cause.getMessage() );
          if( cause.getCause() != null )
          {
              appendCause( buffer, cause.getCause() );
          }
          else
          {
              buffer.append( 
"\n-------------------------------------------------" );
              String[] stack = captureStackTrace( cause );
              for( int i=0; i<stack.length; i++ )
              {
                  buffer.append( "\n" + stack[i] );
              }
          }
      }
  
      private static String[] captureStackTrace( final Throwable throwable )
      {
          final StringWriter sw = new StringWriter();
          throwable.printStackTrace( new PrintWriter( sw, true ) );
          return splitString( sw.toString(), "\n" );
      }
  
      /**
       * Splits the string on every token into an array of stack frames.
       *
       * @param string the string
       * @param onToken the token
       * @return the resultant array
       * @deprecated This is an internal utility method that should not be used
       */
      private static String[] splitString( final String string, final String 
onToken )
      {
          final StringTokenizer tokenizer = new StringTokenizer( string, 
onToken );
          final String[] result = new String[ tokenizer.countTokens() ];
  
          for( int i = 0; i < result.length; i++ )
          {
              result[ i ] = tokenizer.nextToken();
          }
  
          return result;
      }
  
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/PipelineRuntimeException.java
  
  Index: PipelineRuntimeException.java
  ===================================================================
  /*
   * File: PipelineRuntimeException.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.StringWriter;
  import java.util.StringTokenizer;
  import java.io.PrintWriter;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  
  /**
   * Thrown by an Pipeline as a result of an unexpected runtime error 
   * during execution.
   *
   * @author  mcconnell
   * @version 1.0
   */
  
  public class PipelineRuntimeException extends CascadingRuntimeException {
  
      /**
       * Construct a new <code>PipelineRuntimeException</code> instance with 
the 
       * supplied message parameter and a null value for the cause exception.
       *
       * @param message Message summarising the exception.
       */
  
      public PipelineRuntimeException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>PipelineRuntimeException</code> instance with 
the 
       * supplied message parameter and a supplied cause exception.
       *
       * @param message The detail message for this exception.
       * @param cause the root cause of the exception
       */
  
      public PipelineRuntimeException( final String message, final Throwable 
cause ) 
      {
          super( message, cause );
      }
  
      public String toString()
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( "\n=================================================" );
          sb.append( "\nException: " + this.getClass().getName() + ", " + 
getMessage());
          if( this.getCause() != null ) appendCause( sb, this.getCause() );
          sb.append( "\n=================================================" );
          return sb.toString();
      }
  
      private void appendCause( StringBuffer buffer, Throwable cause )
      {
          if( cause == null ) return;
          buffer.append( "\nCause: " + cause.getClass().getName() 
            + ", " + cause.getMessage() );
          if( cause.getCause() != null )
          {
              appendCause( buffer, cause.getCause() );
          }
          else
          {
              buffer.append( 
"\n-------------------------------------------------" );
              String[] stack = captureStackTrace( cause );
              for( int i=0; i<stack.length; i++ )
              {
                  buffer.append( "\n" + stack[i] );
              }
          }
      }
  
      private static String[] captureStackTrace( final Throwable throwable )
      {
          final StringWriter sw = new StringWriter();
          throwable.printStackTrace( new PrintWriter( sw, true ) );
          return splitString( sw.toString(), "\n" );
      }
  
      /**
       * Splits the string on every token into an array of stack frames.
       *
       * @param string the string
       * @param onToken the token
       * @return the resultant array
       * @deprecated This is an internal utility method that should not be used
       */
      private static String[] splitString( final String string, final String 
onToken )
      {
          final StringTokenizer tokenizer = new StringTokenizer( string, 
onToken );
          final String[] result = new String[ tokenizer.countTokens() ];
  
          for( int i = 0; i < result.length; i++ )
          {
              result[ i ] = tokenizer.nextToken();
          }
  
          return result;
      }
  
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceContext.java
  
  Index: ServiceContext.java
  ===================================================================
  /*
   * File: ServiceContext.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.File;
  import org.apache.avalon.phoenix.BlockContext;
  import org.apache.avalon.framework.logger.Logger;
  
  import org.apache.avalon.framework.context.DefaultContext;
  
  /**
   * ServiceContext context object to hold command line arguments and 
   * base directory that is supplied to a <code>Contextualizable</code>
   * component.
   * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   */
  
  public class ServiceContext extends DefaultContext implements BlockContext
  {
  
      public static final String ARGS_KEY = "ARGS";
      public static final String BASE_DIRECTORY_KEY = "APP_DIR";
  
      private String[] m_args;
      private File m_root;
      private String m_name;
      private Logger m_logger;
  
      public ServiceContext( String[] args, File base, String name )
      {
          m_args = args;
          m_root = base;
          m_name = name;
  
          super.put( ARGS_KEY, m_args );
          super.put( BASE_DIRECTORY_KEY, m_root );
      }
  
      public String[] getArgs()
      {
          return m_args;
      }
  
      public File getBaseDirectory()
      {
          return m_root;
      }
  
      public Logger getLogger( String name )
      {
          throw new RuntimeException("Not implemented.");
      }
  
      public String getName()
      {
          return m_name;   
      }
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceFactory.java
  
  Index: ServiceFactory.java
  ===================================================================
  /*
   * File: ServiceFactory.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.File;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.util.Vector;
  
  import org.apache.log.Hierarchy;
  import org.apache.log.Priority;
  import org.apache.log.output.io.StreamTarget;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.logger.LogKitLogger;
  import org.apache.avalon.framework.logger.AvalonFormatter;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  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.framework.component.Component;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.DefaultComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.activity.Disposable;
  
  import org.apache.avalon.excalibur.configuration.CascadingConfiguration;
  
  /**
   * 
   */
  class ServiceFactory extends AbstractLogEnabled implements Disposable
  {
      private Hierarchy m_hierarchy;
      private ServiceRegistry m_registry;
      private Hashtable m_table = new Hashtable();
      private Hashtable m_pools = new Hashtable();
      private Hashtable m_singletons = new Hashtable();
      private Hashtable m_transients = new Hashtable();
      private File m_root;
      private boolean m_verbose;
  
      private Hashtable m_services = new Hashtable();
      private Hashtable m_lookup = new Hashtable();
  
      public ServiceFactory( Hierarchy hierarchy, Configuration config, File 
base, boolean verbose ) throws Exception
      {
          m_hierarchy = hierarchy;
          m_registry = new ServiceRegistry( verbose );
          m_table = initalizeBlockConfigurations( config );
          m_root = base;
          m_verbose = verbose;
      }
  
      public void enableLogging( Logger logger )
      {
          super.enableLogging( logger );
          m_registry.enableLogging( logger.getChildLogger("registry") );
      }
  
     /**
      * Populates the set of available services based on a supplied 
      * vector of jar files.
      * @param list a list of jar files
      */
      public void register( Vector list ) throws PipelineException
      {
          m_registry.register( list );
      }
  
      public void validate( UnitInfo info ) throws Exception
      {
          DependencyInfo[] dependencies = info.getDependencies();
          for( int i=0; i<dependencies.length; i++ )
          {
              ServiceInfo d = dependencies[i];
              if( m_registry.lookup( d ) == null ) throw new Exception(
                 "Could not resolve dependent service " + 
d.getInterface().getName() 
                 + " for block " + info.getClassName() );
          }
      }
  
      private ServiceManager createServiceManager( DependencyInfo[] 
dependencies ) throws ServiceException
      {
          Hashtable providers = new Hashtable();
          try
          {
              for( int i=0; i<dependencies.length; i++ )
              {
                  DependencyInfo info = dependencies[i];
                  providers.put( info.getRole(), getProvider( info ));
              }
              return new DefaultServiceManager( providers );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while attempting to 
create a ServiceManager.";
              throw new ServiceException( error, e );
          }
      }
  
      private Object getProvider( DependencyInfo info ) throws Exception
      {
  
          UnitInfo block_info = m_registry.lookup( info );
  
          //
          // Try to establish the type of object by the interface it implements.
          //
  
          Object provider = null;
          Class provider_class = block_info.getBaseClass();
  
          //
          // Resolve the provider based on meta-infomation in the .xinfo file
          // which will result in a transient service if no other info 
available.
          //
  
          int policy = block_info.getPolicy();
  
          switch( policy )
          {
              case UnitInfo.SINGLETON_LIFETIME_POLICY :
  
                //
                // return a singleton instance
                //
  
                provider = m_singletons.get( provider_class );
                if( provider == null )
                {
                    if( m_verbose ) if( getLogger().isDebugEnabled() ) 
getLogger().debug( 
                      "Creating singleton provider for :" + 
provider_class.getName());
  
                    // create and pipeline the singleton instance and 
                    // add it to the list of singletons
  
                    Object object = pipeline( block_info, info.getRole() );
                    provider = new SingletonProvider( object, info.getRole() );
                    m_singletons.put( provider_class, provider );
                }
                return provider;
  
              case UnitInfo.POOLED_LIFETIME_POLICY :
  
                final String error = "Cannot provide a default provider for a 
pool at this time.";
                throw new RuntimeException( error );
  
              default :
  
                //
                // UnitInfo.TRANSIENT_LIFETIME_POLICY :
                // new service instances are always created on invocation of
                // a service lookup
                //
  
                provider = m_transients.get( provider_class );
                if( provider == null )
                {
                    if( m_verbose ) if( getLogger().isDebugEnabled() ) 
getLogger().debug( 
                      "Creating transient provider for :" + 
provider_class.getName());
  
                    // create and pipeline the singleton instance and 
                    // add it to the list of singletons
  
                    provider = new TransientProvider( this, block_info, 
info.getRole() );
                    m_transients.put( provider_class, provider );
                }
                return provider;
           }
      }
  
      public Object pipeline( UnitInfo info, String role ) throws Exception
      {
  
          //
          // create and pipeline the new instance
          //
  
          Object m_object;
          try
          {
              m_object = info.getBaseClass().newInstance();
          }
          catch( Throwable e )
          {
              final String error = "Failed to instantiate an object: ";
              throw new PipelineException( error + 
info.getBaseClass().getName(), e );
          }
  
          if( m_verbose ) if( getLogger().isDebugEnabled() ) getLogger().debug(
            "pipeline for role: " + role + ", implementation: " + 
m_object.getClass().getName() );
  
  
          //
          // assign a logging channel
          //
  
          if( m_object instanceof LogEnabled ) try
          {
              Logger logger = new LogKitLogger( m_hierarchy.getLoggerFor( role 
) );
              if( m_verbose ) getLogger().debug( "applying logger to " + role );
              ((LogEnabled)m_object).enableLogging( logger );
          }
          catch( Throwable e )
          {
              final String error = "Failed to assign a logger channel.";
              throw new PipelineException( error, e );
          }
  
          //
          // configure the object
          //
  
          if( m_object instanceof Configurable ) try
          {
              if( m_verbose ) getLogger().debug( role + " configuration" );
              Configuration defaults = info.getDefaultConfiguration();
              Configuration primary = getConfigurationForClass( 
info.getClassName() );
              ((Configurable)m_object).configure( new CascadingConfiguration( 
primary, defaults ));
          }
          catch( Throwable e )
          {
              final String error = "Failed to configure an object.";
              throw new PipelineException( error, e );
          }
          else if( m_object instanceof Parameterizable ) try
          {
              if( m_verbose ) getLogger().debug( role + " parameterization" );
              ((Parameterizable)m_object).parameterize( 
                  Parameters.fromConfiguration( getConfigurationForClass( 
info.getClassName() ) ) );
          }
          catch( Throwable e )
          {
              final String error = "Failed to parameterize an object.";
              throw new PipelineException( error, e );
          }
  
          //
          // contextualize the server
          // [need to update this to handle an args sequence]
          //
  
          if( m_object instanceof Contextualizable ) try
          {
              if( m_verbose ) getLogger().debug( role + " contextualization" );
              Context context = new ServiceContext( 
                new String[0], m_root, info.getClassName() );
              ((Contextualizable)m_object).contextualize( context );
          }
          catch( Throwable e )
          {
              final String error = "Failed to contextualize the object.";
              throw new PipelineException( error, e );
          }
  
          //
          // get the blocks required to support the dependencies
          //
  
          if( m_object instanceof Serviceable ) try
          {
              if( m_verbose ) getLogger().debug( role + " service composition" 
);
              DependencyInfo[] dependencies = info.getDependencies();
              ServiceManager manager = createServiceManager( dependencies );
              ((Serviceable)m_object).service( manager );
          }
          catch( Throwable e )
          {
              final String error = "Failed to service the object.";
              throw new PipelineException( error, e );
          }
          else if( m_object instanceof Composable ) try
          {
              if( m_verbose ) getLogger().debug( role + " composition" );
              DefaultComponentManager manager = new DefaultComponentManager();
              DependencyInfo[] dependencies = info.getDependencies();
              for( int i=0; i<dependencies.length; i++ )
              {
                  DependencyInfo dependency = dependencies[i];
                  String dependency_role = dependency.getRole();
                  UnitInfo block_info = m_registry.lookup( dependency );
                  Object object = pipeline( block_info, dependency_role );
                  manager.put( dependency_role, (Component) object );
              }
              ((Composable)m_object).compose( manager );
          }
          catch( Throwable e )
          {
              final String error = "Failed to compose the object.";
              throw new PipelineException( error, e );
          }
  
          //
          // initialize the object
          //
  
          if( m_object instanceof Initializable ) try
          {
              if( m_verbose ) getLogger().debug( role + " initilization" );
              ((Initializable)m_object).initialize();
          }
          catch( Throwable e )
  
          {
              final String error = "Failed to initilize the object.";
              throw new PipelineException( error, e );
          }
  
          //
          // start the object
          //
  
          if( m_object instanceof Startable ) try
          {
              if( m_verbose ) getLogger().debug( "starting " + role );
              ((Startable)m_object).start();
          }
          catch( Throwable e )
          {
              final String error = "Failed to start the service.";
              throw new PipelineException( error, e );
          }
  
          return m_object;
      }
  
     /**
      * Notification byb the controlling application to dispose of the 
      * service factory.
      */
      public void dispose()
      {
          //
          // dispose of all of the service pools
          //
  
          if( m_verbose ) if( getLogger().isDebugEnabled() ) getLogger().debug( 
            "pool disposal (" + m_pools.size() + ")");
          Enumeration pools = m_pools.elements();
          while( pools.hasMoreElements() )
          {
              
              Object pool = pools.nextElement();
              if( pool instanceof Disposable )
              {
                  try
                  {
                      ((Disposable)pool).dispose();
                  }
                  catch( Throwable e )
                  {
                      final String warning = "Ignoring exception while invoking 
pool disposal.";
                      if( getLogger().isWarnEnabled() ) getLogger().warn( 
warning, e );
                  }
              }
          }
  
          //
          // dispose of all of the service singletons
          //
  
          if( m_verbose ) if( getLogger().isDebugEnabled() ) getLogger().debug( 
             "singleton disposal (" + m_singletons.size() + ")");
          Enumeration singletons = m_singletons.elements();
          while( singletons.hasMoreElements() )
          {
              Object singleton = singletons.nextElement();
              if( singleton instanceof Disposable )
              {
                  try
                  {
                      ((Disposable)singleton).dispose();
                  }
                  catch( Throwable e )
                  {
                      final String warning = "Ignoring exception while invoking 
singleton provider disposal.";
                      if( getLogger().isWarnEnabled() ) getLogger().warn( 
warning, e );
                  }
              }
          }
  
          //
          // dispose of all of the transient service providers
          //
  
          if( m_verbose ) if( getLogger().isDebugEnabled() ) getLogger().debug( 
            "transient disposal (" + m_transients.size() + ")");
          Enumeration transients = m_transients.elements();
          while( transients.hasMoreElements() )
          {
              Object object = transients.nextElement();
              if( object instanceof Disposable )
              {
                  try
                  {
                      ((Disposable)object).dispose();
                  }
                  catch( Throwable e )
                  {
                      final String warning = "Ignoring exception while invoking 
transient provider disposal.";
                      if( getLogger().isWarnEnabled() ) getLogger().warn( 
warning, e );
                  }
              }
          }
      }
  
      //==========================================================
      // configuration
      //==========================================================
  
     /**
      * Creates a hashtable of configurations keyed by the block implmentation
      * class name.  The configuration file is ssumed to in the following form.
      * <pre>
      *     &lt;block class="org.apache.demo.MyFirstBlock"&gt;
      *        &lt;any-child value="red"/&gt;
      *     &lt;/block&gt;
      * 
      *     &lt;k class="org.apache.demo.MySecondBlock"/&gt;
      * </pre>
      */
      private Hashtable initalizeBlockConfigurations( Configuration config ) 
throws ConfigurationException
      {
          Hashtable configs = new Hashtable();
          Configuration[] blocks = config.getChildren("block");
          for( int i=0; i<blocks.length; i++ )
          {
              final String key = blocks[i].getAttribute("class");
              configs.put( key, blocks[i] );
          }
          return configs;
      }
  
      private Configuration getConfigurationForClass( String name )
      {
          Configuration config = (Configuration) m_table.get( name );
          if( config != null ) return config;
          return new DefaultConfiguration( name, null );
      }
  
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceInfo.java
  
  Index: ServiceInfo.java
  ===================================================================
  /*
   * File: ServiceInfo.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.configuration.Configuration;
  
  /**
   * Meta-information about a particular <code>service</code> exposed by a 
component.
   */
  
  class ServiceInfo
  {
  
      private Class m_interface;
      private Version m_version;
      
     /**
      * Creation of a new <code>ServiceInfo</code> instance.
      */
      public ServiceInfo( Configuration config ) throws Exception
      {
          ClassLoader loader = Thread.currentThread().getContextClassLoader( ); 
          m_interface = loader.loadClass( config.getAttribute("name") );
          m_version = Version.getVersion( config.getAttribute("version") );
      }
  
     /**
      * Equality test.
      * @return TRUE if this instance is equal to the supplied instance, where 
      *   equality is derived from equivalent interface values and versions.
      */
      public boolean equals( Object object )
      {
          if( object instanceof ServiceInfo ) return equals( (ServiceInfo) 
object );
          return false;
      }
  
     /**
      * Equality test.
      * @return TRUE if this instance is equal to the supplied instance, where 
      *   equality is derived from equivalent interface values and versions.
      */
      public boolean equals( ServiceInfo other )
      {
          if( !other.getInterface().isAssignableFrom( m_interface ) ) return 
false;
          return m_version.equals( other.getVersion() ); 
      }
  
     /**
      * Returns the class representing the service interface.
      * @return the service interface
      */
      public Class getInterface()
      {
          return m_interface;
      }
  
     /**
      * Returns the service version.
      * @return the service version
      */
      public Version getVersion()
      {
          return m_version;
      }
  
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceLoader.java
  
  Index: ServiceLoader.java
  ===================================================================
  /*
   * File: ServiceLoader.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.File;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.net.MalformedURLException;
  import java.util.jar.JarFile;
  import java.util.jar.Attributes;
  import java.util.jar.Attributes.Name;
  import java.util.Vector;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.FileInputStream;
  
  import org.apache.log.Hierarchy;
  import org.apache.log.Priority;
  import org.apache.log.output.io.StreamTarget;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.logger.LogKitLogger;
  import org.apache.avalon.framework.logger.AvalonFormatter;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  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.framework.component.Component;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.DefaultComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.activity.Disposable;
  
  /**
   * A service loader that loads a target class, manages full component 
lifecycle
   * processing for the target and dependent services, and service 
decommissioning.
   *
   * <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
   * <tr bgcolor="#ccccff">
   * <td colspan="2"><b>Pipeline Lifecycle Phases</b></td>
   * <tr><td width="20%"><b>Phase</b></td><td><b>Description</b></td></tr>
   * <tr>
   * <td width="20%" valign="top">Configurable</td>
   * <td>
   * The configuration phase supplies static information to the pipeline 
processor
   * that may be used to configure target and supporting services.  During the 
loading
   * of a component, the pipline processor will attempt to locate a block 
configuration
   * based on the class name of the block.  If there is no configuration 
matching the 
   * class name an empty configuration will be supplied to the component or a 
component
   * the the target component is depedant on (assuming the component in 
question 
   * implements the Configurable interface).
   *
   * <pre>
   * &lt;config&gt;
   *
   *   &lt;block class="com.magic.DirectoryBlock"&gt;
   *     &lt;-- block specific content --&gt;
   *   &lt;/block&gt;
   *
   *   &lt;block class="com.magic.ActivatorBlock"&gt;
   *     &lt;-- block specific content --&gt;
   *   &lt;/block&gt;
   *
   * &lt;/config&gt;
   * </pre>
   * </td></tr>
   * <tr>
   * <td width="20%" valign="top">Contextualizable</td>
   * <td>
   * The contextualization phase hadles the capture of runtime context 
information
   * needed by the pipeline processor.  This information must be provided in 
the 
   * for of a <code>ServiceLoaderContext</code> otherwise the contextualize 
method will
   * throw an exception.  The following information is provided by the 
   * <code>ServiceLoaderContext</code>:
   * <p><table border="0" cellpadding="3" cellspacing="0" width="100%">
   * <tr>
   * <td width="20%" valign="top"><code>ARGS_KEY</code></td>
   * <td>
   * Contains the command line arguments as a <code>String[]</code>. 
   * </td></tr>
   * <tr>
   * <td width="20%" valign="top"><code>BASE_DIRECTORY_KEY</code></td>
   * <td>
   * Contains the application base directory <code>File</code>. 
   * </td></tr>
   * <tr>
   * <td width="20%" valign="top"><code>TARGET_KEY</code></td>
   * <td>
   * Contains the name of the target class to be instantiated. 
   * </td></tr>
   * <tr>
   * <td width="20%" valign="top"><code>INCLUDES_KEY</code></td>
   * <td>
   * Contains an array of jar files that will be added to the pipeline 
classloader.
   * Jar files included in the array will be checked for block manifest 
entries.  If 
   * block entries exist that will be registered as potetentially available 
services
   * that may be instantiated during the recursive dependecy resolution 
process. 
   * </td></tr>
   * <tr>
   * <td width="20%" valign="top"><code>CONFIGURATION_FILE_KEY</code></td>
   * <td>
   * A <code>File</code> instance that may or may not exist. If the file exists 
and is 
   * confiugration, it will be used as the base configuration reference when 
looking up
   * service configuration details.  The default behaviour is to look for a 
file named
   * "config.xml" in the user's working directory. 
   * </td></tr>
   * <tr>
   * <td width="20%" valign="top"><code>DISPOSAL_POLICY_KEY</code></td>
   * <td>
   * A <code>Boolean</code> value that is applied on completionof the startup 
of a 
   * <code>Startable</code> component.  If the value TRUE, the component is 
stopped 
   * and disposed of (including termination of all dependencies) immediately 
following
   * startup.  This policy only applies to <code>Startable</code> components.  
Setting
   * policy value to FALSE ensures that the component can respond as a server.  
Non
   * <code>Startable</code> target component are immediately terminated 
(providing a 
   * useful for component testing during development cycles).
   * </td></tr>
   * <td width="20%" valign="top"><code>LOGGING_PRIORITY_KEY</code></td>
   * <td>
   * Contains the logging priority to be applied during the pipeline session.
   * </td></tr>
   * <td width="20%" valign="top"><code>VERBOSE_POLICY_KEY</code></td>
   * <td>
   * If this value is TRUE, debug logging entries from the pipeline processor 
will be 
   * if the overall logging priority permits this. If FALSE (the default), the 
logging 
   * entires generated by the pipeline processor will be limited to WARN, 
ERROR, 
   * and FATAL_ERROR.
   * </td></tr>
   * </table>
   *
   * </td></tr>
   * <tr><td width="20%">Initalizable</td>
   * <td>
   * The initilization phase handles the creation of a new instance of the 
supplied
   * target class, resolves any service dependencies, and runs the instance 
through 
   * the lifecycle pipeline. 
   * </td></tr>
   * <tr><td width="20%" valign="top">Disposable</td>
   * <td>
   * Cleanup and disposal of state members following termination and diposal of 
   * all current components.
   * </td></tr>
   * </table>
   */
  public class ServiceLoader extends AbstractLogEnabled 
      implements Configurable, Contextualizable, Initializable, Disposable
  {
      private static final String DEFAULT_FORMAT = "[%7.7{priority}] 
(%{category}): %{message}\\n%{throwable}";
      private static OutputStream m_out = System.out;
  
      private String[] m_args;
      private PipelineClassLoader m_classloader;
  
      private Priority m_priority = Priority.INFO;
      private String m_target;
      private Object m_object;
      private File[] m_includes;
      private boolean m_policy = true;
      private boolean m_verbose = false;
  
      private boolean m_terminated = false;
      private boolean m_disposed = false;
  
      private ServiceFactory m_factory;
      private Configuration m_config;
      
     /**
      * Command line entry point supporting establishment and initalization of 
a service 
      * loader instance with a supplied target component and supporting 
services.
      *
      *   <p><strong>java -jar form</strong></p>
      *   <p>Execution using java -jar pattern requires the presence 
      *   of the following files under the same directory:</p>
      *       <ul>
      *         <li><code>merlin.jar</code>
      *         <li><code>avalon-framework.jar</code>
      *         <li><code>logkit.jar</code>
      *       </ul>
      *   <p>An example command line is shown below:</p>
      *   <pre>
      * $ java -jar <strong>merlin.jar</strong> &lt;supporting-jar-files&gt; 
      *     -target &lt;class-name&gt; 
      *   </pre>
      *   <p><strong>java -classpath form</strong></p>
      *   <p>Execution using java -classpath pattern requires the inclusions 
      *   of the pipeline, framework and logkit jar files in the classpath 
      *   statement.</p>
      *   <p>An example command line is shown below:</p>
      *   <pre>
      * $ java -classpath 
<strong>merlin.jar;avalon-framework.jar;logkit.jar</strong> 
      *     org.apache.avalon.excalibur.service.ServiceLoader
      *      &lt;supporting-jar-files&gt; -target &lt;class-name&gt; 
      *   </pre>
      * </ul>
      * 
      * <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
      * <tr bgcolor="#ccccff">
      * <td colspan="2"><b>Command Line Parameters and Arguments</b></td>
      * <tr><td 
width="20%"><b>Parameter</b></td><td><b>Description</b></td></tr>
      * <tr>
      * <td width="20%" valign="top"><code>-target 
&lt;class-name&gt;</code></td>
      * <td>
      * <p>The class to instantiate.  If the class exposes any Avalon lifecycle 
interface
      * (such as <code>Configurable</code>, <code>Contextualizable</code>, 
<code>Serviceable</code>,  
      * <code>Initializable</code>, <code>Startable</code>, or 
<code>Disposable</code>, the 
      * pipeline will automate lifecycle processing and termination.
      * </p>
      * </td></tr>
      * <tr>
      * <td width="20%" 
valign="top"><code>&lt;supporting-jar-files&gt;</code></td>
      * <td>
      * <p>A list of space seperated jar files that will be added to the 
pipeline
      * as supporting classes and components.  Any jar file included in the list
      * that contains an Avalon <code>Block</code> manifest will be registered 
as
      * an available service when resolving component dependecies.</p>
      * </td></tr>
      * <tr><td width="20%"><code>-verbose &lt;boolean&gt;</code></td>
      * <td>
      * <p>A value of <code>true</code> will force debug level logging of the 
actual pipeline
      * processor.  A value of <code>false</code> will disable pipeline debug 
priority logging.
      * Visibility of logging inffomration is dependent on the level supplied 
under the 
      * <code>priority</code parameter.</p>
      * </td></tr>
      * <tr><td width="20%" valign="top"><code>-priority 
&lt;priority&gt;</code></td>
      * <td>
      * <p>Declaration of the logging priority to use during pipeline 
execution.  Valid values
      * include FATAL_ERROR, ERROR, WARN, INFO, and DEBUG. </p>
      * </td></tr>
      * <tr><td width="20%" valign="top"><code>-dispose 
&lt;boolean&gt;</code></td>
      * <td>
      * If the target component is <code>Startable</code>, and the dispose 
argument is <code>FALSE</code> the
      * component will be treated as a server and will continue to run 
following initialization.
      * Otherwise, the component will be disposed of.
      * </td></tr>
      * <tr><td width="20%" valign="top"><code>-configuration 
&lt;file-path&gt;</code></td>
      * <td>
      * Optional parameter naming a file to be used as the configuration source.
      * </td></tr>
      * </table>
      *
      * @param args a array of <code>String</code> argument values passed under 
the command line. 
      */
      public static void main( String[] args )
      {
          ServiceLoader pipeline = null;
          try
          {
              CLI cli = new CLI( args );
              pipeline = new ServiceLoader();
              ServiceLoaderContext context = cli.getContext();
              File path = cli.getConfigurationPath();
              Configuration config = new DefaultConfiguration("-", null );
              if( path != null ) config = getRuntimeConfiguration( path );
              pipeline.configure( config );
              pipeline.contextualize( context );
              pipeline.initialize();
          }
          catch( IllegalParameterException ipe )
          {
              System.err.println( ipe.getMessage() );
          }
          catch( PipelineException e )
          {
              final String error = "Service loader processing exception.";
              System.err.println( error );
              System.err.println( e );
          }
          catch( PipelineRuntimeException e )
          {
              final String error = "Service loader runtime exception.";
              System.err.println( error );
              System.err.println( e );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected service loader exception.";
              System.err.println( error );
              e.printStackTrace();
          }
          finally
          {
              if( pipeline != null )
              {
                  pipeline.dispose();
              }
          }
      }
  
      private boolean getVerbose()
      {
          return m_verbose;
      }
  
     /**
      * Configuration of the pipeline.
      */
      public void configure( Configuration config ) throws 
ConfigurationException
      {
          m_config = config;
      }
  
     /**
      * Contextualization of the pipeline including the supply of command-line
      * arguments, include files, target class, and related execution policies.
      * @see ServiceLoaderContext
      * @param context the pipeline context
      * @exception ContextException if the supplied context is not an instance
      *   of ServiceLoaderContext, or if an internal error occurs while 
resolving 
      *   context information.
      */
      public void contextualize( Context context ) throws ContextException
      {
          try
          { 
              ServiceLoaderContext c = (ServiceLoaderContext) context;
              m_includes = c.getIncludes();
              m_verbose = c.getVerbose();
              m_priority = c.getLoggingPriority();
              m_policy = c.getDisposalPolicy();
              m_target = c.getTarget();
          }
          catch( Throwable e )
          {
              final String error = "Unexpected error while reslving pipeline 
context.";
              throw new ContextException( error, e );
          }
      }
  
     /**
      * Start the pipeline and handle any errors arrising from loader execution.
      */
      public void initialize() throws PipelineException
      {
          if( m_target == null ) throw new PipelineException(
            "The pipeline task required attribute 'target' has not been not 
supplied.");
  
          try
          {
              Hierarchy hierarchy = createBootstrapLogger();
              Logger logger = new LogKitLogger( hierarchy.getLoggerFor( 
"loader" ) );
              if( getLogger() == null ) super.enableLogging( logger );
              if( m_classloader == null ) m_classloader = createClassloader();
              m_factory = new ServiceFactory( hierarchy, m_config,
                new File( System.getProperty("user.dir") ), getVerbose() );
              m_factory.enableLogging( getLogger().getChildLogger("factory") );
          }
          catch( Throwable e )
          {
              final String error = "Service loader validation error.";
              getLogger().error( error, e );
              return;
          }
  
          try
          {
              process();
          }
          catch( PipelineException e )
          {
              final String error = "Service loader processing exception.";
              getLogger().error( error );
          }
          catch( PipelineRuntimeException e )
          {
              final String error = "Service loader runtime exception.";
              getLogger().error( error );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected pipeline exception.";
              getLogger().error( error, e );
          }
          finally
          {
              if( m_policy )
              {
                  if( m_object != null ) terminate();
                  dispose();
                  return;
              }
          }
      }
  
      /**
       * Initates execution of the loading of supporting services derived from 
a 
       * target.
       */
      private void process( ) throws PipelineException
      {
          //
          // add the included jar files to the classloader
          //
  
          Vector list = new Vector();
          Vector stack = new Vector();
          for (int i=0; i<m_includes.length; i++) 
          {
              File target = m_includes[i];
              stack.add( target );
              list.add( target );
          }
          load( stack );
  
          // build the registry of available services
  
          try
          {
              m_factory.register( list );
          }
          catch( Throwable e )
          {
              final String error = "Service loader exception encounter while 
preparing services.";
              throw new PipelineException( error, e ); 
          }
  
          //
          // create an instance of the target and if verify that we can in fact 
build a 
          // service manager if needed
          //
  
          Class target;
          UnitInfo info;
          try
          {
              target = m_classloader.loadClass( m_target );
          }
          catch( Throwable e )
          {
              final String error = "Could not load target class: " + m_target;
              throw new PipelineException( error , e ); 
          }
  
          try
          {
              info = ServiceRegistry.createUnitInfo( target );
              if( getVerbose() ) if( getLogger().isDebugEnabled() ) 
getLogger().debug( "validating target\n" + info );
              try
              {
                  m_factory.validate( info );
              }
              catch( Throwable e )
              {
                  final String error = "Could not resolve a valid dependency 
solution for ";
                  throw new CascadingException( error + info.getClassName(), e 
);
              }
          }
          catch( Throwable e )
          {
              final String error = "Service loader exception encounter while 
preparing services.";
              throw new PipelineException( error, e ); 
          }
  
          //
          // process the target
          //
  
          try
          {
              m_object = m_factory.pipeline( info, "target" );
          }
          catch( Throwable e )
          {
              final String error = "Service loader exception encounter during 
target execution.";
              throw new PipelineException( error, e ); 
          }
  
          //
          // add a shutdown hook so we can stop services and target and invoke 
disposal
          //
  
          Runtime.getRuntime().addShutdownHook( 
            new Thread()
            {
                public void run()
                {
                    terminate();
                    dispose();
                }
            }
          );
      }
  
     /**
      * Run the termination lifecycle actions on the primary object.
      */
      private void terminate( )
      {
          if( m_terminated ) return;
          m_terminated = true;
          if( m_object == null ) return;
          if( getVerbose() ) if( getLogger().isDebugEnabled() ) 
getLogger().debug( 
             "terminating " + m_object.getClass().getName() );
  
          if( m_object instanceof Startable )
          {
              try
              {
                  ((Startable)m_object).stop();
              }
              catch( Throwable e )
              {
                  final String warning = "Ignoring error while stopping 
target.";
                  if( getLogger().isWarnEnabled() ) getLogger().warn( warning, 
e );
              }
          }
  
          if( m_object instanceof Disposable )
          {
              try
              {
                  ((Disposable)m_object).dispose();
              }
              catch( Throwable e )
              {
                  final String warning = "Ignoring error while disposing of 
target.";
                  if( getLogger().isWarnEnabled() ) getLogger().warn( warning, 
e );
              }
          }
      }
  
     /**
      * Disposal of the pipeline and release of all resources.
      */
      public void dispose()
      {
          if( m_disposed ) return;
  
          if( !m_terminated ) try
          {
              terminate();
          }
          catch( Throwable e )
          {
              // ignore and continue
          }
  
          m_disposed = true;
  
          if( getVerbose() ) if( getLogger().isDebugEnabled() ) 
getLogger().debug( "loader disposal" );
          if( m_factory instanceof Disposable )
          {
              try
              {
                  ((Disposable)m_factory).dispose();
              }
              catch( Throwable e )
              {
                  final String warning = "Ignoring error while disposing of 
service factory.";
                  getLogger().warn( warning, e );
              }
          }
      }
  
      //==========================================================
      // classloader
      //==========================================================
      
      private PipelineClassLoader createClassloader()
      {
          try
          {
              PipelineClassLoader loader = new PipelineClassLoader();
              Thread.currentThread().setContextClassLoader( loader );
              return loader;
          }
          catch( Throwable e )
          {
               final String error = "Failed to instantial a classloader.";
               throw new CascadingRuntimeException( error, e );
          }
      }
  
      class PipelineClassLoader extends URLClassLoader
      {
          PipelineClassLoader( )
          {
              super( new URL[0], Thread.currentThread().getContextClassLoader() 
);
          }
  
          protected void addURL( URL url ) 
          {
              try
              {
                  URL jarURL = new URL("jar:" + url.toString() + "!/");
                  super.addURL( jarURL );
              }
              catch( Throwable e )
              {
                  throw new CascadingRuntimeException(
                    "Unexpected error while attempting to add classloader URL: 
" + url, e );
              }
          }
          protected Class loadClass( String name, boolean resolve ) throws 
ClassNotFoundException
          {
              return super.loadClass( name, resolve );
          } 
      }
  
     /**
      * Load the supplied jar files under the pipeline classloader.
      * For each entry in the stack, try to load it and 
      * if sucessfull, remove it from the stack - on completion
      * the stack should be less than its original size - recursivly
      * invoke load until the stack is empty.
      * @param stack a <code>Vecor</code> containing a sequence of jar files
      *   to be added to the classloader.
      */
      private void load( Vector stack )
      {
          int size = stack.size();
          Hashtable errors = new Hashtable();
          Enumeration enum = stack.elements();
          while( enum.hasMoreElements() )
          {
              File target = (File) enum.nextElement();
              try
              {
                  m_classloader.addURL( target.toURL() );
                  if( getVerbose() ) getLogger().debug( "Loaded file: " + 
target );
                  stack.remove( target );
              }
              catch( Throwable error )
              {
                  errors.put( target, error );
              }
          }
  
          if( stack.size() == 0 ) return;
          if( stack.size() < size )
          {
              load( stack );
          }
          else
          {
              Enumeration keys = errors.keys();
              getLogger().error("Load error count = " + errors.size() );
              while( keys.hasMoreElements() )
              {
                  File key = (File) keys.nextElement();
                  getLogger().error( 
                     "Error while loading file."
                     + "\n\tfile: " + key.toString(), (Throwable) errors.get( 
key ) );
              }
              throw new RuntimeException("Unable to load file stack - see trace 
for details.");
          }
      }
  
      //==========================================================
      // configuration
      //==========================================================
  
     /**
      * Get client configuration from a file. 
      */ 
      private static Configuration getRuntimeConfiguration( final File file ) 
      {
          try
          {
              DefaultConfigurationBuilder builder = new 
DefaultConfigurationBuilder( ); 
              InputStream is = new FileInputStream( file );
              if( is == null ) throw new Exception( 
                "Could not load the configuration resource \"" + file + "\"" ); 
              return builder.build( is ); 
          }
          catch( Throwable e )
          {
              final String error = "Unable to create configuration.";
              throw new CascadingRuntimeException( error, e );
          }
      }
  
      //==========================================================
      // logging
      //==========================================================
  
      private Hierarchy createBootstrapLogger()
      {
          try
          {
              Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
              hierarchy.setDefaultLogTarget( 
                 new StreamTarget( m_out, new AvalonFormatter( DEFAULT_FORMAT ) 
) );
              hierarchy.setDefaultPriority( m_priority );
              return hierarchy;
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while creating 
bootstrap logger.";
              throw new CascadingRuntimeException( error, e );
          }
      }
      //==========================================================
      // command-line
      //==========================================================
  
      private static class IllegalParameterException extends Exception 
      {
         /**
          * Construct a new <code>IllegalParameterException</code> instance 
with the 
          * supplied message parameter.
          * @param message Message summarising the exception.
          */
          public IllegalParameterException( final String message ) 
          {
             super( message );
          }
      }
  
      private static class CLI
      {
          private String[] m_args = new String[0];
          private Priority m_priority = Priority.INFO;
          private String m_target = "";
          private boolean m_policy = true;
          private boolean m_verbose = false;
          private File[] m_files = new File[0];
          private File m_path = null;
  
          public CLI( String[] args ) throws IllegalParameterException
          {
              m_args = args;
              Vector vector = new Vector();
              for( int i=0; i < m_args.length; i++ )
              {
                  if( m_args[i].toLowerCase().startsWith("-tar") )
                  {
                      if( i+1 < m_args.length ) 
                      {
                          m_target = m_args[i+1];
                          i = i+1;
                      }
                      else
                      {
                          final String error = "Missing -target parameter.";
                          throw new RuntimeException( error );
                      }
                  }
                  else if( m_args[i].toLowerCase().startsWith("-conf") )
                  {
                      if( i+1 < m_args.length ) 
                      {
                          m_path = new File( m_args[i+1] );
                          i = i+1;
                      }
                      else
                      {
                          final String error = "Missing -configuration 
parameter.";
                          throw new RuntimeException( error );
                      }
                  }
                  else if( m_args[i].toLowerCase().startsWith("-pri") )
                  {
                      if( i+1 < m_args.length ) 
                      {
                          m_priority = Priority.getPriorityForName( 
m_args[i+1].toUpperCase() );
                          i = i+1;
                      }
                      else
                      {
                          final String error = "Missing -priority argument.";
                          throw new RuntimeException( error );
                      }
                  }
                  else if( m_args[i].toLowerCase().startsWith("-dis") )
                  {
                      if( i+1 < m_args.length ) 
                      {
                          m_policy = (m_args[i+1].toUpperCase().equals("TRUE"));
                          i = i+1;
                      }
                      else
                      {
                          final String error = "Missing -disposal argument.";
                          throw new RuntimeException( error );
                      }
                  }
                  else if( m_args[i].toLowerCase().startsWith("-ver") )
                  {
                      if( i+1 < m_args.length ) 
                      {
                          m_verbose = 
(m_args[i+1].toUpperCase().equals("TRUE"));
                          i = i+1;
                      }
                      else
                      {
                          final String error = "Missing -verbose argument.";
                          throw new RuntimeException( error );
                      }
                  }
                  else if( m_args[i].startsWith("-") )
                  {
                      final String error = "Unrecognized parameter: " + 
m_args[i];
                      throw new IllegalParameterException( error );
                  }
                  else
                  {    
                      final File file = new File( m_args[i] );
                      if( file.exists() ) vector.add( file );
                  }
              }
              m_files = (File[]) vector.toArray( new File[0] );
          }
  
          public ServiceLoaderContext getContext()
          {
               return new ServiceLoaderContext( m_args, m_target, m_files, 
m_policy, m_priority, m_verbose );
          }
  
          public File getConfigurationPath()
          {
               return m_path;
          }
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceLoaderContext.java
  
  Index: ServiceLoaderContext.java
  ===================================================================
  /*
   * File: ServiceLoaderContext.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.File;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.log.Priority;
  
  /**
   * <code>ServiceLoaderContext</code> context to hold command line arguments, 
   * base directory, target class name, and include files for a 
   * <code>ServiceLoader</code> component.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   */
  public class ServiceLoaderContext extends DefaultContext
  {
     /**
      * Context key for command line arguments.
      * @see #getArgs()
      */
      public static final String ARGS_KEY = "ARGS";
  
     /**
      * Context key for the base directory.
      * @see #getBaseDirectory()
      */
      public static final String BASE_DIRECTORY_KEY = "APP_DIR";
  
     /**
      * Context key for the target class name.
      * @see #getTarget()
      */
      public static final String TARGET_KEY = "TARGET";
  
     /**
      * Context key for the set of supporting include jar files.
      * @see #getIncludes()
      */
      public static final String INCLUDES_KEY = "INCLUDES";
  
     /**
      * Context key for the disposal policy.
      * @see #getDisposalPolicy()
      */
      public static final String DISPOSAL_POLICY_KEY = "DISPOSAL.POLICY";
  
     /**
      * Context key for the logging priority.
      * @see #getLoggingPriority()
      */
      public static final String LOGGING_PRIORITY_KEY = "LOGGING.PRIORITY";
  
     /**
      * Context key for the verbose policy.
      * @see #getVerbose()
      */
      public static final String VERBOSE_POLICY_KEY = "VERBOSE.POLICY";
  
     /**
      * Creation of a new <oce>ServiceLoaderContext</code> with the supplied 
      * arguments.
      * @param args command line arguments
      * @param target class name of the target object to be loaded
      * @param includes set of jar files to be added to the loader classloader
      * @param disposal boolean disposal policy
      * @param priority logging priority
      * @param verbose policy concerning display of loader debug messages
      */
      public ServiceLoaderContext( final String[] args, final String target, 
final File[] includes, final boolean disposal, final Priority priority, final 
boolean verbose )
      {
          super.put( ARGS_KEY, args );
          super.put( TARGET_KEY, target );
          super.put( BASE_DIRECTORY_KEY, new File( 
System.getProperty("user.dir")) );
          super.put( INCLUDES_KEY, includes );
          super.put( DISPOSAL_POLICY_KEY, new Boolean( disposal ));
          super.put( VERBOSE_POLICY_KEY, new Boolean( verbose ));
          super.put( LOGGING_PRIORITY_KEY, priority );
      }
  
     /**
      * Returns the command-line argument <code>String[]</code>.
      * @return String[] command line arguments
      */
      public String[] getArgs()
      {
          try
          {
              return (String[]) super.get( ARGS_KEY );
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving 
command line arguments.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  
     /**
      * Returns the base directory as a <code>File</code>.
      * @return File the base working directory
      */
      public File getBaseDirectory()
      {
          try
          {
              return (File) super.get( BASE_DIRECTORY_KEY );
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving base 
directory.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  
     /**
      * Returns the disposal policy to apply if the target component implements
      * the <code>Startable</code> interface.
      * @return boolean the target component disposal policy
      */
      public boolean getDisposalPolicy()
      {
          try
          {
              return ((Boolean)super.get( DISPOSAL_POLICY_KEY )).booleanValue();
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving 
disposal policy.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  
     /**
      * Class name of a target object.
      * @return String the class name of the target
      */
      public String getTarget()
      {
          try
          {
              return (String) super.get( TARGET_KEY );
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving 
include files.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  
     /**
      * Returns the set of supporting jar files.
      * @return File[] an array of jar files supporting target composition and 
execution
      */
      public File[] getIncludes()
      {
          try
          {
              return (File[]) super.get( INCLUDES_KEY );
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving 
include files.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  
     /**
      * Returns the logging priority.
      * @return Priority the logging priority to apply.
      */
      public Priority getLoggingPriority()
      {
          try
          {
              return (Priority) super.get( LOGGING_PRIORITY_KEY );
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving 
logging priority.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  
     /**
      * Returns the verbose policy - if true, logging entries from the pipeline 
      * will be inclued, otherwise, logging entries will be restricted to the 
      * target component.
      * @return boolean the verbose policy
      */
      public boolean getVerbose()
      {
          try
          {
              return ((Boolean)super.get( VERBOSE_POLICY_KEY )).booleanValue();
          }
          catch( ContextException e )
          {
              final String error = "Unexpected exception while retrieving 
verbose policy.";
              throw new PipelineRuntimeException( error, e );
          }
      }
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceProvider.java
  
  Index: ServiceProvider.java
  ===================================================================
  /*
   * File: ServiceProvider.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import org.apache.avalon.framework.activity.Disposable;
  
  /**
   * <code>ServiceProvider</code> is an abstract base class to services
   * factories supporting TRANSIENT, POOLED, and SINGLETON services. The 
   * abstract class provides the single <code>getRole</code> method that
   * can be used by a <code>ServiceManager</code> implementation to identity
   * a service provider for a particular role.
   * A concrete <code>ServiceProvider</code> instance will typically be 
   * created by an implementation when constructing a 
<code>ServiceManager</code> 
   * for a target component.
   */
  abstract class ServiceProvider implements Disposable
  {
      private String m_role;
  
     /**
      * Creation of a new <code>ServiceProvider</code> instance based on 
      * a supplied role.
      * @param role the role of the service provided by the provider relative
      *   to a <code>ServiceManager</code> that is exposing provider services.
      */
      public ServiceProvider( String role )
      {
          m_role = role;
      }
  
     /**
      * Returns the role of this provider within the scope of a 
<code>ServiceManager</code>.
      * @return String the role of the service provider by the provider.
      */
      public String getRole()
      {
          return m_role;
      }
  
     /**
      * Disposal of the provider and release of related resources.
      */
      public void dispose()
      {
          m_role = null;
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceRegistry.java
  
  Index: ServiceRegistry.java
  ===================================================================
  /*
   * File: ServiceRegistry.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.io.File;
  import java.io.InputStream;
  import java.io.IOException;
  import java.util.Vector;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.util.jar.JarFile;
  import java.util.jar.Attributes;
  import java.util.jar.Attributes.Name;
  
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  
  /**
   * Internal class supporting registration of available services.
   */
  class ServiceRegistry extends AbstractLogEnabled
  {
  
      private Vector m_repository = new Vector();
      private UnitInfo[] m_block_info_set;
      private Hashtable m_table;
      private boolean m_verbose = false;
  
      public ServiceRegistry( boolean verbose )
      {
          m_verbose = verbose;
      }
  
      public void register( UnitInfo info )
      {
          m_repository.add( info );
      }
  
     /**
      * Populates the set of available services based on a supplied 
      * vector of jar files.
      * @param list a list of jar files
      */
      public void register( Vector list ) throws PipelineException
      {
          Vector registry = new Vector();
          Enumeration enum = list.elements();
          while( enum.hasMoreElements() )
          {
              File target = (File) enum.nextElement();
              UnitInfo[] blocks = register( target );
              if( m_verbose ) if( blocks.length > 0 ) if( 
getLogger().isDebugEnabled() ) 
                getLogger().debug(
                "file: " + target + " has " + blocks.length + " block 
declarations" );
          }
      }
  
     /**
      * Register a jar file with the registry.
      * @param file the jar file to register
      * 
      */
      public UnitInfo[] register( File target ) throws PipelineException
      {
          UnitInfo[] blocks = getUnitInfo( target );
          for( int i=0; i<blocks.length; i++ )
          {
              UnitInfo info = blocks[i];
              m_repository.add( info );
          }
          return blocks;
      }
  
      public UnitInfo lookup( ServiceInfo info )
      {
          Enumeration enum = m_repository.elements();
          while( enum.hasMoreElements() )
          {
              UnitInfo block_info = (UnitInfo) enum.nextElement();
              if( block_info.provides( info ) ) return block_info;
          }
          return null;
      }
  
     /**
      * Returns an array of block infos provided by the jar file.
      * @return a <code>UnitInfo[]<code> provided by the jar file
      */
      private UnitInfo[] getUnitInfo( File file ) throws PipelineException
      {
          Vector vector = new Vector();
          try
          {
              //
              // if the file contains block declarations, then pipeline and
              // blocks as a supporting service that will be provided to the 
              // target server
              //
   
              String[] blocks = getBlocks( file );
              for( int i=0; i<blocks.length; i++ )
              {
                  //
                  // get the block implementation class and check for
                  // dependecies - if dependencies > 0 then ignore it
                  // otherwise pipeline the block and add it as a 
                  // service
                  //
  
                  final String path = blocks[i];
                  Configuration config = loadConfiguration( path + ".conf", 
true );
                  Configuration xinfo = loadConfiguration( path + ".xinfo", 
false );
                  if( xinfo == null ) throw new IllegalStateException(
                        "Could not locate <class>.xinfo resource for: " + path 
);
  
                  final String classname = path.replace('/','.');
                  Class block = 
Thread.currentThread().getContextClassLoader().loadClass( classname );
                  vector.add( new UnitInfo( block, xinfo, config ));
              }
          }
          catch( Throwable e )
          {
              throw new CascadingRuntimeException(
                "Unexpected error while attempting to load file: " + file, e );
          }
          return (UnitInfo[]) vector.toArray( new UnitInfo[0] );
      }
  
     /**
      * Returns a single block info relative to a supplied class.
      * @return a <code>UnitInfo<code> for the class.
      */
      public static UnitInfo createUnitInfo( Class block ) throws 
PipelineException
      {
          try
          {
              String path = block.getName().replace('.','/');
              Configuration config = loadConfiguration( path + ".config", true 
);
              Configuration xinfo = loadConfiguration( path + ".xinfo", false );
              if( xinfo == null ) xinfo = new DefaultConfiguration("", null);
              return new UnitInfo( block, xinfo, config );
          }
          catch( Throwable e )
          {
              throw new CascadingRuntimeException(
                "Unexpected error while attempting to resolve block info for a 
class: " + block.getName(), e );
          }
      }
  
      
//===============================================================================
      // utilities
      
//===============================================================================
  
     /**
      * 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
      */
      private String[] getBlocks( File file )
      throws CascadingException, IllegalArgumentException
      {
          final Vector vector = new Vector();
          try
          {
              JarFile jar = new JarFile( file );
              Map map = jar.getManifest().getEntries();
              Iterator iterator = map.keySet().iterator();
              while( iterator.hasNext() )
              {
                  String name = (String) iterator.next();
                  Attributes attributes = (Attributes) map.get( name );
                  Iterator it = attributes.keySet().iterator();
                  while( it.hasNext() )
                  {
                      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 CascadingException( error, e );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while inspecting 
manifest on file: ";
              throw new CascadingException( error + file, e );
          }
          finally
          {
              return (String[]) vector.toArray( new String[0] );
          }
      }
  
     /**
      * Returns a configuration resource form a jar file. 
      * @param path the package path to the resource e.g. net/osm/config.xml
      * @param create if TRUE and no configuration found, return an empty 
      *    configuration, else, return null
      * @exception ConfigurationException if there is a problem
      */
      private static Configuration loadConfiguration( String path, boolean 
create ) 
      throws ConfigurationException 
      {
          try
          {
              DefaultConfigurationBuilder builder = new 
DefaultConfigurationBuilder( );
              InputStream is = 
Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
              if( is != null ) return builder.build( is );
              if( create ) return new DefaultConfiguration("-",null);
              return null;
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while attempting to 
load a configuration from path: ";
              throw new ConfigurationException( error, e ); 
          } 
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/SingletonProvider.java
  
  Index: SingletonProvider.java
  ===================================================================
  /*
   * File: SingletonProvider.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import org.apache.avalon.framework.activity.Disposable;
  
  /**
   * A <code>SingletonProvider</code> is a provider of singleton services.  A 
   * singleton service is a service that is managed by the container providing 
the
   * the service. The container providing the service is reposible for all 
lifecycle
   * actions including service decommissioning.
   */
  class SingletonProvider extends ServiceProvider
  {
  
      private Object m_object;
  
     /**
      * Creation of a new <code>SingletonProvider</code>.
      * @param object the singleton object to provide.
      */
      public SingletonProvider( Object object, String role )
      {
          super( role );
          m_object = object;
      }
  
     /**
      * Provides a reference to a singleton service.
      * @return Object the singleton service
      */
      public Object provide()
      {
          return m_object;
      }
  
     /**
      * Disposal of the provider and release of related resources.
      */
      public void dispose()
      {
          if(( m_object != null ) && ( m_object instanceof Disposable )) try
          { 
              ((Disposable)m_object).dispose();
          }
          catch( Throwable anything )
          {
              // ignore it
          }
          finally
          {
              super.dispose();
          }
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/TransientProvider.java
  
  Index: TransientProvider.java
  ===================================================================
  /*
   * File: TransientProvider.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  
  /**
   * A <code>TransientProvider</code> is a provider of transient services.  A 
   * transient service is a service where total responsibility for the lifetime
   * of the service rests with client aquiring the service.
   */
  class TransientProvider extends ServiceProvider
  {
      private ServiceFactory m_factory;
      private UnitInfo m_info;
      private boolean m_disposed;
  
      public TransientProvider( ServiceFactory factory, UnitInfo info, String 
role )
      {
          super( role );
          m_info = info;
          m_factory = factory;
      }
  
     /**
      * Create a new instance of a transient service.  
      * @return Object a new instance of a transient service
      */
      public Object create()
      {
          if( m_disposed ) throw new IllegalStateException( "Transient provider 
has been disposed.");
          try
          {
              return m_factory.pipeline( m_info, super.getRole() );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected error while creating transient 
service.";
              throw new CascadingRuntimeException( error, e );
          }
      }
  
     /**
      * Disposal of the provider and release of related resources.
      */
      public void dispose()
      {
          m_disposed = true;
          m_factory = null;
          m_info = null;
          super.dispose();
      }
  
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/UnitInfo.java
  
  Index: UnitInfo.java
  ===================================================================
  /*
   * File: UnitInfo.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service;
  
  import java.util.Vector;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.configuration.Configuration;
  
  /**
   * Meta information about a <code>Serviceable</code> component.  
   */
  class UnitInfo
  {
  
      public static final int SINGLETON_LIFETIME_POLICY = 0;
      public static final int POOLED_LIFETIME_POLICY = 1;
      public static final int TRANSIENT_LIFETIME_POLICY = 2;
  
      private Class m_block;
      private Configuration m_xinfo;
      private Configuration m_config;
      private ServiceInfo[] m_services;
      private DependencyInfo[] m_dependencies;
      private boolean m_installed = false;
      private Object m_object;
      private int m_policy = SINGLETON_LIFETIME_POLICY;
  
     /**
      * Creation of a new UnitInfo based a xinfo configuration
      * derived from the supplied class name.
      * The UnitInfo recognises the the following structures within
      * the xinfo configuration:
      * <pre>
      *   &lt;blockinfo&gt;
      *   
      *     &lt;block>
      *       &lt;version>1.0&lt;/version&gt;
      *     &lt;/block&gt;
      *   
      *     &lt;!--
      *     services that are offered by this block 
      *     --&gt;
      *   
      *     &lt;services&gt;
      *         &lt;service name="hello.Hello" version="1.0"/&gt;
      *     &lt;/services&gt;
      *   
      *     &lt;!--
      *     Implementation policy may one of the following enumerations:
      *     (a) SINGLETON, service is available for the lifetime of the manager
      *     (b) POOLED, the implementation implements Pool
      *     (c) TRANSIENT, manager is a factory of transient service instances
      *     --&gt;
      *   
      *     &lt;implementation policy="SINGLETON" /&gt;
      *   
      *   &lt;/blockinfo&gt;
      * </pre>
      * 
      * @param block the implementation class
      * @param the xinfo meta-information in the form of a Configuration
      * @param the default component configuration
      */
      public UnitInfo( Class block, Configuration xinfo, Configuration config ) 
throws Exception
      {
          m_block = block;
          m_xinfo = xinfo;
          m_config = config;
          try
          {
              Configuration[] services = 
xinfo.getChild("services").getChildren("service");
              Vector vector = new Vector();
              for( int i=0; i<services.length; i++ )
              {
                  vector.add( new ServiceInfo( services[i] ));
              }
              m_services = (ServiceInfo[]) vector.toArray( new ServiceInfo[ 
vector.size() ] );
          }
          catch( Throwable e )
          {
              throw new CascadingException( "Could not construct service 
information.", e );
          }
          try
          {
              Configuration[] dependencies = 
xinfo.getChild("dependencies").getChildren("dependency");
              Vector vector = new Vector();
              for( int i=0; i<dependencies.length; i++ )
              {
                  vector.add( new DependencyInfo( dependencies[i] ));
              }
              m_dependencies = (DependencyInfo[]) vector.toArray( new 
DependencyInfo[ vector.size() ] );
          }
          catch( Throwable e )
          {
              throw new CascadingException( "Could not construct dependency 
information.", e );
          }
  
          String policy = 
xinfo.getChild("implementation").getAttribute("policy","TRANSIENT");
          if( policy.equalsIgnoreCase( "SINGLETON" ) )
          {
              m_policy = SINGLETON_LIFETIME_POLICY;
          }
          else if( policy.equalsIgnoreCase( "POOLED" ) )
          {
              m_policy = POOLED_LIFETIME_POLICY;
          }
          else
          {
              m_policy = TRANSIENT_LIFETIME_POLICY;
          }
      }
  
     /**
      * Returns the name of the class implemenmting the service.
      * @return the class name
      */
      public String getClassName()
      {
          return m_block.getName();
      }
  
     /**
      * Returns the set of services provided by the component.
      * @return an array of <code>ServiceInfo</code> instance
      */
      public ServiceInfo[] getServices()
      {
          return m_services;
      }
  
     /**
      * Returns a <code>ServiceInfo</code> from the <code>UnitInfo</code> 
matching 
      * the supplied service descriptor.
      * @param info a <code>ServiceInfo</code> to locate with the 
<code>UnitInfo</code> instance
      * @return a <code>ServiceInfo</code> instance matching the supplied 
service descriptor
      */
      public ServiceInfo getService( ServiceInfo info )
      {
          ServiceInfo[] services = getServices();
          for( int i=0; i<services.length; i++ )
          {
              if( services[i].equals( info )) return services[i];
          }
          return null;
      }
  
     /**
      * Returns a <code>TRUE</code> if the supplied <code>ServiceInfo</code> 
can be 
      * provided by the implementation. 
      * @param service the requested service
      * @return boolean TRUE if the service is available otherwise FALSE
      */
      public boolean provides( ServiceInfo service )
      {
          return ( getService( service ) != null );
      }
  
     /**
      * Returns a array of <code>DependencyInfo</code> descriptors that detail
      * the dependencies that this component has on other components.
      * @return component dependencies
      */
      public DependencyInfo[] getDependencies()
      {
          return m_dependencies;
      }
  
     /**
      * Returns the implemetation policy.  The value returned shall be one of
      * SINGLETON_LIFETIME_POLICY, POOLED_LIFETIME_POLICY, or 
TRANSIENT_LIFETIME_POLICY.
      * @return implementation policy
      */
      public int getPolicy()
      {
          return m_policy;
      }
  
     /**
      * The component implementation class.
      * @return the component implementation class
      */
      public Class getBaseClass()
      {
          return m_block;
      }
  
     /**
      * Return the default configuration.
      * @return the default configuration
      */
      public Configuration getDefaultConfiguration()
      {
          return m_config;
      }
  
     /**
      * Returns a string representation of the descriptor.
      * @return stringified representation
      */
      public String toString()
      {
          final StringBuffer buffer = new StringBuffer();
          buffer.append( "  block: " + getClassName() );
          ServiceInfo[] services = getServices();
          for( int i=0; i<services.length; i++ )
          {
              buffer.append( "\n  service: " + 
services[i].getInterface().getName() 
                + ", version: " + services[i].getVersion() );
          }
          DependencyInfo[] dependencies = getDependencies();
          for( int i=0; i<dependencies.length; i++ )
          {
              buffer.append( "\n  dependecy: " 
                + "role: " + dependencies[i].getRole() 
                + ", service: " + dependencies[i].getInterface().getName() 
                + ", version: " + dependencies[i].getVersion() );
          }
          return buffer.toString();
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/package.html
  
  Index: package.html
  ===================================================================
  <body>
  <p>Resource supporting the management of components using dynamic service 
composition.</p>
  <table border="1" cellpadding="3" cellspacing="0" width="100%">
  <tr bgcolor="#ccccff">
  <td colspan="2"><b>Features Summary</b></td>
  <tr><td width="20%"><b>Feature</b></td>
  <td><b>Description</b></td></tr>
  
  <tr><td width="20%" valign="top">Service Composition</td>
  <td>Handles automated composition of services based on declared component 
dependencies.</td></tr>
  <tr><td>Default Configurations</td>
  <td>Provides support for configuration using component default configurations 
together
  with supplied configuration information using the CascadingConfiguration 
model.</td></tr>
  <tr><td>Mixed execution modes</td>
  <td>Supports execution from the command line (main method), as a jar file, as 
an Ant task,
  and as an embedded component.</td></tr>
  </table>
  
  <h3>Component Creation</h3>
  
  The pipeline class manages the creation and deployment of a target component 
and dynamic
  resolution of dependencies based on meta-information contained in a jar 
manifest file.  Entries
  in the manifest file reference class names that are used to load the 
component implementation
  and configuration the component based on meta-information contained in .xinfo 
and .conf files 
  of the same name as the implementation class.
  
  <h4>The Manifest File</h4>
  
  <p>Reusable components are published through a manifest declaration show 
below.  When 
  a jar file is supplied to the Pipeline the manifest is checked for any block 
declarations.
  Blocks declared within the manifest are registered by the pipeline as 
potentially available 
  services that can be used in service dependency resolution.  Each 
Avalon-block declaration
  in the manifest refers to a component implementation class and its associated 
.xinfo file.</p>
  
  <pre>
    Manifest-Version: 1.0
  
    Name: org/apache/DirectoryBlock.class
    Avalon-Block: true
  
    Name: org/apache/ReferralBlock.class
    Avalon-Block: true
  </pre>
  
  <h4>The &lt;classname&gt;.xinfo File</h4>
  
  <p>For each component declared in a manifest, the implementation establishes 
the available services
  and dependencies based on information contained in an <code>.xinfo</code> 
file.  Given a component
  implementation class 
<strong><code>org/apache/DirectoryBlock.class</code></strong> the 
<code>Pipeline</code> processor
  will attempt to locate a 
<strong><code>org/apache/DirectoryBlock.xinfo</code></strong> resource in the 
jar file.</P>
  
  <pre>
    &lt;?xml version="1.0"?&gt;
  
    &lt;blockinfo&gt;
  
        <font color="blue"><i>&lt;!--
        Block version.
        --&gt;</i></font>
  
        &lt;block&gt;
          &lt;version&gt;1.0&lt;/version&gt;
        &lt;/block&gt;
  
        <font color="blue"><i>&lt;!--
        Services that are offered by the component are declared under the 
        services element.  A services element may contain multiple service
        declarations.
        --&gt;</i></font>
  
        &lt;services&gt;
  
            <font color="blue"><i>&lt;!--
            A service declaration includes a class name (typically an interface)
            and a service version identifier.  Service versions may have up to 
            three fiels (e.g. 1.1.3).
            --&gt;</i></font>
  
            &lt;service name="org.apache.ReferralService" version="1.0" /&gt;
  
        &lt;/services&gt;
  
        <font color="blue"><i>&lt;!--
        A component declares the dependencies it has with other components 
under 
        the dependencies element.  A dependencies element may contain multiple
        dependency statements.
        --&gt;</i></font>
  
        &lt;dependencies&gt;
  
            <font color="blue"><i>&lt;!--
            A dependency element contains the declaration of a role and a 
service
            that the component is dependent on. The pipeline processor will 
attempt
            to resolve dependencies based on registered services and 
dynamically 
            establish and provide the dependencies via the component 
Serviceable 
            implementation.  The role name corresponds to the identifying string
            that the component implementation will use to lookup a service from
            a service manger during the serviceable lifecycle phase.
            --&gt;</i></font>
  
            &lt;dependency&gt;
                &lt;role&gt;directory&lt;/role&gt;
                &lt;service name="org.apache.DirectoryService" 
version="1.0"/&gt;
            &lt;/dependency&gt;
  
        &lt;/dependencies&gt;
  
        <font color="blue"><i>&lt;!--
        Component implementation policy may one of the following:
        (a) SINGLETON, service is available for the lifetime of the manager
        (b) POOLED, the implementation implements Pool (implementation pending)
        (c) TRANSIENT, manager is a factory of transient service instances
        --&gt;</i></font>
      
        &lt;implementation policy="SINGLETON" /&gt;
  
    &lt;/blockinfo&gt;
  </pre>
  
  <h4>The &lt;classname&gt;.conf File</h4>
  
  <p>The pipeline processor provides support for the automated retrieval of 
default
  configurations for a component.  During lifecycle processing, the pipeline 
processor
  will attempt to locate a configuration resource with the same path and name 
as 
  the component implementation class.  For example, for the component 
<strong><code>org/apache/DirectoryBlock.class</code></strong>, the 
implementation will look for 
  a default configuration under the resource path 
<strong><code>org/apache/DirectoryBlock.conf</code></strong>.
  During the configuration stage, the pipeline processor will supply the 
component with 
  a <code>CascadingConfiguration</code> where the primary configuration is 
configuration 
  derived from the pipeline processor configuration, and a default 
configuration corresponding 
  to the .conf configuration. 
  </p>
  <pre>
  
  </body>
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ant/Load.java
  
  Index: Load.java
  ===================================================================
  /*
   * File: Load.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2002, All Rights Reserved.
   */
  
  package org.apache.avalon.excalibur.service.ant;
  
  import java.io.*;
  import java.io.File;
  import java.util.*;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.net.MalformedURLException;
  import java.util.jar.JarFile;
  import java.util.jar.Attributes;
  import java.util.jar.Attributes.Name;
  
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.DirectoryScanner;
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.taskdefs.Exec;
  import org.apache.tools.ant.taskdefs.Execute;
  import org.apache.tools.ant.taskdefs.PumpStreamHandler;
  import org.apache.tools.ant.types.Commandline;
  import org.apache.tools.ant.types.CommandlineJava;
  import org.apache.tools.ant.types.Path;
  
  import org.apache.log.Hierarchy;
  import org.apache.log.Priority;
  import org.apache.log.output.io.StreamTarget;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.logger.LogKitLogger;
  import org.apache.avalon.framework.logger.AvalonFormatter;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  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.framework.component.Component;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.DefaultComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.activity.Disposable;
  
  /**
   * A service loader task.  Loads a series a blocks as supporting services, 
   * supporting libraries, and runs a target component.</p>
   */
  public class Load extends Task
  {
      private String[] m_args;
  
      private Vector m_filesets = new Vector();
      private String m_target;
      private String m_priority;
      private String m_policy = "true";
      private String m_verbose = "false";
  
      private Commandline m_cmd = new Commandline();
      private Execute m_exe = new Execute(new PumpStreamHandler(System.out, 
System.err));
      private Path m_classpath;
  
      /**
       * Adds a set of files (nested fileset attribute).
       */
      public void addFileset(FileSet set) 
      {
          m_filesets.addElement(set);
      }
  
      public void setClasspath(Path path) 
      {
          if (m_classpath == null) 
          {
              m_classpath = path;
          }
          else 
          {
              m_classpath.append(path);
          }
      }
  
      public Path createClasspath() 
      {
          if (m_classpath == null) m_classpath = new Path(project);
          return m_classpath.createPath();
      }
  
      /**
       * Sets the target class.
       */
      public void setTarget( String target ) 
      {
          m_target = target;
      }
  
      /**
       * Set the log priority.
       */
      public void setPriority( String level ) 
      {
          m_priority = level;
      }
  
      /**
       * Set the disposal policy.
       * @param String boolean equivalent 
       */
      public void setDisposal( String policy ) 
      {
          m_policy = policy;
      }
  
      /**
       * Set the disposal policy.
       * @param String boolean equivalent 
       */
      public void setVerbose( String value ) 
      {
          m_verbose = value;
      }
  
  
      /**
       * Performs execution as an Ant target.
       */
      public void execute() throws BuildException 
      {
  
          // 
          // add the classpath
          //
  
          if (m_classpath == null)
          {
              m_classpath = Path.systemClasspath;
          }
          else
          {
              m_classpath = m_classpath.concatSystemClasspath("ignore");
          }
  
          m_cmd.createArgument().setValue("-classpath");
          m_cmd.createArgument().setPath(m_classpath);
          Commandline toExecute = (Commandline)m_cmd.clone();
          toExecute.setExecutable("java");
  
          // 
          // declare the service loader class
          //
  
          
toExecute.createArgument().setValue("org.apache.avalon.excalibur.service.ServiceLoader");
  
          //
          // preprocess the fileset into a vector of file arguments
          //
  
          for (int i=0; i<m_filesets.size(); i++) 
          {
              final FileSet fs = (FileSet) m_filesets.elementAt(i);
              final File base = fs.getDir( project );
              final DirectoryScanner ds = fs.getDirectoryScanner(project);
              final String[] files = ds.getIncludedFiles();
              for( int j=0; j<files.length; j++ )
              {
                  File target = new File( base, files[j] );
                  toExecute.createArgument().setValue( target.toString() );
              }
          }
  
  
          // add the target parameter
      
          toExecute.createArgument().setValue( "-target" );
          toExecute.createArgument().setValue( m_target );
          
          // add the priority parameter
      
          toExecute.createArgument().setValue( "-priority");
          toExecute.createArgument().setValue( m_priority );
          
          // add the policy parameter
      
          toExecute.createArgument().setValue( "-disposal");
          toExecute.createArgument().setValue( m_policy );
          
          // add the verbose parameter
      
          toExecute.createArgument().setValue( "-verbose");
          toExecute.createArgument().setValue( m_verbose );
  
          try
          {
              m_exe.setAntRun(project);
              m_exe.setWorkingDirectory( new 
File(System.getProperty("user.dir")));
  
              m_exe.setCommandline(toExecute.getCommandline());
              int ret = m_exe.execute();
          }
          catch( Throwable e )
          {
              e.printStackTrace();
              throw new BuildException( e.getMessage() );
          } 
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/phoenix/Block.java
  
  Index: Block.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.avalon.phoenix;
  
  import org.apache.avalon.framework.component.Component;
  
  /**
   * The main interface to implement for Applications hosted in Phoenix.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Federico Barbieri</a>
   */
  public interface Block 
      extends Component
  {
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/phoenix/BlockContext.java
  
  Index: BlockContext.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.avalon.phoenix;
  
  import java.io.File;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.logger.Logger;
  
  /**
   * Context via which Blocks communicate with container.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   */
  public interface BlockContext
      extends Context
  {
      String    APP_HOME_DIR      = "app.home";
      String    NAME              = "block.name";
  
      /**
       * Base directory of .sar application.
       *
       * TODO: Should this be getHomeDirectory() or getWorkingDirectory() or 
other?
       * TODO: Should a Block be able to declare it doesn't use the Filesystem? 
If
       * it declares this then it would be an error to call this method.
       *
       * @return the base directory
       */
      File getBaseDirectory();
  
      /**
       * Retrieve name of block.
       *
       * @return the name of block
       */
      String getName();
  
      /**
       * Retrieve logger coresponding to named category.
       *
       * TODO: Determine if this is really necessary ?
       *
       * @return the logger
       */
      Logger getLogger( String name );
  
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryBlock.java
  
  Index: DirectoryBlock.java
  ===================================================================
  /*
   * DirectoryBlock.java
   */
  
  package org.apache.demo;
  
  import java.io.File;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.phoenix.BlockContext;
  import org.apache.avalon.phoenix.Block;
  
  /**
   * This is a minimal demonstration service that returns the number of
   * files in a directory.  The purpose of this class is to falidate 
   * pipeline dependecy management.  Within that context this class 
   * is declared as a singleton service provider with no dependecies.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   */
  
  public class DirectoryBlock extends AbstractLogEnabled
  implements Block, Disposable, DirectoryService
  {
  
     /**
      * Returns the list of files.
      * @return File[]
      */
      public File[] getFiles( File file ) throws Exception
      {
          if( getLogger().isDebugEnabled() ) getLogger().debug("directory 
count");
          return file.listFiles();
      }
  
      public void dispose()
      {
          if( getLogger().isDebugEnabled() ) getLogger().debug("directory 
disposal");
      }
  
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryBlock.xinfo
  
  Index: DirectoryBlock.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
   File: DirectoryBlock.xinfo
   License: etc/LICENSE.TXT
   Copyright: Copyright (C) The Apache Software Foundation. All rights reserved.
   Copyright: OSM SARL 2001-2002, All Rights Reserved.  
   @author  Stephen McConnell
   @version 1.0 12/03/2001
  -->
  
  <blockinfo>
  
    <block>
      <version>1.0</version>
    </block>
  
    <!--
    services that are offered by this block 
    -->
  
    <services>
        <service name="org.apache.demo.DirectoryService" version="1.0"/>
    </services>
  
    <!--
    Implememtatiuon policy may one of the following enumerations:
    (a) SINGLETON, service is available for the lifetime of the manager
    (b) POOLED, the implementation implements Pool
    (c) TRANSIENT, manager is a factory of transient service instances
    -->
    <implementation policy="SINGLETON" />
  
  </blockinfo>
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryService.java
  
  Index: DirectoryService.java
  ===================================================================
  /**
   * File: DirectoryService.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2001-2002, All Rights Reserved.
   */
  package org.apache.demo;
  
  import java.io.File;
  
  /**
   * <code>DirectoryService</code>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   */
  
  public interface DirectoryService
  {
  
     /**
      * Returns the list of files.
      * @return File[]
      */
      public File[] getFiles( File file ) throws Exception;
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralBlock.java
  
  Index: ReferralBlock.java
  ===================================================================
  /*
   * ExampleBlock.java
   */
  
  package org.apache.demo;
  
  import java.io.File;
  
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.CascadingRuntimeException;
  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.context.Context;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.configuration.Configurable;
  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.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  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.phoenix.BlockContext;
  import org.apache.avalon.phoenix.Block;
  
  
  /**
   * This is a minimal demonstration server.
   * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   */
  
  public class ReferralBlock extends AbstractLogEnabled
  implements Block, Configurable, Contextualizable, Serviceable, Initializable, 
Disposable, ReferralService
  {
  
      private Configuration m_configuration;
      private Context m_context;
      private ServiceManager m_manager;
      private DirectoryService m_directory;
      private boolean m_disposed = false;
  
      //=================================================================
      // Contextualizable
      //=================================================================
  
      public void contextualize( Context context ) throws ContextException
      {
          m_context = context;
      }
  
      //=======================================================================
      // Configurable
      //=======================================================================
      
      public void configure( final Configuration config )
      throws ConfigurationException
      {
          m_configuration = config;
      }
      
      //=================================================================
      // 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
      {
          m_manager = manager;
      }
  
  
      //=======================================================================
      // Initializable
      //=======================================================================
  
      public void initialize()
      throws Exception
      {       
  
          //
          // verify current state
          //
  
          if( getLogger() == null ) throw new IllegalStateException(
            "Logging channel has not been assigned.");
  
          if( m_configuration == null ) throw new IllegalStateException(
            "Configuration has not been declared.");
  
          if( m_manager == null ) throw new IllegalStateException(
            "Manager has not been declared.");
  
          //
          // do something using the directory service
          //
  
          doTest();
  
      }
  
      //=======================================================================
      // ExampleService
      //=======================================================================
  
      public boolean doTest()
      {
          try
          {
              if( getLogger().isDebugEnabled() ) getLogger().debug("aquired 
directory service");
              m_directory = (DirectoryService) m_manager.lookup("directory");
              if( getLogger().isDebugEnabled() ) getLogger().debug("executing 
service");
              File[] files = m_directory.getFiles( new File( 
System.getProperty("user.dir") ));
              getLogger().info( files.length + " file(s)" );
              if( getLogger().isDebugEnabled() ) getLogger().debug("service 
execution ok");
          }
          catch( Throwable e )
          {
              throw new CascadingRuntimeException( "zutt", e );
          }
          return true;
      }
  
      //=======================================================================
      // Disposable
      //=======================================================================
      
      public void dispose()
      {
          if( m_disposed ) return;
          m_disposed = true;
          if( getLogger().isDebugEnabled() ) getLogger().debug("referral 
disposal");
          m_manager.release( m_directory );
          m_configuration = null;
          m_context = null;
          m_manager = null;
      }
  }
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralBlock.xinfo
  
  Index: ReferralBlock.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
   File: ExampleBlock.xinfo
   License: etc/LICENSE.TXT
   Copyright: Copyright (C) The Apache Software Foundation. All rights reserved.
   Copyright: OSM SARL 2001-2002, All Rights Reserved.  
   @author  Stephen McConnell
   @version 1.0 12/03/2001
  -->
  
  <blockinfo>
  
    <block>
      <version>1.0</version>
    </block>
  
    <!--
    services that are offered by this block 
    -->
  
    <services>
        <service name="org.apache.demo.ReferralService" version="1.0" />
    </services>
  
    <dependencies>
        <dependency>
            <role>directory</role>
            <service name="org.apache.demo.DirectoryService" version="1.0"/>
        </dependency>
    </dependencies>
  
  </blockinfo>
  
  
  
  
  1.1                  
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralService.java
  
  Index: ReferralService.java
  ===================================================================
  /**
   * File: ReferralService.java
   * License: etc/LICENSE.TXT
   * Copyright: Copyright (C) The Apache Software Foundation. All rights 
reserved.
   * Copyright: OSM SARL 2001-2002, All Rights Reserved.
   */
  package org.apache.demo;
  
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.ContextException;
  
  import org.omg.CORBA_2_3.ORB;
  
  /**
   * <code>ReferralService</code>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   */
  
  public interface ReferralService
  {
  
     /**
      * Returns TRUE is the demo is working correctly.
      * @return boolean TRUE if the test executes correctly
      */
      public boolean doTest();
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to