avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From f...@apache.org
Subject cvs commit: jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool AbstractPool.java DefaultObjectFactory.java DefaultPool.java ObjectFactory.java Pool.java PoolController.java ThreadSafePool.java
Date Sun, 25 Feb 2001 10:45:52 GMT
fede        01/02/25 02:45:52

  Added:       src/proposal-4.0/org/apache/avalon AbstractLoggable.java
                        CascadingError.java CascadingException.java
                        CascadingRuntimeException.java
                        CascadingThrowable.java Disposable.java
                        Initializable.java Loggable.java Modifiable.java
                        Parameters.java Poolable.java Recyclable.java
                        Resumable.java SingleThreaded.java Startable.java
                        Stoppable.java Suspendable.java ThreadSafe.java
                        changes.txt
               src/proposal-4.0/org/apache/avalon/component Component.java
                        ComponentException.java ComponentManager.java
                        ComponentNotAccessibleException.java
                        ComponentNotFoundException.java
                        ComponentSelector.java Composer.java
                        DefaultComponentManager.java
                        DefaultComponentSelector.java Recomposer.java
               src/proposal-4.0/org/apache/avalon/configuration
                        AbstractConfiguration.java Configurable.java
                        Configuration.java ConfigurationBuilder.java
                        ConfigurationException.java
                        DefaultConfiguration.java
                        DefaultConfigurationBuilder.java
                        Reconfigurable.java SAXConfigurationHandler.java
               src/proposal-4.0/org/apache/avalon/container
                        AbstractCamelotDeployer.java AbstractContainer.java
                        AbstractDeployer.java AbstractZipDeployer.java
                        AvalonState.java CamelotUtil.java Container.java
                        ContainerException.java DefaultFactory.java
                        DefaultLoader.java DefaultLocator.java
                        DefaultLocatorRegistry.java DefaultRegistry.java
                        Deployer.java DeployerUtil.java
                        DeploymentException.java Entry.java Factory.java
                        FactoryException.java Info.java Loader.java
                        Locator.java LocatorRegistry.java MetaInfo.java
                        Registry.java RegistryException.java State.java
               src/proposal-4.0/org/apache/avalon/context Context.java
                        Contextualizable.java DefaultContext.java
                        Recontextualizable.java Resolvable.java
               src/proposal-4.0/org/apache/avalon/datasource
                        DataSourceComponent.java J2eeDataSource.java
                        JdbcConnection.java JdbcConnectionPool.java
                        JdbcDataSource.java
               src/proposal-4.0/org/apache/avalon/log
                        AvalonLogFormatter.java DefaultLogManager.java
               src/proposal-4.0/org/apache/avalon/processor Matcher.java
                        Pipeline.java ProcessorPipeline.java
                        ProcessorTree.java Stage.java
               src/proposal-4.0/org/apache/avalon/security
                        AbstractPolicy.java DefaultPolicy.java
                        PolicyClassLoader.java
               src/proposal-4.0/org/apache/avalon/thread
                        DefaultThreadManager.java ThreadContext.java
                        ThreadManager.java ThreadPool.java
                        WorkerThread.java
               src/proposal-4.0/org/apache/avalon/util
                        ArrayEnumeration.java ArrayStack.java
                        BinaryHeap.java Circuit.java CircularBuffer.java
                        CircularDependencyException.java
                        DependencyGraph.java Enum.java
                        IteratorEnumeration.java ListUtils.java Lock.java
                        LockException.java ObjectUtil.java Primes.java
                        PriorityQueue.java PropertyException.java
                        PropertyUtil.java ProxyClassLoader.java
                        ProxyGenerator.java StringUtil.java ValuedEnum.java
                        Version.java
               src/proposal-4.0/org/apache/avalon/util/cli
                        AbstractMain.java AbstractParserControl.java
                        CLArgsParser.java CLOption.java
                        CLOptionDescriptor.java CLUtil.java
                        ParserControl.java
               src/proposal-4.0/org/apache/avalon/util/i18n
                        ResourceGroup.java XMLResourceBundle.java
                        XMLResourceBundleFactory.java XPathAPI.java
               src/proposal-4.0/org/apache/avalon/util/internet
                        CRLFInputStream.java CRLFOutputStream.java
                        InternetException.java InternetReply.java
                        InternetStream.java LineReader.java LineWriter.java
               src/proposal-4.0/org/apache/avalon/util/io
                        ByteTerminatedInputStream.java
                        DirectoryFileFilter.java ExtensionFileFilter.java
                        FileUtil.java IOUtil.java MergedInputStreams.java
                        ResettableFileInputStream.java
               src/proposal-4.0/org/apache/avalon/util/pool
                        AbstractPool.java DefaultObjectFactory.java
                        DefaultPool.java ObjectFactory.java Pool.java
                        PoolController.java ThreadSafePool.java
  Log:
  Added 4.0 proposal.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/AbstractLoggable.java
  
  Index: AbstractLoggable.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 file.
   */
  package org.apache.avalon;
  
  import org.apache.log.Logger;
  import org.apache.avalon.component.Component;
  
  /**
   * Helper class to inherit from.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractLoggable
      implements Component, Loggable
  {
      protected Logger    m_logger;
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      protected final Logger getLogger()
      {
          return m_logger;
      }
  
      protected void setupLogger( final Component component )
      {
          setupLogger( component, (String)null );
      }
  
      protected void setupLogger( final Component component, final String subCategory )
      {
          if( component instanceof Loggable )
          {
              Logger logger = m_logger;
  
              if( null != subCategory )
              {
                  logger = m_logger.getChildLogger( subCategory );
              }
              
              ((Loggable)component).setLogger( logger );
          }
      }
  
      protected void setupLogger( final Component component, final Logger logger )
      {
          if( component instanceof Loggable )
          {
              ((Loggable)component).setLogger( logger );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/CascadingError.java
  
  Index: CascadingError.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 file.
   */
  package org.apache.avalon;
  
  /**
   * Class from which all exceptions should inherit. 
   * Allows recording of nested exceptions.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class CascadingError 
      extends Error
      implements CascadingThrowable
  {
      private final Throwable         m_throwable;
  
      /**
       * Construct a new <code>CascadingError</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public CascadingError( final String message, final Throwable throwable ) 
      {
          super( message );
          m_throwable = throwable;
      }
  
      /**
       * Retrieve root cause of the exception.
       *
       * @return the root cause
       */
      public final Throwable getCause()
      {
          return m_throwable;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/CascadingException.java
  
  Index: CascadingException.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 file.
   */
  package org.apache.avalon;
  
  /**
   * Class from which all exceptions should inherit. 
   * Allows recording of nested exceptions.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CascadingException 
      extends Exception
      implements CascadingThrowable
  {
      private final Throwable         m_throwable;
  
      /**
       * Construct a new <code>CascadingException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public CascadingException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>CascadingException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public CascadingException( final String message, final Throwable throwable ) 
      {
          super( message );
          m_throwable = throwable;
      }
  
      /**
       * Retrieve root cause of the exception.
       *
       * @return the root cause
       */
      public final Throwable getCause()
      {
          return m_throwable;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/CascadingRuntimeException.java
  
  Index: CascadingRuntimeException.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 file.
   */
  package org.apache.avalon;
  
  /**
   * Class from which all exceptions should inherit. 
   * Allows recording of nested exceptions.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class CascadingRuntimeException 
      extends RuntimeException
      implements CascadingThrowable
  {
      private final Throwable         m_throwable;
  
      /**
       * Construct a new <code>CascadingRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public CascadingRuntimeException( final String message, final Throwable throwable ) 
      {
          super( message );
          m_throwable = throwable;
      }
  
      /**
       * Retrieve root cause of the exception.
       *
       * @return the root cause
       */
      public final Throwable getCause()
      {
          return m_throwable;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/CascadingThrowable.java
  
  Index: CascadingThrowable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * Interface which all cascadign throwables should implement. 
   * Allows recording of nested exceptions.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface CascadingThrowable 
  {
      Throwable getCause();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Disposable.java
  
  Index: Disposable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This interface should be implemented by those classes that
   * need to provide a service that requires some resources to be
   * initialized before being able to operate and properly destroyed
   * before termination and unloading.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Disposable 
  {
      /**
       * Destroys the service. This method is guaranteed to be called always
       * after the stop() method if this class implements <code>Stoppable</code>.
       */
      void dispose()
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Initializable.java
  
  Index: Initializable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This interface should be implemented by those classes that
   * need to provide a service that requires some resources to be
   * initialized before being able to operate.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Initializable
  {
      /**
       * Initialize the service. This method is guaranteed to be called always
       * after methods in <code>Configurable</code> and <code>Component</code>, 
       * if the class implements those interfaces and before the run() method
       * if the class implements <code>Runnable</code>.
       */
      void init()
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Loggable.java
  
  Index: Loggable.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 file.
   */
  package org.apache.avalon;
  
  import org.apache.log.Logger;
  
  /**
   * Interface through which to provide Loggers.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Loggable
  {
      void setLogger( Logger logger );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Modifiable.java
  
  Index: Modifiable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This interface is implemented by those classes that change
   * their behavior/results over time (non-ergodic).
   *
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   */
  public interface Modifiable
  {
      /**
       * Queries the class to estimate its ergodic period termination.
       * <br>
       * This method is called to ensure the validity of a cached product. It
       * is the class responsibility to provide the fastest possible
       * implementation of this method or, whether this is not possible and the
       * costs of the change evaluation is comparable to the production costs,
       * to return <b>true</b> directly with no further delay, thus reducing
       * the evaluation overhead to a minimum.
       *
       * @return <b>true</b> if the class ergodic period is over and the class
       *         would behave differently if processed again, <b>false</b> if the
       *         resource is still ergodic so that it doesn't require
       *         reprocessing.
       */
      boolean modifiedSince( long date );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Parameters.java
  
  Index: Parameters.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 file.
   */
  package org.apache.avalon;
  
  import java.util.Iterator;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.List;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  
  /**
   *
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   */
  public final class Parameters
  {
      protected HashMap            m_parameters;
  
      /**
       * Create a new <code>Parameters</code> instance.
       */
      public Parameters()
      {
          m_parameters = new HashMap();
      }
  
      /**
       * Set the <code>String</code> value of a specified parameter.
       * <p />
       * If the specified value is <b>null</b> the parameter is removed.
       *
       * @return The previous value of the parameter or <b>null</b>.
       */
      public String setParameter( final String name, final String value )
      {
          if( null == name )
          {
              return null;
          }
  
          if( null == value )
          {
              return (String)m_parameters.remove( name );
          }
  
          return (String)m_parameters.put( name, value );
      }
  
      /**
       * Return an <code>Enumeration</code> view of all parameter names.
       */
      public Iterator getParameterNames()
      {
          return m_parameters.keySet().iterator();
      }
  
      /**
       * Check if the specified parameter can be retrieved.
       */
      public boolean isParameter( final String name )
      {
          return m_parameters.containsKey( name );
      }
  
      /**
       * Retrieve the <code>String</code> value of the specified parameter.
       * <p />
       * If the specified parameter cannot be found, <b>null</b> is returned.
       */
      protected String getParameter( final String name )
      {
          if( null == name )
          {
              return null;
          }
  
          return (String)m_parameters.get( name );
      }
  
      /**
       * Retrieve the <code>String</code> value of the specified parameter.
       * <p />
       * If the specified parameter cannot be found, <code>defaultValue</code>
       * is returned.
       */
      public String getParameter( final String name, final String defaultValue )
      {
          final String value = getParameter( name );
  
          if( null == value )
          {
              return defaultValue;
          }
          else
          {
              return value;
          }
      }
  
      /**
       * Retrieve the <code>int</code> value of the specified parameter.
       * <p />
       * If the specified parameter cannot be found, <code>defaultValue</code>
       * is returned.
       */
      public int getParameterAsInteger( final String name, final int defaultValue )
      {
          final String value = getParameter( name );
  
          if( null == value )
          {
              return defaultValue;
          }
  
          try
          {
              if( value.startsWith("0x") )
              {
                  return Integer.parseInt( value.substring(2), 16 );
              }
              else if( value.startsWith("0o") )
              {
                  return Integer.parseInt( value.substring(2), 8 );
              }
              else if( value.startsWith("0b") )
              {
                  return Integer.parseInt( value.substring(2), 2 );
              }
              else
              {
                  return Integer.parseInt( value );
              }
          }
          catch( final NumberFormatException nfe )
          {
              return defaultValue;
          }
      }
  
      /**
       * Retrieve the <code>long</code> value of the specified parameter.
       * <p />
       * If the specified parameter cannot be found, <code>defaultValue</code>
       * is returned.
       */
      public long getParameterAsLong( final String name, final long defaultValue )
      {
          final String value = getParameter( name );
  
          if( null == value )
          {
              return defaultValue;
          }
  
          try
          {
              if( value.startsWith("0x") )
              {
                  return Long.parseLong( value.substring(2), 16 );
              }
              else if( value.startsWith("0o") )
              {
                  return Long.parseLong( value.substring(2), 8 );
              }
              else if( value.startsWith("0b") )
              {
                  return Long.parseLong( value.substring(2), 2 );
              }
              else
              {
                  return Long.parseLong(value);
              }
          }
          catch( final NumberFormatException nfe )
          {
              return defaultValue;
          }
      }
  
      /**
       * Retrieve the <code>float</code> value of the specified parameter.
       * <p />
       * If the specified parameter cannot be found, <code>defaultValue</code>
       * is returned.
       */
      public float getParameterAsFloat( final String name, final float defaultValue )
      {
          final String value = getParameter( name );
  
          if( null == value )
          {
              return defaultValue;
          }
  
          try
          {
              return Float.parseFloat(value);
          }
          catch( final NumberFormatException nfe )
          {
              return defaultValue;
          }
      }
  
      /**
       * Retrieve the <code>boolean</code> value of the specified parameter.
       * <p />
       * If the specified parameter cannot be found, <code>defaultValue</code>
       * is returned.
       */
      public boolean getParameterAsBoolean( final String name, final boolean defaultValue )
      {
          final String value = getParameter( name );
  
          if( null == value )
          {
              return defaultValue;
          }
  
          if( value.equalsIgnoreCase("true") )
          {
              return true;
          }
  
          if( value.equalsIgnoreCase("false") )
          {
              return(false);
          }
  
          return defaultValue;
      }
  
      /**
       * Merge parameters from another <code>Parameters</code> instance
       * into this.
       *
       * @return This <code>Parameters</code> instance.
       */
      public Parameters merge( final Parameters other )
      {
          final Iterator names = other.getParameterNames();
  
          while( names.hasNext() )
          {
              final String name = (String) names.next();
              final String value = other.getParameter( name );
  
              setParameter( name, value );
          }
  
          return this;
      }
  
      /**
       * Create a <code>Parameters</code> object from a <code>Configuration</code>
       * object.
       */
      public static Parameters fromConfiguration( final Configuration configuration  )
          throws ConfigurationException
      {
          if( null == configuration )
          {
              throw new ConfigurationException( "You cannot convert to parameters with " +
                                                "a null Configuration");
          }
  
          final Iterator parameters = configuration.getChildren("parameter");
          final Parameters param = new Parameters();
  
          while( parameters.hasNext() )
          {
              try {
                  final Configuration child =(Configuration) parameters.next();
                  final String name = child.getAttribute("name");
                  final String value = child.getAttribute("value");
                  param.setParameter( name, value );
              } catch (ClassCastException cce) {
                  // ignore this.  Temporary work around until the Iterator
                  // is guaranteed to return Configuration values.  Unfortunately
                  // there are problems with empty strings getting in there.
              } catch (Exception e) {
                  throw new ConfigurationException("Cannot process Configurable", e);
              }
          }
  
          return param;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Poolable.java
  
  Index: Poolable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * Poolable marker interface. 
   *
   * Components implement this interface if it is reasonable to 
   * Pool the object. Components that don't implement this interface 
   * will be created anew via a factory.
   *
   * NB: It was a deliberat e choice not to extend Component. This will have to 
   * be reassed once we see it in action.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Poolable 
  {
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Recyclable.java
  
  Index: Recyclable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This interface standardizes the behaviour of a recyclable object.
   * A recyclable object is defined as an object that can be used to
   * encapsulate another object without being altered by its content.
   * Therefore, a recyclable object may be recycled and reused many times.
   * 
   * This is helpful in cases where recyclable objects are continously 
   * created and destroied, causing a much greater amount of garbage to 
   * be collected by the JVM garbage collector. By making it recyclable, 
   * it is possible to reduce the GC execution time thus incrementing the 
   * overall performance of a process and decrementing the chance of 
   * memory overflow.
   * 
   * Every implementation must provide their own method to allow this 
   * recyclable object to be reused by setting its content.
   *
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Recyclable
      extends Poolable
  {
      /**
       * This method should be implemented to remove all costly resources
       * in object. These resources can be object references, database connections,
       * threads etc. What is categorised as "costly" resources is determined on
       * a case by case analysis.
       */
      void recycle();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Resumable.java
  
  Index: Resumable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This is used to restart execturion after temporarily halt.
   * The halt may have been for some re- configuring|composing|contextualizing
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Resumable 
  {
      /**
       * Resumes the component.
       */
      void resume();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/SingleThreaded.java
  
  Index: SingleThreaded.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 file.
   */
  package org.apache.avalon;
  
  /**
   * A interface to mark a component as not ThreadSafe.
   *
   * NB: It was a deliberat e choice not to extend Component. This will have to 
   * be reassed once we see it in action.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface SingleThreaded 
  {
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Startable.java
  
  Index: Startable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This interface is the dual interface of Stoppable.
   *
   * It provides a method through which components can be "started"
   * without requiring a thread. Useful for reactive or passive objects.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Startable 
  {
      /**
       * Starts the component.
       */
      void start()
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Stoppable.java
  
  Index: Stoppable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This interface is the dual interface of the <code>java.lang.Runnable</code>
   * interface and provides a hook to safely stop the thread of execution.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   */
  public interface Stoppable 
  {
      /**
       * Stops the current thread of execution.
       */
      void stop()
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/Suspendable.java
  
  Index: Suspendable.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 file.
   */
  package org.apache.avalon;
  
  /**
   * This is used to temporarily halt execution of a component.
   * The execution may be halted so that you can reconfigure/
   * recompose/recontextualize component
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Suspendable 
  {
      /**
       * Suspends the component.
       */
      void suspend();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/ThreadSafe.java
  
  Index: ThreadSafe.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 file.
   */
  package org.apache.avalon;
  
  /**
   * A interface to mark a component as ThreadSafe or reentrant.
   *
   * NB: It was a deliberat e choice not to extend Component. This will have to 
   * be reassed once we see it in action.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ThreadSafe
  {
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/changes.txt
  
  Index: changes.txt
  ===================================================================
  -All Context related classes moved to org.apache.avalon.context.
  -All Configuration related classes moved to org.apache.avalon.configuration;
  -All Component related classes moved to org.apache.avalon.component;
  -All Stage related classes moved to org.apache.avalon.processor;
  -Added to processor Matcher and ProcessorTree.
  -Removed frm processor DefaultPipeLine and ProcessingStage.
  -Stage's process return a boolean.
  -Renamed org.apache.avalon.camelot to org.apache.avalon.container.
  -Removed org.apache.avalon.util.lang.
  -Removed all test suites.
  -package org.apache.avalon.util.thread moved to package org.apache.avalon.thread.
  -package org.apache.avalon.util.security moved to package org.apache.avalon.security.
  -package org.apache.avalon.util.datasource moved to package org.apache.avalon.datasource.
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/Component.java
  
  Index: Component.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * This interface identifies classes that can be used as <code>Components</code>
   * by a <code>Composer</code>.
   * <br />
   *
   * The contract surrounding the <code>Component</code> is that it is
   * used, but not a user.  When a class implements this interface, it
   * is stating that other entities may use that class.  As part of the
   * contract with the system, a <code>Component</code> must always
   * declare an empty constructor.
   * <br />
   *
   * A <code>Component</code> is the basic building block of the Avalon.
   * When a class implements this interface, it allows itself to be
   * managed by a <code>ComponentManager</code> and used by an outside
   * element called a <code>Composer</code>.  The <code>Composer</code>
   * must know what type of <code>Component</code> it is accessing, so
   * it will re-cast the <code>Component</code> into the type it needs.
   * <br />
   *
   * In order for a <code>Component</code> to be useful you must either
   * extend this interface, or implement this interface in conjunction
   * with one that actually has methods.  The new interface is the contract
   * with the <code>Composer</code> that this is a particular type of
   * component, and as such it can perform those functions on that type
   * of component.
   * <br />
   *
   * For example, we want a component that performs a logging function
   * so we extend the <code>Component</code> to be a <code>LoggingComponent</code>.
   *
   * <pre>
   *   interface LoggingComponent extends Component {
   *       log(String message);
   *   }
   * </pre>
   *
   * Now all <code>Composer</code>s that want to use this type of component,
   * will re-cast the <code>Component</code> into a <code>LoggingComponent</code>
   * and the <code>Composer</code> will be able to use the <code>log</code>
   * method.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:bloritsch@apache.org>Berin Loritsch</a>
   */
  public interface Component
  {
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/ComponentException.java
  
  Index: ComponentException.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 file.
   */
  package org.apache.avalon.component;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * This base class of exceptions thrown by ComponentManager.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   */
  public class ComponentException 
      extends CascadingException
  {
      /**
       * Construct a new <code>ComponentException</code> instance.
       */
      public ComponentException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/ComponentManager.java
  
  Index: ComponentManager.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * A <code>ComponentManager</code> selects <code>Component</code>s based on a
   * role.  The contract is that all the <code>Component</code>s implement the
   * differing roles and there is one <code>Component</code> per role.  If you
   * need to select on of many <code>Component</code>s that implement the same
   * role, then you need to use a <code>ComponentSelector</code>.  Roles are the
   * full interface name.
   *
   * A role is better understood by the analogy of a play.  There are many
   * different roles in a script.  Any actor or actress can play any given part
   * and you get the same results (phrases said, movements made, etc.).  The exact
   * nuances of the performance is different.
   *
   * Below is a list of things that might be considered the different roles:
   *
   * <ul>
   *   <li> InputAdaptor and OutputAdaptor</li>
   *   <li> Store and Spool</li>
   * </ul>
   *
   * The <code>ComponentManager</code> does not specify the methodology of
   * getting the <code>Component</code>, merely the interface used to get it.
   * Therefore the <code>ComponentManager</code> can be implemented with a
   * factory pattern, an object pool, or a simple Hashtable.
   *
   * @see org.apache.avalon.Component
   * @see org.apache.avalon.Composer
   * @see org.apache.avalon.ComponentSelector
   *
   * @author <a href="mailto:scoobie@betaversion.org">Federico Barbieri</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:bloritsch@apache.org>Berin Loritsch</a>
   */
  public interface ComponentManager
  {
      /**
       * Get the <code>Component</code> associated with the given role.  For
       * instance, If the <code>ComponentManager</code> had a
       * <code>LoggerComponent</code> stored and referenced by role, I would use
       * the following call:
       * <pre>
       * try {
       *     LoggerComponent log;
       *     log = (LoggerComponent) manager.lookup("org.apache.avalon.blocks.Logger");
       * } catch (...) {
       *     ...
       * }
       * </pre>
       *
       * @param name The role name of the <code>Component</code> to retrieve.
       *
       * @exception ComponentNotFoundException If the given role is not associated
       *                                       with a <code>Component</code>.
       * @exception ComponentNotAccessibleException If a <code>Component</code>
       *                                            instance cannot be created.
       */
      Component lookup( String role ) 
          throws ComponentNotFoundException, 
                 ComponentNotAccessibleException;
  
      /**
       * Return the <code>Component</code> when you are finished with it.  This
       * allows the <code>ComponentManager</code> to handle the End-Of-Life Lifecycle
       * events associated with the Component.  Please note, that no Exceptions
       * should be thrown at this point.  This is to allow easy use of the
       * ComponentManager system without having to trap Exceptions on a release.
       *
       * @param component The Component we are releasing.
       */
      void release(Component component);
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/ComponentNotAccessibleException.java
  
  Index: ComponentNotAccessibleException.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * This exception is thrown by the <code>ComponentManager</code> when a
   * <code>Component</code> cannot be accessed.
   *
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   */
  public class ComponentNotAccessibleException 
      extends ComponentException
  {
      /**
       * Construct a new <code>ComponentNotAccessibleException</code> instance.
       */
      public ComponentNotAccessibleException( final String message )
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>ComponentNotAccessibleException</code> instance.
       */
      public ComponentNotAccessibleException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/ComponentNotFoundException.java
  
  Index: ComponentNotFoundException.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * This exception is thrown by the <code>ComponentManager</code> when a
   * <code>Component</code> cannot be found.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   */
  public final class ComponentNotFoundException 
  extends ComponentException
  {
      /**
       * Constructs the ComponentNotFoundException with an initial
       * message.
       */
      public ComponentNotFoundException( final String message )
      {
          this( message, null );
      }
  
      /**
       * Constructs the ComponentNotFoundException with an initial
       * message.
       */
      public ComponentNotFoundException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/ComponentSelector.java
  
  Index: ComponentSelector.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * A <code>ComponentSelector</code> selects <code>Component</code>s based on a
   * hint.  The contract is that all the <code>Component</code>s implement the
   * same role.
   *
   * A role is better understood by the analogy of a play.  There are many
   * different roles in a script.  Any actor or actress can play any given part
   * and you get the same results (phrases said, movements made, etc.).  The exact
   * nuances of the performance is different.
   *
   * Below is a list of things that might be considered the same role:
   *
   * <ul>
   *   <li> XMLInputAdaptor and PropertyInputAdaptor</li>
   *   <li> FileGenerator   and SQLGenerator</li>
   * </ul>
   *
   * The <code>ComponentSelector</code> does not specify the methodology of
   * getting the <code>Component</code>, merely the interface used to get it.
   * Therefore the <code>ComponentSelector</code> can be implemented with a
   * factory pattern, an object pool, or a simple Hashtable.
   *
   * @see org.apache.avalon.Component
   * @see org.apache.avalon.Composer
   * @see org.apache.avalon.ComponentManager
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public interface ComponentSelector 
      extends Component
  {
      /**
       * Select the <code>Component</code> associated with the given hint.
       * For instance, If the <code>ComponentSelector</code> has a
       * <code>Generator</code> stored and referenced by a URL, I would use the
       * following call:
       *
       * <pre>
       * try {
       *     Generator input;
       *     input = (Generator) selector.select(new URL("foo://demo/url"));
       * } catch (...) {
       *     ...
       * }
       * </pre>
       *
       * @param name A hint to retrieve the correct <code>Component</code>.
       *
       * @exception ComponentNotFoundException If the given role is not associated
       *                                       with a <code>Component</code>.
       * @exception ComponentNotAccessibleException If a <code>Component</code>
       *                                            instance cannot be created.
       */
      Component select( Object hint ) 
          throws ComponentNotFoundException, 
                 ComponentNotAccessibleException;
  
      /**
       * Return the <code>Component</code> when you are finished with it.  This
       * allows the <code>ComponentManager</code> to handle the End-Of-Life Lifecycle
       * events associated with the Component.  Please note, that no Exceptions
       * should be thrown at this point.  This is to allow easy use of the
       * ComponentManager system without having to trap Exceptions on a release.
       *
       * @param component The Component we are releasing.
       */
      void release(Component component);
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/Composer.java
  
  Index: Composer.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * A composer is a class that need to connect to software components using
   * a "role" abstraction, thus not depending on particular implementations
   * but on behavioral interfaces.
   * <br />
   *
   * The contract surrounding a <code>Composer</code> is that it is a user.
   * The <code>Composer</code> is able to use <code>Components</code> managed
   * by the <code>ComponentManager</code> it was initialized with.  As part
   * of the contract with the system, the instantiating entity must call
   * the <code>setComponenetManager</code> method before the
   * <code>Composer</code> can be considered valid.  The
   * <code>setComponentManager</code> method must be called after the constructor
   * and before any user methods.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public interface Composer
  {
      /**
       * Pass the <code>ComponentManager</code> to the <code>composer</code>.
       * The <code>Composer</code> implementation should use the specified
       * <code>ComponentManager</code> to acquire the components it needs for
       * execution.
       *
       * @param manager The <code>ComponentManager</code> which this
       *                <code>Composer</code> uses.
       */
      void compose( ComponentManager componentManager );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/DefaultComponentManager.java
  
  Index: DefaultComponentManager.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 file.
   */
  package org.apache.avalon.component;
  
  import java.util.HashMap;
  import java.util.Iterator;
  
  /**
   * This class is a static implementation of a ComponentManager. Allow ineritance
   * and extention so you can generate a tree of ComponentManager each defining
   * Component scope.
   *
   * @author <a href="mailto:scoobie@pop.systemy.it">Federico Barbieri</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultComponentManager
      implements ComponentManager
  {
      protected final HashMap               m_components = new HashMap();
      protected final ComponentManager      m_parent;
  
      public DefaultComponentManager()
      {
          this( null );
      }
  
      public DefaultComponentManager( final ComponentManager parent )
      {
          m_parent = parent;
      }
  
      public Component lookup( final String role )
          throws ComponentNotFoundException, 
                 ComponentNotAccessibleException
      {
          final Component component = (Component)m_components.get( role );
  
          if( null != component )
          {
              return component;
          }
          else if( null != m_parent )
          {
              return m_parent.lookup( role );
          }
          else
          {
              throw new ComponentNotFoundException("Unable to provide implementation for " + role);
          }
      }
  
      public void put( final String name, final Component component )
      {
          m_components.put( name, component );
      }
  
      public void release( final Component component )
      {
          // if the ComponentManager handled pooling, it would be
          // returned to the pool here.
      }
  
      public String toString() 
      {
          final StringBuffer buffer = new StringBuffer();
          final Iterator components = m_components.keySet().iterator();
          buffer.append( "Components:" );
  
          while( components.hasNext() )
          {
              buffer.append( "[" );
              buffer.append( components.next() );
              buffer.append( "]" );
          }
          
          return buffer.toString();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/DefaultComponentSelector.java
  
  Index: DefaultComponentSelector.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 file.
   */
  package org.apache.avalon.component;
  
  import java.util.HashMap;
  
  /**
   * This is the default implementation of the ComponentSelector
   */
  public class DefaultComponentSelector implements ComponentSelector {
  
      protected final HashMap components = new HashMap();
  
      public DefaultComponentSelector() {
          // do nothing
      }
  
      /**
       * Select the desired component.  It does not cascade, neither
       * should it.
       */
      public Component select(Object hint)
      throws ComponentNotFoundException,
             ComponentNotAccessibleException {
  
          final Component component = (Component) components.get(hint);
  
          if ( component != null ) {
              return component;
          } else {
              throw new ComponentNotFoundException("Unable to provide implementation for " + hint.toString());
          }
      }
  
      public void release( final Component component )
      {
          // if the ComponentManager handled pooling, it would be
          // returned to the pool here.
      }
  
      /**
       * Populate the ComponentSelector.
       */
      public void put(final Object hint, final Component component) {
          this.components.put(hint, component);
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/component/Recomposer.java
  
  Index: Recomposer.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 file.
   */
  package org.apache.avalon.component;
  
  /**
   * Extends composer to allow recomposing.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Recomposer
      extends Composer
  {
      void recompose( ComponentManager componentManager );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/AbstractConfiguration.java
  
  Index: AbstractConfiguration.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 file.
   */
  package org.apache.avalon.configuration;
  
  import java.util.Iterator;
  
  /**
   * This is an abstract <code>Configuration</code> implementation that deals
   * with methods that can be abstracted away from underlying implementations.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/02/25 10:45:44 $
   * @deprecated This has been deprecated in favour of configuration interface in org.apache.avalon.configuration interface
   */
  public abstract class AbstractConfiguration
      implements Configuration
  {
      private static int PREFIX = 2;
  
      /**
       * Returns the value of the configuration element as an <code>int</code>.
       */
      public int getValueAsInt()
          throws ConfigurationException
      {
          final String value = getValue();
          try
          {
              if( value.startsWith("0x") )
              {
                  return Integer.parseInt( value.substring(AbstractConfiguration.PREFIX), 16 );
              }
              else if( value.startsWith("0o") )
              {
                  return Integer.parseInt( value.substring(AbstractConfiguration.PREFIX), 8 );
              }
              else if( value.startsWith("0b") )
              {
                  return Integer.parseInt( value.substring(AbstractConfiguration.PREFIX), 2 );
              }
              else
              {
                  return Integer.parseInt( value );
              }
          }
          catch( final Exception nfe )
          {
              throw
                  new ConfigurationException( "Cannot parse the value of the configuration " +
                                              "element \"" + getName() + "\" as an integer" );
          }
      }
  
      /**
       * Returns the value of the configuration element as an <code>int</code>.
       */
      public int getValueAsInt( final int defaultValue )
      {
          try
          {
              return getValueAsInt();
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>long</code>.
       */
      public long getValueAsLong()
          throws ConfigurationException
      {
          final String value = getValue();
          try
          {
              if( value.startsWith("0x") )
              {
                  return Long.parseLong( value.substring(2), 16 );
              }
              else if( value.startsWith("0o") )
              {
                  return Long.parseLong( value.substring(2), 8);
              }
              else if( value.startsWith("0b") )
              {
                  return Long.parseLong(value.substring(2),2);
              }
              else return Integer.parseInt(value);
          }
          catch( final Exception nfe )
          {
              throw new ConfigurationException( "Cannot parse the value of the " +
                                                "configuration element \"" + getName() +
                                                "\" as a long" );
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>long</code>.
       */
      public long getValueAsLong( final long defaultValue )
      {
          try
          {
              return getValueAsLong();
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>float</code>.
       */
      public float getValueAsFloat()
          throws ConfigurationException
      {
          final String value = getValue();
          try
          {
              return Float.parseFloat( value );
          }
          catch( final Exception nfe )
          {
              throw new ConfigurationException( "Cannot parse the value of the " +
                                                "configuration element \"" + getName() +
                                                "\" as a float" );
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>float</code>.
       */
      public float getValueAsFloat( final float defaultValue )
      {
          try
          {
              return getValueAsFloat();
          }
          catch( final ConfigurationException ce )
          {
              return(defaultValue);
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>boolean</code>.
       */
      public boolean getValueAsBoolean()
          throws ConfigurationException
      {
          final String value = getValue();
          if( value.equals("true") ) return true;
          else if( value.equals("false") ) return false;
          else
          {
              throw new ConfigurationException( "Cannot parse the value of the " +
                                                "configuration element \"" +
                                                getName() + "\" as a boolean" );
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>boolean</code>.
       */
      public boolean getValueAsBoolean( final boolean defaultValue )
      {
          try
          {
              return getValueAsBoolean();
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the configuration element as a <code>String</code>.
       */
      public String getValue( final String defaultValue )
      {
          try
          {
              return getValue();
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as an
       * <code>int</code>.
       */
      public int getAttributeAsInt( final String name )
          throws ConfigurationException
      {
          final String value = getAttribute( name );
          try
          {
              if( value.startsWith("0x") )
              {
                  return Integer.parseInt( value.substring(2), 16 );
              }
              else if( value.startsWith("0o") )
              {
                  return Integer.parseInt( value.substring(2), 8);
              }
              else if( value.startsWith("0b") )
              {
                  return Integer.parseInt(value.substring(2),2);
              }
              else
              {
                  return Integer.parseInt(value);
              }
          }
          catch( final Exception nfe )
          {
              throw new ConfigurationException( "Cannot parse the value of the attribute \"" +
                                                name + "\" of the configuration element \"" +
                                                getName() + "\" as an integer" );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as an
       * <code>int</code>.
       */
      public int getAttributeAsInt( final String name, final int defaultValue )
      {
          try
          {
              return getAttributeAsInt( name );
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>long</code>.
       */
      public long getAttributeAsLong( final String name )
          throws ConfigurationException
      {
          final String value = getAttribute( name );
  
          try
          {
              if( value.startsWith("0x") )
              {
                  return Long.parseLong( value.substring(2), 16 );
              }
              else if( value.startsWith("0o") )
              {
                  return Long.parseLong( value.substring(2), 8 );
              }
              else if( value.startsWith("0b") )
              {
                  return Long.parseLong( value.substring(2), 2);
              }
              else
              {
                  return Integer.parseInt( value );
              }
          }
          catch( final Exception nfe )
          {
              throw new ConfigurationException( "Cannot parse the value of the attribute \"" +
                                                name + "\" of the configuration element \"" +
                                                getName() + "\" as a long" );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>long</code>.
       */
      public long getAttributeAsLong( final String name, final long defaultValue )
      {
          try
          {
              return getAttributeAsLong( name );
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>float</code>.
       */
      public float getAttributeAsFloat( final String name )
          throws ConfigurationException
      {
          final String value = getAttribute( name );
          try
          {
              return Float.parseFloat( value );
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Cannot parse the value of the attribute \"" +
                                                name + "\" of the configuration element \"" +
                                                getName() + "\" as a float" );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>float</code>.
       */
      public float getAttributeAsFloat( final String name, final float defaultValue )
      {
          try
          {
              return getAttributeAsFloat( name );
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>boolean</code>.
       */
      public boolean getAttributeAsBoolean( final String name )
          throws ConfigurationException
      {
          final String value = getAttribute( name );
  
          if( value.equals("true") ) return true;
          else if( value.equals("false") ) return false;
          else
          {
              throw new ConfigurationException( "Cannot parse the value of the attribute \"" +
                                                name + "\" of the configuration element \"" +
                                                getName() + "\" as a boolean" );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>boolean</code>.
       */
      public boolean getAttributeAsBoolean( final String name, final boolean defaultValue )
      {
          try
          {
              return getAttributeAsBoolean( name );
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>String</code>.
       */
      public String getAttribute( final String name, final String defaultValue )
      {
          try
          {
              return getAttribute( name );
          }
          catch( final ConfigurationException ce )
          {
              return defaultValue;
          }
      }
  
      /**
       * Return the first <code>Configuration</code> object child of this
       * associated with the given name.
       */
      public Configuration getChild( final String name )
      {
          final Iterator iterator = getChildren( name );
          if( iterator.hasNext() )
          {
              return (Configuration)iterator.next();
          }
          else
          {
              return new DefaultConfiguration( name, "-" );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/Configurable.java
  
  Index: Configurable.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 file.
   */
  package org.apache.avalon.configuration;
  
  /**
   * This interface should be implemented by classes that need to be
   * configured with custom parameters before initialization.
   * <br />
   *
   * The contract surrounding a <code>Configurable</code> is that the
   * instantiating entity must call the <code>configure</code>
   * method before it is valid.  The <code>configure</code> method
   * must be called after the constructor, and before any other method.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Configurable
  {
      /**
       * Pass the <code>Configuration</code> to the <code>Configurable</code>
       * class. This method must always be called after the constructor
       * and before any other method.
       *
       * @param configuration the class configurations.
       */
      void configure( Configuration configuration ) 
          throws ConfigurationException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/Configuration.java
  
  Index: Configuration.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 file.
   */
  package org.apache.avalon.configuration;
  
  import java.util.Iterator;
  
  /**
   * <code>Configuration</code> is a interface encapsulating a configuration node
   * used to retrieve configuration values. This is a "read only" interface
   * preventing applications from modifying their own configurations.
   * <br />
   *
   * The contract surrounding the <code>Configuration</code> is that once
   * it is created, information never changes.  The <code>Configuration</code>
   * is built by the <code>SAXConfigurationBuilder</code> and the
   * <code>ConfigurationImpl</code> helper classes.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Configuration
  {
      /**
       * Return the name of the node.
       *
       * @post getName() != null
       *
       * @return name of the <code>Configuration</code> node.
       */
      String getName();
  
      /**
       * Return a string describing location of 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
       */
      String getLocation();
  
      /**
       * Return a new <code>Configuration</code> instance encapsulating the
       * specified child node.
       *
       * @pre child != null
       * @post getConfiguration() != null
       *
       * @param child The name of the child node.
       * @return Configuration
       */
      Configuration getChild( String child );
  
      /**
       * Return a new <code>Configuration</code> instance encapsulating the
       * specified child node.
       *
       * @pre child != null
       * @post getConfiguration() != null
       *
       * @param child The name of the child node.
       * @return Configuration
       */
  //    Configuration getChild( String child, boolean createNew );
  
      /**
       * Return an <code>Iterator</code> of <code>Configuration<code>
       * elements containing all node children with the specified name.
       *
       * @pre name != null
       * @post getConfigurations() != null
       *
       * @param name The name of the children to get.
       * @return The child nodes with name
       */
      Iterator getChildren( String name );
  
      Configuration[] getChildrenAsArray(String name);
      /**
       * Return the value of specified attribute.
       *
       * @pre paramName != null
       * @post getAttribute != null
       *
       * @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.
       */
      String getAttribute( String paramName ) throws ConfigurationException;
  
      /**
       * Return the <code>int</code> value of the specified attribute contained
       * in this node.
       *
       * @pre paramName != null
       * @post getAttributeAsInt() != null
       *
       * @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.
       */
      int getAttributeAsInt( String paramName ) throws ConfigurationException;
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>long</code>.
       *
       * @pre paramName != null
       * @post getAttributeAsLong() != null
       *
       * @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.
       */
      long getAttributeAsLong( String name ) throws ConfigurationException;
  
      /**
       * Return the <code>float</code> value of the specified parameter contained
       * in this node.
       *
       * @pre paramName != null
       * @post getAttributeAsFloat() != null
       *
       * @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.
       */
      float getAttributeAsFloat( String paramName ) throws ConfigurationException;
  
      /**
       * Return the <code>boolean</code> value of the specified parameter contained
       * in this node.<br>
       *
       * @pre paramName != null
       * @post getAttributeAsBoolean() != null
       *
       * @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.
       */
      boolean getAttributeAsBoolean( String paramName ) throws ConfigurationException;
  
      /**
       * Return the <code>String</code> value of the node.
       *
       * @post getValue() != null
       *
       * @return the value of the node.
       */
      String getValue() throws ConfigurationException;
  
      /**
       * Return the <code>int</code> value of the node.
       *
       * @post getValueAsInt() != null
       *
       * @returns the value of the node.
       *
       * @exception ConfigurationException If conversion to <code>int</code> fails.
       */
      int getValueAsInt() throws ConfigurationException;
  
      /**
       * Return the <code>float</code> value of the node.
       *
       * @post getValueAsFloat() != null
       *
       * @return the value of the node.
       * @exception ConfigurationException If conversion to <code>float</code> fails.
       */
      float getValueAsFloat() throws ConfigurationException;
  
      /**
       * Return the <code>boolean</code> value of the node.
       *
       * @post getValueAsBoolean() != null
       *
       * @return the value of the node.
       * @exception ConfigurationException If conversion to <code>boolean</code> fails.
       */
      boolean getValueAsBoolean() throws ConfigurationException;
  
      /**
       * Return the <code>long</code> value of the node.<br>
       *
       * @post getValueAsLong() != null
       *
       * @return the value of the node.
       * @exception ConfigurationException If conversion to <code>long</code> fails.
       */
      long getValueAsLong() throws ConfigurationException;
  
      /**
       * 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.
       *
       * @pre defaultValue != null
       * @post getValue(defaultValue) != null
       *
       * @param defaultValue The default value desired.
       * @return String value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      String getValue( String 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.
       *
       * @pre defaultValue != null
       * @post getValueAsInt(defaultValue) != null
       *
       * @param defaultValue The default value desired.
       * @return int value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      int getValueAsInt( int 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.
       *
       * @pre defaultValue != null
       * @post getValueAsLong(defaultValue) != null
       *
       * @param defaultValue The default value desired.
       * @return long value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      long getValueAsLong( long 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.
       *
       * @pre defaultValue != null
       * @post getValueAsFloat(defaultValue) != null
       *
       * @param defaultValue The default value desired.
       * @return float value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      float getValueAsFloat( float 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.
       *
       * @pre defaultValue != null
       * @post getValueAsBoolean(defaultValue) != null
       *
       * @param defaultValue The default value desired.
       * @return boolean value of the <code>Configuration</code>, or default
       *          if none specified.
       */
      boolean getValueAsBoolean( boolean 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.
       *
       * @pre name != null
       * @pre defaultValue != null
       * @post getAttribute(name, defaultValue) != null
       *
       * @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.
       */
      String getAttribute( String name, String 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.
       *
       * @pre name != null
       * @pre defaultValue != null
       * @post getAttributeAsInt(name, defaultValue) != null
       *
       * @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.
       */
      int getAttributeAsInt( String name, int 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.
       *
       * @pre name != null
       * @pre defaultValue != null
       * @post getAttributeAsLong(name, defaultValue) != null
       *
       * @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.
       */
      long getAttributeAsLong( String name, long 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.
       *
       * @pre name != null
       * @pre defaultValue != null
       * @post getAttributeAsFloat(name, defaultValue) != null
       * 
       * @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.
       */
      float getAttributeAsFloat( String name, float 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.
       *
       * @pre name != null
       * @pre defaultValue != null
       * @post getAttributeAsBoolean(name, defaultValue) != null
       *
       * @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.
       */
      boolean getAttributeAsBoolean( String name, boolean defaultValue );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/ConfigurationBuilder.java
  
  Index: ConfigurationBuilder.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 file.
   */
  package org.apache.avalon.configuration;
  
  import java.io.IOException;
  import org.xml.sax.SAXException;
  
  /**
   * The interface implemented to build configurations.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ConfigurationBuilder
  {
      Configuration build( String resource )
          throws SAXException, IOException, ConfigurationException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/ConfigurationException.java
  
  Index: ConfigurationException.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 file.
   */
  package org.apache.avalon.configuration;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Thrown when a <code>Configurable</code> component cannot be configured
   * properly, or if a value cannot be retrieved properly.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   */
  public final class ConfigurationException 
      extends CascadingException
  {
      /**
       * Construct a new <code>ConfigurationException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public ConfigurationException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>ConfigurationException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public ConfigurationException( final String message, final Throwable throwable ) 
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/DefaultConfiguration.java
  
  Index: DefaultConfiguration.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 file.
   */
  package org.apache.avalon.configuration;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  
  /**
   * This is the default <code>Configuration</code> implementation.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @deprecated This has been deprecated in favour of configuration interface in org.apache.avalon.configuration interface
   */
  public class DefaultConfiguration 
      extends AbstractConfiguration 
  {
      protected final static Iterator          EMPTY_ITERATOR = (new ArrayList(1)).iterator();
  
      protected final String                   m_name;
      protected final String                   m_location;
      protected HashMap                        m_attributes;
      protected ArrayList                      m_children;
      protected String                         m_value;
  
      /**
       * Create a new <code>DefaultConfiguration</code> instance.
       */
      public DefaultConfiguration( final String name, final String location ) 
      {
          m_name = name;
          m_location = location;
      }
  
      /**
       * Returns the name of this configuration element.
       */
      public String getName() 
      {
          return m_name;
      }
  
      /**
       * Returns a description of location of element.
       */
      public String getLocation()
      {
          return m_location;
      }
  
      /**
       * Returns the value of the configuration element as a <code>String</code>.
       *
       * @exception ConfigurationException If the value is not present.
       */
      public String getValue() throws ConfigurationException 
      {
          if( null != m_value ) return m_value;
          else
          {
              throw new ConfigurationException( "No value is associated with the "+
                                                "configuration element \"" + getName() + "\"" );
          }
      }
  
      /**
       * Returns the value of the attribute specified by its name as a
       * <code>String</code>.
       *
       * @exception ConfigurationException If the attribute is not present.
       */
      public String getAttribute( final String name ) 
          throws ConfigurationException 
      {
          final String value = 
              (null != m_attributes) ? (String)m_attributes.get( name ) : null;
  
          if( null != value ) return value;
          else
          {
              throw new ConfigurationException( "No attribute named \"" + name + "\" is " +
                                                "associated with the configuration element \"" +
                                                getName() + "\"" );
          }
      }
  
      /**
       * Return the first <code>Configuration</code> object child of this
       * associated with the given name. If none exists a new one of that name is created.
       *
       * @param name The name of the required child <code>Configuration</code>.
       */
      public Configuration getChild( final String name ) 
      {
          if( null == m_children ) 
          {
              return new DefaultConfiguration( name, "-" );
          }
          else
          {
              final int size = m_children.size();
              for( int i = 0; i < size; i++ ) 
              {
                  final Configuration configuration = (Configuration)m_children.get( i );
                  if( name.equals( configuration.getName() ) )
                  {
                      return configuration;
                  }
              }
  
              return new DefaultConfiguration( name, "-" );
          }
      }
  
      /**
       * Return an <code>Enumeration</code> of <code>Configuration</code> objects
       * children of this associated with the given name.
       * <br>
       * The returned <code>Enumeration</code> may be empty.
       *
       * @param name The name of the required children <code>Configuration</code>.
       */
      public Iterator getChildren( final String name ) 
      {
          if( null == m_children ) return EMPTY_ITERATOR;
          else
          {
              final ArrayList children = new ArrayList();
              final int size = m_children.size();
  
              for( int i = 0; i < size; i++ ) 
              {
                  final Configuration configuration = (Configuration)m_children.get( i );
                  if( name.equals( configuration.getName() ) )
                  {
                      children.add( configuration );
                  }
              }
  
              return children.iterator();
          }
      }
  
      public Configuration[] getChildrenAsArray( final String name ) 
      {
          if( null == m_children ) return new Configuration[0];
          else
          {
              final ArrayList children = new ArrayList();
              final int size = m_children.size();
  
              for( int i = 0; i < size; i++ ) 
              {
                  final Configuration configuration = (Configuration)m_children.get( i );
                  if( name.equals( configuration.getName() ) )
                  {
                      children.add( configuration );
                  }
              }
              Configuration[] response = new Configuration[children.size()];
              for (int i = 0; i < children.size(); i++) {
                  response[i] = (Configuration) children.get(i);
              }
              return response;
          }
      }
      
  
  
      /**
       * Append data to the value of this configuration element.
       */
      public void appendValueData( final String value ) 
      {
          if( null == m_value ) 
          {
              m_value = value;
          }
          else 
          {
              m_value = m_value + value;
          }
      }
  
      /**
       * Add an attribute to this configuration element, returning its old
       * value or <b>null</b>.
       */
      public String addAttribute( final String name, String value ) 
      {
          if( null == m_attributes ) m_attributes = new HashMap();
  
          return (String) m_attributes.put( name, value );
      }
  
      /**
       * Add a child <code>Configuration</code> to this configuration element.
       */
      public void addChild( final Configuration configuration ) 
      {
          if( null == m_children )
          {
              m_children = new ArrayList();
          }
  
          m_children.add( configuration );
      }
  
      /**
       * Return count of children.
       */
      public int getChildCount() 
      {
          if( null == m_children )
          {
              return 0;
          }
          
          return m_children.size();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/DefaultConfigurationBuilder.java
  
  Index: DefaultConfigurationBuilder.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 file.
   */
  package org.apache.avalon.configuration;
  
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import org.xml.sax.Attributes;
  import org.xml.sax.InputSource;
  import org.xml.sax.Locator;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.XMLReader;
  import org.xml.sax.helpers.XMLReaderFactory;
  
  /**
   * A SAXConfigurationBuilder builds configurations via SAX2 compliant parser.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultConfigurationBuilder
      implements ConfigurationBuilder
  {
      protected final static String                 DEFAULT_PARSER = 
          "org.apache.xerces.parsers.SAXParser";
      protected final static String                 PARSER = 
          System.getProperty("org.xml.sax.parser", DEFAULT_PARSER );
  
      protected SAXConfigurationHandler             m_handler;
      protected XMLReader                           m_parser;
  
      public DefaultConfigurationBuilder()
      {
          this( PARSER );
      }
  
      public DefaultConfigurationBuilder( final String parserClass )
      {
          //yaya the bugs with some compilers and final variables ..
          m_handler = getHandler();
          try 
          {
              m_parser = XMLReaderFactory.createXMLReader( parserClass );
              //m_parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
              m_parser.setContentHandler( m_handler );
              m_parser.setErrorHandler( m_handler );
          }
          catch( final SAXException se )
          {
              throw new Error( "Unable to setup SAX parser" + se );
          }
      }
  
      protected SAXConfigurationHandler getHandler()
      {
          return new SAXConfigurationHandler();
      }
  
      public Configuration build( final String resource )
          throws SAXException, IOException, ConfigurationException
      {
          final InputStream input = new FileInputStream( resource );
        
          try { return build( input ); }
          finally
          {
              try { input.close(); }
              catch( final IOException ioe ) {}            
          }
      }
  
      public Configuration build( final InputStream inputStream )
          throws SAXException, IOException, ConfigurationException
      {
          final InputSource inputSource = new InputSource( inputStream );
          return build( inputSource );
      }
  
      public Configuration build( final InputSource input )
          throws SAXException, IOException, ConfigurationException
      {
          m_handler.clear();
          m_parser.parse( input );
          return m_handler.getConfiguration();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/Reconfigurable.java
  
  Index: Reconfigurable.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 file.
   */
  package org.apache.avalon.configuration;
  
  /**
   * Extends Configurable to allow reconfiguration runtime.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Reconfigurable 
      extends Configurable
  {
      void reconfigure( Configuration configuration ) throws ConfigurationException;
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/configuration/SAXConfigurationHandler.java
  
  Index: SAXConfigurationHandler.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 file.
   */
  package org.apache.avalon.configuration;
  
  import java.io.IOException;
  import java.util.ArrayList;
  import org.xml.sax.Attributes;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.Locator;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.helpers.DefaultHandler;
  
  /**
   * A SAXConfigurationHandler helps build Configurations out of sax events.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class SAXConfigurationHandler 
      extends DefaultHandler 
      implements ErrorHandler
  {
      protected final ArrayList              m_elements        = new ArrayList();
      protected Configuration                m_configuration;
      protected Locator                      m_locator;
  
      public Configuration getConfiguration()
      {
          return m_configuration;
      }
  
      public void clear()
      {
          m_elements.clear();
          m_locator = null;
      }
  
      public void setDocumentLocator( final Locator locator )
      {
          m_locator = locator;
      }
  
      public void characters( final char[] ch, int start, int end )
          throws SAXException 
      {
          final String value = (new String( ch, start, end )).trim();
  
          if( value.equals( "" ) ) return;
          
          final DefaultConfiguration configuration = 
              (DefaultConfiguration)m_elements.get( m_elements.size() - 1 );
  
          if( 0 != configuration.getChildCount() )
          {
              throw new SAXException( "Not allowed to define mixed content in the " +
                                      "element " + configuration.getName() + " at " +
                                      configuration.getLocation() );
          }
  
          configuration.appendValueData( value );
      }
  
      public void endElement( final String namespaceURI, 
                              final String localName,
                              final String rawName ) 
      {
          final int location = m_elements.size() - 1;
          final Object object = m_elements.remove( location );
          
          if( 0 == location )
          {
              m_configuration = (Configuration)object;
          }
      }
  
      protected DefaultConfiguration createConfiguration( final String localName, 
                                                          final String location )
      {
          return new DefaultConfiguration( localName, location );
      }
  
      public void startElement( final String namespaceURI, 
                                final String localName,
                                final String rawName, 
                                final Attributes attributes ) 
          throws SAXException 
      {
          final DefaultConfiguration configuration = 
              createConfiguration( localName, getLocationString() );
          final int size = m_elements.size() - 1;
  
          if( size > -1 )
          {
              final DefaultConfiguration parent = 
                  (DefaultConfiguration)m_elements.get( size );
  
              if( null != parent.getValue( null ) )
              {
                  throw new SAXException( "Not allowed to define mixed content in the " +
                                          "element " + parent.getName() + " at " +
                                          parent.getLocation() );
              }
  
              parent.addChild( configuration );
          }
          
          m_elements.add( configuration );
          
          final int attributesSize = attributes.getLength();
          
          for( int i = 0; i < attributesSize; i++ ) 
          {
              final String name = attributes.getQName( i );
              final String value = attributes.getValue( i );
              configuration.addAttribute( name, value );
          }
      }
  
      /**
       * This just throws an exception on a parse error.
       */
      public void error( final SAXParseException exception )
          throws SAXException 
      {
          throw exception;
      }
  
      /**
       * This just throws an exception on a parse error.
       */
      public void warning( final SAXParseException exception )
          throws SAXException
      {
          throw exception;
      }
  
      /**
       * This just throws an exception on a parse error.
       */
      public void fatalError( final SAXParseException exception ) 
          throws SAXException 
      {
          throw exception;
      }
  
      protected String getLocationString()
      {
          if( null == m_locator ) return "Unknown";
          else
          {
              return 
                  m_locator.getSystemId() + ":" + 
                  m_locator.getLineNumber() + ":" +
                  m_locator.getColumnNumber();
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/AbstractCamelotDeployer.java
  
  Index: AbstractCamelotDeployer.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 file.
   */
  package org.apache.avalon.container;
  
  import java.net.URL;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.component.Composer;
  
  /**
   * This class deploys resources from camelot based system.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractCamelotDeployer
      extends AbstractDeployer
      implements Composer
  {
      protected boolean                      m_deployToContainer;
      protected boolean                      m_deployToLocatorRegistry;
      protected boolean                      m_deployToInfoRegistry;
  
      protected LocatorRegistry              m_locatorRegistry;
      protected Container                    m_container;
      protected Registry                     m_infoRegistry;
      
      /**
       * Retrieve relevent services needed to deploy.
       *
       * @param componentManager the ComponentManager
       * @exception ComponentNotFoundException if an error occurs
       * @exception ComponentNotAccessibleException if an error occurs
       */
      public void compose( final ComponentManager componentManager )
      {
          try {
              if( m_deployToLocatorRegistry )
              {
                  m_locatorRegistry = (LocatorRegistry)componentManager.
                      lookup( "org.apache.avalon.container.LocatorRegistry" );
              }
      
              if( m_deployToInfoRegistry )
              {
                  m_infoRegistry = (Registry)componentManager.
                      lookup( "org.apache.avalon.container.Registry" );
              }
      
              if( m_deployToContainer )
              {
                  m_container = (Container)componentManager.
                      lookup( "org.apache.avalon.container.Container" );
              }
          } catch (Exception e) {
          }
      }
  
      protected void addEntry( final String name, final Entry entry )
          throws DeploymentException
      {
          try { m_container.add( name, entry ); }
          catch( final ContainerException ce )
          {
              throw new DeploymentException( "Error adding component to container", ce );
          }
  
          getLogger().debug( "Adding " + m_type + "Entry " + name + " as " + entry );
      }    
  
      protected void addLocator( final String name, final String classname, final URL url )
          throws DeploymentException
      {
          final DefaultLocator locator = new DefaultLocator( classname, url );
          
          try { m_locatorRegistry.register( name, locator ); }
          catch( final RegistryException re )
          {
              throw new DeploymentException( "Error registering " + name + " due to " + re,
                                             re );
          }
          
          getLogger().debug( "Registered " + m_type + " " + name + " as " + classname );
      }
      
      protected void addInfo( final String name, final Info info )
          throws DeploymentException
      {
          try { m_infoRegistry.register( name, info ); }
          catch( final RegistryException re )
          {
              throw new DeploymentException( "Error registering " + name + " due to " + re,
                                             re );
          }
          
          getLogger().debug( "Registered Info " + m_type + " " + name );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/AbstractContainer.java
  
  Index: AbstractContainer.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.component.Component;
  
  /**
   * This contains it during execution and may provide certain 
   * facilities (like a thread per EJB etc).
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractContainer
      extends AbstractLoggable
      implements Container
  {
      protected final HashMap          m_entries      = new HashMap();
      protected Class                  m_entryClass;
  
      /**
       * Add a component instance to container.
       *
       * @param entry the component entry
       */
      public void add( final String name, final Entry entry )
          throws ContainerException
      {
          checkEntry( name, entry );
          preAdd( name, entry );
          m_entries.put( name, entry );
          postAdd( name, entry );
      }
  
      /**
       * Remove a component instance from container.
       *
       * @param name the name of component
       */
      public void remove( final String name )
          throws ContainerException
      {
          final Entry entry = (Entry)m_entries.get( name );
  
          if( null == entry )
          {
              throw new ContainerException( "Component named " + name + " not contained" );
          }
  
          preRemove( name, entry );
          m_entries.remove( name );
          postRemove( name, entry );
      }
  
      /**
       * Retrieve Entry from container
       *
       * @param name the name of entry
       * @return the entry
       */
      public Entry getEntry( final String name )
          throws ContainerException
      {
          final Entry entry = (Entry)m_entries.get( name );
          
          if( null == entry )
          {
              throw new ContainerException( "Name " + name + " not contained" );
          }
          else
          {
              return entry;
          }
      }
  
      /**
       * List all names of entries in container.
       *
       * @return the list of all entries
       */
      public Iterator list()
      {
          return m_entries.keySet().iterator();
      }
  
      /**
       * This method is called before entry is added to give chance for 
       * sub-class to veto removal.
       *
       * @param name the name of entry
       * @param entry the entry
       * @exception ContainerException to stop removal of entry
       */
      protected void preAdd( final String name, final Entry entry )
          throws ContainerException
      {
      }
  
      /**
       * This method is called after entry is added to give chance for 
       * sub-class to do some cleanup.
       *
       * @param name the name of entry
       * @param entry the entry
       */
      protected void postAdd( final String name, final Entry entry )
      {
      }
      
      /**
       * This method is called before entry is removed to give chance for 
       * sub-class to veto removal.
       *
       * @param name the name of entry
       * @param entry the entry
       * @exception ContainerException to stop removal of entry
       */
      protected void preRemove( final String name, final Entry entry )
          throws ContainerException
      {
      }
  
      /**
       * This method is called after entry is removed to give chance for 
       * sub-class to do some cleanup.
       *
       * @param name the name of entry
       * @param entry the entry
       */
      protected void postRemove( final String name, final Entry entry )
      {
      }
      
      /**
       * List all entries in container.
       *
       * @return the list of all entries
       */
      protected Iterator listEntries()
      {
          return m_entries.values().iterator();
      }   
       
      protected void checkEntry( final String name, final Entry entry )
          throws ContainerException
      {
          if( null != m_entries.get( name ) )
          {
              throw new ContainerException( "Can not add component to container because " + 
                                            "entry already exists with name " + name );
          }
  
          if( !isValidName( name ) )
          {
              throw new ContainerException( "Can not add component to container because " + 
                                            "invalid name " + name );
          }
          
          if( !isValidEntry( entry ) )
          {
              throw new ContainerException( "Can not add component to container because " + 
                                            "invalid entry for " + name );
          }
  
          if( !m_entryClass.isAssignableFrom( entry.getClass() ) )
          {
              throw new ContainerException( "Only Entries of type " + m_entryClass.getName() +
                                            " may be placed in container." );
          }
      }
  
      protected boolean isValidName( final String name )
          throws ContainerException
      {
          return true;
      }
  
      protected boolean isValidEntry( final Entry entry )
          throws ContainerException
      {
          return true;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/AbstractDeployer.java
  
  Index: AbstractDeployer.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.URL;
  import java.util.HashMap;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.component.ComponentNotFoundException;
  import org.apache.avalon.util.io.FileUtil;
  import org.apache.log.Logger;
  
  /**
   * A Deployer is responsible for taking a URL (ie a jar/war/ear) and deploying
   * it to a particular "location". "location" means different things for
   * different containers. For a servlet container it may mean the place to
   * mount servlet (ie /myapp --> /myapp/Cocoon.xml is mapping cocoon servlet to
   * /myapp context).
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractDeployer
      extends AbstractLoggable
      implements Deployer
  {
      protected final HashMap                m_deployments  = new HashMap();
      protected boolean                      m_autoUndeploy;
      protected String                       m_type;
  
      public void deploy( final String location, final URL url )
          throws DeploymentException
      {
          checkDeployment( location, url );
          final File file = getFileFor( url );
  
          getLogger().info( "Deploying " + m_type + " file (" + file + ") as " + location );
          deployFromFile( location, file );
      }
  
      protected void checkDeployment( final String location, final URL url )
          throws DeploymentException
      {
          if( null != m_deployments.get( location ) )
          {
              throw new DeploymentException( m_type + " already exists at " + location );
          }
          
          if( !isValidLocation( location ) )
          {
              throw new DeploymentException( "Invalid location (" + location + 
                                             ") for " + m_type );
          }
      }
  
      public void undeploy( final String location )
          throws DeploymentException
      {
          final Component component = (Component)m_deployments.get( location );
  
          if( null == component )
          {
              throw new DeploymentException( m_type + " does not exist at " + location );
          }
  
          final boolean canUndeploy = canUndeploy( component );
  
          if( !canUndeploy )
          {
              if( !m_autoUndeploy )
              {
                  //we are midstream but not allowed to automagically undeploy .. therefore
                  throw new DeploymentException( m_type + " not ready to undeploy at " + 
                                                 location );
              }
              else
              {
                  shutdownDeployment( component );
              }
          }
  
          //if everything has gone successful then remove application
          m_deployments.remove( location );
      }
  
      protected File getCacheLocationFor( final URL url )
          throws DeploymentException
      {
          throw new DeploymentException( "Unable to deploy non-local resources" );
      }
  
      protected File getFileFor( final URL url )
          throws DeploymentException
      {
          File file = null;
  
          if( url.getProtocol().equals( "file" ) )
          {
              file = new File( url.getFile() );
          }
          else
          {
              file = getCacheLocationFor( url );
              try { FileUtil.copyURLToFile( url, file ); }
              catch( final IOException ioe )
              {
                  throw new DeploymentException( "Failed attempting to copy from  " + url +
                                                 " to local file cache " + file, ioe );
              }
          }
  
          file = file.getAbsoluteFile();
  
          if( !file.exists() )
          {
              throw new DeploymentException( "Could not find application archive at " + 
                                             file );
          }
  
          if( file.isDirectory() )
          {
              throw new DeploymentException( "Could not find application archive at " + 
                                             file + " as it is a directory." );
          }
  
          return file;
      }
  
      protected boolean isValidLocation( String location )
      {
          return true;
      }
  
      protected boolean canUndeploy( Component component )
          throws DeploymentException
      {
          return true;
      }
  
      protected void shutdownDeployment( Component component )
          throws DeploymentException
      {
      }
  
      protected abstract void deployFromFile( String location, File file )
          throws DeploymentException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/AbstractZipDeployer.java
  
  Index: AbstractZipDeployer.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 file.
   */
  package org.apache.avalon.container;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.zip.ZipFile;
  import org.apache.avalon.component.Composer;
  
  /**
   * This class deploys a .zip file into a registry.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractZipDeployer
      extends AbstractCamelotDeployer
      implements Composer
  {
      /**
       * Deploy a file.
       * Eventually this should be cached for performance reasons.
       *
       * @param location the location 
       * @param file the file
       * @exception DeploymentException if an error occurs
       */
      protected void deployFromFile( final String location, final File file )
          throws DeploymentException
      {
          final ZipFile zipFile = DeployerUtil.getZipFileFor( file );
  
          URL url = null;
          
          try
          {
              try { url = file.toURL(); }
              catch( final MalformedURLException mue ) 
              {
                  throw new DeploymentException( "Unable to form url", mue );
              }
              loadResources( zipFile, location, url );
          }
          finally
          {
              try { zipFile.close(); }
              catch( final IOException ioe ) {}
          }
      }
  
      /**
       * Overide this method to provide the actual functionality and 
       * deploy the resources from a zip file.
       *
       * @param zipFile the ZipFile
       * @param location the location that it was deployed to
       * @param url the url of deployment
       * @exception DeploymentException if an error occurs
       */
      protected abstract void loadResources( ZipFile zipFile, String location, URL url )
          throws DeploymentException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/AvalonState.java
  
  Index: AvalonState.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 file. 
   */
  package org.apache.avalon.container;
  
  public final class AvalonState
      extends State
  {
      public final static AvalonState ERROR          = new AvalonState( "ERROR", -10 );
  
      public final static AvalonState BASE           = new AvalonState( "BASE", 0 );
  
      public final static AvalonState CREATED        = new AvalonState( "CREATED", 5 );
      public final static AvalonState LOGGED         = new AvalonState( "LOGGED", 10 );
      public final static AvalonState CONTEXTUALIZED = new AvalonState( "CONTEXTUALIZED", 20 );
      public final static AvalonState COMPOSED       = new AvalonState( "COMPOSED", 30 );
      public final static AvalonState CONFIGURED     = new AvalonState( "CONFIGURED", 40 );
      public final static AvalonState NAMED          = new AvalonState( "NAMED", 50 );
      public final static AvalonState INITIALIZED    = new AvalonState( "INITIALIZED", 60 );
      public final static AvalonState STARTED        = new AvalonState( "STARTED", 70 );
      public final static AvalonState RUNNING        = new AvalonState( "RUNNING", 70 );
  
      //from here to stopped may want to go to a different class ??
      public final static AvalonState EXPORTED       = new AvalonState( "EXPORTED", 80 );
      public final static AvalonState UNEXPORTED     = new AvalonState( "UNEXPORTED", 90 );
      public final static AvalonState SUSPENDED      = new AvalonState( "SUSPENDED", 100 );
      public final static AvalonState RESUMED        = new AvalonState( "RESUMED", 110 );
  
      public final static AvalonState STOPPED        = new AvalonState( "STOPPED", 120 );
      public final static AvalonState DISPOSED       = new AvalonState( "DISPOSED", 130 );
      public final static AvalonState FINALIZED      = new AvalonState( "FINALIZED", 140 );
  
      protected AvalonState( final String name, final int value )
      {
          super( name, value );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/CamelotUtil.java
  
  Index: CamelotUtil.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.util.Iterator;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.util.io.ExtensionFileFilter;
  
  /**
   * Utility methods for Camelot related facilities.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class CamelotUtil
  {
      /**
       * Private constructor so impossible to instantiate.
       */
      private CamelotUtil()
      {
      }
  
      public static void deployFromDirectory( final Deployer deployer, 
                                              final File directory,
                                              final String extention )
          throws DeploymentException
      {
          deployFromDirectory( deployer, directory, new String[] { extention } );
      }
  
      public static void deployFromDirectory( final Deployer deployer, 
                                              final File directory,
                                              final String[] extentions )
          throws DeploymentException
                                            
      {
          final ExtensionFileFilter filter = new ExtensionFileFilter( extentions );
          final File[] files = directory.listFiles( filter );
  
          if( null != files )
          {
              deployFiles( deployer, files );
          }
      }
  
      public static void deployFiles( final Deployer deployer, final File[] files )
          throws DeploymentException
      {
          for( int i = 0; i < files.length; i++ )
          {
              final String filename = files[ i ].getName();
              
              int index = filename.lastIndexOf( '.' );
              if( -1 == index ) index = filename.length();
              
              final String name = filename.substring( 0, index );
              
              try
              { 
                  final File file = files[ i ].getCanonicalFile();
                  deployer.deploy( name, file.toURL() );
              }
              catch( final MalformedURLException mue )
              {
                  throw new DeploymentException( "Malformed URL for " + files[ i ], mue );
              }
              catch( final IOException ioe )
              {
                  throw new DeploymentException( "Unable to get canonical representation " + 
                                                 "for file " + files[ i ], ioe );
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Container.java
  
  Index: Container.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.util.Iterator;
  import org.apache.avalon.component.Component;
  
  /**
   * This contains it during execution and may provide certain 
   * facilities (like a thread per EJB etc).
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Container
      extends Component
  {
      /**
       * Add a component instance to container.
       *
       * @param entry the component entry
       */
      void add( String name, Entry entry )
          throws ContainerException;
  
     /**
      * Remove a component instance from container.
      *
      * @param name the name of component
      */
      void remove( String name )
          throws ContainerException;
  
      /**
       * Retrieve Entry from container
       *
       * @param name the name of entry
       * @return the entry
       */
      Entry getEntry( String name )
          throws ContainerException;
  
      /**
       * List all names of entries in container.
       *
       * @return the list of all entries
       */
      Iterator list();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/ContainerException.java
  
  Index: ContainerException.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 file.
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Exception to indicate error manipulating container.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ContainerException 
      extends CascadingException
  {
      /**
       * Construct a new <code>ContainerException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public ContainerException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>ContainerException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public ContainerException( final String message, final Throwable throwable ) 
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DefaultFactory.java
  
  Index: DefaultFactory.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.net.URL;
  import java.util.HashMap;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.AbstractLoggable;
  
  /**
   * This is the component that creates the components. 
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultFactory
      extends AbstractLoggable
      implements Factory
  {
      protected static class LoaderEntry
      {
          Loader      m_loader;
          long        m_lastModified;
      }
  
      protected final HashMap        m_loaders      = new HashMap();
  
      /**
       * Create a component whos position is indicated by locator.
       *
       * @param locator the locator indicating the component location
       * @return the component
       * @exception FactoryException if an error occurs
       */
      public Object create( final Locator locator ) 
          throws FactoryException
      {
          final Loader loader = getLoaderFor( locator.getLocation() );
  
          try { return loader.load( locator.getName() ); }
          catch( final Exception e )
          {
              throw new FactoryException( "Unable to create " + locator.getName() + 
                                          " from " + locator.getLocation(), e );
          }
      }
  
      public Object create( final Locator locator, final Class clazz )
          throws FactoryException
      {
          final Object object = create( locator );
          
          if( !clazz.isInstance( object ) )
          {
              throw new FactoryException( "Created object of type " + object.getClass().getName() +
                                          " not compatable with type " + clazz.getName() );
          }
          
          return object;
      }
  
      protected Loader getLoaderFor( final URL url )
      {
          final String location = url.toString();
          LoaderEntry loader = (LoaderEntry)m_loaders.get( location );
          
          if( null == loader )
          {
              getLogger().info( "Creating ClassLoader for " + location );
              loader = new LoaderEntry();
  
              loader.m_loader = setupLoader( url );
              loader.m_lastModified = System.currentTimeMillis();
              
              m_loaders.put( location, loader );
          }
          else
          {
              //TODO: Check it up to date and reload if necessary
          }
          
          return loader.m_loader;
      }
  
      protected Loader setupLoader( final URL url )
      {
          final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          final Loader loader = createLoader( url, classLoader );
          setupLogger( loader );
  
          return loader;
      }
      
      /**
       * Create a new loader.
       * Put in another method so that it can be overridden.
       *
       * @param location the location the Loader will load from
       * @return the loader
       */
      protected Loader createLoader( final URL url, final ClassLoader classLoader )
      {
          return new DefaultLoader( url, classLoader );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DefaultLoader.java
  
  Index: DefaultLoader.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import org.apache.avalon.util.ObjectUtil;
  import org.apache.avalon.util.StringUtil;
  
  /**
   * Class used to load resources from a source.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultLoader
      implements Loader
  {
      protected ClassLoader         m_classLoader;
  
      public DefaultLoader( final ClassLoader classLoader )
      {
          m_classLoader = classLoader;
      }
  
      public DefaultLoader( final URL location, final ClassLoader classLoader )
      {
          m_classLoader = new URLClassLoader( new URL[] { location }, classLoader );
      }
  
      public DefaultLoader( final URL location )
      {
          this( location, Thread.currentThread().getContextClassLoader() );
      }    
  
      public DefaultLoader()
      {
          final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          m_classLoader = new URLClassLoader( new URL[0], classLoader );
      }
  
      /**
       * Retrieve classloader associated with source.
       *
       * @return the ClassLoader
       */
      public ClassLoader getClassLoader()
      {
          return m_classLoader;
      }
  
      public Object load( final String classname, final Class clazz )
          throws FactoryException
      {
          final Object object = load( classname );
  
          if( !clazz.isInstance( object ) )
          {
              throw new FactoryException( "Created object of type " + object.getClass().getName() +
                                          " not compatable with type " + clazz.getName() );
          }
  
          return object;
      }
  
      /**
       * Load an object from source.
       *
       * @param classname the name of object
       * @return the Object
       * @exception Exception if an error occurs
       */
      public Object load( final String classname )
          throws FactoryException
      {
          try
          {
              return ObjectUtil.createObject( m_classLoader, classname );
          }
          catch( final ClassNotFoundException cnfe )
          {
              throw new FactoryException( "Failed to locate class " + classname, cnfe );
          }
          catch( final InstantiationException ie )
          {
              throw new FactoryException( "Failed to instantiate class " + classname, ie );
          }
          catch( final IllegalAccessException iae )
          {
              throw new FactoryException( "Failed to instantiate class " + classname + 
                                          " as it does not have a publicly accesable " +
                                          "default constructor", iae );
          }
          catch( final Throwable t )
          {
              throw new FactoryException( "Failed to get class " + classname + 
                                          " due to " + StringUtil.printStackTrace( t, 5, true ),
                                          t );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DefaultLocator.java
  
  Index: DefaultLocator.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.net.URL;
  import org.apache.avalon.component.Component;
  
  /**
   * This contains information required to locate a component.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultLocator
      implements Locator
  {
      protected final String     m_name;
      protected final URL        m_location;
  
      public DefaultLocator( final String name, final URL location )
      {
          m_name = name;
          m_location = location;
      }
      
      /**
       * Retrieve "name" of component type.
       * The "name" usually indicates the classname.
       *
       * @return the name
       */
      public String getName()
      {
          return m_name;
      }
  
      /**
       * Retrieve location of component.
       * Usually references the archive (zip/jar/war/ear)
       * which contains the name (ie classname)
       *
       * @return the URL of location
       */
      public URL getLocation()
      {
          return m_location;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DefaultLocatorRegistry.java
  
  Index: DefaultLocatorRegistry.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 file. 
   */
  package org.apache.avalon.container;
  
  /**
   * Represents a Registry of locators.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultLocatorRegistry
      extends DefaultRegistry
      implements LocatorRegistry
  {
      public DefaultLocatorRegistry()
      {
          super( Locator.class );
      }
  
      /**
       * Retrieve a Locator by name.
       *
       * @param name the name
       * @return the Info
       * @exception RegistryException if an error occurs
       */
      public Locator getLocator( String name ) 
          throws RegistryException
      {
          return (Locator)getInfo( name );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DefaultRegistry.java
  
  Index: DefaultRegistry.java
  ===================================================================
  /* 
   * Copyright (C) The Apache Software Foundation. All rights reserved. 
   * 
   * This software is published under the terms of the Apache Software License 
   * version 1.1, a copy of which has been included with this distribution in 
   * the LICENSE file. 
   */
  package org.apache.avalon.container;
  
  import java.util.HashMap;
  import java.util.Iterator;
  
  /**
   * Represents a Registry of names to types.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultRegistry
      implements Registry
  {
      protected final HashMap        m_infos       = new HashMap();
      protected final Class          m_infoClass;
  
      public DefaultRegistry( final Class clazz )
      {
          m_infoClass = clazz;
      }
  
      public void register( final String name, final Info info )
          throws RegistryException
      {
          if( null != m_infos.get( name ) )
          {
              throw new RegistryException( "Name " + name + " already registered" );
          }
          else
          {
              checkInfo( name, info );
              m_infos.put( name, info );
          }
      }
  
      public void unregister( final String name )
          throws RegistryException
      {
          if( null == m_infos.remove( name ) )
          {
              throw new RegistryException( "Name " + name + " not registered" );
          }
      }
  
      public Info getInfo( final String name )
          throws RegistryException
      {
          final Info info = (Info)m_infos.get( name );
  
          if( null == info )
          {
              throw new RegistryException( "Name " + name + " not registered" );
          }
          else
          {
              return info;
          }
      }
  
      public Iterator getInfoNames()
      {
          return m_infos.keySet().iterator();
      }
  
      protected void checkInfo( final String name, final Info info )
          throws RegistryException
      {
          if( !m_infoClass.isAssignableFrom( info.getClass() ) )
          {
              throw new RegistryException( "Only Infos of type " + m_infoClass.getName() +
                                           " may be placed in registry." );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Deployer.java
  
  Index: Deployer.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.net.URL;
  import org.apache.avalon.component.ComponentNotFoundException;
  import org.apache.avalon.component.Component;
  
  /**
   * A Deployer is responsible for taking a URL (ie a jar/war/ear) and deploying
   * it to a particular "location". "location" means different things for
   * different containers. For a servlet container it may mean the place to
   * mount servlet (ie /myapp --> /myapp/Cocoon.xml is mapping cocoon servlet to
   * /myapp context).
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Deployer
      extends Component
  {
      /**
       * Deploy a resource indicate by url to location.
       *
       * @param location the location to deploy to
       * @param url the url of deployment
       * @exception DeploymentException if an error occurs
       */
      void deploy( String location, URL url )
          throws DeploymentException;
  
      /**
       * undeploy a resource from a location.
       *
       * @param location the location
       * @exception DeploymentException if an error occurs
       */
      void undeploy( String location )
          throws DeploymentException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DeployerUtil.java
  
  Index: DeployerUtil.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 file.
   */
  package org.apache.avalon.container;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URL;
  import java.util.Properties;
  import java.util.jar.Manifest;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipException;
  import java.util.zip.ZipFile;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.component.ComponentNotAccessibleException;
  import org.apache.avalon.component.ComponentNotFoundException;
  import org.apache.avalon.component.Composer;
  import org.apache.avalon.component.Composer;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.configuration.DefaultConfigurationBuilder;
  import org.xml.sax.SAXException;
  
  /**
   * This class deploys resources from camelot based system.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class DeployerUtil
  {
      protected static DefaultConfigurationBuilder  c_configurationBuilder;
  
      /**
       * Private constructor to block instantiation.
       */
      private DeployerUtil()
      {
      }
  
      protected static DefaultConfigurationBuilder getBuilder()
      {
          if( null == c_configurationBuilder )
          {
              c_configurationBuilder = new DefaultConfigurationBuilder();
          }
  
          return c_configurationBuilder;
      }
  
      /**
       * Get zipFile represented by URL.
       *
       * @param url the URL
       * @return the ZipFile
       * @exception DeploymentException if an error occurs
       */
  /*
      public final static ZipFile getZipFileFor( final URL url )
          throws DeploymentException
      {
          final File file = getFileFor( url );
          return getZipFileFor( file );
      }
  */  
      /**
       * Retrieve zip file for file.
       *
       * @param file the file
       * @return the zipFile
       * @exception DeploymentException if an error occurs
       */
      public final static ZipFile getZipFileFor( final File file )
          throws DeploymentException
      {
          try { return new ZipFile( file ); }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error opening " + file + 
                                             " due to " + ioe.getMessage(),
                                             ioe );
          }        
      }
      
      /**
       * Utility method to load configuration from zip.
       *
       * @param zipFile the zip file
       * @param filename the property filename
       * @return the Configuration
       * @exception DeploymentException if an error occurs
       */
      public final static Configuration loadConfiguration( final ZipFile zipFile, 
                                                           final String filename )
          throws DeploymentException
      {
          return buildConfiguration( loadResourceStream( zipFile, filename ) );
      }
      
      /**
       * Build a configuration tree based on input stream.
       *
       * @param input the InputStream
       * @return the Configuration tree
       * @exception DeploymentException if an error occurs
       */
      public final static Configuration buildConfiguration( final InputStream input )
          throws DeploymentException
      {
          try { return getBuilder().build( input ); }
          catch( final SAXException se )
          {
              throw new DeploymentException( "Malformed configuration data", se );
          }
          catch( final ConfigurationException ce )
          {
              throw new DeploymentException( "Error building configuration", ce );
          }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error reading configuration", ioe );
          }
      }
      
      /**
       * Utility method to load a manifest from a zip file.
       *
       * @param zipFile the zip file
       * @return the Manifest
       */
      public final static Manifest loadManifest( final ZipFile zipFile )
          throws DeploymentException
      {
          final InputStream input = loadResourceStream( zipFile, "META-INF/MANIFEST.MF" );
          
          try { return new Manifest( input ); }
          catch( final IOException ioe ) 
          {
              throw new DeploymentException( "Error reading manifest", ioe );
          }
          finally
          {
              try { input.close(); }
              catch( final IOException ioe ) {}
          }
      }
      
      /**
       * Utility method to load properties from zip.
       *
       * @param zipFile the zip file
       * @param filename the property filename
       * @return the Properties
       * @exception DeploymentException if an error occurs
       */
      public final static Properties loadProperties( final ZipFile zipFile, 
                                                     final String filename )
          throws DeploymentException
      {
          final Properties properties = new Properties();
          
          try { properties.load( loadResourceStream( zipFile, filename ) ); }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error reading " + filename + 
                                             " from " + zipFile.getName(),
                                             ioe );
          }
          
          return properties;
      }
      
      /**
       * Load a resource from a zip file.
       *
       * @param zipFile the ZipFile
       * @param filename the filename
       * @return the InputStream
       * @exception DeploymentException if an error occurs
       */
      public final static InputStream loadResourceStream( final ZipFile zipFile, 
                                                          final String filename )
          throws DeploymentException
      {
          final ZipEntry entry = zipFile.getEntry( filename );
          
          if( null == entry )
          {
              throw new DeploymentException( "Unable to locate " + filename + 
                                             " in " + zipFile.getName() );
          }
          
          try { return zipFile.getInputStream( entry ); }
          catch( final IOException ioe )
          {
              throw new DeploymentException( "Error reading " + filename + 
                                             " from " + zipFile.getName(),
                                             ioe );
          }        
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/DeploymentException.java
  
  Index: DeploymentException.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 file.
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Exception to indicate error deploying.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class DeploymentException 
      extends CascadingException
  {
      /**
       * Construct a new <code>DeploymentException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public DeploymentException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>DeploymentException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public DeploymentException( final String message, final Throwable throwable ) 
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Entry.java
  
  Index: Entry.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 file. 
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.component.Component;
  
  /**
   * Contains information about a particular instance of contained component. 
   * This would contain name, configuration data, parameters, log entries etc. 
   * Basically instance data.
  *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class Entry
      implements Component
  {
      protected Info          m_info;
      protected Object        m_instance;
      protected State         m_state;
  
      public Entry()
      {
      }
  
      public Entry( final Info info, final Object instance, final State state )
      {
          m_info = info;
          m_instance = instance;
          m_state = state;
      }
  
      /**
       * Retrieve Info describing instance.
       *
       * @return the info
       */
      public Info getInfo()
      {
          return m_info;
      }
  
      /**
       * Mutator for info property.
       *
       * @param info the Info
       */
      public void setInfo( final Info info )
      {
          m_info = info;
      }
  
      /**
       * Retrieve instance of component.
       *
       * @return the component instance
       */
      public Object getInstance()
      {
          return m_instance;
      }
      
      /**
       * Set instance of component.
       *
       * @return the component instance
       */
      public void setInstance( final Object instance )
      {
          m_instance = instance;
      }
      
      /**
       * Retrieve state of a component.
       *
       * @return the components state
       */
      public State getState()
      {
          return m_state;
      }
      
      /**
       * set state of a component.
       *
       * @param state  the components state
       */
      public void setState( final State state )
      {
          m_state = state;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Factory.java
  
  Index: Factory.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 file. 
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.component.Component;
  
  /**
   * This is the component that creates the components. 
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Factory
      extends Component
  {
      /**
       * Create a component whos position is indicated by locator.
       *
       * @param locator the locator indicating the component location
       * @return the component
       * @exception FactoryException if an error occurs
       */
      Object create( Locator locator ) 
          throws FactoryException;
  
      /**
       * Create a component whos position is indicated by locator. 
       * Make sure it is of the correct type.
       *
       * @param locator the locator indicating the component location
       * @param clazz the expected type of component
       * @return the component
       * @exception FactoryException if an error occurs
       */
      Object create( Locator locator, Class clazz ) 
          throws FactoryException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/FactoryException.java
  
  Index: FactoryException.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 file.
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Exception to indicate error creating entries in factory.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class FactoryException 
      extends CascadingException
  {
      /**
       * Construct a new <code>FactoryException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public FactoryException( final String message ) 
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>FactoryException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public FactoryException( final String message, final Throwable throwable ) 
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Info.java
  
  Index: Info.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 file. 
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.component.Component;
  
  /**
   * This contains information relating to a component.
   * There is currently two different sub-interfaces - MetaInfo and Locator.
   * MetaInfo describes meta information about component while Locator 
   * locates it in the system.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Info
      extends Component
  {
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Loader.java
  
  Index: Loader.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 file. 
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.component.Component;
  
  /**
   * Class used to load resources from a source.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Loader
      extends Component
  {
      /**
       * Retrieve classloader associated with source.
       *
       * @return the ClassLoader
       */
      ClassLoader getClassLoader();
  
      /**
       * Load an object from source.
       *
       * @param component the name of object
       * @return the Object
       * @exception Exception if an error occurs
       */
      Object load( String component )
          throws FactoryException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Locator.java
  
  Index: Locator.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 file. 
   */
  package org.apache.avalon.container;
  
  import java.net.URL;
  import org.apache.avalon.component.Component;
  
  /**
   * This contains information required to locate a component.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Locator
      extends Info
  {
      /**
       * Retrieve "name" of component type.
       * The "name" usually indicates the classname.
       *
       * @return the name
       */
      String getName();
  
      /**
       * Retrieve location of component.
       * Usually references the archive (zip/jar/war/ear)
       * which contains the name (ie classname)
       *
       * @return the URL of location
       */
      URL getLocation();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/LocatorRegistry.java
  
  Index: LocatorRegistry.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 file. 
   */
  package org.apache.avalon.container;
  
  /**
   * Represents a database of Locators.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface LocatorRegistry
      extends Registry
  {
      /**
       * Retrieve a Locator by name.
       *
       * @param name the name
       * @return the Info
       * @exception RegistryException if an error occurs
       */
      Locator getLocator( String name ) throws RegistryException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/MetaInfo.java
  
  Index: MetaInfo.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 file. 
   */
  package org.apache.avalon.container;
  
  /**
   * This contains information about the component.
   * (ie would be a BlockInfo, an EJBDescriptor, a MailetInfo etc)
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface MetaInfo
      extends Info
  {
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/Registry.java
  
  Index: Registry.java
  ===================================================================
  /* 
   * Copyright (C) The Apache Software Foundation. All rights reserved. 
   * 
   * This software is published under the terms of the Apache Software License 
   * version 1.1, a copy of which has been included with this distribution in 
   * the LICENSE file. 
   */
  package org.apache.avalon.container;
  
  import java.util.Iterator;
  import org.apache.avalon.component.Component;
  
  /**
   * Represents a database of Infos.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Registry
      extends Component
  {
      /**
       * register an info under a particular name.
       *
       * @param name the name
       * @param info the info
       * @exception RegistryException if info is invalid or name already contains info under name
       */
      void register( String name, Info info ) throws RegistryException;
  
      /**
       * unregister an info.
       *
       * @param name the name of info
       * @exception RegistryException if no such info exists
       */
      void unregister( String name ) throws RegistryException;
  
      /**
       * Retrieve an Info by name.
       *
       * @param name the name
       * @return the Info
       * @exception RegistryException if an error occurs
       */
      Info getInfo( String name ) throws RegistryException;
  
      /**
       * Return an iterator of all names of infos registered.
       *
       * @return the info names
       */
      Iterator getInfoNames();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/RegistryException.java
  
  Index: RegistryException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Exception to indicate registry error.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class RegistryException 
      extends CascadingException
  {
      /**
       * Construct a new <code>RegistryException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public RegistryException( final String message ) 
      {
          this( message, null );
      }
      
      /**
       * Construct a new <code>RegistryException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public RegistryException( final String message, final Throwable throwable ) 
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/container/State.java
  
  Index: State.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 file. 
   */
  package org.apache.avalon.container;
  
  import org.apache.avalon.util.ValuedEnum;
  
  /**
   * Defines possible states for contained components. 
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class State
      extends ValuedEnum
  {
      public State( final String name, final int value )
      {
          super( name, value );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/context/Context.java
  
  Index: Context.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 file.
   */
  package org.apache.avalon.context;
  
  /**
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   */
  public interface Context
  {
      Object get( Object key );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/context/Contextualizable.java
  
  Index: Contextualizable.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 file.
   */
  package org.apache.avalon.context;
  
  /**
   * This inteface should be implemented by classes that need 
   * a Context to work. Context contains runtime generated object 
   * provided by the parent to this class.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   */
  public interface Contextualizable
  {
      /**
       * Pass the Context to the contextualizable class. This method
       * is always called after the constructor and, if present, 
       * after configure but before any other method.
       *
       */
       void contextualize( Context context );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/context/DefaultContext.java
  
  Index: DefaultContext.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 file.
   */
  package org.apache.avalon.context;
  
  import java.util.Hashtable;
  import java.util.Map;
  
  /**
   * Default implementation of Context.
   * This implementation is a static hierarchial store.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultContext 
      implements Context 
  {
      protected final Map                       m_contextData;
      protected final Context                   m_parent;
  
      public DefaultContext( final Map contextData, final Context parent ) 
      {
          m_parent = parent;
          m_contextData = contextData;
      }
  
      public DefaultContext( final Map contextData )
      {
          this( contextData, null );
      }
      
      public DefaultContext( final Context parent ) 
      {
          this( new Hashtable(), parent );
      }
  
      public DefaultContext() 
      {
          this( (Context)null );
      }
      
      public Object get( final Object key ) 
      {
          final Object data = m_contextData.get( key );
  
          if( null == m_parent || null != data )
          {
              return data;
          }
  
          return m_parent.get( key );
      }
  
      public void put( final Object key, final Object value ) 
      {
          m_contextData.put( key, value );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/context/Recontextualizable.java
  
  Index: Recontextualizable.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 file.
   */
  package org.apache.avalon.context;
  
  /**
   * Extends composer to allow recontextualizing.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Recontextualizable
      extends Contextualizable
  {
      void recontextualizable( Context context ) ;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/context/Resolvable.java
  
  Index: Resolvable.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 file.
   */
  package org.apache.avalon.context;
  
  /**
   * This interface is used to indicate objects that need to be 
   * resolved in some particular context.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Resolvable
  {
      /**
       * Resolve a object to a value.
       *
       * @param context the contextwith respect which to resolve
       * @return the resolved object
       */
      Object resolve( Context context );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/datasource/DataSourceComponent.java
  
  Index: DataSourceComponent.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 file. 
   */ 
  package org.apache.avalon.datasource;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.ThreadSafe;
  
  /**
   * The standard interface for DataSources in Avalon.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/02/25 10:45:46 $
   */
  public interface DataSourceComponent 
      extends Component, Configurable, ThreadSafe
  {
      /**
       * Gets the Connection to the database
       */
      Connection getConnection() 
          throws SQLException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/datasource/J2eeDataSource.java
  
  Index: J2eeDataSource.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 file. 
   */ 
  package org.apache.avalon.datasource;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import javax.sql.DataSource;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.AbstractLoggable;
  
  /**
   * The J2EE implementation for DataSources in Cocoon.  This uses the
   * <code>javax.sql.DataSource</code> object and assumes that the
   * J2EE container pools the datasources properly.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/02/25 10:45:46 $
   */
  public class J2eeDataSource 
      extends AbstractLoggable
      implements DataSourceComponent
  {
      public final static String  JDBC_NAME     = "java:comp/env/jdbc/";
      protected DataSource        m_dataSource  = null;
  
      /**
       *  Configure and set up DB connection.  Here we set the connection
       *  information needed to create the Connection objects.  It must
       *  be called only once.
       *
       * @param conf The Configuration object needed to describe the
       *             connection.
       *
       * @throws ConfigurationException
       */
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          if( null == m_dataSource ) 
          {
              final String databaseName = configuration.getChild("dbname").getValue();
  
              try
              {
                  final Context initialContext = new InitialContext();
                  m_dataSource = (DataSource)initialContext.lookup( JDBC_NAME + databaseName );
              } 
              catch( final NamingException ne ) 
              {
                  getLogger().error( "Problem with JNDI lookup of datasource", ne );
                  throw new ConfigurationException( "Could not use JNDI to find datasource", ne );
              }
          }
      }
  
      /** Get the database connection */
      public Connection getConnection()
          throws SQLException 
      {
          if( null == m_dataSource )
          {
              throw new SQLException( "Can not access DataSource object" );
          }
  
          return m_dataSource.getConnection();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/datasource/JdbcConnection.java
  
  Index: JdbcConnection.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 file. 
   */ 
  package org.apache.avalon.datasource;
  
  import java.sql.CallableStatement;
  import java.sql.Connection;
  import java.sql.DatabaseMetaData;
  import java.sql.PreparedStatement;
  import java.sql.SQLException;
  import java.sql.SQLWarning;
  import java.sql.Statement;
  import java.util.Map;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.util.pool.Pool;
  
  /**
   * The Connection object used in conjunction with the JdbcDataSource
   * object.
   *
   * TODO: Implement a configurable closed end Pool, where the Connection
   * acts like JDBC PooledConnections work.  That means we can limit the
   * total number of Connection objects that are created.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/02/25 10:45:46 $
   */
  public class JdbcConnection 
      extends AbstractLoggable
      implements Connection, Recyclable
  {
      private Connection         m_connection;
      private Pool               m_pool;
  
      public JdbcConnection( final Connection connection, final Pool pool )
      {
          m_connection = connection;
          m_pool = pool;
      }
  
      public Statement createStatement() 
          throws SQLException
      {
          return m_connection.createStatement();
      }
  
      public PreparedStatement prepareStatement( final String sql ) 
          throws SQLException
      {
          return m_connection.prepareStatement( sql );
      }
  
      public CallableStatement prepareCall( final String sql ) 
          throws SQLException
      {
          return m_connection.prepareCall( sql );
      }
  
      public String nativeSQL( final String sql ) 
          throws SQLException
      {
          return m_connection.nativeSQL( sql );
      }
  
      public void setAutoCommit( final boolean autoCommit ) 
          throws SQLException
      {
          m_connection.setAutoCommit( autoCommit );
      }
  
      public boolean getAutoCommit() 
          throws SQLException
      {
          return m_connection.getAutoCommit();
      }
  
      public void commit() 
          throws SQLException
      {
          m_connection.commit();
      }
  
      public void rollback() 
          throws SQLException
      {
          m_connection.rollback();
      }
  
      public void close() 
          throws SQLException
      {
          setAutoCommit( false );
          m_pool.put( this );
      }
  
      public void recycle() 
      {
          try { m_connection.close(); } 
          catch( final SQLException se )
          {
              getLogger().warn( "Could not close connection", se );
          }
      }
  
      public boolean isClosed() 
          throws SQLException
      {
          return m_connection.isClosed();
      }
  
      public DatabaseMetaData getMetaData() 
          throws SQLException
      {
          return m_connection.getMetaData();
      }
  
      public void setReadOnly( final boolean readOnly ) 
          throws SQLException
      {
          m_connection.setReadOnly( readOnly );
      }
  
      public boolean isReadOnly() 
          throws SQLException
      {
          return m_connection.isReadOnly();
      }
  
      public void setCatalog( final String catalog ) 
          throws SQLException
      {
          m_connection.setCatalog( catalog );
      }
  
      public String getCatalog() 
          throws SQLException
      {
          return m_connection.getCatalog();
      }
  
      public void setTransactionIsolation( final int level ) 
          throws SQLException
      {
          m_connection.setTransactionIsolation(level);
      }
  
      public int getTransactionIsolation() 
          throws SQLException
      {
          return m_connection.getTransactionIsolation();
      }
  
      public SQLWarning getWarnings() 
          throws SQLException
      {
          return m_connection.getWarnings();
      }
  
      public void clearWarnings() 
          throws SQLException
      {
          m_connection.clearWarnings();
      }
  
      public Statement createStatement( final int resultSetType, 
                                        final int resultSetConcurrency ) 
          throws SQLException
      {
          return m_connection.createStatement(resultSetType, resultSetConcurrency);
      }
  
      public PreparedStatement prepareStatement( final String sql, 
                                                 final int resultSetType, 
                                                 final int resultSetConcurrency ) 
          throws SQLException
      {
          return m_connection.prepareStatement( sql, resultSetType, resultSetConcurrency );
      }
  
      public CallableStatement prepareCall( final String sql, 
                                            final int resultSetType, 
                                            final int resultSetConcurrency )
          throws SQLException
      {
          return m_connection.prepareCall( sql, resultSetType, resultSetConcurrency );
      }
  
      public Map getTypeMap() 
          throws SQLException
      {
          return m_connection.getTypeMap();
      }
  
      public void setTypeMap( final Map map )
          throws SQLException
      {
          m_connection.setTypeMap( map );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/datasource/JdbcConnectionPool.java
  
  Index: JdbcConnectionPool.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 file.
   */
  package org.apache.avalon.datasource;
  
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.SQLException;
  import java.util.ArrayList;
  import java.util.List;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.util.pool.Pool;
  
  /**
   * The Pool implementation for JdbcConnections.  It uses a background
   * thread to manage the number of SQL Connections.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/02/25 10:45:46 $
   */
  public class JdbcConnectionPool
      extends AbstractLoggable
      implements Pool, Runnable, Disposable, Initializable
  {
      private final String           m_dburl;
      private final String           m_username;
      private final String           m_password;
      private final int              m_min;
      private final int              m_max;
      private int                    m_currentCount;
      private List                   m_active        = new ArrayList();
      private List                   m_ready         = new ArrayList();
      private boolean                m_monitoring    = true;
  
      public JdbcConnectionPool( final String url,
                                 final String username,
                                 final String password,
                                 final int min,
                                 final int max )
      {
          m_dburl = url;
          m_username = username;
          m_password = password;
  
          if( min < 0 )
          {
              getLogger().warn( "Minumum number of connections specified is " +
                                "less than 0, using 0" );
              m_min = 0;
          }
          else
          {
              m_min = min;
          }
  
          if( ( max < min ) || ( max < 1 ) )
          {
              getLogger().warn( "Maximum number of connections specified must be at " +
                                "least 1 and must be greater than the minumum number " +
                                "of connections" );
              m_max = ( min > 1 ) ? min : 1;
          }
          else
          {
              m_max = max;
          }
      }
  
      public void init()
      {
          for( int i = 0; i < m_min; i++ )
          {
              m_ready.add( createJdbcConnection() );
          }
  
          new Thread( this );
      }
  
      private JdbcConnection createJdbcConnection()
      {
          JdbcConnection connection = null;
  
          try
          {
              if( null == m_username )
              {
                  connection = new JdbcConnection( DriverManager.getConnection( m_dburl ), this );
                  connection.setLogger(getLogger());
                  m_currentCount++;
              }
              else
              {
                  connection =
                      new JdbcConnection( DriverManager.getConnection( m_dburl,
                                                                       m_username,
                                                                       m_password ),
                                          this);
                  connection.setLogger(getLogger());
                  m_currentCount++;
              }
          }
  
          catch( final SQLException se )
          {
              getLogger().error( "Could not create connection to database", se );
          }
  
          getLogger().debug( "JdbcConnection object created" );
          return connection;
      }
  
      private void recycle( final Recyclable obj )
      {
          getLogger().debug( "JdbcConnection object recycled" );
          obj.recycle();
      }
  
      public Poolable get()
          throws Exception
      {
          Poolable obj = null;
  
          if( 0 == m_ready.size() )
          {
              if( m_currentCount < m_max )
              {
                  synchronized( m_active )
                  {
                      obj = createJdbcConnection();
                      m_active.add( obj );
                  }
              }
              else
              {
                  throw new SQLException("There are no more Connections available");
              }
          }
          else
          {
              synchronized( m_active )
              {
                  obj = (Poolable)m_ready.remove( 0 );
                  m_active.add( obj );
              }
          }
  
          getLogger().debug( "JdbcConnection '" + m_dburl +
                             "' has been requested from pool." );
  
          return obj;
      }
  
      public synchronized void put( final Poolable obj )
      {
          int location = m_active.indexOf( obj );
          m_active.remove( obj );
  
          if( m_monitoring )
          {
              m_ready.add( obj );
          }
  
          getLogger().debug( "JdbcConnection '" + m_dburl + "' has been returned to the pool." );
      }
  
      public void run()
      {
          while( m_monitoring )
          {
              synchronized( m_ready )
              {
                  if( m_ready.size() < m_min )
                  {
                      getLogger().debug( "There are not enough Connections for pool: " + m_dburl );
                      
                      while( ( m_ready.size() < m_min ) && ( m_currentCount < m_max ) )
                      {
                          m_ready.add( createJdbcConnection() );
                      }
                  }
                  else
                  {
                      getLogger().debug( "Trimming excess fat from pool: " + m_dburl );
  
                      while( m_ready.size() > m_min ) 
                      {
                          recycle( (Recyclable)m_ready.remove( 0 ) );
                      } 
                  }
              }
  
              try
              {
                  Thread.sleep( 1 * 60 * 1000 );
              } 
              catch( final InterruptedException ie )
              {
                  getLogger().warn( "Caught an InterruptedException", ie );
              }
          }
      }
  
      public void dispose()
      {
          m_monitoring = false;
  
          synchronized (m_ready)
          {
              while( !m_ready.isEmpty() )
              {
                  recycle( (Recyclable)m_ready.remove( 0 ) );
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/datasource/JdbcDataSource.java
  
  Index: JdbcDataSource.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 file. 
   */ 
  package org.apache.avalon.datasource;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.AbstractLoggable;
  
  /**
   * The Default implementation for DataSources in Avalon.  This uses the
   * normal <code>java.sql.Connection</code> object and
   * <code>java.sql.DriverManager</code>.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/02/25 10:45:46 $
   */
  public class JdbcDataSource 
      extends AbstractLoggable
      implements DataSourceComponent
  {
      protected JdbcConnectionPool        m_pool;
  
      /**
       *  Configure and set up DB connection.  Here we set the connection
       *  information needed to create the Connection objects.  It must
       *  be called only once.
       *
       * @param conf The Configuration object needed to describe the
       *             connection.
       *
       * @throws ConfigurationException
       */
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          if( null == m_pool )
          {
              final String dburl = configuration.getChild( "dburl" ).getValue();
              final String user = configuration.getChild( "user" ).getValue( null );
              final String passwd = configuration.getChild( "password" ).getValue( null );
              final Configuration controler = configuration.getChild( "pool-controller" );
  
              final int min = controler.getAttributeAsInt( "min", 0 );
              final int max = controler.getAttributeAsInt( "max", 3 );
  
              m_pool = new JdbcConnectionPool( dburl, user, passwd, min, max );
              m_pool.setLogger(getLogger());
              m_pool.init();
          }
      }
  
      /** Get the database connection */
      public Connection getConnection()
          throws SQLException 
      {
          try { return (Connection) m_pool.get(); } 
          catch( final Exception e )
          {
              getLogger().error( "Could not return Connection", e );
              throw new SQLException( e.getMessage() );
          }
      }
  
      /** Dispose properly of the pool */
      public void dispose() 
      {
          m_pool.dispose();
          m_pool = null;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/log/AvalonLogFormatter.java
  
  Index: AvalonLogFormatter.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 file. 
   */ 
  package org.apache.avalon.log;
  
  import java.util.Date;
  import org.apache.avalon.util.StringUtil;
  import org.apache.log.format.PatternFormatter;
  
  /**
   * Specialized formatter that knows about CascadingThrowables.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class AvalonLogFormatter 
      extends PatternFormatter
  {
      protected String getStackTrace( final Throwable throwable, final String format )
      {
          if( null == throwable ) return "";
          return StringUtil.printStackTrace( throwable, 8, true );
      }
  
      /**
       * Utility method to format time.
       *
       * @param time the time
       * @param format ancilliary format parameter - allowed to be null
       * @return the formatted string
       */
      protected String getTime( final long time, final String format )
      {
          return new Date().toString();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/log/DefaultLogManager.java
  
  Index: DefaultLogManager.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 file.
   */
  package org.apache.avalon.log;
  
  import java.io.File;
  import java.io.IOException;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.Iterator;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.context.Context;
  import org.apache.avalon.context.Contextualizable;
  import org.apache.log.Category;
  import org.apache.log.LogKit;
  import org.apache.log.LogTarget;
  import org.apache.log.output.FileOutputLogTarget;
  
  /**
   * Component responsible for managing logs.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultLogManager
      extends AbstractLoggable
      implements Component, Contextualizable, Configurable
  {
      protected String        m_baseName;
      protected File          m_baseDirectory;
  
      public void contextualize( final Context context )
      {
          m_baseName = (String)context.get( "name" );
          if( null == m_baseName ) m_baseName = "<base>";
  
          m_baseDirectory = (File)context.get( "directory" );
          if( null == m_baseDirectory ) m_baseDirectory = new File( "." );
      }
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          final Configuration[] targets = configuration.getChildrenAsArray( "log-target" );
          configureTargets( m_baseName, m_baseDirectory, targets );
          
          final Configuration[] categories = configuration.getChildrenAsArray( "category" );
          configureCategories( m_baseName, categories );
  
          /*
            final String logPriority = configuration.getChild( "global-priority" ).getValue();
            final Priority.Enum priority = LogKit.getPriorityForName( logPriority );
            LogKit.setGlobalPriority( priority );
          */
      }
    
      protected void configureTargets( final String baseName, 
                                       final File baseDirectory, 
                                       final Configuration[] targets )
          throws ConfigurationException
      {
          for( int i = 0; i < targets.length; i++ )
          {
              final Configuration target = targets[ i ];
              final String name = baseName + '.' + target.getAttribute( "name" );
              String location = target.getAttribute( "location" ).trim();
              final String format = target.getAttribute( "format", null );
              
              if( '/' == location.charAt( 0 ) )
              {
                  location = location.substring( 1 );
              }
              
              final File file = new File( baseDirectory, location );
              
              final FileOutputLogTarget logTarget = new FileOutputLogTarget();
              final AvalonLogFormatter formatter = new AvalonLogFormatter();
              formatter.setFormat( "%{time} [%7.7{priority}] <<%{category}>> " +
                                   "(%{context}): %{message}\\n%{throwable}" );
              logTarget.setFormatter( formatter );
              
              try { logTarget.setFilename( file.getAbsolutePath() ); }
              catch( final IOException ioe )
              {
                  throw new ConfigurationException( "Error initializing log files", ioe );
              }
              
              if( null != format ) 
              {
                  logTarget.setFormat( format );
              }
              
              LogKit.addLogTarget( name, logTarget );
          }
      }
      
      protected void configureCategories( final String baseName, final Configuration[] categories )
          throws ConfigurationException
      {
          for( int i = 0; i < categories.length; i++ )
          {
              final Configuration category = categories[ i ];
              String name = category.getAttribute( "name" );
              final String target = baseName + '.' + category.getAttribute( "target" );
              final String priority = category.getAttribute( "priority" );
              
              if( name.trim().equals( "" ) )
              {
                  name = baseName;
              }
              else
              {
                  name = baseName + '.' + name;
              }
              
              final Category logCategory = 
                  LogKit.createCategory( name, LogKit.getPriorityForName( priority ) );
              final LogTarget logTarget = LogKit.getLogTarget( target );
              LogTarget logTargets[] = null;
              
              if( null != target ) logTargets = new LogTarget[] { logTarget };
              
              LogKit.createLogger( logCategory, logTargets );    
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/processor/Matcher.java
  
  Index: Matcher.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 file.
   */
  package org.apache.avalon.processor;
  
  /**
   * This represents a conditional procesing rule.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public interface Matcher 
  {
      /**
       * Returns true if the object match the specific condition defined by this matcher.
       */
      boolean match( Object object );
      
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/processor/Pipeline.java
  
  Index: Pipeline.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 file.
   */
  package org.apache.avalon.processor;
  
  import java.util.NoSuchElementException;
  
  /**
   * This represents a pipeline made up of stages.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
  */
  public interface Pipeline 
      extends Stage
  {
      /**
       * Retrieve size of pipeline (number of stages).
       *
       * @return the size of pipeline
       */
      int getSize();
      
      /**
       * Retrieve a particular stage of pipeline
       *
       * @param index the index of stage
       * @return the stage
       * @exception NoSuchElementException if index >= getSize() or index < 0 
       */
      Stage getStage( int index )
          throws NoSuchElementException;
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/processor/ProcessorPipeline.java
  
  Index: ProcessorPipeline.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 file.
   */
  package org.apache.avalon.processor;
  
  import java.util.ArrayList;
  import java.lang.IndexOutOfBoundsException;
  
  /**
   * This is the default implementation of a Pipeline.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public class ProcessorPipeline 
      implements Pipeline 
  {
      
      private final ArrayList m_stages = new ArrayList();
  
      /**
       * Process the specified object calling 
       * <code> process(Object object) </code> 
       * in all stages in this pipeline. 
       */
  
      public boolean process( final Object object )
      {
          boolean cont = true;
          for (int i = 0; i < getSize() && cont; i++) {
              cont = getStage(i).process(object);
          }
          return cont;
      }
  
      /**
       * Return the number of stages in this pipeline.
       */
      public int getSize()
      {
          return m_stages.size();
      }
      
      /**
       * Return the stage at the specified index.
       */
      public Stage getStage( final int index )
          throws IndexOutOfBoundsException
      {
          return (Stage)m_stages.get( index );
      }
  
      /**
       * Add the specified stage at the end of this pipeline.
       */
      public void addStage( final Stage stage )
      {
          m_stages.add( stage );
      }
  
      /**
       * Insert the specified stage in the specified position.
       */
      public void addStage(int index, Stage stage)
      {
          m_stages.add(index, stage);
      }
      
      /**
       * Remove the specified stage from the specified position.
       */
      public Stage removeStage(int index) {
          return (Stage) m_stages.remove(index );
      }
  }
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/processor/ProcessorTree.java
  
  Index: ProcessorTree.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 file.
   */
  package org.apache.avalon.processor;
  
  /**
   * This implements a single conditional processing node. Incoming object are 
   * checked agaist the matcher and go to the <code> trueBranch </code> if the 
   * object match the matcher requirements else the <code> falseBranch </code>.
   * Using many ProcessorTree is possible to implement any processing graph.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public class ProcessorTree
      implements Stage 
  {
      private Matcher matcher;
      private Stage trueBranch, falseBranch;
      
      /**
       * Create a new ProcessorTree with the specified matcher, trueBranch and falseBranch.
       */
      public ProcessorTree( Matcher matcher, Stage trueBranch, Stage falseBranch) {
          this.matcher = matcher;
          this.trueBranch = trueBranch;
          this.falseBranch = falseBranch;
      }
  
      /**
       * Process the spefified object through the trueBranc if the object matchs 
       * the requirements of this matcher, through the falseBranch else.
       */
      public boolean process(Object object) {
          if (matcher.match(object)) {
              return trueBranch.process(object);
          } else {
              return falseBranch.process(object);
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/processor/Stage.java
  
  Index: Stage.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 file.
   */
  package org.apache.avalon.processor;
  
  /**
   * This represents a stage in a pipeline.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   */
  public interface Stage 
  {
  
      /**
       * Process the specified object. Returns false if the 
       * object should be destroyed after processing.
       */
      boolean process( Object object );
      
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/security/AbstractPolicy.java
  
  Index: AbstractPolicy.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 file. 
   */
  package org.apache.avalon.security;
  
  import java.io.File;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.security.AccessController;
  import java.security.CodeSource;
  import java.security.Permission;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Policy;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  import java.security.cert.Certificate;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.PropertyPermission;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.Loggable;
  import org.apache.avalon.util.io.FileUtil;
  import org.apache.log.Logger;
  
  /**
   * Abstract policy extended in avalon.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractPolicy
      extends Policy
      implements Component, Loggable
  {
      protected final static boolean     DEBUG         = true;
  
      protected final ArrayList        m_entries     = new ArrayList();
      
      protected Logger                 m_logger;
  
      /**
       * Internal Policy Entry holder class.
       */
      protected final static class PolicyEntry
      {
          CodeSource                      m_codeSource;
          Permissions                     m_permissions;
      }
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      /**
       * Overide so we can have a per-application security policy with 
       * no side-effects to other applications.
       *
       * @param codeSource the codeSource to get permissions for 
       * @return the PermissionCollection
       */
      public PermissionCollection getPermissions( CodeSource codeSource )
      {
          codeSource = normalize( codeSource );
  
          getLogger().debug( "getPermissions(" + codeSource.getLocation() + ");" );
          
          final Permissions permissions = new Permissions();
          final int size = m_entries.size();
          
          for( int i = 0; i < size; i++ )
          {
              final PolicyEntry entry = (PolicyEntry)m_entries.get( i );
              
              if( entry.m_codeSource.implies( codeSource ) )
              {
                  if( DEBUG )
                  {
                      getLogger().debug( entry.m_codeSource.getLocation() + " implies " +
                                         codeSource.getLocation() );
                  }
  
                  copyPermissions( permissions, entry.m_permissions );
              }
          }
          
          if( DEBUG )
          {
              getLogger().debug( codeSource.getLocation() + " permissions = " + permissions );
          }
          
          return permissions;        
      }
  
      /**
       * Refresh policy. Ignored in this implementation.
       */
      public void refresh()
      {
      }
      
      /**
       * Normalizing CodeSource involves removing relative addressing 
       * (like .. and .) for file urls.
       *
       * @param codeSource the codeSource to be normalized
       * @return the normalized codeSource
       */
      protected CodeSource normalize( final CodeSource codeSource )
      {
          final URL initialLocation = codeSource.getLocation();
          
          // This is a bit of a hack.  I don't know why CodeSource should behave like this
          // Fear not, this only seems to be a problem for home grown classloaders.
          // - Paul Hammant, Nov 2000
          if( null == initialLocation ) return codeSource;
  
          String location = null;
          
          if( !initialLocation.getProtocol().equalsIgnoreCase( "file" ) )
          {
              location = initialLocation.getFile();
              location = FileUtil.normalize( location );
          }
          else
          {
              final File file = new File( initialLocation.getFile() );
              location = file.getAbsoluteFile().toString().replace( File.separatorChar, '/' );
              location =  FileUtil.normalize( location );
          }
          
          URL finalLocation = null;
          
          try
          {
              finalLocation = new URL( initialLocation.getProtocol(),
                                       initialLocation.getHost(),
                                       initialLocation.getPort(),
                                       location );
          }
          catch( final MalformedURLException mue ) 
          {
              getLogger().warn( "Error building codeBase", mue );
          }
  
          return new CodeSource( finalLocation, codeSource.getCertificates() );
      }
  
      protected void copyPermissions( final Permissions destination, final Permissions src )
      {
          final Enumeration enum = src.elements();
          while( enum.hasMoreElements() )
          {
              destination.add( (Permission)enum.nextElement() );
          }
      }
      
      /**
       * Create a permission set for a codeBase. 
       * These are read-write permissions and can be written till until the 
       * time in which they are applied to code.
       *
       * @param location the location of codes to apply permission set to.
       * @param signers a comma seperated string of thos who signed codebase
       * @return the new permission set
       * @exception MalformedURLException if location string is malformed
       */
      protected Permissions createPermissionSetFor( final String location, 
                                                    final Certificate[] signers )
          throws MalformedURLException
      {
          final PolicyEntry entry = new PolicyEntry();
          entry.m_codeSource = new CodeSource( new URL( location ), signers );
          entry.m_codeSource = normalize( entry.m_codeSource );
          
          getLogger().debug( "createPermissionSetFor(" + 
                             entry.m_codeSource.getLocation() + ");" );
          
          entry.m_permissions = new Permissions();
          
          m_entries.add( entry );
          return entry.m_permissions;
      }   
  
      protected final Logger getLogger()
      {
          return m_logger;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/security/DefaultPolicy.java
  
  Index: DefaultPolicy.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 file. 
   */
  package org.apache.avalon.security;
  
  import java.io.File;
  import java.io.InputStream;
  import java.lang.reflect.Constructor;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.security.KeyStore;
  import java.security.KeyStoreException;
  import java.security.Permission;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.UnresolvedPermission;
  import java.security.cert.Certificate;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.PropertyPermission;
  import java.util.StringTokenizer;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.context.Context;
  import org.apache.avalon.context.Contextualizable;
  import org.apache.avalon.context.DefaultContext;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.util.PropertyException;
  import org.apache.avalon.util.PropertyUtil;
  import org.apache.avalon.util.security.AbstractPolicy;
  
  /**
   * Policy that extracts information from policy files.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultPolicy
      extends AbstractPolicy
      implements Component, Contextualizable, Configurable, Initializable
  {
      protected DefaultContext    m_context;
  
      public void contextualize( final Context context )
      {
          m_context = new DefaultContext( System.getProperties(), context );
          m_context.put( "/", File.separator );
      }
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          final Configuration[] keyStoreConfigurations = configuration.getChildrenAsArray( "keystore" );
          final HashMap keyStores = configureKeyStores( keyStoreConfigurations );
  
          final Configuration[] grants = configuration.getChildrenAsArray( "grant" );
          configureGrants( grants, keyStores );
      }
  
      public void init()
          throws Exception
      {
          //these properties straight out ot ${java.home}/lib/security/java.policy
          final Permissions permissions = createPermissionSetFor( "file:/-", null );
  
          permissions.add( new PropertyPermission( "os.name", "read" ) );
          permissions.add( new PropertyPermission( "os.arch", "read" ) );
          permissions.add( new PropertyPermission( "os.version", "read" ) );
          permissions.add( new PropertyPermission( "file.separator", "read" ) );
          permissions.add( new PropertyPermission( "path.separator", "read" ) );
          permissions.add( new PropertyPermission( "line.separator", "read" ) );
          
          permissions.add( new PropertyPermission( "java.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.vendor.url", "read" ) );
          
          permissions.add( new PropertyPermission( "java.class.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.name", "read" ) );
          
          permissions.add( new PropertyPermission( "java.specification.version", "read" ) );
          permissions.add( new PropertyPermission( "java.specification.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.specification.name", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.specification.version", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.specification.vendor", "read" ) );
          permissions.add( new PropertyPermission( "java.vm.specification.name", "read" ) );
      }
  
      protected HashMap configureKeyStores( final Configuration[] configurations )
          throws ConfigurationException
      {
          final HashMap keyStores = new HashMap();
  
          for( int i = 0; i < configurations.length; i++ )
          {
              final Configuration configuration = configurations[ i ];
              final String type = configuration.getAttribute( "type" );
              final String location = configuration.getAttribute( "location" );
              final String name = configuration.getAttribute( "name" );
  
              try
              {
                  final KeyStore keyStore = KeyStore.getInstance( type );
                  final URL url = new URL( location );
                  final InputStream ins = url.openStream();
                  
                  keyStore.load( ins, null );
  
                  keyStores.put( name, keyStore );
              }
              catch( final Exception e )
              {
                  throw new ConfigurationException( "Error configuring keystore " + name, e );
              }
          }
  
          return keyStores;
      }
      
      protected void configureGrants( final Configuration[] configurations, 
                                      final HashMap keyStores )
          throws ConfigurationException
      {
          for( int i = 0; i < configurations.length; i++ )
          {
              configureGrant( configurations[ i ], keyStores );
          }
      }
  
      protected void configureGrant( final Configuration configuration, final HashMap keyStores )
          throws ConfigurationException
      {
          //<grant signed-by="Fred" code-base="file:${sar.home}/blocks/*" key-store="foo-keystore">
          //<permission class="java.io.FilePermission" target="/tmp/*" action="read,write" />
          //</grant>
  
          final String signedBy = configuration.getAttribute( "signed-by", null );
          final String keyStoreName = configuration.getAttribute( "key-store", null );
  
          String codeBase = configuration.getAttribute( "code-base", null );
          if( null != codeBase )
          {
              codeBase = expand( codeBase );
          }
  
          final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
  
          Permissions permissions = null;
  
          try { permissions = createPermissionSetFor( codeBase, signers ); }
          catch( final MalformedURLException mue )
          {
              throw new ConfigurationException( "Malformed code-base " + codeBase, mue );
          }
  
          
          configurePermissions( configuration.getChildrenAsArray( "permission" ), 
                                permissions,
                                keyStores );
      }
  
      protected void configurePermissions( final Configuration[] configurations, 
                                           final Permissions permissions,
                                           final HashMap keyStores )
          throws ConfigurationException
      {
          for( int i = 0; i < configurations.length; i++ )
          {
              configurePermission( configurations[ i ], permissions, keyStores );
          }
      }
  
      protected void configurePermission( final Configuration configuration,
                                          final Permissions permissions,
                                          final HashMap keyStores )
          throws ConfigurationException
      {
          final String type = configuration.getAttribute( "class" );
          final String actions = configuration.getAttribute( "actions", null );
          final String signedBy = configuration.getAttribute( "signed-by", null );
          final String keyStoreName = configuration.getAttribute( "key-store", null );
  
          String target = configuration.getAttribute( "target", null );
          if( null != target )
          {
              target = expand( target );
          }
  
          final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
          final Permission permission = createPermission( type, target, actions, signers );
  
          permissions.add( permission );
      }
  
      protected String expand( final String value )
          throws ConfigurationException
      {
          try
          {
              final Object resolvedValue = PropertyUtil.resolveProperty( value, m_context, false );
              return resolvedValue.toString();
          }
          catch( final PropertyException pe )
          {
              throw new ConfigurationException( "Error resolving property " + value, pe );
          }
      }
  
      protected Permission createPermission( final String type, 
                                             final String target, 
                                             final String actions, 
                                             final Certificate[] signers )
          throws ConfigurationException
      {
          if( null != signers ) 
          {
              return createUnresolvedPermission( type, target, actions, signers );
          }
          
          try
          {
              final Class c = Class.forName( type );
              
              Class paramClasses[] = null;
              Object params[] = null;
  
              if( null == actions && null == target )
              {
                  paramClasses = new Class[ 0 ];
                  params = new Object[ 0 ];
              }
              else if( null == actions ) 
              {
                  paramClasses = new Class[1];
                  paramClasses[0] = String.class;
                  params = new Object[1];
                  params[0] = target;
              }
              else
              {
                  paramClasses = new Class[2];
                  paramClasses[0] = String.class;
                  paramClasses[1] = String.class;
                  params = new Object[2];
                  params[0] = target;
                  params[1] = actions;
              }
              
              final Constructor constructor = c.getConstructor( paramClasses );
              final Object o = constructor.newInstance( params );
              return (Permission)o;                
          }
          catch( final ClassNotFoundException cnfe )
          {
              return createUnresolvedPermission( type, target, actions, signers );
          }
          catch( final Exception e )
          {
              throw new ConfigurationException( "Failed to create permission " + type + 
                                                " due to " + e, e );
          }
      }
      
      protected Permission createUnresolvedPermission( final String type, 
                                                       final String target, 
                                                       final String actions, 
                                                       final Certificate[] signers )
      {
          return new UnresolvedPermission( type, target, actions, signers );
      }
  
      protected Certificate[] getSigners( final String signedBy,
                                          String keyStoreName,
                                          final HashMap keyStores )
          throws ConfigurationException
      {
          if( null != signedBy && null == keyStoreName )
          {
              keyStoreName = "default";
          }
  
          Certificate[] signers = null;
           
          if( null != signedBy )
          {
              signers = getCertificates( signedBy, keyStoreName, keyStores );
          }
  
          return signers;
      }
  
      protected Certificate[] getCertificates( final String signedBy, 
                                               final String keyStoreName,
                                               final HashMap keyStores )
          throws ConfigurationException
      {
          final KeyStore keyStore = (KeyStore)keyStores.get( keyStoreName );
          
          if( null == keyStore )
          {
              throw new ConfigurationException( "Unable to aquire keyStore " + keyStoreName );
          }
  
          final ArrayList certificateSet = new ArrayList();
  
          final StringTokenizer tokenizer = new StringTokenizer( signedBy, "," );
          
          while( tokenizer.hasMoreTokens() ) 
          {
              final String alias = ((String)tokenizer.nextToken()).trim();
              Certificate certificate = null;
              
              try { certificate = keyStore.getCertificate( alias ); }
              catch( final KeyStoreException kse )
              {
                  throw new ConfigurationException( "Error aquiring certificate " + alias,
                                                    kse );
              }
  
              if( null == certificate )
              {
                  throw new ConfigurationException( "Unable to locate alias " + alias + 
                                                    " in keystore named " + keyStoreName );
              }
  
              if( !certificateSet.contains( certificate ) ) 
              {
                  if( DEBUG ) getLogger().debug( "Certificate " + certificate );
                  certificateSet.add( certificate );
              }
          }
          
          return (Certificate[])certificateSet.toArray( new Certificate[ 0 ] );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/security/PolicyClassLoader.java
  
  Index: PolicyClassLoader.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 file. 
   */
  package org.apache.avalon.security;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Policy;
  
  /**
   * Classloader that applies correct policy information.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class PolicyClassLoader
      extends URLClassLoader
  {
      protected Policy      m_policy;
  
      public PolicyClassLoader( final URL[] urls, 
                                final ClassLoader classLoader, 
                                final Policy policy )
      {
          super( urls, classLoader );
          m_policy = policy;
      }
  
      /**
       * Overide so we can have a per-application security policy with 
       * no side-effects to other applications.
       *
       * @param codeSource the codeSource to get permissions for 
       * @return the PermissionCollection
       */
      protected PermissionCollection getPermissions( final CodeSource codeSource )
      {
          if( null == m_policy )
          {
              final Permissions permissions = new Permissions();
              permissions.add( new java.security.AllPermission() );
              return permissions;
          }
          else
          {
              return m_policy.getPermissions( codeSource );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/thread/DefaultThreadManager.java
  
  Index: DefaultThreadManager.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 file.
   */
  package org.apache.avalon.thread;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  
  /**
   *
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultThreadManager
      extends AbstractLoggable
      implements ThreadManager, Configurable 
  {
      protected final Hashtable       m_pools = new Hashtable();
  
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          final Iterator groups = configuration.getChildren( "thread-group" );
          while (groups.hasNext())
          {
              final Configuration group = (Configuration) groups.next();
  
              final String name = group.getChild( "name" ).getValue();            
              final int priority = group.getChild( "priority" ).getValueAsInt( 5 );
              final boolean isDaemon = group.getChild( "is-daemon" ).getValueAsBoolean( false );
  
              final int minThreads = group.getChild( "min-threads" ).getValueAsInt( 5 );
              final int maxThreads = group.getChild( "max-threads" ).getValueAsInt( 10 );
              final int minSpareThreads = group.getChild( "min-spare-threads" ).
                  getValueAsInt( maxThreads - minThreads );
  
              try
              {
                  final ThreadPool threadPool = new ThreadPool( name, maxThreads );
                  threadPool.setDaemon( isDaemon );
                  setupLogger( threadPool );
                  m_pools.put( name, threadPool );
              }
              catch( final Exception e )
              {
                  throw new ConfigurationException( "Error creating thread pool " + name, e );
              }
          }
      }
  
      public ThreadPool getDefaultThreadPool()
      {
          return getThreadPool( "default" );
      }
  
      public ThreadPool getThreadPool( final String name ) 
      {
          final ThreadPool threadPool = (ThreadPool)m_pools.get( name );
  
          if( null == threadPool )
          {
              //Should this be a ComponentNotFoundException ????
              throw new IllegalArgumentException( "No such thread group " + name );
          }
  
          return threadPool;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/thread/ThreadContext.java
  
  Index: ThreadContext.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 file.
   */
  package org.apache.avalon.thread;
  
  import org.apache.avalon.Poolable;
  import org.apache.avalon.util.pool.ObjectFactory;
  import org.apache.avalon.util.pool.ThreadSafePool;
  
  /**
   * To deal with *current* ThreadContext.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ThreadContext 
  {
      protected final static InheritableThreadLocal   c_context = new InheritableThreadLocal();
  
      public static ThreadPool getCurrentThreadPool()
      {
          return (ThreadPool)c_context.get();
      }
  
      public static void setCurrentThreadPool( final ThreadPool threadPool )
      {
          //TODO: protect by a permission guard
          c_context.set( threadPool );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/thread/ThreadManager.java
  
  Index: ThreadManager.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 file.
   */
  package org.apache.avalon.thread;
  
  import org.apache.avalon.component.Component;
  
  /**
   * Interface for component that hands out thread pools.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ThreadManager
      extends Component
  {
      ThreadPool getThreadPool( String name );
      ThreadPool getDefaultThreadPool();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/thread/ThreadPool.java
  
  Index: ThreadPool.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 file.
   */
  package org.apache.avalon.thread;
  
  import org.apache.avalon.Loggable;
  import org.apache.avalon.Poolable;
  import org.apache.avalon.util.pool.ObjectFactory;
  import org.apache.avalon.util.pool.ThreadSafePool;
  import org.apache.log.Logger;
  
  /**
   * This class is the public frontend for the thread pool code.
   *
   * TODO: Should this be configured with min threads, max threads and min spare threads ?
   *
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ThreadPool 
      extends ThreadGroup
      implements ObjectFactory, Loggable
  {
      protected final ThreadSafePool        m_pool;
      protected int                         m_level;
      protected Logger                      m_logger;
  
      public ThreadPool( final int capacity )
          throws Exception
      {
          this( "Worker Pool", capacity );
      }
  
      public ThreadPool( final String name, final int capacity )
          throws Exception 
      {
          super( name );
          m_pool = new ThreadSafePool( this, 0 );
          m_pool.init();
          m_pool.grow( capacity );
      }
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      public Poolable newInstance()
      {
          final WorkerThread worker = 
              new WorkerThread( this, m_pool, getName() + " Worker #" + m_level++ );
          worker.setLogger( m_logger );
          worker.start();
          return worker;
      }
  
      public Class getCreatedClass()
      {
          return WorkerThread.class;
      }
          
      public void execute( final Runnable work ) 
          throws Exception
      {
          execute( work, Thread.NORM_PRIORITY );
      }
  
      public void execute( final Runnable work, final int priority ) 
          throws Exception
      {
          final WorkerThread worker = getWorker( priority );
          worker.execute( work );
      }
      
      public void executeAndWait( final Runnable work ) 
          throws Exception
      {
          executeAndWait( work, Thread.NORM_PRIORITY );
      }
  
      public void executeAndWait( final Runnable work, final int priority ) 
          throws Exception
      {
          final WorkerThread worker = getWorker( priority );
          worker.executeAndWait( work );
      }
  
      protected WorkerThread getWorker( final int priority )
          throws Exception
      {
          final WorkerThread worker = (WorkerThread)m_pool.get();
          worker.setContextClassLoader( Thread.currentThread().getContextClassLoader() );
          worker.setPriority( priority );
          return worker;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/thread/WorkerThread.java
  
  Index: WorkerThread.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 file.
   */
  package org.apache.avalon.thread;
  
  import org.apache.avalon.Loggable;
  import org.apache.avalon.Poolable;
  import org.apache.avalon.util.pool.ThreadSafePool;
  import org.apache.log.Logger;
  
  /**
   * This class extends the Thread class to add recyclable functionalities.
   *
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  class WorkerThread 
      extends Thread 
      implements Poolable, Loggable
  {
      protected final static boolean  DEBUG          = false;
  
      protected Logger                m_logger;
      protected ThreadPool            m_threadPool;
      protected ThreadSafePool        m_pool;
  
      protected Runnable              m_work;
      protected boolean               m_alive;
  
      /**
       * Allocates a new <code>Worker</code> object.
       */
      protected WorkerThread( final ThreadPool threadPool,
                              final ThreadSafePool pool, 
                              final String name )
      {
          super( threadPool, name );
          
          m_threadPool = threadPool;
          m_pool = pool;
  
          m_work = null;
          m_alive = true;
          setDaemon( false );
      }
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      /**
       * The main execution loop.
       */
      public final synchronized void run()
      {
          ThreadContext.setCurrentThreadPool( m_threadPool );
  
          if( DEBUG ) m_logger.info( getName() + ": starting." );
                  
          // Notify the pool this worker started running.
          //notifyAll();
  
          while( m_alive )
          {
              waitUntilCondition( true );
  
              if( DEBUG ) m_logger.debug( getName() + ": running." );
                  
              try 
              {
                  m_work.run();
              } 
              catch( final ThreadDeath td )
              {
                  if ( DEBUG ) m_logger.debug( getName() + ": thread has died." );
                          
                  // This is to let the thread death propagate to the runtime
                  // enviroment to let it know it must kill this worker
                  throw td;
              } 
              catch( final Throwable t )
              {
                  // Error thrown while working.
                  if( DEBUG ) m_logger.debug( getName() + ": error caught: " + t );
                  // XXX: what should we do when this happens?
              }
  
              if( DEBUG ) m_logger.debug( getName() + ": done." );
  
              m_work = null;
  
              //should this be just notify or notifyAll ??? 
              //It seems to resource intensive option to use notify()
              //notifyAll();
              notify();
  
              // recycle ourselves
              if( null != m_pool )
              {
                  m_pool.put( this );
              }
              else
              {
                  m_alive = false;
              }
          }
      }
  
      /**
       * Set the <code>Work</code> code this <code>Worker</code> must
       * execute and <i>notifies</i> its thread to do it.
       */
      protected synchronized void executeAndWait( final Runnable work )
      {
          execute( work );
          waitUntilCondition( false );
      }
  
      protected synchronized void waitUntilCondition( final boolean hasWork )
      {
          while( hasWork == (null == m_work) )
          {
              try 
              {
                  if( DEBUG ) m_logger.debug( getName() + ": waiting." );
                  wait(); 
                  if( DEBUG ) m_logger.debug( getName() + ": notified." );
              }
              catch( final InterruptedException ie ) {}
          }
      }
  
      protected synchronized void execute( final Runnable work )
      {
          if( DEBUG ) m_logger.debug( getName() + ": notifying this worker." );
          m_work = work;
          notify();
      }
  
      /**
       * Set the <code>alive</code> variable to false causing the worker to die.
       * If the worker is stalled and a timeout generated this call, this method
       * does not change the state of the worker (that must be destroyed in other
       * ways).
       */
      public void dispose() 
      {
          if( DEBUG ) m_logger.debug( getName() + ": destroying." );
          m_alive = false;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ArrayEnumeration.java
  
  Index: ArrayEnumeration.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import java.util.Enumeration;
  import java.util.List;
  import java.util.NoSuchElementException;
  
  /**
   * Enumeration wrapper for array.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ArrayEnumeration 
      implements Enumeration
  {
      protected Object[]       m_elements;
      protected int            m_index;
  
      public ArrayEnumeration( final List elements )
      {
          m_elements = elements.toArray();
      }
  
      public ArrayEnumeration( final Object[] elements )
      {
          m_elements = elements;
      }
  
      public boolean hasMoreElements()
      {
          return ( m_index < m_elements.length );
      }
  
      public Object nextElement()
      {
          if( !hasMoreElements() ) 
          {
              throw new NoSuchElementException("No more elements exist");
          }
  
          return m_elements[ m_index++ ];
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ArrayStack.java
  
  Index: ArrayStack.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import java.util.ArrayList;
  import java.util.EmptyStackException;
  
  /**
   * Unsynchronized stakc.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ArrayStack 
      extends ArrayList
  {
  	public void setSize( final int size )
      {
  	    if( 0 == size ) clear();
  	    else 
          {
              removeRange( size, size() - 1 );
  	    }
  	}
  
      /**
       * Adds the object to the top of the stack.
       *
       * @param element object to add to stack
       * @return the object
       */
      public Object push( final Object element )
      {
  	    add( element );
  	    return element;
  	}
  
  	/**
       * Remove element from top of stack and return it
       *
       * @return the element from stack
       * @exception EmptyStackException if no elements left on stack
       */
      public Object pop()
          throws EmptyStackException 
      {
          final int size = size();
          if( 0 == size ) throw new EmptyStackException();
  
          return remove( size - 1 );
  	}
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/BinaryHeap.java
  
  Index: BinaryHeap.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import java.util.NoSuchElementException;
  
  /**
   * Iterface for priority queues.
   * This interface does not dictate whether it is min or max heap.
   *
   * @author  <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */
  public final class BinaryHeap 
      implements PriorityQueue
  {
      protected final static int      DEFAULT_CAPACITY   = 13;
  
      protected int                   m_size;
      protected Comparable[]          m_elements;
      protected boolean               m_isMinHeap;
  
      public BinaryHeap()
      {
          this( DEFAULT_CAPACITY, true );
      }
  
      public BinaryHeap( final int capacity )
      {
          this( capacity, true );
      }
  
      public BinaryHeap( final boolean isMinHeap )
      {
          this( DEFAULT_CAPACITY, isMinHeap );
      }
  
      public BinaryHeap( final int capacity, final boolean isMinHeap )
      {
          m_isMinHeap = isMinHeap;
  
          //+1 as 0 is noop
          m_elements = new Comparable[ capacity + 1 ];
      }
  
      /**
       * Clear all elements from queue.
       */
      public void clear()
      {
          m_size = 0;
      }
  
      /**
       * Test if queue is empty.
       *
       * @return true if queue is empty else false.
       */
      public boolean isEmpty()
      {
          return ( 0 == m_size );
      }
  
      /**
       * Test if queue is full.
       *
       * @return true if queue is full else false.
       */
      public boolean isFull()
      {
          return ( m_elements.length == m_size );
      }
  
      /**
       * Insert an element into queue.
       *
       * @param element the element to be inserted
       */
      public void insert( final Comparable element )
      {
          if( isFull() ) grow();
  
          //percolate element to it's place in tree
          if( m_isMinHeap ) percolateUpMinHeap( element );
          else percolateUpMaxHeap( element );
      }
  
      /**
       * Return element on top of heap but don't remove it.
       *
       * @return the element at top of heap
       * @exception NoSuchElementException if isEmpty() == true
       */
      public Comparable peek() throws NoSuchElementException
      {
          if( isEmpty() ) throw new NoSuchElementException();
          else return m_elements[ 1 ];
      }
  
      /**
       * Return element on top of heap and remove it.
       *
       * @return the element at top of heap
       * @exception NoSuchElementException if isEmpty() == true
       */
      public Comparable pop() throws NoSuchElementException
      {
          final Comparable result = peek();
          m_elements[ 1 ] = m_elements[ m_size-- ];
  
          if( m_size != 0 )
          {
              //percolate top element to it's place in tree
              if( m_isMinHeap ) percolateDownMinHeap( 1 );
              else percolateDownMaxHeap( 1 );
          }
  
          return result;
      }
  
      /**
       * Percolate element down heap from top. 
       * Assume it is a maximum heap.
       *
       * @param element the element
       */
      protected void percolateDownMinHeap( final int index )
      {
          final Comparable element = m_elements[ index ];
  
          int hole = index;
  
          while( (hole * 2) <= m_size )
          {
              int child = hole * 2;
  
              //if we have a right child and that child can not be percolated
              //up then move onto other child
              if( child != m_size && 
                  m_elements[ child + 1 ].compareTo( m_elements[ child ] ) < 0 )
              {
                  child++;
              }
  
              //if we found resting place of bubble then terminate search
              if( m_elements[ child ].compareTo( element ) >= 0 )
              {
                  break;
              }
  
              m_elements[ hole ] = m_elements[ child ];
              hole = child;
          }
          
          m_elements[ hole ] = element;
      }
  
      /**
       * Percolate element down heap from top. 
       * Assume it is a maximum heap.
       *
       * @param element the element
       */
      protected void percolateDownMaxHeap( final int index )
      {
          final Comparable element = m_elements[ index ];
  
          int hole = index;
  
          while( (hole * 2) <= m_size )
          {
              int child = hole * 2;
  
              //if we have a right child and that child can not be percolated
              //up then move onto other child
              if( child != m_size && 
                  m_elements[ child + 1 ].compareTo( m_elements[ child ] ) > 0 )
              {
                  child++;
              }
  
              //if we found resting place of bubble then terminate search
              if( m_elements[ child ].compareTo( element ) <= 0 )
              {
                  break;
              }
  
              m_elements[ hole ] = m_elements[ child ];
              hole = child;
          }
          
          m_elements[ hole ] = element;
      }
  
      /**
       * Percolate element up heap from bottom. 
       * Assume it is a maximum heap.
       *
       * @param element the element
       */
      protected void percolateUpMinHeap( final Comparable element )
      {
          int hole = ++m_size;
          
          m_elements[ hole ] = element;
  
          while( hole > 1 &&
                 element.compareTo( m_elements[ hole / 2 ] ) < 0 )
          {
              //save element that is being pushed down
              //as the element "bubble" is percolated up
              final int next = hole / 2;
              m_elements[ hole ] = m_elements[ next ];
              hole = next;
          }
  
          m_elements[ hole ] = element;
      }
  
      /**
       * Percolate element up heap from bottom. 
       * Assume it is a maximum heap.
       *
       * @param element the element
       */
      protected void percolateUpMaxHeap( final Comparable element )
      {
          int hole = ++m_size;
  
          while( hole > 1 &&
                 element.compareTo( m_elements[ hole / 2 ] ) > 0 )
          {
              //save element that is being pushed down
              //as the element "bubble" is percolated up
              final int next = hole / 2;
              m_elements[ hole ] = m_elements[ next ];
              hole = next;
          }
  
          m_elements[ hole ] = element;
      }
  
      protected void grow()
      {
          final Comparable[] elements = 
              new Comparable[ m_elements.length * 2 ]; 
          System.arraycopy( m_elements, 0, elements, 0, m_elements.length );
          m_elements = elements;
      }
  
      public String toString()
      {
          final StringBuffer sb = new StringBuffer();
  
          sb.append( "[ " );
  
          for( int i = 1; i < m_size + 1; i++ )
          {
              if( i != 1 ) sb.append( ", " );
              sb.append( m_elements[ i ] );
          }
  
          sb.append( " ]" );
  
          return sb.toString();
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/Circuit.java
  
  Index: Circuit.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 file.
   */
  package org.apache.avalon.util;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  
  /**
   *
   * @version 0.0.20, 04/07/1998
   * @author  Federico Barbieri <fede@apache.org>
   * @author  Stefano Mazzocchi <mazzocch@mbox.systemy.it>
   */
  public class Circuit
  {
      protected Hashtable m_map;
  
      public Circuit() 
      {
          m_map = new Hashtable();
      }
  
      public void addNode( final String name )
      {
          if( null == m_map.get( name ) )
          {
              m_map.put( name, new Node( name ) );
          }
      }
  
      public void removeNode( final String name )
      {
          String tmp = null;
          Enumeration e = m_map.keys();
          
          while( e.hasMoreElements() )
          {
              tmp = (String)e.nextElement();
              
              if( !tmp.equals( name ) )
              {
                  try { unlink( tmp, name ); } 
                  catch( final CircuitException ce) {}
                  try { unlink( name, tmp ); } 
                  catch( final CircuitException ce ) {}
              }
              
          }
          
          m_map.remove( name );
      }
  
      public void link( final String parent, final String child )
          throws CircuitException
      {
          Node tempNode = null;
          Node pnode = (Node)m_map.get( parent );
          Node cnode = (Node)m_map.get( child );
          if( null == pnode ) 
          {
              throw new CircuitException( "Unknown node " + parent );
          } 
          else if( null == cnode )
          {
              throw new CircuitException( "Unknown node " + child );
          } 
          else if( pnode.isChildOf( cnode ) )
          {
              throw new CircuitException( "Loop! Node " + parent + 
                                          " is already child of node " + child );
          } 
          else
          {
              final Enumeration e = m_map.elements();
  
              while( e.hasMoreElements() )
              {
                  tempNode = (Node)e.nextElement();
                  if( tempNode.isChildOf( cnode ) )
                  {
                      tempNode.m_parents.addAll( pnode.m_parents );
                  }
              }
          }
      }
  
      public void unlink( final String parent, final String child )
          throws CircuitException 
      {
          Node cnode = (Node)m_map.get( child );
          Node pnode = (Node)m_map.get( parent );
  
          if( cnode.m_parents.contains( pnode ) )
          {
              Node tempNode = null;
              Enumeration e = m_map.elements();
  
              while( e.hasMoreElements() )
              {
                  tempNode = (Node)e.nextElement();
  
                  if( tempNode.m_parents.contains( cnode ) )
                  {
                      tempNode.m_parents.removeAll( pnode.m_parents );
                  }
              }
          } 
          else
          {
              throw new CircuitException( "Node " + parent + " is not parent of node " + child );
          }
      }
  
      public Vector getAncestors() 
      {
          Vector ancestors = new Vector();
          String name = null;
          Node tempNode = null;
          Enumeration e = m_map.keys();
  
          while( e.hasMoreElements() )
          {
              name = (String)e.nextElement();
              tempNode = (Node)m_map.get( name );
  
              if( 1 == tempNode.m_parents.size() )
              {
                  ancestors.addElement( name );
              }
          }
  
          return ancestors;
      }
  
      public String getAncestor() 
      {
          String name = null;
          Node tempNode = null;
          Enumeration e = m_map.keys();
  
          while( e.hasMoreElements() )
          {
              name = (String)e.nextElement();
              tempNode = (Node)m_map.get( name );
  
              if( 1 == tempNode.m_parents.size() )
              {
                  return name;
              }
          }
  
          return null;
      }
      
      public boolean isEmpty() 
      {
          return m_map.isEmpty();
      }
      
      protected final class Node 
      {
          protected Vector m_parents;
          protected String m_name;
      
          protected Node( final String name )
          {
              m_parents = new Vector( 5 );
              m_parents.addElement( this );
              m_name = name;
          }
              
          protected boolean isChildOf( final Node parent ) 
          {
              return m_parents.contains( parent );
          }
              
          public String toString() 
          {
              StringBuffer buffer = new StringBuffer();
              Enumeration e = m_parents.elements();
              buffer.append( m_name + "[" );
              
              while( e.hasMoreElements() )
              {
                  buffer.append(((Node) e.nextElement()).m_name + " ");
              }
  
              buffer.append("]");
              return buffer.toString();
          }
      }
      
      public final class CircuitException 
          extends RuntimeException
      {
          public CircuitException()
          {
          }
          
          public CircuitException( final String message )
          {
              super( message );
          }
      }
      
      public String toString() 
      {
          StringBuffer buffer = new StringBuffer();
          String name = null;
          Node tempNode = null;
          Enumeration e = m_map.keys();
  
          while( e.hasMoreElements() )
          {
              name = (String)e.nextElement();
              tempNode = (Node)m_map.get( name );
              buffer.append( name + "(" + ( tempNode.m_parents.size() - 1 ) + ") " );
          }
  
          return buffer.toString();
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/CircularBuffer.java
  
  Index: CircularBuffer.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 file.
   */
  package org.apache.avalon.util;
  
  /**
   *
   * @author  Federico Barbieri <fede@apache.org>
   */
  public class CircularBuffer
  {
      protected Object[]   m_buffer;
      protected int        m_bufferSize;
      protected int        m_contentSize;
      protected int        m_head;
      protected int        m_tail;
  
      public CircularBuffer( int size )
      {
          m_buffer = new Object[size];
          m_bufferSize = size;
          m_contentSize = 0;
          m_head = 0;
          m_tail = 0;
      }
  
      public CircularBuffer() 
      {
          this( 32 );
      }
  
      public boolean isEmpty() 
      {
          return (m_contentSize == 0);
      }
  
      public int getContentSize() 
      {
          return m_contentSize;
      }
  
      public int getBufferSize() 
      {
          return m_bufferSize;
      }
  
      public void append( final Object o )
      {
          if( m_contentSize >= m_bufferSize )
          {
              int j = 0;
              int i = m_tail;
              Object[] tmp = new Object[ m_bufferSize * 2 ];
              
              while( m_contentSize > 0 )
              {
                  i++;
                  i %= m_bufferSize;
                  j++;
                  m_contentSize--;
                  tmp[ j ] = m_buffer[ i ];
              }
              m_buffer = tmp;
              m_tail = 0;
              m_head = j;
              m_contentSize = j;
              m_bufferSize *= 2;
          }
          
          m_buffer[ m_head ] = o;
          m_head++;
          m_head %= m_bufferSize;
          m_contentSize++;
      }
  
      public Object get() 
      {
          if( m_contentSize <= 0 )
          {
              return null;
          }
  
          Object o = m_buffer[ m_tail ];
          m_tail++;
          m_tail %= m_bufferSize;
          m_contentSize--;
          return o;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/CircularDependencyException.java
  
  Index: CircularDependencyException.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 file.
   */
  package org.apache.avalon.util;
  
  import java.util.List;
  import org.apache.avalon.CascadingException;
  
  /**
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */
  public class CircularDependencyException
      extends CascadingException
  {
      protected List   m_stack;
  
      public CircularDependencyException( final String dependee, 
                                          final String dependent, 
                                          final List stack )
      {
          super( dependee + " depends upon " + dependent + " which depends upong " + dependee );
          m_stack = stack;
      }
      
      public List getStack()
      {
          return m_stack;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/DependencyGraph.java
  
  Index: DependencyGraph.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 file.
   */
  package org.apache.avalon.util;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  
  /**
   * DirectedGraph is a acyclic Directed graph implementation.  
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */
  public class DependencyGraph 
  {
      protected final HashMap  m_map               = new HashMap();
      protected boolean        m_allowCircularity  = true;      
  
      public void setAllowCircularity( final boolean allowCircularity )
      {
          m_allowCircularity = allowCircularity;
      }
  
      public void add( final String name, final String[] dependencies )
      {
          m_map.put( name, new GraphNode( name, dependencies ) );
      }
      
      public void remove( final String name ) 
      {
          m_map.remove( name );
      }
  
      public Dependency[] getDependencyList( final String name )
          throws CircularDependencyException
      {
          final ArrayList list = new ArrayList();
          final Dependency dependency = new Dependency( name , null );
          list.add( dependency );
  
          if( null != m_map.get( name ) )
          {
              final ArrayList stack = new ArrayList();
              stack.add( name );
              buildDependencyList( name, list, new ArrayList(), stack );
          }
  
          return (Dependency[])list.toArray( new Dependency[ 0 ] );        
      }
  
      protected void buildDependencyList( final String name, 
                                          final ArrayList list, 
                                          final ArrayList done,
                                          final ArrayList stack )
          throws CircularDependencyException
      {
          if( done.contains( name ) ) return;
          done.add( name );
  
          final GraphNode node = (GraphNode)m_map.get( name );
          if( null == node ) return;
  
          final String[] dependencies = node.getDependencies();
          for( int i = 0; i < dependencies.length; i++ )
          {
              if( stack.contains( dependencies[ i ] ) )
              {
                  if( m_allowCircularity ) continue;
                  else
                  {
                      throw new CircularDependencyException( dependencies[ i ], name, stack );
                  }
              }
  
              if( done.contains( dependencies[ i ] ) ) continue;
   
              final Dependency dependency = new Dependency( dependencies[ i ], name );
              list.add( dependency );
  
              stack.add( dependencies[ i ] );
              buildDependencyList( dependencies[ i ], list, done, stack );
              stack.remove( stack.size() - 1 );
          }        
      }
  
      public final static class Dependency
      {
          protected final String       m_name;
          protected final String       m_requiredBy;
  
          protected Dependency( final String name, final String requiredBy )
          {
              m_name = name;
              m_requiredBy = requiredBy;
          }
  
          public String getName()
          {
              return m_name;
          }
  
          public String getRequiredBy()
          {
              return m_requiredBy;
          }
          
          public String toString()
          {
              return getName();
          }
      }
  
      protected final static class GraphNode 
      {
          protected final String     m_name;
          protected final String[]   m_dependencies;
  
          protected GraphNode( final String name, final String[] dependencies ) 
          {
              m_name = name;
              m_dependencies = dependencies;
          }
  
          public String getName()
          {
              return m_name;
          }
  
          public String[] getDependencies()
          {
              return m_dependencies;
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/Enum.java
  
  Index: Enum.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import java.util.Map;
  
  /**
   * Basic enum class for type-safe enums. Should be used as an abstract base.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class Enum 
  {
      protected final String        m_name;
      
      public Enum( final String name )
      {
          this( name, null );
      } 
   
      public Enum( final String name, final Map map )
      {
          m_name = name;
          if( null != map )
          {
              map.put( name, this );
          }
      } 
  
      public final String getName()
      {
          return m_name;
      }
      
      public String toString()
      {
          return getClass().getName() + "[" + m_name + "]";
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/IteratorEnumeration.java
  
  Index: IteratorEnumeration.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.NoSuchElementException;
  
  /**
   * Enumeration wrapper for iterator.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class IteratorEnumeration 
      implements Enumeration
  {
      protected Iterator       m_iterator;
  
      public IteratorEnumeration( final Iterator iterator )
      {
          m_iterator = iterator;
      }
  
      public boolean hasMoreElements()
      {
          return m_iterator.hasNext();
      }
  
      public Object nextElement()
      {
          return m_iterator.next();
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ListUtils.java
  
  Index: ListUtils.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 file.
   */
  package org.apache.avalon.util;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  /**
   * Miscelaneous utilities to manipulate Lists.
   *
   * @author  <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author  <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ListUtils
  {
      public static List intersection( final List list1, final List list2 ) 
      {
          final ArrayList result = new ArrayList();
          final Iterator iterator = list2.iterator();
  
          while( iterator.hasNext() ) 
          {
              final Object o = iterator.next();
  
              if ( list1.contains( o ) ) 
              {
                  result.add( o );
              }
          }
  
          return result;
      }
      
      public static List subtract( final List list1, final List list2 ) 
      {
          final ArrayList result = new ArrayList( list1 );
          final Iterator iterator = list2.iterator();
  
          while( iterator.hasNext() ) 
          {
              result.remove( iterator.next() );
          }
  
          return result;
      }
      
      public static List sum( final List list1, final List list2 ) 
      {
          return subtract( union( list1, list2 ), 
                           intersection( list1, list2 ) );
      }
      
      public static List union( final List list1, final List list2 ) 
      {
          final ArrayList result = new ArrayList( list1 );
          result.addAll( list2 );
          return result;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/Lock.java
  
  Index: Lock.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 file.
   */
  package org.apache.avalon.util;
  
  import java.util.Hashtable;
  
  /**
   * @author Federico Barbieri <fede@apache.org>
   */
  public class Lock
  {
      private Hashtable locks = new Hashtable();
  
      public boolean isLocked( final Object key )
      {
          return (locks.get(key) != null);
      }
  
      public boolean canI( final Object key )
      {
          Object o = locks.get( key );
  
          if( null == o || o == this.getCallerId() )
          {
              return true;
          }
  
          return false;
      }
  
      public boolean lock( final Object key )
      {
          Object theLock;
          
          synchronized( this )
          {
              theLock = locks.get( key );
          }
  
          if( null == theLock )
          {
              locks.put( key, getCallerId() );
              return true;
          } 
          else if( getCallerId() == theLock )
          {
              return true;
          } 
          else
          {
              return false;
          }
      }
  
      public boolean unlock( final Object key ) 
      {
          Object theLock;
          synchronized( this )
          {
              theLock = locks.get( key );
          }
  
          if( null == theLock )
          {
              return true;
          } 
          else if( getCallerId() == theLock )
          {
              locks.remove( key );
              return true;
          } 
          else
          {
              return false;
          }
      }
  
      private Object getCallerId() 
      {
          return Thread.currentThread();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/LockException.java
  
  Index: LockException.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 file.
   */
  package org.apache.avalon.util;
  
  public class LockException 
      extends RuntimeException
  {
      public LockException( final String message )
      {
          super( message );
      }
      
      public LockException() 
      {
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ObjectUtil.java
  
  Index: ObjectUtil.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 file.
   */
  package org.apache.avalon.util;
  
  /**
   * This class provides basic facilities for manipulating objects.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ObjectUtil
  {
      /**
       * Private constructor to prevent instantiation.
       */
      private ObjectUtil()
      {
      }
  
      public static boolean isEqual( final Object o1, final Object o2 )
      {
          if( null == o1 )
          {
              if( null == o2 ) 
              {
                  return true;
              }
              else
              {
                  return false;
              }
          }
          else if( null == o2 )
          {
              return false;
          }
          else 
          {
              return o1.equals( o2 );
          }
      }
  
      public static Object createObject( final ClassLoader classLoader, final String classname )
          throws ClassNotFoundException, InstantiationException, IllegalAccessException
      {
          final Class clazz = classLoader.loadClass( classname );
          return clazz.newInstance();
      }
  
      
      public static Object createObject( final String classname )
          throws ClassNotFoundException, InstantiationException, IllegalAccessException
      {
          final Class clazz = Class.forName( classname );
          return clazz.newInstance();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/Primes.java
  
  Index: Primes.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 file.
   */
  package org.apache.avalon.util;
  
  /**
   *
   * @author  Federico Barbieri <fede@apache.org>
   * @author  Stefano Mazzocchi <stefano@apache.org>
   */
  public class Primes
  {
      /**
       * Last prime found.
       *
       */
      protected static long                c_lastPrime              = 1;
  
      /**
       * Return next prime.
       *
       */
      public static long nextPrime() 
      {
          long l = c_lastPrime + 1;
          long v = 2;
  
          while( true )
          {
              l++;
                  
              while( v < l )
              {
                  v++;
  
                  if( (l % v) == 0 )
                  {
                      v = 0;
                      break;
                  }
              } // while v < l
                  
              if( v == l )
              {
                  c_lastPrime = l;
                  return l;
              } // if v is l
          } // while true (break is used to escape)
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/PriorityQueue.java
  
  Index: PriorityQueue.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import java.util.NoSuchElementException;
  
  /**
   * Iterface for priority queues.
   * This interface does not dictate whether it is min or max heap.
   *
   * @author  <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */
  public interface PriorityQueue
  {
      /**
       * Clear all elements from queue.
       */
      void clear();
  
      /**
       * Test if queue is empty.
       *
       * @return true if queue is empty else false.
       */
      boolean isEmpty();
  
      /**
       * Insert an element into queue.
       *
       * @param element the element to be inserted
       */
      void insert( Comparable element );
  
      /**
       * Return element on top of heap but don't remove it.
       *
       * @return the element at top of heap
       * @exception NoSuchElementException if isEmpty() == true
       */
      Comparable peek() throws NoSuchElementException;
  
      /**
       * Return element on top of heap and remove it.
       *
       * @return the element at top of heap
       * @exception NoSuchElementException if isEmpty() == true
       */
      Comparable pop() throws NoSuchElementException;
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/PropertyException.java
  
  Index: PropertyException.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 file.
   */
  package org.apache.avalon.util;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Thrown when a property can not be resolved properly.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class PropertyException 
      extends CascadingException
  {
      /**
       * Construct a new <code>PropertyException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public PropertyException( final String message ) 
      {
          this( message, null );
      }
      
      /**
       * Construct a new <code>PropertyException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public PropertyException( final String message, final Throwable throwable ) 
      {
          super( message, throwable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/PropertyUtil.java
  
  Index: PropertyUtil.java
  ===================================================================
  package org.apache.avalon.util;
  
  import org.apache.avalon.context.Context;
  import org.apache.avalon.context.Resolvable;
  
  /**
   * This provides utility methods for properties.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class PropertyUtil
  {
      private PropertyUtil()
      {
      }
      
      /**
       * Resolve property. 
       * This evaluates all property substitutions based on current context.
       *
       * @param property the property to resolve
       * @param context the context in which to resolve property
       * @param ignoreUndefined if false will throw an PropertyException if property is not found 
       * @return the reolved property
       * @exception PropertyException if an error occurs
       */
      public static Object resolveProperty( final String property, 
                                            final Context context, 
                                            final boolean ignoreUndefined )
          throws PropertyException
      {
          int start = property.indexOf( "${" );
          if( -1 == start ) return property;
          
          int end = property.indexOf( '}', start );
          if( -1 == end ) return property;
          
          final int length = property.length();
          
          if( 0 == start && end == (length - 1) )
          {
              return resolveValue( property.substring( start + 2, end ), 
                                   context, 
                                   ignoreUndefined );
          }
          
          final StringBuffer sb = new StringBuffer();
          int lastPlace = 0;
          
          while( true )
          {
              final Object value = 
                  resolveValue( property.substring( start + 2, end ), 
                                context, 
                                ignoreUndefined );
  
              sb.append( property.substring( lastPlace, start ) );
              sb.append( value );
  
              lastPlace = end + 1;
              
              start = property.indexOf( "${", end );
              if( -1 == start ) break;
              
              end = property.indexOf( '}', start );
              if( -1 == end ) break;
          }
          
          sb.append( property.substring( lastPlace, length ) );
  
          return sb.toString();
      }
      
      protected static Object resolveValue( final String key, 
                                            final Context context,
                                            final boolean ignoreUndefined )
          throws PropertyException
      {
          Object value = context.get( key );
  
          while( null != value && value instanceof Resolvable )
          {
              value = ((Resolvable)value).resolve( context );
          }
  
          if( null == value )
          {
              if( ignoreUndefined )
              {
                  return "";
              }
              else
              {
                  throw new PropertyException( "Unable to find " + key + " to expand during " + 
                                               "property resolution." );
              }
          }
  
          return value;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ProxyClassLoader.java
  
  Index: ProxyClassLoader.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 file. 
   */ 
  package org.apache.avalon.util;
  
  /**
   * Utility class to help load dynamically generated classes.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */
  public class ProxyClassLoader 
      extends ClassLoader
  {
      public ProxyClassLoader( final ClassLoader parent )
      {
          super( parent );
      }
  
      public Class loadClass( final String name, 
                              final boolean resolve, 
                              final byte[] classData )
          throws ClassNotFoundException
      {
          final Class result =
              defineClass( name, classData, 0, classData.length );
          
          if( resolve )
          {
              resolveClass( result );
          }
          
          return result;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ProxyGenerator.java
  
  Index: ProxyGenerator.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 file. 
   */ 
  package org.apache.avalon.util;
  
  import gnu.bytecode.Access;
  import gnu.bytecode.ClassType;
  import gnu.bytecode.ClassTypeWriter;
  import gnu.bytecode.CodeAttr;
  import gnu.bytecode.Field;
  import gnu.bytecode.Scope;
  import gnu.bytecode.Type;
  import gnu.bytecode.Variable;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  import java.util.HashMap;
  import java.util.Iterator;
  import org.apache.log.LogKit; 
  import org.apache.log.Logger; 
  
  /**
   * A class to generate proxies for objects.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */
  public final class ProxyGenerator
  {
      protected final static boolean    DEBUG       = false; 
      protected final static Logger     LOGGER      =  
          ( DEBUG ) ? LogKit.getLoggerFor( "ProxyGenerator" ) : null; 
  
      protected final static Object     MONITOR     = new Object();
      protected final static ClassType  BASE_CLASS  = 
          (ClassType)Type.getType( "java.lang.Object" );
  
      protected static long             c_currentId;          
  
      /**
       * Private constructor to block subclassing.
       *
       */
      private ProxyGenerator()
      {
      }
  
      /**
       * Way to generate unique id for each class.
       *
       * @return a unique id
       */
      protected static long getNextId()
      {
          synchronized( MONITOR )
          {
              return c_currentId++;
          }
      }
  
      /**
       * Generate a proxy for object with certain interfaces.
       *
       * @param object the object
       * @param interfaces[] the interfaces
       * @return the proxy object
       * @exception IllegalArgumentException if an error occurs
       */
      public static Object generateProxy( final Object object, 
                                          final Class[] interfaces )
          throws IllegalArgumentException
      {
          if( DEBUG )
          {
              LOGGER.debug( "Generating proxy for " + object.getClass().getName() );
              LOGGER.debug( "Interfaces generating:" );
  
              for( int i = 0; i < interfaces.length; i++ )
              {
                  LOGGER.debug( interfaces[ i ].getName() );
              }
          }
  
          for( int i = 0; i < interfaces.length; i++ )
          {
              if( !interfaces[ i ].isInterface() )
              {
                  throw new IllegalArgumentException( "Class " + interfaces[ i ].getName() +
                                                      " is not an interface" );
              }
              else if( !interfaces[ i ].isInstance( object ) )
              {
                  throw new IllegalArgumentException( "Object does not implement interface " +
                                                      interfaces[ i ].getName() );
              }
          }
  
          final HashMap methodSet = determineMethods( interfaces );
          
          final String classname = "org.apache.avalon.tmp.Proxy" + getNextId();
  
          if( DEBUG ) { LOGGER.debug( "Generating proxy named " + classname ); }
  
          final ClassType proxy = createProxyType( classname );
  
          //generate all interface declarations
          generateInterfaces( proxy, interfaces );
  
          final ClassType target = 
              (ClassType)Type.make( object.getClass() );
  
          target.doFixups();
  
          //generate variables/constructor
          generateBase( proxy, target );
  
          //generate methods
          final Iterator methods = methodSet.values().iterator();
          while( methods.hasNext() )
          {
              generateMethod( proxy, target, (Method)methods.next() );
          }
  
          if( DEBUG )
          {
              //help while debugging
              //ClassTypeWriter.print( target, System.out, 0 );
              //try { proxy.writeToFile( "/tmp/" + classname.replace('.','/') + ".class" ); }
              //catch( final Throwable throwable ) { throwable.printStackTrace(); }
          }
  
          proxy.doFixups();
          
          Class proxyClass = null;
          try 
          { 
              final byte[] classData = proxy.writeToArray();
  
              //extremely inneficient - must fix in future
              final ProxyClassLoader classLoader = 
                  new ProxyClassLoader( object.getClass().getClassLoader() );
              
              proxyClass = classLoader.loadClass( classname, true, classData );
              final Constructor ctor = 
                  proxyClass.getConstructor( new Class[] { object.getClass() } );
              return ctor.newInstance( new Object[] { object } );
          }
          catch( final Throwable throwable ) { throwable.printStackTrace(); }
  
          return null;
      }
  
      /**
       * Create Proxy class.
       *
       * @param classname name of class
       * @return the proxy class
       */
      protected static ClassType createProxyType( final String classname )
      {
          final ClassType proxy = new ClassType( classname );
          proxy.setModifiers( Access.PUBLIC | /*ACC_SUPER*/ 0x0020 | Access.FINAL );
          proxy.setSuper( BASE_CLASS );
  
          return proxy;
      }
  
      /**
       * generate the list of Interfaces class implements.
       *
       * @param proxy the proxy class
       * @param interfaces[] the interfaces to add
       */
      protected static void generateInterfaces( final ClassType proxy, 
                                                final Class[] interfaces )
      {
          final ClassType[] interfaceTypes = new ClassType[ interfaces.length ];
          
          for( int i = 0; i < interfaceTypes.length; i++ )
          {
              interfaceTypes[ i ] = (ClassType)Type.getType( interfaces[ i ].getName() );
          }
          
          proxy.setInterfaces( interfaceTypes );
      }
  
      /**
       * Generate code for wrapper method.
       *
       * @param proxy the class to add to
       * @param target the class wrapping
       * @param method the method to wrap
       */
      protected static void generateMethod( final ClassType proxy, 
                                            final ClassType target, 
                                            final Method method )
      {
          final Class[] parameters = method.getParameterTypes();
          final Type[] parameterTypes = new Type[ parameters.length ];
  
          for( int i = 0; i < parameterTypes.length; i++ )
          {
              parameterTypes[ i ] = Type.getType( parameters[ i ].getName() );
          }
  
          final Type returnType = 
              Type.getType( method.getReturnType().getName() );
          
          final gnu.bytecode.Method newMethod = 
              proxy.addMethod( method.getName(), 
                               Access.PUBLIC, 
                               parameterTypes,
                               returnType );
  
          newMethod.init_param_slots();
          newMethod.pushScope();
          final CodeAttr code = newMethod.getCode();
  
          //put m_core on stack;
          final Field field = proxy.getField( "m_core" );
  
          code.emitPushThis();
          code.emitGetField( field );
  
          for( int i = 0; i < parameterTypes.length; i++ )
          {
              code.emitLoad( code.getArg( 1 + i ) );
          }
  
          //call target method
          final gnu.bytecode.Method targetMethod = 
              target.getMethod( method.getName(), parameterTypes );
          code.emitInvokeVirtual( targetMethod );
  
          //return
          code.emitReturn();
          newMethod.popScope();    
      }
  
      /**
       * Generate constructor code and field data.
       *
       * @param proxy the representation of class so far
       * @param target the type that is wrapped
       */
      protected static void generateBase( final ClassType proxy,
                                          final Type target )
      {
          final Field field = proxy.addField( "m_core", target );
          field.flags |= Access.PRIVATE;
  
          final gnu.bytecode.Method constructor = 
              proxy.addMethod( "<init>", 
                               Access.PUBLIC, 
                               new Type[] { target },
                               Type.void_type );
  
          final gnu.bytecode.Method superConstructor
              = proxy.getSuperclass().addMethod( "<init>", 
                                                 Access.PUBLIC,
                                                 null, 
                                                 Type.void_type );
  
          constructor.init_param_slots();
          constructor.pushScope();
          final CodeAttr code = constructor.getCode();
  
          //super();
          code.emitPushThis();
          code.emitInvokeSpecial( superConstructor );
  
          //m_core = param1;
          code.emitPushThis();
          code.emitLoad( code.getArg( 1 ) );
          code.emitPutField( field );
  
          //return
          code.emitReturn();
  
          constructor.popScope();
      }
  
      /**
       * Determine the methods that must be implemented to 
       * implement interface, eliminating duplicates.
       *
       * @param interfaces[] the interfaces to extract methods from
       * @return methods
       */
      protected static HashMap determineMethods( final Class[] interfaces )
      {
          final HashMap methodSet = new HashMap();
          final StringBuffer sb = new StringBuffer();
   
          for( int i = 0; i < interfaces.length; i++ )
          {
              if( DEBUG )
              {
                  LOGGER.debug( "Scanning interface " + interfaces[ i ].getName() +
                                " for methods" );
              }
  
              final Method[] methods = interfaces[ i ].getMethods();
  
              //for each method generate a pseudo signature
              //Add the method to methodSet under that signature.
              //This is to ensure that only one version of a method is 
              //entered into set even if multiple interfaces declare it
  
              for( int j = 0; j < methods.length; j++ )
              {
                  sb.append( methods[ j ].getName() );
                  sb.append( '(' );
  
                  final Class[] parameters = methods[ j ].getParameterTypes();
  
                  for( int k = 0; k < parameters.length; k++ )
                  {
                      sb.append( parameters[ k ].getName() );
                      sb.append( ' ' );
                  }
  
                  sb.append( ";)" );
  
                  if( DEBUG )
                  {
                      LOGGER.debug( "Found method with pseudo-signature " + sb );
                  }
  
                  methodSet.put( sb.toString(), methods[ j ] );
                  sb.setLength( 0 );
              }
          }
  
          return methodSet;
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/StringUtil.java
  
  Index: StringUtil.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 file.
   */
  package org.apache.avalon.util;
  
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.util.ArrayList;
  import java.util.StringTokenizer;
  import org.apache.avalon.CascadingThrowable;
  
  /**
   * This class provides basic facilities for manipulating strings.
   *
   * Some exception handling stuff thieved from Turbine...
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
   */
  public final class StringUtil
  {
      /**
       * Private constructor to prevent instantiation.
       */
      private StringUtil()
      {
      }
      
      /**
       * Replace substrings of one string with another string and return altered string.
       *
       * @param original input string
       * @param oldString the substring section to replace
       * @param newString the new substring replacing old substring section
       * @return converted string
       */
      public static String replaceSubString( final String original,
                                             final String oldString,
                                             final String newString )
      {
          final StringBuffer sb = new StringBuffer();
          
          int end = original.indexOf( oldString );
          int start = 0;
          final int stringSize = oldString.length();
          
          while( end != -1 )
          {
              sb.append( original.substring( start, end ) );
              sb.append( newString );
              start = end + stringSize;
              end = original.indexOf( oldString, start );
          }
          
          end = original.length();
          sb.append( original.substring( start, end ) );
          
          return sb.toString();
      }
      
      public static String printStackTrace( final Throwable throwable )
      {
          return printStackTrace( throwable, 0, true );
      }
      
      public static String printStackTrace( final Throwable throwable, 
                                            final boolean printCascading )
      {
          return printStackTrace( throwable, 0, printCascading );
      }
      
      public static String printStackTrace( final Throwable throwable, int depth )
      {
          final String[] lines = captureStackTrace( throwable );
  
          if( 0 == depth || depth > lines.length ) depth = lines.length;
  
          final StringBuffer sb = new StringBuffer();
  
          for( int i = 0; i < depth; i++ )
          {
              sb.append( lines[ i ] );
              sb.append( '\n' );
          }
  
          return sb.toString();
      }
  
      public static String printStackTrace( Throwable throwable, 
                                            final int depth,
                                            final boolean printCascading )
      {
          final String result = printStackTrace( throwable, depth );
  
          if( !printCascading || !(throwable instanceof CascadingThrowable) ) 
          {
              return result;
          }
          else
          {
              final StringBuffer sb = new StringBuffer();
              sb.append( result );
  
              throwable = ((CascadingThrowable)throwable).getCause();
  
              while( null != throwable )
              {
                  sb.append( "rethrown from\n" );
                  sb.append( printStackTrace( throwable, depth ) );
  
                  if( throwable instanceof CascadingThrowable )
                  {
                      throwable = ((CascadingThrowable)throwable).getCause();
                  }
                  else
                  {
                      throwable = null;
                  }
              }
  
              return sb.toString();
          }
      }
                                            
      /**
       * Captures the stack trace associated with this exception.
       *
       * @return an array of Strings describing stack frames.
       */ 
      public 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
       */
      public static String[] splitString( final String string, final String onToken ) 
      {
          final StringTokenizer tokenizer = new StringTokenizer( string, onToken );
          
          final ArrayList lines = new ArrayList();
          
          while( tokenizer.hasMoreTokens() ) 
          {
              lines.add( tokenizer.nextToken() );
          }
          
          return (String[])lines.toArray( new String[ 0 ] );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/ValuedEnum.java
  
  Index: ValuedEnum.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 file. 
   */ 
  package org.apache.avalon.util;
  
  /**
   * Basic enum class for type-safe enums with values. Should be used as an abstract base.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class ValuedEnum 
      extends Enum
  {
      protected final int        m_value;
      
      public ValuedEnum( final String name, final int value )
      {
          super( name );
          m_value = value;
      } 
  
      public final int getValue()
      {
          return m_value;
      }
  
      public final boolean isEqualTo( final ValuedEnum enum )
      {
          return m_value == enum.m_value;
      }
  
      public final boolean isGreaterThan( final ValuedEnum enum )
      {
          return m_value > enum.m_value;
      }
      
      public final boolean isGreaterThanOrEqual( final ValuedEnum enum )
      {
          return m_value >= enum.m_value;
      }
      
      public final boolean isLessThan( final ValuedEnum enum )
      {
          return m_value < enum.m_value;
      }
      
      public final boolean isLessThanOrEqual( final ValuedEnum enum )
      {
          return m_value <= enum.m_value;
      }
      
      public String toString()
      {
          return getClass().getName() + "[" + m_name + "=" + m_value + "]";
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/Version.java
  
  Index: Version.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 file.
   */
  package org.apache.avalon.util;
  
  /**
   * This document is NOT RIGHT.
   * <p />
   *
   * The version number of a <code>Block</code> is made up of three
   * dot-separated fields:
   * <p />
   * &quot;<b>major.minor.patchlevel</b>&quot;
   * <p />
   * and (optionally) by a fourth field (always <b>&quot;-dev&quot;</b>)
   * specifying that this version is under development.
   * <p />
   * The <b>major</b>, <b>minor</b> and <b>patchlevel</b> fields are
   * <i>integer</i> numbers represented in decimal notation and have the
   * following meaning:
   * <ul>
   * <p /><li><b>major</b> - When the major version changes (in ex. from
   * &quot;1.5.12&quot; to &quot;2.0.0&quot;), then backward compatibility
   * with previous releases is not granted (this usually happens this
   * <code>Block</code> is implementing a new major version of an interface
   * specified in <b>org.apache.avalon.blocks</b> package).
   * </li><p />
   * <p /><li><b>minor</b> - When the minor version changes (in ex. from
   * &quot;1.5.12&quot; to &quot;1.6.0&quot;), then backward compatibility
   * with previous releases is granted, but something changed in the
   * implementation (in ex. new features were added, the configuration
   * syntax may be different, or the <code>Block</code> is implementing a
   * new minor version of an interface specified in
   * <b>org.apache.avalon.blocks</b> package).
   * </li><p />
   * <p /><li><b>patchlevel</b> - When the patchlevel version changes (in ex.
   * from &quot;1.5.12&quot; to &quot;1.5.13&quot;), then the only changed
   * things are fixes in the code implementation, but no new features or
   * changes were made to the behaviour of the code.
   * </li>
   * </ul>
   * <p />
   * The fourth field, optional and always &quot;<b>-dev</b>&quot; (in ex.
   * &quot;1.5.12-dev&quot;) specifies that current <code>Block</code>
   * implementation is under development, and so may contain not-working
   * code or not all features were implemented.
   * <p />
   * <p />
   * <b>NOTE: The absence of the &quot;-dev&quot; tag does not endorse
   * any warranty of particular stability, safety or compliancy.
   * The only source for such informations is the (usually provided) license
   * file accompaining the block itself.</b>
   *
   * The class defining versioning pattern.
   * <p />
   * <p />
   * Any interface in <b>org.apache.avalon.blocks</b> package <b>MUST</b> provides
   * a Version instance containing versioning informations on this interface.<p />
   * Any BlockInfo returned by a Block implementation <b>MUST</b> provides a
   * Version instances containing versioning informations on this implementation.
   * <p /><p />
   * Version numbers are:<p />
   * &quot;<b>major.minor.revision.dev</b>&quot;
   * <p />
   * The <b>major</b> , <b>minor</b> and <b>revision</b>fields are <i>integer</i>
   * numbers represented in decimal notation and have the following meaning:
   * <ul><b> - Refering to an interface</b>
   * <ul>
   * <li><b>major</b> - When the major version changes (in ex. from
   * &quot;1.5&quot; to &quot;2.0&quot;), then backward compatibility with
   * previous releases is not granted.
   * </li><p />
   * <p /><li><b>minor</b> - When the minor version changes (in ex. from
   * &quot;1.5&quot; to &quot;1.6&quot;), then backward compatibility
   * with previous releases is granted, but something changed in the
   * interface (in ex. new methods were added).
   * </li><p />
   * <li><b>revision</b> - When refering to an interface may represent a change
   * in documentation or other minor changes. If some methods are modified a minor
   * version changes is needed.<p />
   * - When refering to a Block implementation this represent minor changes in
   * implementation like bugs fix.
   * </li><p />
   * <li><b>dev</b> - The boolean dev field specify if this Block or interface
   * is under development and not yet approved by the Java Apache org.apache.avalon.interfaces;
   * developers group (mailing-list).
   * </li><p />
   * </ul>
   * </ul>
   * <ul><b> - Refering to a Block</b>
   * <ul>
   * <li><b>major</b> - When the major version changes (in ex. from
   * &quot;1.5&quot; to &quot;2.0&quot;), then backward compatibility with
   * previous releases is not granted.
   * </li><p />
   * <p /><li><b>minor</b> - When the minor version changes (in ex. from
   * &quot;1.5&quot; to &quot;1.6&quot;), then backward compatibility
   * with previous releases is granted, but something changed in the
   * interface (in ex. new methods were added).
   * </li><p />
   * <li><b>revision</b> - When refering to an interface may represent a change
   * in documentation or other minor changes. If some methods are modified a minor
   * version changes is needed.<p />
   * - When refering to a Block implementation this represent minor changes in
   * implementation like bugs fix.
   * </li><p />
   * <li><b>dev</b> - The boolean dev field specify if this Block or interface
   * is under development and not yet approved by the Java Apache org.apache.avalon.interfaces;
   * developers group (mailing-list).
   * </li><p />
   * </ul>
   * </ul>
   * The third field, optional and always &quot;<b>-dev</b>&quot; (in ex.
   * &quot;1.5-dev&quot;) specifies that the interface is currently under
   * development, or it was not yet approved by the Java Apache org.apache.avalon.interfaces;
   * developers group (mailing-list) and so, not yet integrated with the
   * org.apache.avalon.interfaces; distributions.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:rlogiacco@mail.com">Roberto Lo Giacco</a>
   * @author <a href="http://java.apache.org/">Java Apache Project</a>
  
   */
  public final class Version
  {
      protected int                   m_major;
      protected int                   m_minor;
      protected int                   m_revision;
  
      /**
       * Create a new instance of a <code>Version</code> object with the
       * specified version numbers.
       *
       * @param major This <code>Version</code> major number.
       * @param minor This <code>Version</code> minor number.
       * @param rev This <code>Version</code> revision number.
       */
      public Version( final int major, final int minor, final int revision )
      {
          m_major = major;
          m_minor = minor;
          m_revision = revision;
      }
  
      /**
       * Check this <code>Version</code> against another for equality.
       * <p />
       * If this <code>Version</code> is compatible with the specified one, then
       * <b>true</b> is returned, otherwise <b>false</b>.
       *
       * @param other The other <code>Version</code> object to be compared with this
       *          for equality.
       */
      public boolean equals( final Version other )
      {
          if( m_major != other.m_major) return false;
          else if( m_minor != other.m_minor) return false;
          else if( m_revision != other.m_revision ) return false;
          else return true;
      }
  
      /**
       * Check this <code>Version</code> against another for compliancy
       * (compatibility).
       * <p />
       * If this <code>Version</code> is compatible with the specified one, then
       * <b>true</b> is returned, otherwise <b>false</b>. Be careful when using
       * this method since, in example, version 1.3.7 is compliant to version
       * 1.3.6, while the opposite is not.
       *
       * @param v The other <code>Version</code> object to be compared with this
       *          for compliancy (compatibility).
       */
      public boolean complies( final Version other )
      {
          if( m_major != other.m_major) return false;
          else if( m_minor < other.m_minor) return false;
          else return true;
      }
  
      /**
       * Overload toString to report version correctly.
       *
       * @return the dot seperated version string
       */
      public String toString()
      {
          return m_major + "." + m_minor + "." + m_revision;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/AbstractMain.java
  
  Index: AbstractMain.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 file.
   */
  package org.apache.avalon.util.cli;
  
  import java.util.List;
  import org.apache.avalon.AbstractLoggable;
  
  /**
   * Abstract main entry point.
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public abstract class AbstractMain
      extends AbstractLoggable
  {
      protected CLOptionDescriptor[]          m_options;
  
      /**
       * Return string describing how command is executed.
       *
       * @return the string describing exectution command
       */
      protected String getExecutionCommand()
      {
          return "java " + getClass().getName() + " [options]";
      }    
  
      /**
       * Display usage report.
       *
       */
      protected void usage()
      {
          System.out.println( getExecutionCommand() );
          System.out.println( "\tAvailable options:");
          System.out.println( CLUtil.describeOptions( m_options ) );
      }
  
      /**
       * Initialise the options for command line parser.
       *
       */
      protected abstract CLOptionDescriptor[] createCLOptions();
  
      /**
       * Main entry point.
       *
       * @param args[] the command line arguments
       * @Throwable Throwable if an error occurs
       */
      public void execute( final String[] args )
          throws Exception
      { 
          m_options = createCLOptions();
          final CLArgsParser parser = new CLArgsParser( args, m_options );
          
          if( null != parser.getErrorString() ) 
          {
              System.err.println( "Error: " + parser.getErrorString() );
              return;
          }
  
          execute( parser.getArguments() );
      }
  
      /**
       * Overide this method to provide functionality for your application.
       *
       * @param clOptions the list of command line options
       */
      protected abstract void execute( final List clOptions )
          throws Exception;
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/AbstractParserControl.java
  
  Index: AbstractParserControl.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 file.
   */
  package org.apache.avalon.util.cli;
  
  /**
   * Class to inherit from so when in future when new controls are added
   * clients will no have to implement them.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class AbstractParserControl 
      implements ParserControl
  {
      public boolean isFinished( int lastOptionCode )
      {
          return false;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/CLArgsParser.java
  
  Index: CLArgsParser.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 file.
   */
  package org.apache.avalon.util.cli;
  
  import java.text.ParseException;
  import java.util.Arrays;
  import java.util.Vector;
  
  /**
   * Parser for command line arguments.
   *
   * This parses command lines according to the standard (?) of 
   * gnu utilities.
   *
   * Note: This is still used in 1.1 libraries so do not add 1.2+ dependancies.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class CLArgsParser
  {
      protected class Token
      {
          protected final int                m_type;
          protected final String             m_value;
  
          public Token( final int type, final String value )
          {
              m_type = type;
              m_value = value;
          }
  
          public String getValue()
          {
              return m_value;
          }
  
          public int getType()
          {
              return m_type;
          }
  
          public String toString()
          {
              return "" + m_type + ":" + m_value;
          }
      }
  
      private final static int                 STATE_NORMAL           = 0;
      private final static int                 STATE_REQUIRE_2ARGS    = 1;
      private final static int                 STATE_REQUIRE_ARG      = 2;
      private final static int                 STATE_OPTIONAL_ARG     = 3;
      private final static int                 STATE_NO_OPTIONS       = 4;
      private final static int                 STATE_OPTION_MODE      = 5;
  
      protected final static int               TOKEN_SEPERATOR        = 0;
      protected final static int               TOKEN_STRING           = 1;
  
  
      protected final static char[]            ARG2_SEPERATORS        = 
          new char[] { (char)0, '=', '-' };
  
      protected final static char[]            ARG_SEPERATORS         = 
          new char[] { (char)0, '=' };
  
      protected final static char[]            NULL_SEPERATORS        = 
          new char[] { (char)0 };
  
      protected final CLOptionDescriptor[]     m_optionDescriptors;
      protected final Vector                   m_options;
      protected final ParserControl            m_control;
  
      protected String                         m_errorMessage;
      protected String[]                       m_unparsedArgs         = new String[] {};
  
      //variables used while parsing options.
      protected char                           ch;
      protected String[]                       args;
      protected boolean                        isLong;
      protected int                            argIndex;
      protected int                            stringIndex;
      protected int                            stringLength;
  
      //cached character == Integer.MAX_VALUE when invalid
      protected final static int               INVALID         = Integer.MAX_VALUE;
      protected int                            m_lastChar      = INVALID;
  
      protected int                            m_lastOptionId;
      protected CLOption                       m_option;
      protected int                            m_state         = STATE_NORMAL;
  
      public String[] getUnparsedArgs()
      {
          return m_unparsedArgs;
      }
  
      /**
       * Retrieve a list of options that were parsed from command list.
       *
       * @return the list of options
       */
      public Vector getArguments()
      {
          //System.out.println( "Arguments: " + m_options );
          return m_options; 
      }  
  
      /**
       * Get Descriptor for option id.
       *
       * @param id the id
       * @return the descriptor
       */
      private CLOptionDescriptor getDescriptorFor( final int id )
      {
          for( int i = 0; i < m_optionDescriptors.length; i++ )
          {
              if( m_optionDescriptors[i].getId() == id )
              {
                  return m_optionDescriptors[i];
              }
          }
  
          return null;
      }
  
      /**
       * Retrieve a descriptor by name.
       *
       * @param name the name
       * @return the descriptor
       */
      private CLOptionDescriptor getDescriptorFor( final String name )
      {
          for( int i = 0; i < m_optionDescriptors.length; i++ )
          {
              if( m_optionDescriptors[i].getName().equals( name ) )
              {
                  return m_optionDescriptors[i];
              }
          }
  
          return null;
      }  
  
      /**
       * Retrieve an error message that occured during parsing if one existed.
       *
       * @return the error string
       */
      public String getErrorString() 
      {
          //System.out.println( "ErrorString: " + m_errorMessage );
          return m_errorMessage; 
      }
  
      /**
       * Requier state to be placed in for option.
       *
       * @param descriptor the Option Descriptor
       * @return the state
       */
      private int getStateFor( final CLOptionDescriptor descriptor )
      {
          int flags = descriptor.getFlags();
          if( ( flags & CLOptionDescriptor.ARGUMENTS_REQUIRED_2 ) == 
              CLOptionDescriptor.ARGUMENTS_REQUIRED_2 )
          {
              return STATE_REQUIRE_2ARGS;
          }
          else if( ( flags & CLOptionDescriptor.ARGUMENT_REQUIRED ) == 
                   CLOptionDescriptor.ARGUMENT_REQUIRED )
          {
              return STATE_REQUIRE_ARG;
          }
          else if( ( flags & CLOptionDescriptor.ARGUMENT_OPTIONAL ) == 
                   CLOptionDescriptor.ARGUMENT_OPTIONAL )
          {
              return STATE_OPTIONAL_ARG;
          }
          else
          {
              return STATE_NORMAL;
          }
      }  
  
      /**
       * Create a parser that can deals with options and parses certain args.
       *
       * @param args[] the args 
       * @param optionDescriptors[] the option descriptors
       */
      public CLArgsParser( final String[] args, 
                           final CLOptionDescriptor[] optionDescriptors,
                           final ParserControl control )
      {
          m_optionDescriptors = optionDescriptors;
          m_control = control;
          m_options = new Vector();
          this.args = args;
  
          try 
          {
              parse(); 
              checkIncompatabilities( m_options );
          }
          catch( final ParseException pe )
          {
              m_errorMessage = pe.getMessage();
          }
  
          //System.out.println( "Built : " + m_options );
          //System.out.println( "From : " + Arrays.asList( args ) );
      }
  
      /**
       * Check for duplicates of an option. 
       * It is an error to have duplicates unless appropriate flags is set in descriptor.
       *
       * @param arguments the arguments
       */
      protected void checkIncompatabilities( final Vector arguments )
          throws ParseException
      {
          final int size = arguments.size();
  
          for( int i = 0; i < size; i++ )
          {
              final CLOption option = (CLOption)arguments.elementAt( i );
              final int id = option.getId();
              final CLOptionDescriptor descriptor = getDescriptorFor( id );
  
              //this occurs when id == 0 and user has not supplied a descriptor 
              //for arguments
              if( null == descriptor ) continue;
  
              final int[] incompatable = descriptor.getIncompatble();
  
              checkIncompatable( arguments, incompatable, i );
          }
      }
      
      protected void checkIncompatable( final Vector arguments, 
                                        final int[] incompatable,
                                        final int original )
          throws ParseException
      {
          final int size = arguments.size();
          
          for( int i = 0; i < size; i++ )
          {
              if( original == i ) continue;
  
              final CLOption option = (CLOption)arguments.elementAt( i );
              final int id = option.getId();
              final CLOptionDescriptor descriptor = getDescriptorFor( id );
              
              for( int j = 0; j < incompatable.length; j++ )
              {
                  if( id == incompatable[ j ] )
                  {
                      final CLOption originalOption = (CLOption)arguments.elementAt( original );
                      final int originalId = originalOption.getId();
  
                      String message = null;
  
                      if( id == originalId )
                      {
                          message = 
                              "Duplicate options for " + describeDualOption( originalId ) +
                              " found.";
                      }
                      else
                      {
                          message = "Incompatable options -" + 
                              describeDualOption( id ) + " and " + 
                              describeDualOption( originalId ) + " found.";
                      }
                      throw new ParseException( message, 0 );
                  }
              }
          }
      }
  
      protected String describeDualOption( final int id )
      {
          final CLOptionDescriptor descriptor = getDescriptorFor( id );
          if( null == descriptor ) return "<parameter>";
          else
          {
              final StringBuffer sb = new StringBuffer();
              boolean hasCharOption = false;
  
              if( Character.isLetter( (char)id ) )
              {
                  sb.append( '-' );
                  sb.append( (char)id );
                  hasCharOption = true;
              }
              
              final String longOption = descriptor.getName();
              if( null != longOption )
              {
                  if( hasCharOption ) sb.append( '/' );
                  sb.append( "--" );
                  sb.append( longOption );
              }
  
              return sb.toString();
          }            
      }
  
      /**
       * Create a parser that can deals with options and parses certain args.
       *
       * @param args[] the args 
       * @param optionDescriptors[] the option descriptors
       */
      public CLArgsParser( final String[] args, 
                           final CLOptionDescriptor[] optionDescriptors )
      {
          this( args, optionDescriptors, null );
      }
  
      /**
       * Create a string array that is subset of input array. 
       * The sub-array should start at array entry indicated by index. That array element
       * should only include characters from charIndex onwards.
       *
       * @param array[] the original array
       * @param index the cut-point in array
       * @param charIndex the cut-point in element of array
       * @return the result array
       */
      protected String[] subArray( final String[] array,
                                   final int index,
                                   final int charIndex )
      {
          final int remaining = array.length - index;
          final String[] result = new String[ remaining ];
  
          if( remaining > 1 )
          {
              System.arraycopy( array, index + 1, result, 1, remaining - 1 );
          }
  
          result[0] = array[ index ].substring( charIndex - 1 );
          
          return result;
      }
  
      /**
       * Actually parse arguments
       *
       * @param args[] arguments
       */
      protected void parse()
          throws ParseException
      {
          if( 0 == args.length ) return;
  
          stringLength = args[ argIndex ].length();
  
          //ch = peekAtChar();
  
          while( true )
          {
              ch = peekAtChar();
  
              if( argIndex >= args.length ) break;
              
              if( null != m_control && m_control.isFinished( m_lastOptionId ) )
              {
                  //this may need mangling due to peeks
                  m_unparsedArgs = subArray( args, argIndex, stringIndex );
                  return;
              }
  
              //System.out.println( "State=" + m_state );
              //System.out.println( "Char=" + (char)ch );
  
              if( STATE_OPTION_MODE == m_state ) 
              {
                  //if get to an arg barrier then return to normal mode
                  //else continue accumulating options
                  if( 0 == ch ) 
                  {
                      getChar(); //strip the null
                      m_state = STATE_NORMAL;
                  }
                  else parseShortOption();
              }
              else if( STATE_NORMAL == m_state )
              {
                  parseNormal();
              }
              else if( STATE_NO_OPTIONS == m_state )
              {
                  //should never get to here when stringIndex != 0
                  addOption( new CLOption( args[ argIndex++ ] ) );
              }
              else if( STATE_OPTIONAL_ARG == m_state && '-' == ch )
              {
                  m_state = STATE_NORMAL;
                  addOption( m_option );
              }
              else 
              {
                  parseArguments();
              }
          }
  
          if( m_option != null )
          {
              if( STATE_OPTIONAL_ARG == m_state )
              {
                  m_options.addElement( m_option );
              }
              else if( STATE_REQUIRE_ARG == m_state )
              {
                  final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
                  final String message = 
                      "Missing argument to option " + getOptionDescription( descriptor );
                  throw new ParseException( message, 0 );
              }
              else if( STATE_REQUIRE_2ARGS == m_state )
              {
                  if( 1 == m_option.getArgumentCount() )
                  {
                      m_option.addArgument( "" );
                      m_options.addElement( m_option );
                  }
                  else
                  {
                      final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
                      final String message = 
                          "Missing argument to option " + getOptionDescription( descriptor );
                      throw new ParseException( message, 0 );
                  }
              }
              else
              {
                  throw new ParseException( "IllegalState " + m_state + ": " + m_option, 0 );
              }
          }
      }
  
      protected final String getOptionDescription( final CLOptionDescriptor descriptor )
      {
          if( isLong ) return "--" + descriptor.getName();
          else return "-" + (char)descriptor.getId();
      }
  
      protected final char peekAtChar()
      {
          if( INVALID == m_lastChar ) m_lastChar = readChar();
          return (char)m_lastChar;
      }
  
      protected final char getChar()
      {
          if( INVALID != m_lastChar ) 
          {
              final char result = (char)m_lastChar;
              m_lastChar = INVALID;
              return result;
          }
          else return readChar();
      }
  
      private final char readChar()
      {
          if( stringIndex >= stringLength )
          { 
              argIndex++;
              stringIndex = 0;
  
              if( argIndex < args.length ) stringLength = args[ argIndex ].length();
              else stringLength = 0;
  
              return 0;
          }
  
          if( argIndex >= args.length ) return 0;
  
          return args[ argIndex ].charAt( stringIndex++ );
      }
  
      protected final Token nextToken( final char[] seperators )
      {
          ch = getChar();
  
          if( isSeperator( ch, seperators ) ) 
          {
              ch = getChar();
              return new Token( TOKEN_SEPERATOR, null );
          }
  
          final StringBuffer sb = new StringBuffer();
  
          do
          {
              sb.append( ch );
              ch = getChar();
          }
          while( !isSeperator( ch, seperators ) );
  
          return new Token( TOKEN_STRING, sb.toString() );
      }
  
      private final boolean isSeperator( final char ch, final char[] seperators )
      {
          for( int i = 0; i < seperators.length; i++ )
          {
              if( ch == seperators[ i ] ) return true;
          }
  
          return false;
      }
  
      protected void addOption( final CLOption option )
      {
          m_options.addElement( option );
          m_lastOptionId = option.getId();
          m_option = null;
      }
  
      protected void parseOption( final CLOptionDescriptor descriptor, 
                                  final String optionString )
          throws ParseException
      {
          if( null == descriptor )
          {
              throw new ParseException( "Unknown option " + optionString, 0 );
          }
          
          m_state = getStateFor( descriptor );
          m_option = new CLOption( descriptor.getId() );
          
          if( STATE_NORMAL == m_state ) addOption( m_option );
      }
  
      protected void parseShortOption()
          throws ParseException
      {
          ch = getChar();
          final CLOptionDescriptor descriptor = getDescriptorFor( (int)ch );
          isLong = false;
          parseOption( descriptor, "-" + ch );
          
          if( STATE_NORMAL == m_state ) m_state = STATE_OPTION_MODE;
      }
  
      protected boolean parseArguments()
          throws ParseException
      {
          if( STATE_REQUIRE_ARG == m_state )
          {
              if( '=' == ch || 0 == ch ) getChar();
  
              final Token token = nextToken( NULL_SEPERATORS );
              m_option.addArgument( token.getValue() );
  
              addOption( m_option );
              m_state = STATE_NORMAL;
          }
          else if( STATE_REQUIRE_2ARGS == m_state )
          {
              if( 0 == m_option.getArgumentCount() )
              {
                  final Token token = nextToken( ARG_SEPERATORS );
  
                  if( TOKEN_SEPERATOR == token.getType() )
                  {
                      final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
                      final String message = 
                          "Unable to parse first argument for option " +
                          getOptionDescription( descriptor );
                      throw new ParseException( message, 0 );
                  }
                  else
                  {
                      m_option.addArgument( token.getValue() );
                  }
              }
              else //2nd argument
              {
                  final StringBuffer sb = new StringBuffer();
  
                  ch = getChar();
                  if( '-' == ch ) m_lastChar = ch;
  
                  while( !isSeperator( ch, ARG2_SEPERATORS ) )
                  {
                      sb.append( ch );
                      ch = getChar();
                  }
  
                  final String argument = sb.toString();
  
                  //System.out.println( "Arguement:" + argument );
  
                  m_option.addArgument( argument );
                  addOption( m_option );
                  m_option = null;
                  m_state = STATE_NORMAL;
              }
          }
  
          return true;
      }
  
      /**
       * Parse Options from Normal mode.
       */
      protected void parseNormal()
          throws ParseException
      {
          if( '-' != ch )
          {
              //Parse the arguments that are not options
              final String argument = nextToken( NULL_SEPERATORS ).getValue();
              addOption( new CLOption( argument ) );
              m_state = STATE_NORMAL;
          }
          else
          {
              getChar(); // strip the -
  
              if( 0 == peekAtChar() )
              {
                  throw new ParseException( "Malformed option -", 0 );
              }
              else
              {
                  ch = peekAtChar();
                  
                  //if it is a short option then parse it else ...
                  if( '-' != ch ) parseShortOption();
                  else
                  {
                      getChar(); // strip the - 
                      //-- sequence .. it can either mean a change of state
                      //to STATE_NO_OPTIONS or else a long option
                      
                      if( 0 == peekAtChar() )
                      {
                          getChar();
                          m_state = STATE_NO_OPTIONS;
                      }
                      else
                      {
                          //its a long option
                          final String optionName = nextToken( ARG_SEPERATORS ).getValue();
                          final CLOptionDescriptor descriptor = getDescriptorFor( optionName );
                          isLong = true;
                          parseOption( descriptor, "--" + optionName );
                      }
                  }
              }
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/CLOption.java
  
  Index: CLOption.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 file.
   */
  package org.apache.avalon.util.cli;
  
  import java.util.Arrays;
  
  /**
   * Basic class describing an instance of option.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CLOption
  {
      protected final int                      m_id;
      protected String[]                       m_arguments;
  
      /**
       * Retrieve argument to option if it takes arguments.
       *
       * @return the argument
       */
      public final String getArgument()
      {
          return getArgument( 0 );
      }
      
      /**
       * Retrieve argument to option if it takes arguments.
       *
       * @return the argument
       */
      public final String getArgument( final int index )
      {
          if( null == m_arguments || index < 0 || index >= m_arguments.length ) 
          {
              return null;
          }
          else return m_arguments[ index ]; 
      }
  
      /**
       * Retrieve id of option. 
       * 
       * The id is eqivelent to character code if it can be a single letter option.
       *
       * @return the id
       */
      public final int getId() 
      {
          return m_id; 
      }
  
      /**
       * Constructor taking an id (that must be a proper character code)
       *
       * @param id the new id
       */
      public CLOption( final int id ) 
      {
          m_id = id; 
      }
  
      /**
       * Constructor taking argument for option.
       *
       * @param argument the argument
       */
      public CLOption( final String argument ) 
      {
          this( 0 );
          addArgument( argument );
      }  
  
      /**
       * Mutator fo Argument property.
       *
       * @param argument the argument
       */
      public final void addArgument( final String argument ) 
      {
          if( null == m_arguments ) m_arguments = new String[] { argument };
          else
          {
              final String[] arguments = new String[ m_arguments.length + 1 ];
              System.arraycopy( m_arguments, 0, arguments, 0, m_arguments.length );
              arguments[ m_arguments.length ] = argument;
              m_arguments = arguments;
          }
      }  
  
      public int getArgumentCount()
      {
          if( null == m_arguments ) return 0;
          else return m_arguments.length;
      }
  
      /**
       * Convert to String.
       *
       * @return the string value
       */
      public String toString()
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( "[Option " );
          sb.append( (char)m_id );
  
          if( null != m_arguments )
          {
              sb.append( ", " );
              sb.append( Arrays.asList( m_arguments ) );
          }
  
          sb.append( " ]" );
          
          return sb.toString();
      }  
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/CLOptionDescriptor.java
  
  Index: CLOptionDescriptor.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 file.
   */
  package org.apache.avalon.util.cli;
  
  /**
   * Basic class describing an type of option.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CLOptionDescriptor
  {
      public final static int                  ARGUMENT_REQUIRED         = 1 << 1;
      public final static int                  ARGUMENT_OPTIONAL         = 1 << 2;
      public final static int                  ARGUMENT_DISALLOWED       = 1 << 3;
      public final static int                  ARGUMENTS_REQUIRED_2      = 1 << 4;
  
      protected final int                      m_id;
      protected final int                      m_flags;
      protected final String                   m_name;
      protected final String                   m_description;
      protected final int[]                    m_incompatable;
  
      /**
       * Constructor.
       *
       * @param name the name/long option
       * @param flags the flags
       * @param id the id/character option
       * @param description description of option usage
       */
      public CLOptionDescriptor( final String name, 
                                 final int flags, 
                                 final int id,
                                 final String description )
      {
          this( name, flags, id, description, new int[] { id } );
      }
  
      /**
       * Constructor.
       *
       * @param name the name/long option
       * @param flags the flags
       * @param id the id/character option
       * @param description description of option usage
       */
      public CLOptionDescriptor( final String name, 
                                 final int flags, 
                                 final int id,
                                 final String description,
                                 final int[] incompatable )
      {
          m_id = id;
          m_name = name;
          m_flags = flags;
          m_description = description;
          m_incompatable = incompatable;
      }  
  
      protected int[] getIncompatble()
      {
          return m_incompatable;
      }
  
      /**
       * Retrieve textual description.
       *
       * @return the description 
       */
      public final String getDescription() 
      { 
          return m_description; 
      }
    
      /**
       * Retrieve flags about option.
       * Flags include details such as whether it allows parameters etc.
       *
       * @return the flags
       */
      public final int getFlags() 
      {
          return m_flags; 
      }
    
      /**
       * Retrieve the id for option.
       * The id is also the character if using single character options.
       *
       * @return the id
       */
      public final int getId() 
      { 
          return m_id; 
      }  
    
      /**
       * Retrieve name of option which is also text for long option.
       *
       * @return name/long option
       */
      public final String getName() 
      { 
          return m_name; 
      }  
  
      /**
       * Convert to String.
       *
       * @return the converted value to string.
       */
      public String toString()
      {
          return 
              "[OptionDescriptor " + m_name + 
              ", " + m_id + ", " + m_flags + 
              ", " + m_description + " ]";
      }  
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/CLUtil.java
  
  Index: CLUtil.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 file.
   */
  package org.apache.avalon.util.cli;
  
  /**
   * CLUtil offers basic utility operations for use both internal and external to package.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class CLUtil
  {
      protected static int              MAX_DESCRIPTION_COLUMN_LENGTH = 60;
  
      /**
       * Format options into StringBuffer and return.
       *
       * @param options[] the option descriptors
       * @return the formatted description/help for options
       */
      public static StringBuffer describeOptions( final CLOptionDescriptor[] options )
      {
          StringBuffer sb = new StringBuffer();
          for (int i = 0; i < options.length; i++)
          {
              final char ch = (char) options[i].getId();
              final String name = options[i].getName();
              String description = options[i].getDescription();
              boolean needComma = false;
          
              sb.append('\t');
          
              if( Character.isLetter(ch) )
              {
                  sb.append("-");
                  sb.append(ch);
                  needComma = true;
              }
          
              if (null != name)
              {
                  if( needComma ) sb.append(", ");
              
                  sb.append("--");
                  sb.append(name);
                  sb.append('\n');
              }
          
              if( null != description )
              {
                  while( description.length() > MAX_DESCRIPTION_COLUMN_LENGTH )
                  {
                      final String descriptionPart = 
                          description.substring( 0, MAX_DESCRIPTION_COLUMN_LENGTH );
                      description = 
                          description.substring( MAX_DESCRIPTION_COLUMN_LENGTH );
                      sb.append( "\t\t" );
                      sb.append( descriptionPart );
                      sb.append( '\n' );
                  }
              
                  sb.append( "\t\t" );
                  sb.append( description );
                  sb.append( '\n' );
              }
          }
          return sb;
      }
  
      /**
       * Private Constructor so that no instance can ever be created.
       *
       */
      private CLUtil() 
      {
      }  
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/cli/ParserControl.java
  
  Index: ParserControl.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 file.
   */
  package org.apache.avalon.util.cli;
  
  /**
   * ParserControl is used to control particular behaviour of the parser.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ParserControl
  {
      boolean isFinished( int lastOptionCode );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/i18n/ResourceGroup.java
  
  Index: ResourceGroup.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 file. 
   */ 
  package org.apache.avalon.util.i18n;
  
  import java.text.MessageFormat;
  import java.util.HashMap;
  import java.util.Locale;
  import java.util.MissingResourceException;
  import java.util.Random;
  import java.util.ResourceBundle;
  
  /**
   * A class used to manage resource bundles.
   */
  public class ResourceGroup
  {
      protected final static Random  RANDOM        = new Random();
      protected final HashMap        m_bundles     = new HashMap();
      protected final Locale         m_locale;
  
      /**
       * Create a ResourceGroup to manage resource bundles for a particular locale.
       *
       * @param locale the locale
       */
      public ResourceGroup( final Locale locale ) 
      {
          m_locale = locale;
      }
  
      public Locale getLocale()
      {
          return m_locale;
      }
  
      public String format( final String base, final String key, final Object[] args ) 
      {
          final String pattern = getPattern( base, key );
          final MessageFormat messageFormat = new MessageFormat( pattern );
          messageFormat.setLocale( m_locale );
          return messageFormat.format( args );
      }
  
      public ResourceBundle getBundle( final String base ) 
          throws MissingResourceException
      {
          ResourceBundle result = (ResourceBundle) m_bundles.get( base );
          if( null != result ) return result;
          
          // bundle wasn't cached, so load it, cache it, and return it.
          final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          result = ResourceBundle.getBundle( base, m_locale, classLoader );
  
          m_bundles.put( base, result );
  
          return result;                
      }
  
      public String getPattern( final String base, final String key ) 
          throws MissingResourceException
      {
          final ResourceBundle bundle = getBundle( base );
          final Object object = bundle.getObject( key );
          
          // is the resource a single string
          if( object instanceof String ) 
          {
              return (String)object;
          }
          else if( object instanceof String[] )
          {
              //if string array then randomly pick one
              final String[] strings = (String[])object;
              return strings[ RANDOM.nextInt( strings.length ) ];
          }
          else
          {
              throw new MissingResourceException( "Unable to find resource of appropriate type.",
                                                  "java.lang.String",
                                                  key );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/i18n/XMLResourceBundle.java
  
  Index: XMLResourceBundle.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 file.
   */
  package org.apache.avalon.util.i18n;
  
  /**
   * @author <a href="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
   * @author <a href="mailto:neeme@one.lv">Neeme Praks</a>
   * @author <a href="mailto:oleg@one.lv">Oleg Podolsky</a>
   * @version $Id: XMLResourceBundle.java,v 1.1 2001/02/25 10:45:50 fede Exp $
   */
  
  /** JDK classes **/
  import java.io.IOException;
  import java.lang.ref.SoftReference;
  import java.util.Hashtable;
  import java.util.Locale;
  import java.util.MissingResourceException;
  
  /** W3C DOM classes **/
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.NamedNodeMap;
  
  /** Xerces classes **/
  import org.apache.xerces.dom.DocumentImpl;
  import org.apache.xerces.dom.TextImpl;
  import org.apache.xerces.parsers.DOMParser;
  import org.xml.sax.SAXException;
  
  /** Xalan classes **/
  import org.apache.xalan.xpath.XPathSupport;
  import org.apache.xalan.xpath.XPath;
  import org.apache.xalan.xpath.XPathProcessorImpl;
  import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
  import org.apache.xalan.xpath.xml.PrefixResolverDefault;
  import org.apache.xalan.xpath.XObject;
  
  public class XMLResourceBundle {
      // Cache for storing string values for existing XPaths
      private Hashtable cacheIS = new Hashtable();
      // Cache for storing non-existing XPaths
      private Hashtable cacheNO = new Hashtable();
  
      private Document resource;
      public String bundleName = ""; //used by getLocale()
      protected XMLResourceBundle parent = null;
  
  
      public XMLResourceBundle( Document doc, String name, XMLResourceBundle p ) {
          System.out.print( "Constructing XMLResourceBundle: " + name );
          if ( p != null )
              System.out.println( "  --> parent: " + p.bundleName );
          else
              System.out.println( "  --> parent: " + p );
  
          this.resource = doc;
          this.bundleName = name;
          this.parent = p;
      }
  
      public void addToCache( String key, String value ) {
          cacheIS.put( key, value );
      }
  
      public Document getResource() {
          return this.resource;
      }
  
      // gets string without throwing an exception, returns empty string instead
      public String getStringSimple( String xPathKey ) {
          String result = "";
          try {
              result = getString( xPathKey );
          } catch ( MissingResourceException e ) {
              // do nothing
          }
  
  
  
          return result;
      }
  
      public String getString( String xPathKey ) throws MissingResourceException {
          if ( cacheIS.containsKey( xPathKey ) )
              return ( String ) cacheIS.get( xPathKey );
          if ( cacheNO.containsKey( xPathKey ) )
              new MissingResourceException( "Unable to locate resource: " + xPathKey, "XMLResourceBundle", xPathKey );
  
          Node root = this.resource.getDocumentElement();
          try {
              Node node = XPathAPI.selectSingleNode( root, xPathKey );
              if ( node != null ) {
                  String temp = getTextNodeAsString( node );
                  addToCache( xPathKey, temp );
                  return temp;
              } else {
                  if ( this.parent != null )
                      return this.parent.getString( xPathKey );
                  else
                      throw new Exception();
              }
          } catch ( Exception e ) {
              // no nodes returned??
              cacheNO.put( xPathKey, "" );
              throw new MissingResourceException( "Unable to locate resource: " + xPathKey, "XMLResourceBundle", xPathKey );
          }
      }
  
      public String getString( Node role, String key ) throws MissingResourceException {
          try {
              Node node = XPathAPI.selectSingleNode( role, key );
              if ( node != null )
                  return getTextNodeAsString( node );
              else
                  throw new Exception();
          } catch ( Exception e ) {
              // no nodes returned??
              throw new MissingResourceException( "Unable to locate resource: " + key, "XMLResourceBundle", key );
          }
      }
  
      private String getTextNodeAsString( Node node ) throws MissingResourceException {
          node = node.getFirstChild();
          if ( node.getNodeType() == Node.TEXT_NODE )
              return ( ( TextImpl ) node ).getData();
          else
              throw new MissingResourceException( "Unable to locate XMLResourceBundle", "XMLResourceBundleFactory", "" );
      }
  
      public Node getRole( String xPath ) {
          Node root = resource.getDocumentElement();
          try {
              Node node = XPathAPI.selectSingleNode( root, xPath );
              if ( node != null )
                  return node;
              else
                  throw new Exception();
          } catch ( Exception e ) {
              // no nodes returned??
              throw new MissingResourceException( "Unable to locate resource: " + xPath, "XMLResourceBundle", xPath );
          }
      }
  
      public Node getRole( Node role, String xPath ) {
          try {
              Node node = XPathAPI.selectSingleNode( role, xPath );
              if ( node != null )
                  return node;
              else
                  throw new Exception();
          } catch ( Exception e ) {
              // no nodes returned??
              throw new MissingResourceException( "Unable to locate resource: " + xPath, "XMLResourceBundle", xPath );
          }
      }
  
      public XPath createXPath( String str, Node namespaceNode ) throws SAXException {
          XPathSupport xpathSupport = new XMLParserLiaisonDefault();
  
          if ( null == namespaceNode )
              throw new SAXException( "A namespace node is required to resolve prefixes!" );
  
          PrefixResolverDefault prefixResolver = new PrefixResolverDefault( ( namespaceNode.getNodeType() == Node.DOCUMENT_NODE ) ? ( ( Document ) namespaceNode ).getDocumentElement() : namespaceNode );
  
          // Create the XPath object.
          XPath xpath = new XPath();
  
          // Create a XPath parser.
          XPathProcessorImpl parser = new XPathProcessorImpl( xpathSupport );
          parser.initXPath( xpath, str, prefixResolver );
  
          return xpath;
      }
  
      public Locale getLocale() {
          String bundle = bundleName.substring( 0, bundleName.indexOf( ".xml" ) );
          int localeStart = bundle.indexOf( "_" );
          if ( localeStart == -1 )
              return new Locale( "", "", "" );
          bundle = bundle.substring( localeStart + 1 );
          localeStart = bundle.indexOf( "_" );
          if ( localeStart == -1 )
              return new Locale( bundle, "", "" );
  
          String lang = bundle.substring( 0, localeStart );
          bundle = bundle.substring( localeStart + 1 );
          localeStart = bundle.indexOf( "_" );
          if ( localeStart == -1 )
              return new Locale( lang, bundle, "" );
  
          String country = bundle.substring( 0, localeStart );
          bundle = bundle.substring( localeStart + 1 );
          return new Locale( lang, country, bundle );
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/i18n/XMLResourceBundleFactory.java
  
  Index: XMLResourceBundleFactory.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 file.
   */
  package org.apache.avalon.util.i18n;
  
  /**
   * @author <a href="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
   * @author <a href="mailto:neeme@one.lv">Neeme Praks</a>
   * @author <a href="mailto:oleg@one.lv">Oleg Podolsky</a>
   * @version $Id: XMLResourceBundleFactory.java,v 1.1 2001/02/25 10:45:50 fede Exp $
    */
  
  /** JDK classes **/
  
  
  /** W3C DOM classes **/
  /** Xerces-J classes **/
  //import java.lang.ref.SoftReference;
  import java.io.IOException;
  import java.util.Hashtable;
  import java.util.Locale;
  import java.util.MissingResourceException;
  import java.util.Vector;
  import org.apache.xerces.dom.DocumentImpl;
  import org.apache.xerces.dom.TextImpl;
  import org.apache.xerces.parsers.DOMParser;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.xml.sax.SAXException;
  
  public class XMLResourceBundleFactory {
      protected static Hashtable cache = new Hashtable();
      protected static String directory;
  
      protected XMLResourceBundleFactory() {}
  
  
  
  
      public static XMLResourceBundle getBundle( String name ) throws MissingResourceException {
          return getBundle( name, Locale.getDefault() );
      }
  
      public static XMLResourceBundle getBundle( String name, Locale loc ) throws MissingResourceException {
          return getBundle( name, loc, false );
      }
  
      public static XMLResourceBundle getBundle( String name, Locale loc, boolean cacheAtStartup ) throws MissingResourceException {
          XMLResourceBundle parent = null;
          String bundleName = getBundleName( name, loc );
          // first look in the cache - if there grab it
          XMLResourceBundle bundle = getCachedBundle( bundleName );
          if ( bundle != null )
              return bundle;
  
          // if bundle is not in cache try loading the bundle using the given name and locale bundleName
          Document doc = null;
          doc = loadResourceBundle( bundleName );
          if ( doc != null ) {
              if ( ! loc.getLanguage().equals( "" ) )
                  parent = getParentBundle( name, loc, cacheAtStartup );
              bundle = new XMLResourceBundle( doc, bundleName, parent );
              if ( cacheAtStartup )
                  storeTextElements( bundle, bundle.getResource(), "" );
              updateCache( bundleName, bundle );
              return bundle;
          }
          // if the locale's language is "" then we've already tried to load the default resource and it's not available
          while ( ! loc.getLanguage().equals( "" ) ) {
              // if the given bundle name is not found, then try loading using a shortened Locale
              loc = getParentLocale( loc );
              bundleName = getBundleName( name, loc );
              // first look in the cache - if there grab it and return
              bundle = getCachedBundle( bundleName );
              if ( bundle != null )
                  return bundle;
  
              // try loading the bundle using the given name and locale bundleName
              doc = loadResourceBundle( bundleName );
              if ( doc != null ) {
                  if ( ! loc.getLanguage().equals( "" ) )
                      parent = getParentBundle( name, loc, cacheAtStartup );
                  bundle = new XMLResourceBundle( doc, bundleName, parent );
                  if ( cacheAtStartup )
                      storeTextElements( bundle, bundle.getResource(), "" );
                  updateCache( bundleName, bundle );
                  return bundle;
              }
          }
          throw new MissingResourceException( "Unable to locate resource: " + bundleName, "XMLResourceBundleFactory", "" );
      }
  
      protected synchronized static XMLResourceBundle getParentBundle( String name, Locale loc ) {
          return getParentBundle( name, loc, false );
      }
  
      protected synchronized static XMLResourceBundle getParentBundle( String name, Locale loc, boolean cacheAtStartup ) {
          loc = getParentLocale( loc );
          String bundleName = getBundleName( name, loc );
          Document doc = loadResourceBundle( bundleName );
          XMLResourceBundle bundle = null;
          if ( doc != null ) {
              if ( ! loc.getLanguage().equals( "" ) )
                  bundle = getParentBundle( name, loc );
              bundle = new XMLResourceBundle( doc, bundleName, bundle );
              if ( cacheAtStartup )
                  storeTextElements( bundle, bundle.getResource(), "" );
              updateCache( bundleName, bundle );
          }
          return bundle;
      }
  
      // this method returns the next locale up the parent hierarchy
      // e.g.; the parent of new Locale("en","us","mac")
      // would be new Locale("en", "us", "");
      protected static Locale getParentLocale( Locale loc ) {
          if ( loc.getVariant().equals( "" ) ) {
              if ( loc.getCountry().equals( "" ) )
                  loc = new Locale( "", "", "" );
              else
                  loc = new Locale( loc.getLanguage(), "", "" );
          } else
              loc = new Locale( loc.getLanguage(), loc.getCountry(), "" );
  
          return loc;
      }
  
      protected synchronized static XMLResourceBundle getCachedBundle( String bundleName ) {
          /*
            SoftReference ref = (SoftReference)(cache.get(bundleName));
            if (ref != null)
            return (XMLResourceBundle) ref.get();
            else
            return null;
          */ 
          return ( XMLResourceBundle ) ( cache.get( bundleName ) );
      }
  
      protected synchronized static void updateCache( String bundleName, XMLResourceBundle bundle ) {
          cache.put( bundleName, bundle );
      }
  
      /*        protected static String getBundleName(String name, Locale loc)
              {
          StringBuffer sb = new StringBuffer(name);
          if (! loc.getLanguage().equals(""))
          {
          sb.append("_");
          sb.append(loc.getLanguage());
          }
          if (! loc.getCountry().equals(""))
          {
          sb.append("_");
          sb.append(loc.getCountry());
          }
          if (! loc.getVariant().equals(""))
          {
          sb.append("_");
          sb.append(loc.getVariant());
          }
          // should all the files have an extension of .xml?  Seems reasonable
          sb.append(".xml");
       
          return sb.toString();
              }
      */
  
      protected static String getBundleName( String name, Locale loc ) {
          String lang = loc.getLanguage();
          StringBuffer sb = new StringBuffer( getDirectory() );
  
          if ( lang.length() > 0 ) sb.append( "/" ).append( lang );
          sb.append( "/" ).append( name ).append( ".xml" );
  
          return sb.toString();
      }
  
      public static XMLResourceBundle getBundle( String fileName, String localeName ) throws MissingResourceException {
          return getBundle( fileName, new Locale( localeName, localeName ) );
      }
  
      public static XMLResourceBundle getBundleFromFilename( String bundleName ) throws MissingResourceException {
          return getBundleFromFilename( bundleName, true );
      }
  
      public static XMLResourceBundle getBundleFromFilename( String bundleName, boolean cacheAtStartup ) throws MissingResourceException {
          Document doc = null;
          doc = loadResourceBundle( getDirectory() + "/" + bundleName );
  
          XMLResourceBundle bundle = getCachedBundle( bundleName );
          if ( bundle != null )
              return bundle;
  
          if ( doc != null ) {
              bundle = new XMLResourceBundle( doc, bundleName, null );
              if ( cacheAtStartup )
                  storeTextElements( bundle, bundle.getResource(), "" );
              updateCache( bundleName, bundle );
              return bundle;
          }
          throw new MissingResourceException( "Unable to locate resource: " + bundleName, "XMLResourceBundleFactory", "" );
      }
  
      // Load the XML document based on bundleName
      protected static Document loadResourceBundle( String bundleName ) {
          try {
              DOMParser parser = new DOMParser();
              parser.parse( bundleName );
              return parser.getDocument();
          } catch ( IOException e ) {
              return null;
          }
          catch ( SAXException e ) {
              return null;
          }
      }
  
      public static void setDirectory( String dir ) {
          directory = dir;
      }
  
      public static String getDirectory() {
          return ( directory != null ? directory : "" );
      }
  
      // Steps through the bundle tree and stores all text element values
      // in bundle's cache, and also stores attributes for all element nodes.
      // Parent must be am element-type node.
      private static void storeTextElements( XMLResourceBundle bundle, Node parent, String pathToParent ) {
          NodeList children = parent.getChildNodes();
          int childnum = children.getLength();
  
          for ( int i = 0; i < childnum; i++ ) {
              Node child = children.item( i );
  
              if ( child.getNodeType() == Node.ELEMENT_NODE ) {
                  String pathToChild = pathToParent + '/' + child.getNodeName();
  
                  NamedNodeMap attrs = child.getAttributes();
                  if ( attrs != null ) {
                      Node temp = null;
                      String pathToAttr = null;
                      int attrnum = attrs.getLength();
                      for ( int j = 0; j < attrnum; j++ ) {
                          temp = attrs.item( j );
                          pathToAttr = "/@" + temp.getNodeName();
                          bundle.addToCache( pathToChild + pathToAttr, temp.getNodeValue() );
                      }
                  }
  
                  String childValue = getTextValue( child );
                  if ( childValue != null )
                      bundle.addToCache( pathToChild, childValue );
                  else
                      storeTextElements( bundle, child, pathToChild );
              }
          }
      }
  
      private static String getTextValue( Node element ) {
          NodeList list = element.getChildNodes();
          int listsize = list.getLength();
  
          Node item = null;
          String itemValue = null;
  
          for ( int i = 0; i < listsize; i++ ) {
              item = list.item( i );
              if ( item.getNodeType() != Node.TEXT_NODE ) return null;
              itemValue = item.getNodeValue(); if ( itemValue == null ) return null;
              itemValue = itemValue.trim(); if ( itemValue.length() == 0 ) return null;
              return itemValue;
          }
          return null;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/i18n/XPathAPI.java
  
  Index: XPathAPI.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 file.
   */
  package org.apache.avalon.util.i18n;
  
  import org.xml.sax.SAXException;
  import org.w3c.dom.Node;
  import org.w3c.dom.Document;
  import org.w3c.dom.NodeList;
  import org.apache.xalan.xpath.XPathSupport;
  import org.apache.xalan.xpath.XPath;
  import org.apache.xalan.xpath.XPathProcessorImpl;
  import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
  import org.apache.xalan.xpath.xml.PrefixResolverDefault;
  import org.apache.xalan.xpath.XObject;
  
  /**
   * The methods in this class are convenience methods into the
   * low-level XPath API.  We would like to eventually move these
   * methods into the XPath core, but would like to do some peer
   * review first to make sure we have it right.
   * Please note that these methods execute pure XPaths. They do not
   * implement those parts of XPath extended by XSLT, such as the
   * document() function).  If you want to install XSLT functions, you
   * have to use the low-level API.
   * These functions tend to be a little slow, since a number of objects must be
   * created for each evaluation.  A faster way is to precompile the
   * XPaths using the low-level API, and then just use the XPaths
   * over and over.
   *
   * @author <a href="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
   * @see http://www.w3.org/TR/xpath
   * @version $Id: XPathAPI.java,v 1.1 2001/02/25 10:45:50 fede Exp $
   */
  public class XPathAPI {
      /**
       * Use an XPath string to select a single node. XPath namespace
       * prefixes are resolved from the context node, which may not
       * be what you want (see the next method).
       *
       * @param contextNode The node to start searching from.
       * @param str A valid XPath string.
       * @return The first node found that matches the XPath, or null.
       */
      public static Node selectSingleNode( Node contextNode, String str )
      throws SAXException {
          return selectSingleNode( contextNode, str, contextNode );
      }
  
      /**
       * Use an XPath string to select a single node.
       * XPath namespace prefixes are resolved from the namespaceNode.
       *
       * @param contextNode The node to start searching from.
       * @param str A valid XPath string.
       * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
       * @return The first node found that matches the XPath, or null.
       */
      public static Node selectSingleNode( Node contextNode, String str, Node namespaceNode )
      throws SAXException {
          // Have the XObject return its result as a NodeSet.
          NodeList nl = selectNodeList( contextNode, str, namespaceNode );
  
          // Return the first node, or null
          return ( nl.getLength() > 0 ) ? nl.item( 0 ) : null;
      }
  
      /**
       * Use an XPath string to select a nodelist.
       * XPath namespace prefixes are resolved from the contextNode.
       *
       * @param contextNode The node to start searching from.
       * @param str A valid XPath string.
       * @return A nodelist, should never be null.
       */
      public static NodeList selectNodeList( Node contextNode, String str )
      throws SAXException {
          return selectNodeList( contextNode, str, contextNode );
      }
  
      /**
        * Use an XPath string to select a nodelist.
        * XPath namespace prefixes are resolved from the namespaceNode.
        *
        * @param contextNode The node to start searching from.
        * @param str A valid XPath string.
        * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
        * @return A nodelist, should never be null.
        */
      public static NodeList selectNodeList( Node contextNode, String str, Node namespaceNode )
      throws SAXException {
          // Execute the XPath, and have it return the result
          XObject list = eval( contextNode, str, namespaceNode );
  
          // Have the XObject return its result as a NodeSet.
          return list.nodeset();
  
      }
  
      /**
       * Evaluate XPath string to an XObject.  Using this method,
       * XPath namespace prefixes will be resolved from the namespaceNode.
       * @param contextNode The node to start searching from.
       * @param str A valid XPath string.
       * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
       * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
       * @see org.apache.xalan.xpath.XObject
       * @see org.apache.xalan.xpath.XNull
       * @see org.apache.xalan.xpath.XBoolean
       * @see org.apache.xalan.xpath.XNumber
       * @see org.apache.xalan.xpath.XString
       * @see org.apache.xalan.xpath.XRTreeFrag
       */
      public static XObject eval( Node contextNode, String str )
      throws SAXException {
          return eval( contextNode, str, contextNode );
      }
  
      /**
       * Evaluate XPath string to an XObject.
       * XPath namespace prefixes are resolved from the namespaceNode.
       * The implementation of this is a little slow, since it creates
       * a number of objects each time it is called.  This could be optimized
       * to keep the same objects around, but then thread-safety issues would arise.
       *
       * @param contextNode The node to start searching from.
       * @param str A valid XPath string.
       * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
       * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
       * @see org.apache.xalan.xpath.XObject
       * @see org.apache.xalan.xpath.XNull
       * @see org.apache.xalan.xpath.XBoolean
       * @see org.apache.xalan.xpath.XNumber
       * @see org.apache.xalan.xpath.XString
       * @see org.apache.xalan.xpath.XRTreeFrag   */
      public static XObject eval( Node contextNode, String str, Node namespaceNode )
      throws SAXException {
          // Since we don't have a XML Parser involved here, install some default support
          // for things like namespaces, etc.
          // (Changed from: XPathSupportDefault xpathSupport = new XPathSupportDefault();
          //    because XPathSupportDefault is weak in a number of areas... perhaps
          //    XPathSupportDefault should be done away with.)
          XPathSupport xpathSupport = new XMLParserLiaisonDefault();
  
          if ( null == namespaceNode )
              namespaceNode = contextNode;
  
          // Create an object to resolve namespace prefixes.
          // XPath namespaces are resolved from the input context node's document element
          // if it is a root node, or else the current context node (for lack of a better
          // resolution space, given the simplicity of this sample code).
          PrefixResolverDefault prefixResolver = new PrefixResolverDefault( ( namespaceNode.getNodeType() == Node.DOCUMENT_NODE )
                                                 ? ( ( Document ) namespaceNode ).getDocumentElement() :
                                                 namespaceNode );
  
          // Create the XPath object.
          XPath xpath = new XPath();
  
          // Create a XPath parser.
          XPathProcessorImpl parser = new XPathProcessorImpl( xpathSupport );
          parser.initXPath( xpath, str, prefixResolver );
  
          // Execute the XPath, and have it return the result
          return xpath.execute( xpathSupport, contextNode, prefixResolver );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/CRLFInputStream.java
  
  Index: CRLFInputStream.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 file.
   */
  package org.apache.avalon.util.internet;
  
  import java.io.FilterInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  /**
   * Transform line endings to CRLF in input stream.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CRLFInputStream
      extends FilterInputStream
  {
      protected int       m_lastChar;
  
      public CRLFInputStream( final InputStream inputStream )
      {
          super( inputStream );
          m_lastChar = -1;
      }
      
      public int read()
          throws IOException
      {
          if( '\r' != m_lastChar )
          {
              final int result = m_lastChar;
              m_lastChar = -1;
              return result;
          }
  
          final int data = in.read();
  
          if( -1 == data )
          {
              if( -1 != m_lastChar ) return m_lastChar;
              else return data;
          }
          else if( '\r' == data )
          {
              m_lastChar = data;
              return read();
          }
          else if( '\n' != data ) 
          {
              if( -1 != m_lastChar )
              {
                  final int result = m_lastChar;
                  m_lastChar = -1;
                  return result;
              }
              else return data;
          }
          else return data;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/CRLFOutputStream.java
  
  Index: CRLFOutputStream.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 file.
   */
  package org.apache.avalon.util.internet;
  
  import java.io.FilterOutputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  
  /**
   * Transform line endings to CRLF in output stream.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class CRLFOutputStream
      extends FilterOutputStream
  {
      public CRLFOutputStream( final OutputStream outputStream )
      {
          super( outputStream );
      }
      
      public void write( final int data )
          throws IOException
      {
          if( '\n' == data ) out.write( '\r' );
          out.write( data );
      }
      
      public void write( final byte data[], final int offset, final int len )
          throws IOException
      {
          for( int i = 0; i < len; i++)
          {
              final byte element = data[ offset + i ];
              if( '\n' == element ) out.write( '\r' );
              out.write( element );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/InternetException.java
  
  Index: InternetException.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 file.
   */
  package org.apache.avalon.util.internet;
  
  import org.apache.avalon.CascadingException;
  
  /**
   * Connection thrown during various internet related protocol handling.
   * The code field will handle the common 3 digit code + message
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class InternetException
      extends CascadingException
  {
      protected InternetReply   m_reply;
  
      public InternetException( final int code, final String description )
      {
          this( code, description, null );
      }
      
      public InternetException( final int code, 
                                final String description, 
                                final Throwable throwable )
      {
          super( description, throwable );
          m_reply = new InternetReply( code, description );
      }
  
      public InternetReply getReply()
      {
          return m_reply;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/InternetReply.java
  
  Index: InternetReply.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 file.
   */    
  package org.apache.avalon.util.internet;
  
  /**
   * This is for holding Internet reply codes + descriptions.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class InternetReply
  {
      protected int     m_code;
      protected String  m_description;
  
      public InternetReply( final int code, final String description )
      {
          m_code = code;
          m_description = description;
      }
      
      public int getCode()
      {
          return m_code;
      }
      
      public String getDescription()
      {
          return m_description;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/InternetStream.java
  
  Index: InternetStream.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 file.
   */
  package org.apache.avalon.util.internet;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.ProtocolException;
  
  /**
   * This is the Internet output/input stream.
   * Used for such things as SMTP, NNTP, FTP? etc.
   *
   * TODO: Need to be able to set a flag to allow lax input-reading
   * to cope with some non-compliant sources
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class InternetStream
  {
      protected final static int           MAX_OUTGOING_LINE_LENGTH   = 512;
  
      protected LineReader                 m_reader;
      protected LineWriter                 m_writer;
      protected String                     m_lastLine;
  
      protected String                     m_responseText;
      protected int                        m_responseCode;
      protected String                     m_requestVerb;
      protected String                     m_requestParameter;
  
      /**
       * Constructor taking an input and output.
       *
       * @param input the InputStream
       * @param output the OutputStream
       */
      public InternetStream( final InputStream input, final OutputStream output )
      {
          m_reader = new LineReader( input );
          m_writer = new LineWriter( output );
      }
  
      /**
       * Retrieve request verb last received.
       *
       * @return the request verb
       */
      public String getRequestVerb()
      {
          return m_requestVerb;
      }
  
      /**
       * Retrieve request parameter
       *
       * @return the request parameter
       */
      public String getRequestParameter()
      {
          return m_requestParameter;
      }
      
      public String getResponseText()
      {
          return m_responseText;
      }
  
      public int getResponseCode()
      {
          return m_responseCode;
      }
  
      /**
       * Retrieve last line received from connection. 
       *
       * @return the last line received
       */
      public String getLastLine()
      {
          return m_lastLine;
      }
  
      /**
       * Send a request to server.
       *
       * @param verb the request verb
       * @exception IOException if an error occurs
       */
      public void sendRequest( final String verb )
          throws IOException
      {
          sendRequest( verb, null );
      }
  
      /**
       * Send a Request to server.
       *
       * @param verb the request verb
       * @param parameter the parameter (or null if none)
       * @exception IOException if an error occurs
       */
      public void sendRequest( final String verb, final String parameter )
          throws IOException
      {
          final StringBuffer sb = new StringBuffer();
          sb.append( verb );
  
          if( null != parameter )
          {
              sb.append( ' ' );
              sb.append( parameter );
          }
  
          m_writer.println( sb.toString() );
      }
  
      /**
       * Send a response. 
       * Format the message so that it conforms to line length/contents rules.
       *
       * @param responseCode the response code
       * @param message the message
       * @exception IOException if an error occurs
       */
      public void sendResponse( final int responseCode, final String message )
          throws IOException
      {
          int start = 0;
          int end = message.indexOf( '\n' );
          
          while( -1 != end )
          {
              sendResponseLines( responseCode, false, message.substring( start, end ) );
              start = end + 1;
              end = message.indexOf( '\n', start );
          }
          
          end = message.length();
  
          sendResponseLines( responseCode, true, message.substring( start, end ) );        
      }
  
      /**
       * Receive a Request from client.
       *
       * @exception IOException if an error occurs
       */
      public void receiveRequest()
          throws IOException
      {
          m_requestVerb = null;
          m_requestParameter = null;
  
          final String line = m_reader.readln();
          
          int space = line.indexOf( ' ' );
          
          if( -1 == space )
          {
              m_requestVerb = line.toUpperCase();
          }
          else
          {
              m_requestVerb = line.substring( 0, space ).toUpperCase();
              m_requestParameter = line.substring( space + 1 ).trim();
  
              if( m_requestParameter.equals( "" ) )
              {
                  m_requestParameter = null;
              }
          }
      }
  
      /**
       * receive a response from server.
       *
       * @exception IOException if an error occurs
       */
      public void receiveResponse()
          throws IOException
      {
          boolean lastLine = false;
  
          m_responseCode = 0;
          m_responseText = null;
  
          while( !lastLine )
          {
              final String line = m_reader.readln();
              int responseCode = Integer.parseInt( line.substring( 0, 3 ) );
                  
              if( 0 != m_responseCode && responseCode != m_responseCode )
              {
                  throw new ProtocolException( "Badly formed response with differing codes" );
              }
                  
              m_responseCode = responseCode;
  
              lastLine = ( ' ' == line.charAt( 3 ) );
                  
              final String messagePart = line.substring( 4, line.length() );
  
              if( null == m_responseText ) m_responseText = messagePart;
              else m_responseText += '\n' + messagePart;
          }
      }
      
      /**
       * Helper method to build a response line. 
       * If message is greater than MAX_OUTGOING_LINE_LENGTH it is broken into multiple lines.
       *
       * @param responseCode the response code.
       * @param isLastLine true if this is last line in response
       * @param message the message
       * @exception IOException if an error occurs
       */
      protected void sendResponseLines( final int responseCode, 
                                        final boolean isLastLine,
                                        final String message )
          throws IOException
      {
          final int size = message.length();
          
          if( size < MAX_OUTGOING_LINE_LENGTH )
          {
              sendResponseLine( responseCode, isLastLine, message );
          }
          else
          {
              int start = 0;
              int end = MAX_OUTGOING_LINE_LENGTH;
  
              while( end < size )
              {
                  sendResponseLine( responseCode, false, message.substring( start, end ) );
                  start = end + 1;
                  end = end + MAX_OUTGOING_LINE_LENGTH;
              }
                  
              sendResponseLine( responseCode, isLastLine, message.substring( start, size ) );
          }
      }
  
      /**
       * Helper method to build a response line.
       *
       * @param responseCode the response code.
       * @param isLastLine true if this is last line in response
       * @param message the message
       * @exception IOException if an error occurs
       */
      protected void sendResponseLine( final int responseCode, 
                                       final boolean isLastLine,
                                       final String message )
          throws IOException
      {
          final char seperator = ( isLastLine ) ? ' ' : '-';
          final String responseLine = Integer.toString( responseCode ) + seperator + message;
          sendLine( responseLine );
      }
      
      /**
       * Send a raw line and terminate it with a \r\n.
       * This assumes thaat the parameters does not have \r\n 
       * sequence in it (or \n byitself).
       *
       * @param line the line
       * @exception IOException if an error occurs
       */
      public final void sendLine( final String line )
          throws IOException
      {
          m_writer.println( line );
      }
      
      /**
       * Receive a line.
       *
       * @return the line received
       * @exception IOException if an error occurs
       */
      public final String receiveLine()
          throws IOException
      {
          m_lastLine = m_reader.readln();
          return m_lastLine;
      } 
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/LineReader.java
  
  Index: LineReader.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 file.
   */
  package org.apache.avalon.util.internet;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.ProtocolException;
  
  /**
   * Used to write lines with appropriate line endings.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class LineReader
  {
      protected final static byte[]      LINE_TERMINATOR = { (byte)'\r', (byte)'\n' };
  
      protected InputStream        m_input;
      protected boolean            m_laxLineFormat;
  
      public LineReader( final InputStream input )
      {
          m_input = input;
      }
  
      public void setLaxLineFormat( final boolean laxLineFormat )
      {
          m_laxLineFormat = laxLineFormat;
      }
  
      public String readln()
          throws IOException
      {
          final StringBuffer sb = new StringBuffer();
          
          int data = m_input.read();
          int last = -1;
  
          while( LINE_TERMINATOR[ 1 ] != data )
          {
              if( last == LINE_TERMINATOR[ 0 ] )
              {
                  if( data == LINE_TERMINATOR[ 1 ] ) break;
                  else sb.append( (char)last );
              }
              else if( data == LINE_TERMINATOR[ 1 ] )
              {
                  break;
              }
              else
              {
                  last = data;
                  if( data != LINE_TERMINATOR[ 0 ] ) sb.append( (char)data );
              }
  
              data = m_input.read();
          }
  
          return sb.toString();
      }
  
      public void close()
          throws IOException
      {
          m_input.close();
      }
  }
  
      
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/internet/LineWriter.java
  
  Index: LineWriter.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 file.
   */
  package org.apache.avalon.util.internet;
  
  import java.io.IOException;
  import java.io.OutputStream;
  import java.net.ProtocolException;
  
  /**
   * Used to write lines with appropriate line endings.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class LineWriter
  {
      protected final static byte[]      LINE_TERMINATOR = { (byte)'\r', (byte)'\n' };
  
      protected OutputStream       m_output;
  
      public LineWriter( final OutputStream output )
      {
          m_output = output;
      }
  
      public void println( final String data )
              throws IOException
      {
          m_output.write( data.getBytes() );
          m_output.write( LINE_TERMINATOR );
          m_output.flush();
      }
  
      public void close()
          throws IOException
      {
          m_output.close();
      }
  }
  
      
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/ByteTerminatedInputStream.java
  
  Index: ByteTerminatedInputStream.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.IOException;
  import java.io.InputStream;
  
  /**
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author  Federico Barbieri <fede@apache.org>
   */
  public class ByteTerminatedInputStream 
      extends InputStream
  {
      protected final boolean              m_includeTerminator;
      protected final InputStream          m_inputStream;
      protected final byte[]               m_terminator;
      protected final int                  m_matchLength;
      protected int                        m_match;
      
      public ByteTerminatedInputStream( final InputStream inputStream, 
                                        final byte[] terminator,
                                        final boolean includeTerminator ) 
      {
          m_includeTerminator = includeTerminator;
          m_matchLength = terminator.length;
          m_terminator = terminator;
          m_inputStream = inputStream;
          m_match = 0;
      }
      
      public int read()
          throws IOException
      {
          if( m_match == m_matchLength ) return -1;
  
          int next = getNext();
  
          if( !m_includeTerminator && 0 != m_match )
          {
              m_inputStream.mark( m_matchLength );
  
              int matchTest = next;
  
              while( -1 != matchTest )
              {
                  matchTest = getNext();
                  if( m_match == m_matchLength ) return -1;
                  else if( m_match == 0 ) break;
              }
              m_match = 0;
              m_inputStream.reset();
          }
  
          return next;
      }
  
      protected final int getNext()
          throws IOException
      {
          final int next = m_inputStream.read();
          
          if( next == m_terminator[ m_match ] ) m_match++;
          else if( next == m_terminator[ 0 ] ) m_match = 1;
          else m_match = 0;
  
          return next;
      }
  }
      
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/DirectoryFileFilter.java
  
  Index: DirectoryFileFilter.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.File;
  import java.io.FilenameFilter;
  
  /**
   * This filters files based if not a directory.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DirectoryFileFilter 
      implements FilenameFilter
  {
      public boolean accept( final File file, final String name ) 
      {
          return file.isDirectory();
      }
  }
  
      
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/ExtensionFileFilter.java
  
  Index: ExtensionFileFilter.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.File;
  import java.io.FilenameFilter;
  
  /**
   * This filters files based on the extension (what the filename 
   * ends with).  This is used in retrieving all the files of a 
   * particular type.
   *
   * @author  Federico Barbieri <fede@apache.org>
   * @author Serge Knystautas <sergek@lokitech.com>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ExtensionFileFilter 
      implements FilenameFilter
  {
      private String[]           m_extensions;
  
      public ExtensionFileFilter( final String[] extensions ) 
      {
          m_extensions = extensions;
      }
  
      public ExtensionFileFilter( final String extension ) 
      {
          m_extensions = new String[] { extension };
      }
  
      public boolean accept( final File file, final String name ) 
      {
          for( int i = 0; i < m_extensions.length; i++ ) 
          {
              if( name.endsWith( m_extensions[ i ] ) ) return true;
          }
          return false;        
      }
  }
  
      
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/FileUtil.java
  
  Index: FileUtil.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.*;
  import java.net.URL;
  import org.apache.avalon.util.StringUtil;
  
  /**
   * This class provides basic facilities for manipulating files.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class FileUtil
  {
      /**
       * Private constructor to prevent instantiation.
       *
       */
      private FileUtil()
      {
      }
  
      public static File toFile( final URL url )
      {
          if( !url.getProtocol().equals( "file" ) )
          {
              return null;
          }
          else
          {
              final String filename = url.getFile().replace( '/', File.separatorChar );
              return new File( filename );
          }        
      }
  
      /**
       * Remove extention from filename.
       * ie
       * fo.txt --> foo
       * a\b\c.jpg --> a\b\c
       * a\b\c --> a\b\c
       *
       * @param filename the filename
       * @return the filename minus extention
       */
      public static String removeExtention( final String filename )
      {
          final int index = filename.lastIndexOf( '.' );
          
          if( -1 == index ) 
          {
              return filename;
          }
          else
          {
              return filename.substring( 0, index );
          }
      }
  
      /**
       * remove path from filename.
       * ie.
       * a/b/c.txt --> c.txt
       * a.txt --> a.txt
       *
       * @param filepath the filepath
       * @return the filename minus path
       */
      public static String removePath( final String filepath )
      {
          final int index = filepath.lastIndexOf( File.separator );
  
          if( -1 == index ) 
          {
              return filepath;
          }
          else
          {
              return filepath.substring( index + 1 );
          }
      }
  
      /**
       * Copy file from source to destination.
       */
      public static void copyFileToDirectory( final String source, 
                                              final String destinationDirectory ) 
          throws IOException 
      {
          copyFileToDirectory( new File( source ), new File( destinationDirectory ) );
      }
  
      /**
       * Copy file from source to destination.
       */
      public static void copyFileToDirectory( final File source, 
                                              final File destinationDirectory ) 
          throws IOException 
      {
          if( destinationDirectory.exists() && !destinationDirectory.isDirectory() )
          {
              throw new IllegalArgumentException( "Destination is not a directory" );
          }
  
          copyFile( source, new File( destinationDirectory, source.getName() ) );
      }
  
      /**
       * Copy file from source to destination.
       */
      public static void copyFile( final File source, final File destination ) 
          throws IOException 
      {
          //check source exists
          if( !source.exists() )
          {
              throw new IOException( "File " + source + " does not exist" );
          }
  
          //does destinations directory exist ?
          if( !destination.getParentFile().exists() )
          {
              destination.mkdirs();
          }
  
          //make sure we can write to destination
          if( destination.exists() && !destination.canWrite() )
          {
              throw new IOException( "Unable to open file " + destination + " for writing." );
          }
  
          IOUtil.copy( new FileInputStream( source ), new FileOutputStream( destination ) );
  
          if( source.length() != destination.length() )
          {
              throw new IOException( "Failed to copy full contents from " + source + 
                                     " to " + destination );
          }
      } 
  
      public static void copyURLToFile( final URL source, final File destination ) 
          throws IOException 
      {
          //does destinations directory exist ?
          if( !destination.getParentFile().exists() )
          {
              destination.mkdirs();
          }
          
          //make sure we can write to destination
          if( destination.exists() && !destination.canWrite() )
          {
              throw new IOException( "Unable to open file " + destination + " for writing." );
          }
          
          IOUtil.copy( source.openStream(), new FileOutputStream( destination ) );
      } 
  
      public static String normalize( String location )
      {
          location = StringUtil.replaceSubString( location, "/./", "/" );
          
          final StringBuffer sb = new StringBuffer();
          
          int trail = 0;
          int end = location.indexOf( "/../" );
          int start = 0;
          
          while( end != -1 )
          {
              //TODO: fix when starts with /../
              trail = location.lastIndexOf( "/", end - 1 );
              sb.append( location.substring( start, trail ) );
              sb.append( '/' );
              start = end + 4;
              end = location.indexOf( "/../", start );
          }
          
          end = location.length();
          sb.append( location.substring( start, end ) );
          
          return sb.toString();
      }
  
      /** Will concatenate 2 paths, dealing with ..
       * ( /a/b/c + d = /a/b/d, /a/b/c + ../d = /a/d )
       * 
       * Thieved from Tomcat sources...
       * 
       * @return null if error occurs
       */
      public static String catPath( String lookupPath, String path )
      {
          // Cut off the last slash and everything beyond
          int index = lookupPath.lastIndexOf( "/" );
          lookupPath = lookupPath.substring( 0, index );
          
          // Deal with .. by chopping dirs off the lookup path
          while( path.startsWith( "../" ) ) 
          { 
              if( lookupPath.length() > 0 )
              {
                  index = lookupPath.lastIndexOf( "/" );
                  lookupPath = lookupPath.substring( 0, index );
              } 
              else
              {
                  // More ..'s than dirs, return null
                  return null;
              }
              
              index = path.indexOf( "../" ) + 3;
              path = path.substring( index );
          }
          
          return lookupPath + "/" + path;
      }
  
      public static File resolveFile( final File baseFile, String filename ) 
      {
          if( '/' != File.separatorChar ) 
          {
              filename = filename.replace( '/', File.separatorChar );
          }
  
          if( '\\' != File.separatorChar ) 
          {
              filename = filename.replace( '\\', File.separatorChar );
          }
  
          // deal with absolute files
          if( filename.startsWith( File.separator ) )
          {
              File file = new File( filename );
  
              try { file = file.getCanonicalFile(); } 
              catch( final IOException ioe ) {}
  
              return file;
          }
  
          final char[] chars = filename.toCharArray();
          final StringBuffer sb = new StringBuffer();
  
          //remove duplicate file seperators in succession - except 
          //on win32 as UNC filenames can be \\AComputer\AShare\myfile.txt
          int start = 0;
          if( '\\' == File.separatorChar ) 
          {
              sb.append( filename.charAt( 0 ) );
              start++;
          }
  
          for( int i = start; i < chars.length; i++ )
          {
              final boolean doubleSeperator = 
                  File.separatorChar == chars[ i ] && File.separatorChar == chars[ i - 1 ];
  
              if( !doubleSeperator ) sb.append( chars[ i ] );
          }
          
          filename = sb.toString();
  
          //must be relative
          File file = (new File( baseFile, filename )).getAbsoluteFile();
  
          try { file = file.getCanonicalFile(); }
          catch( final IOException ioe ) {}
  
          return file;
      }
  
      /**
       * Delete a file. If file is directory delete it and all sub-directories.
       */
      public static void forceDelete( final String file )
          throws IOException 
      {
          forceDelete( new File( file ) );
      }
  
      /**
       * Delete a file. If file is directory delete it and all sub-directories.
       */
      public static void forceDelete( final File file )
          throws IOException 
      {
          if( file.isDirectory() ) deleteDirectory( file );
          else
          {
              if( false == file.delete() )
              {
                  throw new IOException( "File " + file + " unable to be deleted." );
              }
          }
      }
  
      /**
       * Recursively delete a directory.
       */
      public static void deleteDirectory( final String directory )
          throws IOException 
      {
          deleteDirectory( new File( directory ) );
      }
  
      /**
       * Recursively delete a directory.
       */
      public static void deleteDirectory( final File directory )
          throws IOException 
      {
          if( !directory.exists() ) return;
  
          cleanDirectory( directory );
          if( false == directory.delete() )
          {
              throw new IOException( "Directory " + directory + " unable to be deleted." );
          }
      }  
  
      /**
       * Clean a directory without deleting it.
       */
      public static void cleanDirectory( final String directory )
          throws IOException 
      {
          cleanDirectory( new File( directory ) );
      }
      
      /**
       * Clean a directory without deleting it.
       */
      public static void cleanDirectory( final File directory )
          throws IOException 
      {
          if( !directory.exists() ) 
          {
              throw new IllegalArgumentException( directory + " does not exist" );
          }
          
          if( !directory.isDirectory() )
          {
              throw new IllegalArgumentException( directory + " is not a directory" );
          }
          
          final File[] files = directory.listFiles();
          
          for( int i = 0; i < files.length; i++ ) 
          {
              final File file = files[ i ];
              
              if( file.isFile() ) file.delete();
              else if( file.isDirectory() ) 
              {
                  cleanDirectory( file );
                  if( false == file.delete() )
                  {
                      throw new IOException( "Directory " + file + " unable to be deleted." );
                  }
              }
          }
      } 
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/IOUtil.java
  
  Index: IOUtil.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.*;
  
  /**
   * This class provides basic facilities for manipulating io streams.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class IOUtil
  {
      /**
       * Private constructor to prevent instantiation.
       */
      private IOUtil()
      {
      }
  
      public static void shutdownStream( final OutputStream output )
      {
          if( null == output ) return;
          
          try { output.close(); }
          catch( final IOException ioe ) {}
      }
      
      public static void shutdownStream( final InputStream input )
      {
          if( null == input ) return;
          
          try { input.close(); }
          catch( final IOException ioe ) {}
      }
  
      /**
       * Copy stream-data from source to destination.
       */
      public static void copy( final InputStream source, final OutputStream destination ) 
          throws IOException 
      {
          try
          {
              final BufferedInputStream input = new BufferedInputStream( source );
              final BufferedOutputStream output = new BufferedOutputStream( destination );
              
              final int BUFFER_SIZE = 1024 * 4;
              final byte[] buffer = new byte[ BUFFER_SIZE ];
              
              while( true )
              {
                  final int count = input.read( buffer, 0, BUFFER_SIZE );
                  if( -1 == count ) break;
                  
                  // write out those same bytes
                  output.write( buffer, 0, count );
              }
              
              //needed to flush cache
              output.flush();
          }
          finally
          {
              shutdownStream( source );
              shutdownStream( destination );
          }
      } 
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/MergedInputStreams.java
  
  Index: MergedInputStreams.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.IOException;
  import java.io.InputStream;
  
  /**
   * Merges multiple input streams into one.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class MergedInputStreams 
      extends InputStream 
  {
      protected final InputStream[]          m_streams;
      protected int                          m_index;
  
      public MergedInputStreams( final InputStream[] inputStreams )
      {
          super();
          m_streams = inputStreams;
      }
  
      public int read() 
          throws IOException
      {
          if( m_index >= m_streams.length ) return -1;
  
          int returnVal = m_streams[ m_index ].read();
  
          if( -1 == returnVal && (++m_index) < m_streams.length )
          {
              returnVal = m_streams[ m_index ].read();
          }
          
          return returnVal;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/io/ResettableFileInputStream.java
  
  Index: ResettableFileInputStream.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 file.
   */
  package org.apache.avalon.util.io;
  
  import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  /**
   * @author  Federico Barbieri <fede@apache.org>
   */
  public class ResettableFileInputStream 
      extends InputStream
  {
      protected static final int         DEFAULT_BUFFER_SIZE          = 1024;
  
      protected final String             m_filename;
      protected int                      m_bufferSize;
      protected InputStream              m_inputStream;
      protected long                     m_position;
      protected long                     m_mark;
      protected boolean                  m_isMarkSet;
  
      public ResettableFileInputStream( final File file )
          throws IOException 
      {
          this( file.getCanonicalPath() );
      }
      
      public ResettableFileInputStream( final String filename )
          throws IOException 
      {
          this( filename, DEFAULT_BUFFER_SIZE );
      }
      
      public ResettableFileInputStream( final String filename, final int bufferSize )
          throws IOException 
      {
          m_bufferSize = bufferSize;
          m_filename = filename;
          m_position = 0;
  
          m_inputStream = newStream();
      }
      
      public void mark( final int readLimit )
      {
          m_isMarkSet = true;
          m_mark = m_position;
          m_inputStream.mark( readLimit );
      }
      
      public boolean markSupported()
      {
          return true;
      }
      
      public void reset()
          throws IOException 
      {
          if( !m_isMarkSet )
          {
              throw new IOException( "Unmarked Stream" );
          }
          try 
          {
              m_inputStream.reset();
          } 
          catch( final IOException ioe )
          {
              try
              {
                  m_inputStream.close();
                  m_inputStream = newStream();
                  m_inputStream.skip( m_mark );
                  m_position = m_mark;
              } 
              catch( final Exception e )
              {
                  throw new IOException( "Cannot reset current Stream: " + e.getMessage() );
              }
          }
      }
  
      protected InputStream newStream()
          throws IOException
      {
          return new BufferedInputStream( new FileInputStream( m_filename ), m_bufferSize );
      }
  
      public int available()
          throws IOException
      {
          return m_inputStream.available();
      }
      
      public void close() throws IOException
      {
          m_inputStream.close();
      }
      
      public int read() throws IOException
      {
          m_position++;
          return m_inputStream.read();
      }
      
      public int read( final byte[] bytes, final int offset, final int length )
          throws IOException 
      {
          final int count = m_inputStream.read( bytes, offset, length );
          m_position += count;
          return count;
      }
      
      public long skip( final long count )
          throws IOException 
      {
          m_position += count;
          return m_inputStream.skip( count );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/AbstractPool.java
  
  Index: AbstractPool.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 file.
   */
  package org.apache.avalon.util.pool;
  
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.Initializable;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class AbstractPool
      implements Pool, Initializable
  {
      protected int                     m_count;
      protected Poolable[]              m_pool;
      protected ObjectFactory           m_factory;
      protected PoolController          m_controller;
      protected int                     m_maximum;
      protected int                     m_initial;
  
      public AbstractPool( final ObjectFactory factory,
                           final PoolController controller,
                           final int initial,
                           final int maximum )
      {
          m_count = 0;
          m_factory = factory;
          m_controller = controller;
          m_maximum = maximum;
          m_initial = initial;
      }
  
      public void init() 
          throws Exception
      {
          grow( m_maximum );
          fill( m_initial );
      }
  
      /**
       * Retrieve an object from pool.
       *
       * @return an object from Pool
       */
      public Poolable get() throws Exception
      {
          if( null == m_pool && null != m_controller )
          {
              final int increase = m_controller.grow();
              if( increase > 0 ) grow( increase );
          }
  
          if( 0 == m_count )
          {
              return m_factory.newInstance();
          }
  
          m_count--;
  
          final Poolable poolable = m_pool[ m_count ];
          m_pool[ m_count ] = null;
          return poolable;
      }
  
      /**
       * Place an object in pool.
       *
       * @param poolable the object to be placed in pool
       */
      public void put( final Poolable poolable )
      {
          if( poolable instanceof Recyclable )
          {
              ((Recyclable)poolable).recycle();
          }
  
          if(  m_pool.length == (m_count + 1) && null != m_controller )
          {
              final int decrease = m_controller.shrink();
              if( decrease > 0 ) shrink( decrease );
          }
  
          if ( m_pool.length > m_count + 1 )
          {
              m_pool[ m_count++ ] = poolable;
          }
      }
  
      /**
       * Return the total number of slots in Pool
       *
       * @return the total number of slots
       */
      public final int getCapacity()
      {
          return m_pool.length;
      }
  
      /**
       * Get the number of used slots in Pool
       *
       * @return the number of used slots
       */
      public final int getSize()
      {
          return m_count;
      }
  
      /**
       * This fills the pool to the size specified in parameter.
       */
      public final void fill( final int fillSize ) throws Exception
      {
          final int size = Math.min( m_pool.length, fillSize );
  
          for( int i = m_count; i < size; i++ )
          {
              m_pool[i] = m_factory.newInstance();
          }
  
          m_count = size;
      }
  
      /**
       * This fills the pool by the size specified in parameter.
       */
      public final void grow( final int increase )
      {
          if( null == m_pool )
          {
              m_pool = new Poolable[ increase ];
              return;
          }
  
          final Poolable[] poolables = new Poolable[ increase + m_pool.length ];
          System.arraycopy( m_pool, 0, poolables, 0, m_pool.length );
          m_pool = poolables;
      }
  
      /**
       * This shrinks the pool by parameter size.
       */
      public final void shrink( final int decrease )
      {
          final Poolable[] poolables = new Poolable[ m_pool.length - decrease ];
          System.arraycopy( m_pool, 0, poolables, 0, poolables.length );
          m_pool = poolables;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/DefaultObjectFactory.java
  
  Index: DefaultObjectFactory.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 file.
   */
  package org.apache.avalon.util.pool;
  
  import java.lang.reflect.Constructor;
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  
  /**
   * This is the default for factory that is used to create objects for Pool.
   *
   * It creates objects via reflection and constructor.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultObjectFactory
      implements ObjectFactory
  {
      protected Constructor            m_constructor;
      protected Object[]               m_arguements;
  
      public DefaultObjectFactory( final Constructor constructor, final Object[] arguements )
      {
          m_arguements = arguements;
          m_constructor = constructor;
      }
  
      public DefaultObjectFactory( final Class clazz, 
                                   final Class[] arguementClasses, 
                                   final Object[] arguements )
          throws NoSuchMethodException
      {
          this( clazz.getConstructor( arguementClasses ), arguements );
      }
  
      public DefaultObjectFactory( final Class clazz )
          throws NoSuchMethodException
      {
          this( clazz, null, null );
      }
  
      public Class getCreatedClass()
      {
          return m_constructor.getDeclaringClass();
      }
  
      public Poolable newInstance()
      {
          try
          {
              return (Poolable)m_constructor.newInstance( m_arguements );
          } 
          catch( final Exception e ) 
          {
              throw new Error( "Failed to instantiate the class " + 
                               m_constructor.getDeclaringClass().getName() + " due to " + e );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/DefaultPool.java
  
  Index: DefaultPool.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 file.
   */
  package org.apache.avalon.util.pool;
  
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultPool
      extends AbstractPool
  {
      public final static int           DEFAULT_POOL_SIZE           = 8;
  
      public DefaultPool( final ObjectFactory factory, 
                          final PoolController controller ) 
          throws Exception
      {
          super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
      }
  
      public DefaultPool( final ObjectFactory factory ) 
          throws Exception
      {
          this( factory, null );
      }
  
      public DefaultPool( final Class clazz, final int initial, final int maximum ) 
          throws NoSuchMethodException, Exception
      {
          super( new DefaultObjectFactory( clazz ), null, initial, maximum );
      }
  
      public DefaultPool( final Class clazz, final int initial ) 
          throws NoSuchMethodException, Exception
      {
          this( clazz, initial, initial );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/ObjectFactory.java
  
  Index: ObjectFactory.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 file.
   */
  package org.apache.avalon.util.pool;
  
  import org.apache.avalon.component.Component;
  import org.apache.avalon.Poolable;
  
  /**
   * This is the interface for factory that is used to create objects for Pool.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ObjectFactory 
      extends Component
  {
      Poolable newInstance() throws Exception;
      Class getCreatedClass();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/Pool.java
  
  Index: Pool.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 file.
   */
  package org.apache.avalon.util.pool;
  
  import org.apache.avalon.component.Component;
  import org.apache.avalon.Poolable;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@mad.scientist.com">Peter Donald</a>
   */
  public interface Pool 
      extends Component
  {
      Poolable get() throws Exception;
      void put( Poolable poolable );
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/PoolController.java
  
  Index: PoolController.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 file.
   */
  package org.apache.avalon.util.pool;
  
  /**
   * This is the interface you implement if you want to control how Pools capacity 
   * changes overtime.
   * 
   * It gets called everytime that a Pool tries to go below or above it's minimum or maximum.
   * 
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public interface PoolController
  {
      /**
       * Called when a Pool reaches it's minimum. 
       *
       * Return the number of elements to increase minimum and maximum by.
       *
       * @return the element increase
       */
      int grow();
  
      /**
       * Called when a pool reaches it's maximum.
       *
       * Returns the number of elements to decrease mi and max by.
       *
       * @return the element decrease
       */
      int shrink();
  }
  
  
  
  1.1                  jakarta-avalon/src/proposal-4.0/org/apache/avalon/util/pool/ThreadSafePool.java
  
  Index: ThreadSafePool.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 file.
   */
  package org.apache.avalon.util.pool;
  
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.ThreadSafe;
  
  /**
   * This is a implementation of  <code>Pool</code> that is thread safe.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ThreadSafePool
      extends AbstractPool
      implements ThreadSafe
  {
      public final static int           DEFAULT_POOL_SIZE           = 8;
  
      protected boolean                 m_blocking                  = false;
  
      public ThreadSafePool( final ObjectFactory factory, final PoolController controller )
          throws Exception 
      {
          super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
      }
  
      public ThreadSafePool( final ObjectFactory factory )
          throws Exception 
      {
          this( factory, null );
      }
  
      public ThreadSafePool( final ObjectFactory factory, 
                             final int initial, 
                             final int maximum  )
          throws Exception 
      {
          super( factory, null, initial, maximum );
      }
  
      public ThreadSafePool( final ObjectFactory factory, final int initial )
          throws Exception 
      {
          this( factory, initial, initial );
      }
  
      public ThreadSafePool( final Class clazz, final int initial, final int maximum ) 
          throws NoSuchMethodException, Exception
      {
          this( new DefaultObjectFactory( clazz ), initial, maximum );
      }
  
      public ThreadSafePool( final Class clazz, final int initial ) 
          throws NoSuchMethodException, Exception
      {
          this( clazz, initial, initial );
      }
  
      public final boolean isBlocking() 
      {
          return m_blocking;
      }
  
      /**
       * Set whether this pool is blocking. 
       * 
       * If this pool is blocking and empties the Pool then the thread will block until
       * an object is placed back in the pool. This has to be used with care as an errant
       * thread who never does a put will force blocked clients to wait forever.
       *
       * @param blocking a boolean indicating if it is blocking or not
       */
      public final void setBlocking( final boolean blocking ) 
      {
          m_blocking = blocking;
      }
  
      /**
       * Retrieve an object from pool.
       *
       * @return an object from Pool
       */
      public final Poolable get() throws Exception 
      {
          //Require this or else the wait later will cause 
          final Poolable[] pool = m_pool;
  
          synchronized( pool )
          {
              if( 0 == m_count )
              {
                  if( !m_blocking ) 
                  {
                      return m_factory.newInstance();
                  }
                  else
                  {
                      while( 0 == m_count )
                      {
                          try { pool.wait(); }
                          catch( final InterruptedException ie ) { }
                      }
                  }
              }
  
              m_count--;
              final Poolable poolable = m_pool[ m_count ];
              m_pool[ m_count ] = null;
              return poolable;
          }
      }
  
      /**
       * Place an object in pool.
       *
       * @param poolable the object to be placed in pool
       */
      public final void put( final Poolable poolable ) 
      {
          final Poolable[] pool = m_pool;
  
          synchronized( pool )
          {
              super.put( poolable );
  
              //if someone was waiting on the old pool then we have to notify them
              pool.notifyAll();
          }
      }
  }
  
  
  

Mime
View raw message