avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-avalon/src/test/org/apache/excalibur/pool/test PoolProfile.java
Date Tue, 17 Apr 2001 03:07:54 GMT
donaldp     01/04/16 20:07:54

  Modified:    .        build.xml
               proposal/4.0 build.sh
               src/java/org/apache/avalon/camelot AbstractDeployer.java
                        CamelotUtil.java
               src/java/org/apache/avalon/component
                        DefaultComponentFactory.java
                        DefaultComponentPool.java
                        DefaultComponentPoolController.java
  Added:       src/java/org/apache/excalibur/cli AbstractParserControl.java
                        CLArgsParser.java CLOption.java
                        CLOptionDescriptor.java CLUtil.java
                        ParserControl.java
               src/java/org/apache/excalibur/collections
                        ArrayEnumeration.java ArrayStack.java
                        BinaryHeap.java CircularBuffer.java
                        IteratorEnumeration.java ListUtils.java
                        PriorityQueue.java SynchronizedPriorityQueue.java
               src/java/org/apache/excalibur/concurrent
                        ConditionalEvent.java DjikstraSemaphore.java
                        Lock.java ThreadBarrier.java
               src/java/org/apache/excalibur/datasource
                        DataSourceComponent.java J2eeDataSource.java
                        JdbcConnection.java JdbcConnectionPool.java
                        JdbcDataSource.java
               src/java/org/apache/excalibur/i18n ResourceGroup.java
                        XMLResourceBundle.java
                        XMLResourceBundleFactory.java XPathAPI.java
               src/java/org/apache/excalibur/io AndFileFilter.java
                        DirectoryFileFilter.java ExtensionFileFilter.java
                        FileUtil.java IOUtil.java InvertedFileFilter.java
                        OrFileFilter.java
               src/java/org/apache/excalibur/pool AbstractPool.java
                        DefaultObjectFactory.java DefaultPool.java
                        HardResourceLimitingPool.java ObjectFactory.java
                        Pool.java PoolController.java Resizable.java
                        SingleThreadedPool.java
                        SoftResourceLimitingPool.java
               src/java/org/apache/excalibur/thread DefaultThreadPool.java
                        ThreadContext.java ThreadPool.java
                        WorkerThread.java
               src/test/org/apache/excalibur/cli/test ClutilTestlet.java
               src/test/org/apache/excalibur/collections/test
                        BinaryHeapTestlet.java
               src/test/org/apache/excalibur/datasource/test
                        DataSourceTestlet.java
               src/test/org/apache/excalibur/io/test FileUtilTestlet.java
               src/test/org/apache/excalibur/pool/test PoolProfile.java
  Removed:     src/java/org/apache/avalon/util/cli
                        AbstractParserControl.java CLArgsParser.java
                        CLOption.java CLOptionDescriptor.java CLUtil.java
                        ParserControl.java
               src/java/org/apache/avalon/util/collections
                        ArrayEnumeration.java ArrayStack.java
                        BinaryHeap.java CircularBuffer.java
                        IteratorEnumeration.java ListUtils.java
                        PriorityQueue.java SynchronizedPriorityQueue.java
               src/java/org/apache/avalon/util/concurrent
                        ConditionalEvent.java DjikstraSemaphore.java
                        Lock.java ThreadBarrier.java
               src/java/org/apache/avalon/util/datasource
                        DataSourceComponent.java J2eeDataSource.java
                        JdbcConnection.java JdbcConnectionPool.java
                        JdbcDataSource.java
               src/java/org/apache/avalon/util/i18n ResourceGroup.java
                        XMLResourceBundle.java
                        XMLResourceBundleFactory.java XPathAPI.java
               src/java/org/apache/avalon/util/io AndFileFilter.java
                        DirectoryFileFilter.java ExtensionFileFilter.java
                        FileUtil.java IOUtil.java InvertedFileFilter.java
                        OrFileFilter.java
               src/java/org/apache/avalon/util/pool AbstractPool.java
                        DefaultObjectFactory.java DefaultPool.java
                        HardResourceLimitingPool.java ObjectFactory.java
                        Pool.java PoolController.java Resizable.java
                        SingleThreadedPool.java
                        SoftResourceLimitingPool.java
               src/java/org/apache/avalon/util/thread
                        DefaultThreadPool.java ThreadContext.java
                        ThreadManager.java ThreadPool.java
                        WorkerThread.java
               src/test/org/apache/avalon/util/cli/test ClutilTestlet.java
               src/test/org/apache/avalon/util/collections/test
                        BinaryHeapTestlet.java
               src/test/org/apache/avalon/util/datasource/test
                        DataSourceTestlet.java
               src/test/org/apache/avalon/util/io/test FileUtilTestlet.java
               src/test/org/apache/avalon/util/pool/test PoolProfile.java
  Log:
  Updated to excalibur hierarchy
  
  Revision  Changes    Path
  1.28      +1 -1      jakarta-avalon/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/build.xml,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- build.xml	2001/04/11 13:21:28	1.27
  +++ build.xml	2001/04/17 03:07:24	1.28
  @@ -400,7 +400,7 @@
   
       <mkdir dir="${build.lib}"/>
       <jar jarfile="${build.lib}/avalonapi.jar" basedir="${build.classes}">
  -      <include name="org/apache/avalon/**"/>
  +      <include name="org/apache/**"/>
         <exclude name="**/test/*"/>
       </jar>
     </target>
  
  
  
  1.2       +5 -5      jakarta-avalon/proposal/4.0/build.sh
  
  Index: build.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/build.sh,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- build.sh	2001/02/25 14:29:41	1.1
  +++ build.sh	2001/04/17 03:07:25	1.2
  @@ -4,11 +4,11 @@
   echo "Avalon Build System"
   echo "-------------------"
   
  -export CLASSPATH=`echo $PWD/lib/*.jar | tr ' ' ':'`
  +chmod u+x ../../tools/bin/antRun
  +chmod u+x ../../tools/bin/ant
   
  -chmod u+x ./tools/bin/antRun
  -chmod u+x ./tools/bin/ant
  -
   unset ANT_HOME
  +
  +export CLASSPATH=../../lib/xerces.jar
   
  -$PWD/tools/bin/ant -logger org.apache.tools.ant.NoBannerLogger -emacs $@ 
  +../../tools/bin/ant -logger org.apache.tools.ant.NoBannerLogger -emacs $@ 
  
  
  
  1.2       +1 -1      jakarta-avalon/src/java/org/apache/avalon/camelot/AbstractDeployer.java
  
  Index: AbstractDeployer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/camelot/AbstractDeployer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractDeployer.java	2001/02/24 04:00:36	1.1
  +++ AbstractDeployer.java	2001/04/17 03:07:25	1.2
  @@ -17,7 +17,7 @@
   import org.apache.avalon.AbstractLoggable;
   import org.apache.avalon.Component;
   import org.apache.avalon.ComponentNotFoundException;
  -import org.apache.avalon.util.io.FileUtil;
  +import org.apache.excalibur.io.FileUtil;
   import org.apache.log.Logger;
   
   /**
  
  
  
  1.4       +2 -2      jakarta-avalon/src/java/org/apache/avalon/camelot/CamelotUtil.java
  
  Index: CamelotUtil.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/camelot/CamelotUtil.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CamelotUtil.java	2001/04/15 00:26:18	1.3
  +++ CamelotUtil.java	2001/04/17 03:07:26	1.4
  @@ -13,8 +13,8 @@
   import java.net.MalformedURLException;
   import java.util.Iterator;
   import org.apache.avalon.Component;
  -import org.apache.avalon.util.io.DirectoryFileFilter;
  -import org.apache.avalon.util.io.ExtensionFileFilter;
  +import org.apache.excalibur.io.DirectoryFileFilter;
  +import org.apache.excalibur.io.ExtensionFileFilter;
   
   /**
    * Utility methods for Camelot related facilities.
  
  
  
  1.4       +3 -3      jakarta-avalon/src/java/org/apache/avalon/component/DefaultComponentFactory.java
  
  Index: DefaultComponentFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/component/DefaultComponentFactory.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultComponentFactory.java	2001/04/11 04:18:09	1.3
  +++ DefaultComponentFactory.java	2001/04/17 03:07:26	1.4
  @@ -21,15 +21,15 @@
   import org.apache.avalon.ThreadSafe;
   import org.apache.avalon.configuration.Configurable;
   import org.apache.avalon.configuration.Configuration;
  -import org.apache.avalon.util.pool.ObjectFactory;
  -import org.apache.avalon.util.pool.Pool;
  +import org.apache.excalibur.pool.ObjectFactory;
  +import org.apache.excalibur.pool.Pool;
   
   /**
    * Factory for Avalon components.
    *
    * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
    * @author <a href="mailto:paul@luminas.co.uk">Paul Russell</a>
  - * @version CVS $Revision: 1.3 $ $Date: 2001/04/11 04:18:09 $
  + * @version CVS $Revision: 1.4 $ $Date: 2001/04/17 03:07:26 $
    */
   public class DefaultComponentFactory 
       extends AbstractLoggable 
  
  
  
  1.4       +2 -2      jakarta-avalon/src/java/org/apache/avalon/component/DefaultComponentPool.java
  
  Index: DefaultComponentPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/component/DefaultComponentPool.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultComponentPool.java	2001/04/11 04:18:10	1.3
  +++ DefaultComponentPool.java	2001/04/17 03:07:27	1.4
  @@ -16,8 +16,8 @@
   import org.apache.avalon.Recyclable;
   import org.apache.avalon.ThreadSafe;
   import org.apache.avalon.util.Lock;
  -import org.apache.avalon.util.pool.ObjectFactory;
  -import org.apache.avalon.util.pool.Pool;
  +import org.apache.excalibur.pool.ObjectFactory;
  +import org.apache.excalibur.pool.Pool;
   
   /**
    * This is a implementation of <code>Pool</code> for SitemapComponents
  
  
  
  1.3       +2 -2      jakarta-avalon/src/java/org/apache/avalon/component/DefaultComponentPoolController.java
  
  Index: DefaultComponentPoolController.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/component/DefaultComponentPoolController.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DefaultComponentPoolController.java	2001/04/11 04:18:10	1.2
  +++ DefaultComponentPoolController.java	2001/04/17 03:07:27	1.3
  @@ -13,14 +13,14 @@
   import org.apache.avalon.ThreadSafe;
   import org.apache.avalon.configuration.Configurable;
   import org.apache.avalon.configuration.Configuration;
  -import org.apache.avalon.util.pool.PoolController;
  +import org.apache.excalibur.pool.PoolController;
   
   /**
    * This class holds a sitemap component which is not specially marked as having
    * a spezial behaviour or treatment.
    *
    * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
  - * @version CVS $Revision: 1.2 $ $Date: 2001/04/11 04:18:10 $
  + * @version CVS $Revision: 1.3 $ $Date: 2001/04/17 03:07:27 $
    */
   public class DefaultComponentPoolController 
       implements PoolController, ThreadSafe, Component
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  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>
   * @author <a href="mailto:ram.chidambaram@telus.com">Ram Chidambaram</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()
      {
          //+1 as element 0 is noop
          return ( m_elements.length == m_size+1 );
      }
  
      /**
       * 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-- ];
  
          //set the unused element to 'null' so that the garbage collector
          //can free the object if not used anywhere else.(remove reference)
          m_elements[ m_size + 1 ] = null;
  
          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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  /**
   *
   * @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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  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/java/org/apache/excalibur/collections/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.excalibur.collections;
  
  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/java/org/apache/excalibur/collections/SynchronizedPriorityQueue.java
  
  Index: SynchronizedPriorityQueue.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.excalibur.collections;
  
  import java.util.NoSuchElementException;
  
  /**
   * A thread safe version of the PriorityQueue.
   * Provides synchronized wrapper methods for all the methods
   * defined in the PriorityQueue interface.
   *
   * @author <a href="mailto:ram.chidambaram@telus.com">Ram Chidambaram</a>
   */
  public final class SynchronizedPriorityQueue
      implements PriorityQueue
  {
      protected final PriorityQueue   m_priorityQueue;
  
      public SynchronizedPriorityQueue( final PriorityQueue priorityQueue )
      {
          m_priorityQueue = priorityQueue;
      }
  
      /**
       * Clear all elements from queue.
       */
      public synchronized void clear()
      {
          m_priorityQueue.clear();
      }
  
      /**
       * Test if queue is empty.
       *
       * @return true if queue is empty else false.
       */
      public synchronized boolean isEmpty()
      {
          return m_priorityQueue.isEmpty();
      }
  
      /**
       * Insert an element into queue.
       *
       * @param element the element to be inserted
       */
      public synchronized void insert( final Comparable element )
      {
          m_priorityQueue.insert( 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 synchronized Comparable peek() throws NoSuchElementException
      {
          return m_priorityQueue.peek();
      }
  
      /**
       * Return element on top of heap and remove it.
       *
       * @return the element at top of heap
       * @exception NoSuchElementException if isEmpty() == true
       */
      public synchronized Comparable pop() throws NoSuchElementException
      {
          return m_priorityQueue.pop();
      }
  
      public synchronized String toString()
      {
          return m_priorityQueue.toString();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/concurrent/ConditionalEvent.java
  
  Index: ConditionalEvent.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.excalibur.concurrent;
  
  /**
   * This class implements a POSIX style "Event" object. The difference
   * between the ConditionalEvent and the java wait()/notify() technique is in
   * handling of event state. If a ConditionalEvent is signalled, a thread
   * that subsequently waits on it is immediately released. In case of auto
   * reset EventObjects, the object resets (unsignalled) itself as soon as it
   * is signalled and waiting thread(s) are released (based on whether signal()
   * or signalAll() was called).
   *
   * @author <a href="mailto:kranga@sapient.com">Karthik Rangaraju</a>
   */
  public class ConditionalEvent
  {
      private boolean m_state = false;
      private boolean m_autoReset = false;
  
      // TODO: Need to add methods that block until a specified time and
      // return (though in real-life, I've never known what to do if a thread
      // timesout other than call the method again)!
  
      /**
       * Creates a manual reset ConditionalEvent with a specified initial state
       * @param pInitialState Sets the initial state of the ConditionalEvent.
       * Signalled if pInitialState is true, unsignalled otherwise.
       */
      public ConditionalEvent( boolean initialState )
      {
          m_state = initialState;
      }
  
      /**
       * Creates a ConditionalEvent with the defined initial state
       * @param pInitialState if true, the ConditionalEvent is signalled when
       * created.
       * @param pAutoReset if true creates an auto-reset ConditionalEvent
       */
      public ConditionalEvent( boolean initialState, boolean autoReset )
      {
          m_state = initialState;
          m_autoReset = autoReset;
      }
  
      /**
       * Checks if the event is signalled. Does not block on the operation
       * @return true is event is signalled, false otherwise. Does not reset
       * an autoreset event
       */
      public boolean isSignalled()
      {
          return m_state;
      }
  
      /**
       * Signals the event. A single thread blocked on waitForSignal() is released
       * @see #signalAll()
       * @see #waitForSignal()
       */
      public void signal()
      {
          synchronized ( this )
          {
              m_state = true;
              notify();
          }
      }
  
      /**
       * Current implementation only works with manual reset events. Releases
       * all threads blocked on waitForSignal()
       * @see #waitForSignal()
       */
      public void signalAll()
      {
          synchronized ( this )
          {
              m_state = true;
              notifyAll();
          }
      }
  
      /**
       * Resets the event to an unsignalled state
       */
      public void reset()
      {
          synchronized ( this )
          {
              m_state = false;
          }
      }
  
      /**
       * If the event is signalled, this method returns immediately resetting the
       * signal, otherwise it blocks until the event is signalled.
       * @throws InterruptedException if the thread is interrupted when blocked
       */
      public void waitForSignal()
          throws InterruptedException
      {
          synchronized ( this )
          {
              while ( m_state == false )
              {
                  wait();
              }
              if ( m_autoReset == true )
              {
                  m_state = false;
              }
          }
      }
  
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/concurrent/DjikstraSemaphore.java
  
  Index: DjikstraSemaphore.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.excalibur.concurrent;
  
  /**
   * Also called counting semaphores, Djikstra semaphores are used to control
   * access to a set of resources. A Djikstra semaphore has a count associated
   * with it and each acquire() call reduces the count. A thread that tries to
   * acquire() a Djikstra semaphore with a zero count blocks until someone else
   * calls release() thus increasing the count.
   *
   * @author <a href="mailto:kranga@sapient.com">Karthik Rangaraju</a>
   */
  public class DjikstraSemaphore
  {
      private int m_count;
      private int m_maxCount;
      private Object m_starvationLock = new Object();
  
      /**
       * Creates a Djikstra semaphore with the specified max count and initial
       * count set to the max count (all resources released)
       * @param pMaxCount is the max semaphores that can be acquired
       */
      public DjikstraSemaphore( int maxCount )
      {
          this( maxCount, maxCount);
      }
  
      /**
       * Creates a Djikstra semaphore with the specified max count and an initial
       * count of acquire() operations that are assumed to have already been
       * performed.
       * @param pMaxCount is the max semaphores that can be acquired
       * @pInitialCount is the current count (setting it to zero means all
       * semaphores have already been acquired). 0 <= pInitialCount <= pMaxCount
       */
      public DjikstraSemaphore( int maxCount, int initialCount )
      {
          m_count = initialCount;
          m_maxCount = maxCount;
      }
  
      /**
       * If the count is non-zero, acquires a semaphore and decrements the count
       * by 1, otherwise blocks until a release() is executed by some other thread.
       * @throws InterruptedException is the thread is interrupted when blocked
       * @see #tryAcquire()
       * @see #acquireAll()
       */
      public void acquire()
          throws InterruptedException
      {
          synchronized ( this )
          {
              // Using a spin lock to take care of rogue threads that can enter
              // before a thread that has exited the wait state acquires the monitor
              while ( m_count == 0 )
              {
                  wait();
              }
              m_count--;
              synchronized ( m_starvationLock )
              {
                  if ( m_count == 0 )
                  {
                      m_starvationLock.notify();
                  }
              }
          }
      }
  
      /**
       * Non-blocking version of acquire().
       * @return true if semaphore was acquired (count is decremented by 1), false
       * otherwise
       */
      public boolean tryAcquire()
      {
          synchronized ( this )
          {
              if ( m_count != 0 )
              {
                  m_count--;
                  synchronized ( m_starvationLock )
                  {
                      if ( m_count == 0 )
                      {
                          m_starvationLock.notify();
                      }
                  }
                  return true;
              }
              else
              {
                  return false;
              }
          }
      }
  
      /**
       * Releases a previously acquires semaphore and increments the count by one.
       * Does not check if the thread releasing the semaphore was a thread that
       * acquired the semaphore previously. If more releases are performed than
       * acquires, the count is not increased beyond the max count specified during
       * construction.
       * @see #release( int pCount )
       * @see #releaseAll()
       */
      public void release()
      {
          synchronized ( this )
          {
              m_count++;
              if ( m_count > m_maxCount )
              {
                  m_count = m_maxCount;
              }
              notify();
          }
      }
  
      /**
       * Same as release() except that the count is increased by pCount instead
       * of 1. The resulting count is capped at max count specified in the
       * constructor
       * @param pCount is the amount by which the counter should be incremented
       * @see #release()
       */
      public void release(int count)
      {
          synchronized ( this )
          {
              if ( m_count + count > m_maxCount )
              {
                  m_count = m_maxCount;
              }
              else
              {
                  m_count += count;
              }
              notifyAll();
          }
      }
  
      /**
       * Tries to acquire all the semaphores thus bringing the count to zero.
       * @throws InterruptedException if the thread is interrupted when blocked on
       * this call
       * @see #acquire()
       * @see #releaseAll()
       */
      public void acquireAll()
          throws InterruptedException
      {
          synchronized ( this )
          {
              for ( int index = 0; index < m_maxCount; index++ )
              {
                  acquire();
              }
          }
      }
  
      /**
       * Releases all semaphores setting the count to max count.
       * Warning: If this method is called by a thread that did not make a
       * corresponding acquireAll() call, then you better know what you are doing!
       * @see #acquireAll()
       */
      public void releaseAll()
      {
          synchronized ( this )
          {
              release( m_maxCount );
              notifyAll();
          }
      }
  
      /**
       * This method blocks the calling thread until the count drops to zero.
       * The method is not stateful and hence a drop to zero will not be recognized
       * if a release happens before this call. You can use this method to implement
       * threads that dynamically increase the resource pool or that log occurences
       * of resource starvation. Also called a reverse-sensing semaphore
       * @throws InterruptedException if the thread is interrupted while waiting
       */
      public void starvationCheck()
          throws InterruptedException
      {
          synchronized ( m_starvationLock )
          {
              if ( m_count != 0 )
              {
                  m_starvationLock.wait();
              }
          }
      }
  }
  
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/concurrent/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.excalibur.concurrent;
  
  /**
   * A class to perform a blocking lock.
   *
   * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public class Lock
  {
      /**
       * Is this locked?.
       */
      private boolean m_isLocked;
  
      /**
       * Locks.
       */
      public final void lock()
          throws InterruptedException
      {
          synchronized( this )
          {
              while( m_isLocked ) wait();
              m_isLocked = true;
          }
      }
  
      /**
       * Unlocks.
       */
      public final void unlock()
      {
          synchronized( this )
          {
              m_isLocked = false;
              notify();
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/concurrent/ThreadBarrier.java
  
  Index: ThreadBarrier.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.excalibur.concurrent;
  
  /**
   * A thread barrier blocks all threads hitting it until a pre-defined number
   * of threads arrive at the barrier. This is useful for implementing release
   * consistent concurrency where you don't want to take the performance penalty
   * of providing mutual exclusion to shared resources
   *
   * @author <a href="mailto:kranga@sapient.com">Karthik Rangaraju</a>
   */
  public class ThreadBarrier
  {
      private int m_threshold;
      private int m_count;
  
      /**
       * Initializes a thread barrier object with a given thread count
       * @param pCount is the number of threads that need to block on
       * barrierSynchronize() before they will be allowed to pass through
       * @see #barrierSynchronize()
       */
      public ThreadBarrier( int count )
      {
          m_threshold = count;
          m_count = 0;
      }
  
      /**
       * This method blocks all threads calling it until the threshold number of
       * threads have called it. It then releases all threads blocked by it
       * @throws InterruptedException if any thread blocked during the call is
       * interrupted
       */
      public void barrierSynchronize()
          throws InterruptedException
      {
          synchronized ( this )
          {
              if ( m_count != m_threshold - 1 )
              {
                  m_count++;
                  wait();
              }
              else
              {
                  m_count = 0;
                  notifyAll();
              }
          }
      }
  
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.datasource;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import org.apache.avalon.Component;
  import org.apache.avalon.ThreadSafe;
  import org.apache.avalon.configuration.Configurable;
  
  /**
   * The standard interface for DataSources in Avalon.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/04/17 03:07:46 $
   */
  public interface DataSourceComponent
      extends Component, Configurable, ThreadSafe
  {
      /**
       * Gets the Connection to the database
       */
      Connection getConnection()
          throws SQLException;
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.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.AbstractLoggable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  
  /**
   * 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/04/17 03:07: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/java/org/apache/excalibur/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.excalibur.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.excalibur.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/04/17 03:07: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
      {
          clearWarnings();
          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/java/org/apache/excalibur/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.excalibur.datasource;
  
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.SQLException;
  import java.util.ArrayList;
  import java.util.Date;
  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.Lock;
  import org.apache.excalibur.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/04/17 03:07: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_max;
      private final boolean          m_autoCommit;
      private List                   m_active        = new ArrayList();
      private List                   m_ready         = new ArrayList();
      private boolean                m_initialized   = false;
      private boolean                m_disposed      = false;
      private Lock                   m_mutex         = new Lock();
      private Thread                 m_initThread;
  
      public JdbcConnectionPool( final String url,
                                 final String username,
                                 final String password,
                                 final int max,
                                 final boolean autoCommit )
      {
          m_dburl = url;
          m_username = username;
          m_password = password;
  
          if( 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 = 1;
          }
          else
          {
              m_max = max;
          }
  
          m_autoCommit = autoCommit;
      }
  
      public void init()
      {
          m_initThread = new Thread( this );
          m_initThread.start();
      }
  
      private JdbcConnection createJdbcConnection()
          throws SQLException
      {
          JdbcConnection connection = null;
  
          if( null == m_username )
          {
              connection = new JdbcConnection( DriverManager.getConnection( m_dburl ), this );
              connection.setLogger(getLogger());
          }
          else
          {
              connection =
                  new JdbcConnection( DriverManager.getConnection( m_dburl,
                                                                   m_username,
                                                                   m_password ),
                                      this);
              connection.setLogger(getLogger());
          }
  
          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
      {
          if (! m_initialized)
          {
              if (m_initThread == null)
              {
                  throw new IllegalStateException("You cannot get a Connection before the pool is initialized");
              }
              else
              {
                  m_initThread.join();
              }
          }
  
          if (m_disposed)
          {
              throw new IllegalStateException("You cannot get a Connection after the pool is disposed");
          }
  
          Poolable obj = null;
  
          try {
              this.m_mutex.lock();
              final int size;
  
              if( 0 == m_ready.size() )
              {
                  if (m_active.size() < m_max)
                  {
                      obj = this.createJdbcConnection();
  
                      m_active.add(obj);
                  }
                  else
                  {
                      throw new SQLException("There are no more Connections available");
                  }
              }
              else
              {
                  obj = (Poolable)m_ready.remove( 0 );
  
                  m_active.add( obj );
              }
          } catch (Exception e) {
              getLogger().debug("JdbcConnectionPool.get()", e);
          } finally {
              this.m_mutex.unlock();
          }
  
          if (((Connection)obj).getAutoCommit() != m_autoCommit) {
              ((Connection)obj).setAutoCommit(m_autoCommit);
          }
  
          getLogger().debug( "JdbcConnection '" + m_dburl +
                             "' has been requested from pool." );
  
          return obj;
      }
  
      public void put( final Poolable obj )
      {
          if (! m_initialized)
          {
              throw new IllegalStateException("You cannot return an object to an uninitialized pool");
          }
  
          try {
              this.m_mutex.lock();
              m_active.remove( obj );
  
              if(! m_disposed)
              {
                  JdbcConnection connection = (JdbcConnection) obj;
  
                  if (connection.isClosed()) {
                      getLogger().warn("Connection was closed by server, attempting to create a new one in its stead.");
                      connection.recycle();
                      connection = this.createJdbcConnection();
                  }
  
                  m_ready.add( connection );
              } else {
                  recycle((Recyclable) obj);
              }
          } catch (Exception e) {
              getLogger().warn("Error returning connection to pool", e);
          } finally {
              this.m_mutex.unlock();
          }
  
          getLogger().debug( "JdbcConnection '" + m_dburl + "' has been returned to the pool." );
      }
  
      public void run()
      {
          try {
              this.m_mutex.lock();
              for (int i = 0; i < m_max; i++)
              {
                  try {
                      m_ready.add( createJdbcConnection() );
                  } catch (SQLException se) {
                      getLogger().error( "Could not create connection to database", se );
                  }
              }
  
              if (m_ready.size() > 0) {
                  m_initialized = true;
              }
          } catch (Exception e) {
              getLogger().debug("JdbcConnectionPool.run()", e);
          } finally {
              this.m_mutex.unlock();
          }
      }
  
      public void dispose()
      {
          try {
              this.m_mutex.lock();
              m_disposed = true;
  
              while( ! m_ready.isEmpty() )
              {
                  recycle( (Recyclable)m_ready.remove( 0 ) );
              }
          } catch (Exception e) {
              getLogger().debug("JdbcConnectionPool.dispose()", e);
          } finally {
              this.m_mutex.unlock();
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.datasource;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  
  /**
   * 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/04/17 03:07: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 max = controler.getAttributeAsInt( "max", 3 );
              final boolean autoCommit = configuration.getChild("auto-commit").getValueAsBoolean(true);
  
              m_pool = new JdbcConnectionPool( dburl, user, passwd, max, autoCommit );
              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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.i18n;
  
  import java.io.IOException;
  import java.lang.ref.SoftReference;
  import java.util.Hashtable;
  import java.util.Locale;
  import java.util.MissingResourceException;
  import org.apache.xalan.xpath.XObject;
  import org.apache.xalan.xpath.XPath;
  import org.apache.xalan.xpath.XPathProcessorImpl;
  import org.apache.xalan.xpath.XPathSupport;
  import org.apache.xalan.xpath.xml.PrefixResolverDefault;
  import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
  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;
  
  /**
   * @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/04/17 03:07:47 donaldp Exp $
   */
  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/java/org/apache/excalibur/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.excalibur.i18n;
  
  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;
  
  /**
   * @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/04/17 03:07:47 donaldp Exp $
   */
  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/java/org/apache/excalibur/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.excalibur.i18n;
  
  import org.apache.xalan.xpath.XObject;
  import org.apache.xalan.xpath.XPath;
  import org.apache.xalan.xpath.XPathProcessorImpl;
  import org.apache.xalan.xpath.XPathSupport;
  import org.apache.xalan.xpath.xml.PrefixResolverDefault;
  import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
  import org.w3c.dom.Document;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.xml.sax.SAXException;
  
  /**
   * 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>
   * @version $Id: XPathAPI.java,v 1.1 2001/04/17 03:07:47 donaldp 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.
       */
      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.
       */
      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/java/org/apache/excalibur/io/AndFileFilter.java
  
  Index: AndFileFilter.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.excalibur.io;
  
  import java.io.File;
  import java.io.FilenameFilter;
  
  /**
   * This takes two file fiters as input. Accepts a selection only if it is
   * accpetable to both the input filters
   *
   * @author  Harmeet Bedi <harmeet@kodemuse.com>
   */
  public class AndFileFilter
      implements FilenameFilter
  {
      private final FilenameFilter m_filter1;
      private final FilenameFilter m_filter2;
  
      public AndFileFilter( FilenameFilter filter1, FilenameFilter filter2 )
      {
          m_filter1 = filter1;
          m_filter2 = filter2;
      }
  
      public boolean accept( final File file, final String name )
      {
          return m_filter1.accept( file, name ) && m_filter2.accept( file, name );
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.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 new File( file, name ).isDirectory();
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/io/InvertedFileFilter.java
  
  Index: InvertedFileFilter.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.excalibur.io;
  
  import java.io.File;
  import java.io.FilenameFilter;
  
  /**
   * This takes a file filter as input and inverts the selection.
   * This is used in retrieving files that are not accepted by a filter.
   *
   * @author  Harmeet Bedi <harmeet@kodemuse.com>
   */
  public class InvertedFileFilter 
      implements FilenameFilter
  {
      private final FilenameFilter m_originalFilter;
  
      public InvertedFileFilter( final FilenameFilter originalFilter )
      {
          m_originalFilter = originalFilter;
      }
  
      public boolean accept( final File file, final String name )
      {
          return !m_originalFilter.accept( file, name );
      }
  }
  
  
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/io/OrFileFilter.java
  
  Index: OrFileFilter.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.excalibur.io;
  
  import java.io.File;
  import java.io.FilenameFilter;
  
  /**
   * This takes two file fiters as input. Accepts a selection if it is
   * accpetable to either input filter
   *
   * @author  Harmeet Bedi <harmeet@kodemuse.com>
   */
  public class OrFileFilter
      implements FilenameFilter
  {
      private final FilenameFilter m_filter1;
      private final FilenameFilter m_filter2;
  
      public OrFileFilter( final FilenameFilter filter1, final FilenameFilter filter2 )
      {
          m_filter1 = filter1;
          m_filter2 = filter2;
      }
  
      public boolean accept( final File file, final String name )
      {
          return m_filter1.accept( file, name ) || m_filter2.accept( file, name );
      }
  }
  
  
  
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.pool;
  
  import java.util.Stack;
  import java.util.Vector;
  import org.apache.avalon.AbstractLoggable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.ThreadSafe;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public class AbstractPool
      extends AbstractLoggable
      implements Pool, ThreadSafe
  {
      protected final ObjectFactory  m_factory;
      protected final int            m_min;
      protected int                  m_max;
      protected int                  m_currentCount  = 0;
      protected Vector               m_active        = new Vector();
      protected Stack                m_ready         = new Stack();
  
      /**
       * Create an AbstractPool.  The pool requires a factory, and can
       * optionally have a controller.
       */
      public AbstractPool( final ObjectFactory factory,
                           final int min,
                           final int max ) throws Exception
      {
          m_factory = factory;
          int t_max = max;
          int t_min = min;
  
          if( min < 0 )
          {
              if( null != getLogger() )
              {
                  getLogger().warn( "Minumum number of poolables specified is " +
                                    "less than 0, using 0" );
              }
  
              t_min = 0;
          }
          else
          {
              t_min = min;
          }
  
          if( ( max < min ) || ( max < 1 ) )
          {
              if( null != getLogger() )
              {
                  getLogger().warn( "Maximum number of poolables specified must be at " +
                                    "least 1 and must be greater than the minumum number " +
                                    "of connections" );
              }
              t_max = ( min > 1 ) ? min : 1;
          }
          else
          {
              t_max = max;
          }
  
          m_max = t_max;
          m_min = t_min;
  
          if( !(this instanceof Initializable) )
          {
              init();
          }
      }
  
      protected void init()
          throws Exception
      {
          for( int i = 0; i < m_min; i++ )
          {
              m_ready.push( m_factory.newInstance() );
              m_currentCount++;
          }
      }
  
      public int size() {
          int count = this.m_currentCount;
          return count;
      }
  
      public synchronized Poolable get()
          throws Exception
      {
          Poolable obj = null;
  
          if( 0 == m_ready.size() )
          {
              obj = (Poolable)m_factory.newInstance();
              m_currentCount++;
          }
          else
          {
              obj = (Poolable)m_ready.pop();
          }
  
          m_active.addElement( obj );
  
          if( null != getLogger() )
          {
              getLogger().debug( m_factory.getCreatedClass().getName() + ": requested from the pool." );
          }
  
          return obj;
      }
  
      public synchronized void put( final Poolable obj )
      {
          m_active.removeElement( obj );
          m_ready.push( obj );
  
          if( null != getLogger() )
          {
              getLogger().debug( m_factory.getCreatedClass().getName() + ": returned to the pool." );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.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 Object 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 );
          }
      }
  
      public void decommission(Object object)
      {
          object = null;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.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 SingleThreadedPool
  {
      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/java/org/apache/excalibur/pool/HardResourceLimitingPool.java
  
  Index: HardResourceLimitingPool.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.excalibur.pool;
  
  import org.apache.avalon.Initializable;
  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 HardResourceLimitingPool
      extends SoftResourceLimitingPool
      implements ThreadSafe, Initializable
  {
      public final static int           DEFAULT_POOL_SIZE           = 8;
  
      public HardResourceLimitingPool( final ObjectFactory factory, final PoolController controller )
          throws Exception
      {
          super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
      }
  
      public HardResourceLimitingPool( final ObjectFactory factory )
          throws Exception
      {
          this( factory, null );
      }
  
      public HardResourceLimitingPool( final ObjectFactory factory,
                                       final int initial,
                                       final int maximum  )
          throws Exception
      {
          super( factory, null, initial, maximum );
      }
  
      public HardResourceLimitingPool( final ObjectFactory factory, final int initial )
          throws Exception
      {
          this( factory, initial, initial );
      }
  
      public HardResourceLimitingPool( final Class clazz, final int initial, final int maximum )
          throws NoSuchMethodException, Exception
      {
          this( new DefaultObjectFactory( clazz ), initial, maximum );
      }
  
      public HardResourceLimitingPool( final Class clazz, final int initial )
          throws NoSuchMethodException, Exception
      {
          this( clazz, initial, initial );
      }
  
      public void init() {
          try {
              super.init();
          } catch (Exception e) {
              getLogger().debug("Caught init exception", e);
          }
      }
      /**
       * Retrieve an object from pool.
       *
       * @return an object from Pool
       */
      public final synchronized Poolable get() throws Exception
      {
          while ( this.m_ready.size() == 0 || this.m_currentCount > this.m_max )
          {
              try { wait(); }
              catch( final InterruptedException ie ) { }
          }
  
          return super.get();
      }
  
      /**
       * Place an object in pool.
       *
       * @param poolable the object to be placed in pool
       */
      public final synchronized void put( final Poolable poolable )
      {
          super.put( poolable );
  
          notify();
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.pool;
  
  import org.apache.avalon.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
  {
      Object newInstance() throws Exception;
      Class getCreatedClass();
      void decommission(Object object) throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.pool;
  
  import org.apache.avalon.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/java/org/apache/excalibur/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.excalibur.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/java/org/apache/excalibur/pool/Resizable.java
  
  Index: Resizable.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.excalibur.pool;
  
  /**
   * This is the interface for Pools that are not a fixed size.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public interface Resizable
  {
      void grow(int amount);
      void shrink(int amount);
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/pool/SingleThreadedPool.java
  
  Index: SingleThreadedPool.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.excalibur.pool;
  
  import org.apache.avalon.Initializable;
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.SingleThreaded;
  
  /**
   * 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 SingleThreadedPool
      implements Pool, SingleThreaded, Resizable
  {
      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 SingleThreadedPool( final ObjectFactory factory,
                                 final PoolController controller,
                                 final int initial,
                                 final int maximum ) throws Exception
      {
          m_count = 0;
          m_factory = factory;
          m_controller = controller;
          m_maximum = maximum;
          m_initial = initial;
  
          if( !(this instanceof Initializable) )
          {
              init();
          }
      }
  
      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 (Poolable)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] = (Poolable)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/java/org/apache/excalibur/pool/SoftResourceLimitingPool.java
  
  Index: SoftResourceLimitingPool.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.excalibur.pool;
  
  import org.apache.avalon.Initializable;
  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>
   */
  public class SoftResourceLimitingPool 
      extends AbstractPool 
      implements Resizable
  {
      protected final PoolController m_controller;
  
      /**
       * Create an SoftResourceLimitingPool.  The pool requires a factory,
       * and can optionally have a controller.
       */
      public SoftResourceLimitingPool( final ObjectFactory factory,
                                       final int min ) throws Exception
      {
          super(factory, min, min * 2);
          this.m_controller = null;
      }
  
      /**
       * Create an SoftResourceLimitingPool.  The pool requires a factory,
       * and can optionally have a controller.
       */
      public SoftResourceLimitingPool( final ObjectFactory factory,
                                       final int min,
                                       final int max ) throws Exception
      {
          super(factory, min, max);
          this.m_controller = null;
      }
  
      /**
       * Create an SoftResourceLimitingPool.  The pool requires a factory,
       * and can optionally have a controller.
       */
      public SoftResourceLimitingPool( final ObjectFactory factory,
                                       final PoolController controller,
                                       final int min,
                                       final int max ) 
          throws Exception
      {
          super( factory, min, max );
          m_controller = controller;
      }
  
      public void init() 
      {
          grow( m_min );
      }
  
      public synchronized void grow( final int amount )
      {
          for( int i = 0; i < amount; i++ ) 
          {
              try
              {
                  m_ready.push( m_factory.newInstance() );
                  m_currentCount++;
              } 
              catch( final Exception e )
              {
                  if( null != getLogger() )
                  {
                      getLogger().debug( m_factory.getCreatedClass().getName() +
                                         ": could not be instantiated.", e );
                  }
              }
              
              notify();
          }
      }
  
      public synchronized void shrink( final int amount )
      {
          for( int i = 0; i < amount; i++ )
          {
              if( m_ready.size() > m_min )
              {
                  try
                  {
                      m_factory.decommission( m_ready.pop() );
                      m_currentCount--;
                  } 
                  catch( final Exception e )
                  {
                      if( null != getLogger() )
                      {
                          getLogger().debug( m_factory.getCreatedClass().getName() +
                                             ": improperly decommissioned.", e );
                      }
                  }
              }
          }
      }
  
      public Poolable get() 
          throws Exception
      {
          if( m_ready.size() == 0 )
          {
              grow( (null == m_controller) ? m_max - m_min : m_controller.grow() );
          }
  
          return super.get();
      }
  
      public void put( final Poolable poolable )
      {
          if( m_ready.size() > m_max )
          {
              shrink( (null == m_controller) ? m_ready.size() - (m_max + 1) : m_controller.shrink() );
          }
  
          super.put( poolable );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/thread/DefaultThreadPool.java
  
  Index: DefaultThreadPool.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.excalibur.thread;
  
  import org.apache.avalon.Loggable;
  import org.apache.avalon.Poolable;
  import org.apache.excalibur.pool.ObjectFactory;
  import org.apache.excalibur.pool.SoftResourceLimitingPool;
  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 DefaultThreadPool
      extends ThreadGroup
      implements ObjectFactory, Loggable, ThreadPool
  {
      protected final SoftResourceLimitingPool  m_pool;
      protected int                             m_level;
      protected Logger                          m_logger;
  
      public DefaultThreadPool( final int capacity )
          throws Exception
      {
          this( "Worker Pool", capacity );
      }
  
      public DefaultThreadPool( final String name, final int capacity )
          throws Exception
      {
          super( name );
          m_pool = new SoftResourceLimitingPool( this, 0 );
          m_pool.init();
      }
  
      public void setLogger( final Logger logger )
      {
          m_logger = logger;
      }
  
      public Object newInstance()
      {
          final WorkerThread worker =
              new WorkerThread( this, this, m_pool, getName() + " Worker #" + m_level++ );
          worker.setLogger( m_logger );
          worker.start();
          return worker;
      }
  
      public void decommission( final Object object )
      {
          if( object instanceof WorkerThread )
          {
              ((WorkerThread)object).dispose();
          }
      }
  
      public Class getCreatedClass()
      {
          return WorkerThread.class;
      }
  
      /**
       * Run work in separate thread.
       *
       * @param work the work to be executed.
       * @exception Exception if an error occurs
       */
      public void execute( final Runnable work )
          throws Exception
      {
          execute( work, Thread.NORM_PRIORITY );
      }
  
      /**
       * Run work in separate thread at a particular priority.
       *
       * @param work the work to be executed.
       * @param priority the priority
       * @exception Exception if an error occurs
       */
      public void execute( final Runnable work, final int priority )
          throws Exception
      {
          final WorkerThread worker = getWorker( priority );
          worker.execute( work );
      }
  
      /**
       * Run work in separate thread.
       * Wait till work is complete before returning.
       *
       * @param work the work to be executed.
       * @exception Exception if an error occurs
       */
      public void executeAndWait( final Runnable work )
          throws Exception
      {
          executeAndWait( work, Thread.NORM_PRIORITY );
      }
  
      /**
       * Run work in separate thread at a particular priority.
       * Wait till work is complete before returning.
       *
       * @param work the work to be executed.
       * @param priority the priority
       * @exception Exception if an error occurs
       */
      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/java/org/apache/excalibur/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.excalibur.thread;
  
  /**
   * To deal with *current* ThreadContext.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ThreadContext
  {
      private final static RuntimePermission      c_permission =
          new RuntimePermission( "ThreadContext.setCurrentThreadPool" );
      private final static InheritableThreadLocal c_context    = new InheritableThreadLocal();
  
      /**
       * Retrieve thread pool associated with current thread
       *
       * @return a thread pool
       */
      public static ThreadPool getCurrentThreadPool()
      {
          return (ThreadPool)c_context.get();
      }
  
      /**
       * Set the thread pool that will be returned by getCurrentThreadPool() in this thread
       * and decendent threads.
       *
       * @param threadPool the new thread pool
       * @exception SecurityException if the caller does not have permission to set thread pool
       */
      public static void setCurrentThreadPool( final ThreadPool threadPool )
          throws SecurityException
      {
          final SecurityManager securityManager = System.getSecurityManager();
  
          if( null != securityManager )
          {
              securityManager.checkPermission( c_permission );
          }
  
          c_context.set( threadPool );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.thread;
  
  /**
   * This class is the public frontend for the thread pool code.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ThreadPool
  {
      /**
       * Run work in separate thread.
       *
       * @param work the work to be executed.
       * @exception Exception if an error occurs
       */
      void execute( final Runnable work )
          throws Exception;
  
      /**
       * Run work in separate thread at a particular priority.
       *
       * @param work the work to be executed.
       * @param priority the priority
       * @exception Exception if an error occurs
       */
      void execute( final Runnable work, final int priority )
          throws Exception;
  
      /**
       * Run work in separate thread.
       * Wait till work is complete before returning.
       *
       * @param work the work to be executed.
       * @exception Exception if an error occurs
       */
      void executeAndWait( final Runnable work )
          throws Exception;
  
      /**
       * Run work in separate thread at a particular priority.
       * Wait till work is complete before returning.
       *
       * @param work the work to be executed.
       * @param priority the priority
       * @exception Exception if an error occurs
       */
      void executeAndWait( final Runnable work, final int priority )
          throws Exception;
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/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.excalibur.thread;
  
  import org.apache.avalon.Loggable;
  import org.apache.avalon.Poolable;
  import org.apache.excalibur.pool.SoftResourceLimitingPool;
  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 SoftResourceLimitingPool  m_pool;
  
      protected Runnable                  m_work;
      protected boolean                   m_alive;
  
      /**
       * Allocates a new <code>Worker</code> object.
       */
      protected WorkerThread( final ThreadGroup group,
                              final ThreadPool threadPool,
                              final SoftResourceLimitingPool pool,
                              final String name )
      {
          super( group, 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/test/org/apache/excalibur/cli/test/ClutilTestlet.java
  
  Index: ClutilTestlet.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.excalibur.cli.test;
  
  import java.util.List;
  import org.apache.excalibur.cli.AbstractParserControl;
  import org.apache.excalibur.cli.CLArgsParser;
  import org.apache.excalibur.cli.CLOption;
  import org.apache.excalibur.cli.CLOptionDescriptor;
  import org.apache.excalibur.cli.ParserControl;
  import org.apache.testlet.AbstractTestlet;
  
  /**
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ClutilTestlet
      extends AbstractTestlet
  { 
      protected final static String[] ARGLIST1 = 
      {
          "--you","are","--all","-cler","kid"
      };
  
      protected final static String[] ARGLIST2 = 
      {
          "-Dstupid=idiot","are","--all","here"
      };
      
      protected final static String[] ARGLIST3 = 
      {
          //duplicates
          "-Dstupid=idiot","are","--all","--all","here"
      };
      
      protected final static String[] ARGLIST4 = 
      {
          //incompatable (blee/all)
          "-Dstupid=idiot","are","--all","--blee","here"
      };
  
      protected final static String[] ARGLIST5 = 
      {
          "-f","myfile.txt"
      };
  
      private static final int                DEFINE_OPT        = 'D';
      private static final int                YOU_OPT           = 'y';
      private static final int                ALL_OPT           = 'a';
      private static final int                CLEAR1_OPT        = 'c';
      private static final int                CLEAR2_OPT        = 'l';
      private static final int                CLEAR3_OPT        = 'e';
      private static final int                CLEAR5_OPT        = 'r';
      private static final int                BLEE_OPT          = 'b';
      private static final int                FILE_OPT          = 'f';
  
      protected final static CLOptionDescriptor DEFINE          =
          new CLOptionDescriptor( "define", 
                                  CLOptionDescriptor.ARGUMENTS_REQUIRED_2, 
                                  DEFINE_OPT, 
                                  "define" );
      protected final static CLOptionDescriptor YOU             =
          new CLOptionDescriptor( "you", CLOptionDescriptor.ARGUMENT_DISALLOWED, YOU_OPT, "you" );
  
      protected final static CLOptionDescriptor ALL             =
          new CLOptionDescriptor( "all", 
                                  CLOptionDescriptor.ARGUMENT_DISALLOWED, 
                                  ALL_OPT, 
                                  "all",
                                  new int[] { BLEE_OPT } );
  
      protected final static CLOptionDescriptor CLEAR1          =
          new CLOptionDescriptor( "c", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR1_OPT, "c" );
      protected final static CLOptionDescriptor CLEAR2          =
          new CLOptionDescriptor( "l", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR2_OPT, "l" );
      protected final static CLOptionDescriptor CLEAR3          =
          new CLOptionDescriptor( "e", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR3_OPT, "e" );
      protected final static CLOptionDescriptor CLEAR5          =
          new CLOptionDescriptor( "r", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR5_OPT, "r" );
      protected final static CLOptionDescriptor BLEE            =
          new CLOptionDescriptor( "blee", 
                                  CLOptionDescriptor.ARGUMENT_DISALLOWED, 
                                  BLEE_OPT, 
                                  "blee" );
      protected final static CLOptionDescriptor FILE            =
          new CLOptionDescriptor( "file",
                                  CLOptionDescriptor.ARGUMENT_REQUIRED,
                                  FILE_OPT,
                                  "the build file." );
  
      public void testFullParse()
      {
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              YOU, ALL, CLEAR1, CLEAR2, CLEAR3, CLEAR5
          };
          
          final CLArgsParser parser = new CLArgsParser( ARGLIST1, options );
          
          assertNull( parser.getErrorString() );
          
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          
          assertEquality( size, 8 );
          assertEquality( ((CLOption)clOptions.get( 0 )).getId(), YOU_OPT );
          assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions.get( 3 )).getId(), CLEAR1_OPT );
          assertEquality( ((CLOption)clOptions.get( 4 )).getId(), CLEAR2_OPT );
          assertEquality( ((CLOption)clOptions.get( 5 )).getId(), CLEAR3_OPT );
          assertEquality( ((CLOption)clOptions.get( 6 )).getId(), CLEAR5_OPT );
          assertEquality( ((CLOption)clOptions.get( 7 )).getId(), 0 );
      }
  
      public void testDuplicateOptions()
      {
          //"-Dstupid=idiot","are","--all","--all","here"
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              DEFINE, ALL, CLEAR1
          };
  
          final CLArgsParser parser = new CLArgsParser( ARGLIST3, options );
  
          assertNull( parser.getErrorString() );
  
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
  
          assertEquality( size, 5 );
          assertEquality( ((CLOption)clOptions.get( 0 )).getId(), DEFINE_OPT );
          assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions.get( 3 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions.get( 4 )).getId(), 0 );
      }
      
      public void testIncompatableOptions()
      {
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              DEFINE, ALL, CLEAR1, BLEE
          };
          
          final CLArgsParser parser = new CLArgsParser( ARGLIST4, options );
          
          assertNotNull( parser.getErrorString() );
          
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          
          assertEquality( size, 5 );
          assertEquality( ((CLOption)clOptions.get( 0 )).getId(), DEFINE_OPT );
          assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions.get( 3 )).getId(), BLEE_OPT );
          assertEquality( ((CLOption)clOptions.get( 4 )).getId(), 0 );
      }        
  
      public void testSingleArg()
      {
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              FILE
          };
          
          final CLArgsParser parser = new CLArgsParser( ARGLIST5, options );
          
          assertNull( parser.getErrorString() );
          
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          
          assertEquality( size, 1 );
          assertEquality( ((CLOption)clOptions.get( 0 )).getId(), FILE_OPT );
          assertEquality( ((CLOption)clOptions.get( 0 )).getArgument(), "myfile.txt" );
      }        
  
      public void test2ArgsParse()
      {
          //"-Dstupid=idiot","are","--all","here"
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              DEFINE, ALL, CLEAR1
          };
          
          final CLArgsParser parser = new CLArgsParser( ARGLIST2, options );
          
          assertNull( parser.getErrorString() );
          
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          
          assertEquality( size, 4 );
          assertEquality( ((CLOption)clOptions.get( 0 )).getId(), DEFINE_OPT );
          assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions.get( 3 )).getId(), 0 );
          
          final CLOption option = (CLOption)clOptions.get( 0 );
          assertEquality( "stupid", option.getArgument( 0 ) );
          assertEquality( "idiot", option.getArgument( 1 ) );
      }
  
      public void testPartParse()
      {
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              YOU
          };
  
          final ParserControl control = new AbstractParserControl() 
          {
              public boolean isFinished( int lastOptionCode )
              {
                  return (lastOptionCode == YOU_OPT);
              }
          };
  
          final CLArgsParser parser = new CLArgsParser( ARGLIST1, options, control );
  
          assertNull( parser.getErrorString() );
  
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
  
          assertEquality( size, 1 );
          assertEquality( ((CLOption)clOptions.get( 0 )).getId(), YOU_OPT );
      }
  
      public void test2PartParse()
      {
          final CLOptionDescriptor[] options1 = new CLOptionDescriptor[] 
          {
              YOU
          };
  
          final CLOptionDescriptor[] options2 = new CLOptionDescriptor[] 
          {
              ALL, CLEAR1, CLEAR2, CLEAR3, CLEAR5
          };
  
          final ParserControl control1 = new AbstractParserControl() 
          {
              public boolean isFinished( int lastOptionCode )
              {
                  return (lastOptionCode == YOU_OPT);
              }
          };
  
          final CLArgsParser parser1 = new CLArgsParser( ARGLIST1, options1, control1 );
  
          assertNull( parser1.getErrorString() );
  
          final List clOptions1 = parser1.getArguments();
          final int size1 = clOptions1.size();
  
          assertEquality( size1, 1 );
          assertEquality( ((CLOption)clOptions1.get( 0 )).getId(), YOU_OPT );
  
          final CLArgsParser parser2 = 
              new CLArgsParser( parser1.getUnparsedArgs(), options2 );
  
          assertNull( parser2.getErrorString() );
  
          final List clOptions2 = parser2.getArguments();
          final int size2 = clOptions2.size();
  
          assertEquality( size2, 7 );
          assertEquality( ((CLOption)clOptions2.get( 0 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions2.get( 1 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions2.get( 2 )).getId(), CLEAR1_OPT );
          assertEquality( ((CLOption)clOptions2.get( 3 )).getId(), CLEAR2_OPT );
          assertEquality( ((CLOption)clOptions2.get( 4 )).getId(), CLEAR3_OPT );
          assertEquality( ((CLOption)clOptions2.get( 5 )).getId(), CLEAR5_OPT );
          assertEquality( ((CLOption)clOptions2.get( 6 )).getId(), 0 );
      }
  
      public void test2PartPartialParse()
      {
          final CLOptionDescriptor[] options1 = new CLOptionDescriptor[] 
          {
              YOU, ALL, CLEAR1
          };
  
          final CLOptionDescriptor[] options2 = new CLOptionDescriptor[] {};
  
          final ParserControl control1 = new AbstractParserControl() 
          {
              public boolean isFinished( final int lastOptionCode )
              {
                  return (lastOptionCode == CLEAR1_OPT);
              }
          };
  
          final CLArgsParser parser1 = new CLArgsParser( ARGLIST1, options1, control1 );
  
          assertNull( parser1.getErrorString() );
  
          final List clOptions1 = parser1.getArguments();
          final int size1 = clOptions1.size();
  
          assertEquality( size1, 4 );
          assertEquality( ((CLOption)clOptions1.get( 0 )).getId(), YOU_OPT );
          assertEquality( ((CLOption)clOptions1.get( 1 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions1.get( 2 )).getId(), ALL_OPT );
          assertEquality( ((CLOption)clOptions1.get( 3 )).getId(), CLEAR1_OPT );
  
          assert( parser1.getUnparsedArgs()[0].equals("ler") );
          
          final CLArgsParser parser2 = 
              new CLArgsParser( parser1.getUnparsedArgs(), options2 );
  
          assertNull( parser2.getErrorString() );
  
          final List clOptions2 = parser2.getArguments();
          final int size2 = clOptions2.size();
  
          assertEquality( size2, 2 );
          assertEquality( ((CLOption)clOptions2.get( 0 )).getId(), 0 );
          assertEquality( ((CLOption)clOptions2.get( 1 )).getId(), 0 );
      }
  
      
      public void testDuplicatesFail()
      {
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              YOU, ALL, CLEAR1, CLEAR2, CLEAR3, CLEAR5
          };
  
          //duplicate as
          final String[] DUPLICATE_ARGLIST = 
          {
              "--you","are","--all","-clear","kid"
          };
          
          final CLArgsParser parser = new CLArgsParser( ARGLIST1, options );
          
          assertNull( parser.getErrorString() );
      }
  
      public void testIncomplete2Args()
      {
          //"-Dstupid="
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              DEFINE
          };
  
          final CLArgsParser parser = new CLArgsParser( new String[] { "-Dstupid=" }, options );
  
          assertNull( parser.getErrorString() );
  
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
  
          assertEquality( size, 1 );
          final CLOption option = (CLOption)clOptions.get( 0 );
          assertEquality( option.getId(), DEFINE_OPT );
          assertEquality( option.getArgument( 0 ), "stupid" );
          assertEquality( option.getArgument( 1 ), "" );
      }
      
      public void testIncomplete2ArgsMixed()
      {
          //"-Dstupid=","-c"
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              DEFINE, CLEAR1
          };
  
          final String[] args = new String[] { "-Dstupid=", "-c" };
  
          final CLArgsParser parser = new CLArgsParser( args, options );
          
          assertNull( parser.getErrorString() );
          
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          
          assertEquality( size, 2 );
          assertEquality( ((CLOption)clOptions.get( 1 )).getId(), CLEAR1_OPT );
          final CLOption option = (CLOption)clOptions.get( 0 );
          assertEquality( option.getId(), DEFINE_OPT );
          assertEquality( option.getArgument( 0 ), "stupid" );
          assertEquality( option.getArgument( 1 ), "" );
      }
  
      public void fail_testIncomplete2ArgsMixedNoEq()
      {
          //"-Dstupid","-c"
          final CLOptionDescriptor[] options = new CLOptionDescriptor[] 
          {
              DEFINE, CLEAR1
          };
          
          final String[] args = new String[] { "-Dstupid", "-c" };
          
          final CLArgsParser parser = new CLArgsParser( args, options );
          
          assertNull( parser.getErrorString() );
          
          final List clOptions = parser.getArguments();
          final int size = clOptions.size();
          
          assertEquality( size, 2 );
          assertEquality( ((CLOption)clOptions.get( 1 )).getId(), CLEAR1_OPT );
          final CLOption option = (CLOption)clOptions.get( 0 );
          assertEquality( option.getId(), DEFINE_OPT );
          assertEquality( option.getArgument( 0 ), "stupid" );
          assertEquality( option.getArgument( 1 ), "" );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/test/org/apache/excalibur/collections/test/BinaryHeapTestlet.java
  
  Index: BinaryHeapTestlet.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.excalibur.collections.test;
   
  import org.apache.testlet.AbstractTestlet; 
  import org.apache.excalibur.collections.BinaryHeap;
   
  /** 
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */ 
  public final class BinaryHeapTestlet
      extends AbstractTestlet 
  {
      protected final static Integer VAL1 = new Integer( 1 );
      protected final static Integer VAL2 = new Integer( 2 );
      protected final static Integer VAL3 = new Integer( 3 );
      protected final static Integer VAL4 = new Integer( 4 );
      protected final static Integer VAL5 = new Integer( 5 );
      protected final static Integer VAL6 = new Integer( 6 );
      protected final static Integer VAL7 = new Integer( 7 );
  
      public void testSimpleOrder() 
      {
          final BinaryHeap heap = new BinaryHeap();
  
          heap.clear();
          heap.insert( VAL1 );
          heap.insert( VAL2 );
          heap.insert( VAL3 );
          heap.insert( VAL4 );
          
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL4 == heap.pop() );
      }  
  
      public void testReverseOrder() 
      {
          final BinaryHeap heap = new BinaryHeap();
  
          heap.clear();
          heap.insert( VAL4 );
          heap.insert( VAL3 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
  
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL4 == heap.pop() );
      }  
  
      public void testMixedOrder() 
      {
          final BinaryHeap heap = new BinaryHeap();
  
          heap.clear();
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL3 );
  
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL4 == heap.pop() );
      }  
  
      public void testDuplicates() 
      {
          final BinaryHeap heap = new BinaryHeap();
  
          heap.clear();
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );
          heap.insert( VAL3 );
  
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL4 == heap.pop() );
      }  
  
      public void testMixedInsertPopOrder() 
      {
          final BinaryHeap heap = new BinaryHeap();
  
          heap.clear();
          heap.insert( VAL1 );
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );
          heap.insert( VAL3 );
  
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
  
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );
          heap.insert( VAL3 );
  
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL4 == heap.pop() );
          assert( VAL4 == heap.pop() );
      }
  
      public void testReverseSimpleOrder() 
      {
          final BinaryHeap heap = new BinaryHeap( false );
  
          heap.clear();
          heap.insert( VAL1 );
          heap.insert( VAL2 );
          heap.insert( VAL3 );
          heap.insert( VAL4 );
  
          assert( VAL4 == heap.pop() );
          assert( VAL3 == heap.pop() );        
          assert( VAL2 == heap.pop() );
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
  
      }  
  
      public void testReverseReverseOrder() 
      {
          final BinaryHeap heap = new BinaryHeap( false );
  
          heap.clear();
          heap.insert( VAL4 );
          heap.insert( VAL3 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
  
          assert( VAL4 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
      }  
  
      public void testReverseMixedOrder() 
      {
          final BinaryHeap heap = new BinaryHeap( false );
  
          heap.clear();
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL3 );
  
          assert( VAL4 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
      }  
  
      public void testReverseDuplicates() 
      {
          final BinaryHeap heap = new BinaryHeap( false );
  
          heap.clear();
          heap.insert( VAL4 );
          heap.insert( VAL3 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );
  
          assert( VAL4 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
      }  
  
      public void testReverseMixedInsertPopOrder() 
      {
          final BinaryHeap heap = new BinaryHeap( false );
  
          heap.clear();
          heap.insert( VAL1 );
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );
          heap.insert( VAL3 );
  
          assert( VAL4 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL2 == heap.pop() );
  
          heap.insert( VAL4 );
          heap.insert( VAL2 );
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );        
          heap.insert( VAL1 );
          heap.insert( VAL3 );
  
          assert( VAL4 == heap.pop() );
          assert( VAL3 == heap.pop() );
          assert( VAL2 == heap.pop() );
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.peek() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
          assert( VAL1 == heap.pop() );
      }  
  }
  
  
  
  1.1                  jakarta-avalon/src/test/org/apache/excalibur/datasource/test/DataSourceTestlet.java
  
  Index: DataSourceTestlet.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.excalibur.datasource.test;
  
  import java.sql.Connection;
  import java.sql.SQLException;
  import java.util.Random;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.configuration.DefaultConfiguration;
  import org.apache.excalibur.datasource.DataSourceComponent;
  import org.apache.excalibur.datasource.JdbcDataSource;
  import org.apache.log.LogKit;
  import org.apache.testlet.AbstractTestlet;
  
  /**
   * Test the DataSource Component.  I don't know how to make this generic,
   * so I'll throw some bones out there, and hope someone can set this up
   * better.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public class DataSourceTestlet
      extends AbstractTestlet
  {
      static final Configuration conf;
      static final String LOCATION = "Testlet Framework";
  
      static
      {
          DefaultConfiguration dc = new DefaultConfiguration( "", LOCATION );
          DefaultConfiguration pool = new DefaultConfiguration( "pool-controller", LOCATION );
          DefaultConfiguration dburl = new DefaultConfiguration( "dburl", LOCATION );
          DefaultConfiguration user = new DefaultConfiguration( "user", LOCATION );
          DefaultConfiguration password = new DefaultConfiguration( "password", LOCATION );
          pool.addAttribute( "min", "5" );
          pool.addAttribute( "max", "10" );
          dc.addChild( pool );
          dburl.appendValueData( "jdbc:odbc://test" );
          dc.addChild( dburl );
          user.appendValueData( "test" );
          dc.addChild( user );
          password.appendValueData( "test" );
          dc.addChild( password );
          conf = dc;
  
          LogKit.setGlobalPriority( org.apache.log.Priority.INFO );
  
          try
          {
              Class.forName( "Your Driver Class Here" );
          }
          catch( final Exception e )
          {
              LogKit.getLoggerFor( "test" ).error( e.getMessage(), e );
          }
      }
  
      public void testOverAllocation()
      {
          boolean result = false;
          JdbcDataSource ds = new JdbcDataSource();
          ds.setLogger( LogKit.getLoggerFor( "test" ) );
  
          try
          {
              ds.configure( conf );
          }
          catch( final ConfigurationException ce )
          {
              assert( "Over Allocation Test", false );
          }
  
          try
          {
              for( int i = 0; i < 11; i++ )
              {
                  ds.getConnection();
              }
          }
          catch( final SQLException se )
          {
              result = true;
              LogKit.getLoggerFor( "test" ).info( "The test was successful" );
          }
  
          assert( "Over Allocation Test", result );
      }
  
      public void testNormalUse()
      {
          boolean result = true;
          JdbcDataSource ds = new JdbcDataSource();
          ds.setLogger( LogKit.getLoggerFor( "test" ) );
  
          try
          {
              ds.configure( conf );
          }
          catch( final ConfigurationException ce )
          {
              LogKit.getLoggerFor( "test" ).error( ce.getMessage(), ce );
              assert( "Over Allocation Test", false );
          }
  
          Thread one = new Thread( new ConnectionThread( this, ds ) );
          Thread two = new Thread( new ConnectionThread( this, ds ) );
  
          one.start();
          two.start();
  
          while( one.isAlive() || two.isAlive() )
          {
              try
              {
                  Thread.sleep( 100 );
              }
              catch( final InterruptedException ie )
              {
                  // Ignore
              }
          }
  
          LogKit.getLoggerFor( "test" ).
              info( "If you saw no failure messages, then the test passed" );
          assert( "Normal Use Test", result );
      }
  
      public void runDBTest( final DataSourceComponent datasource )
      {
          long end = System.currentTimeMillis() + 5000; // run for 5 seconds
  
          while( System.currentTimeMillis() < end )
          {
              try
              {
                  Connection con = datasource.getConnection();
                  long sleeptime = (long)(Math.random() * 100.0);
                  Thread.sleep( sleeptime );
                  con.close();
              }
              catch( final SQLException se )
              {
                  LogKit.getLoggerFor( "test" ).info( "Failed to get Connection, test failed" );
                  assert( "Normal Use Test", false );
              }
              catch( final InterruptedException ie )
              {
                  // Ignore
              }
          }
      }
  }
  
  class ConnectionThread
      implements Runnable
  {
      protected DataSourceComponent datasource;
      protected DataSourceTestlet testlet;
  
      ConnectionThread( final DataSourceTestlet testlet,
                        final DataSourceComponent datasource )
      {
          this.datasource = datasource;
          this.testlet = testlet;
      }
  
      public void run()
      {
          testlet.runDBTest( datasource );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/test/org/apache/excalibur/io/test/FileUtilTestlet.java
  
  Index: FileUtilTestlet.java
  ===================================================================
  /* 
   * Copyright  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.excalibur.io.test;
  
  import java.io.*;
  import org.apache.excalibur.io.FileUtil;
  import org.apache.testlet.AbstractTestlet;
  import org.apache.testlet.TestFailedException;  
  
  /** 
   * This is used to test FileUtil for correctness. 
   * 
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 
   */ 
  public final class FileUtilTestlet 
      extends AbstractTestlet 
  {  
      protected final int      FILE1_SIZE  = 1;
      protected final int      FILE2_SIZE  = 1024 * 4 + 1;
  
      protected final File     m_testDirectory;
      protected final File     m_testFile1;
      protected final File     m_testFile2;
  
      public FileUtilTestlet()
          throws IOException
      {
          m_testDirectory = (new File( "test/io/" )).getAbsoluteFile();
          if( !m_testDirectory.exists() )
          {
              m_testDirectory.mkdirs();
          }
  
          m_testFile1 = new File( m_testDirectory, "file1-test.txt" );
          m_testFile2 = new File( m_testDirectory, "file2-test.txt" );
          
          createFile( m_testFile1, FILE1_SIZE );
          createFile( m_testFile2, FILE2_SIZE );
      }
  
      protected void createFile( final File file, final long size )
          throws IOException
      {
          final BufferedOutputStream output = 
              new BufferedOutputStream( new FileOutputStream( file ) );
          
          for( int i = 0; i < size; i++ )
          {
              output.write( (byte)'X' );
          }
  
          output.close();
      }
  
      public void testCopyFile1() 
          throws Exception 
      {
          final File destination = new File( m_testDirectory, "copy1.txt" );
          FileUtil.copyFile( m_testFile1, destination );
          assert( "Check Exist", destination.exists() );
          assert( "Check Full copy", destination.length() == FILE1_SIZE );
      }
      
      public void testCopyFile2() 
          throws Exception 
      {
          final File destination = new File( m_testDirectory, "copy2.txt" );
          FileUtil.copyFile( m_testFile2, destination );
          assert( "Check Exist", destination.exists() );
          assert( "Check Full copy", destination.length() == FILE2_SIZE );
      }
      
      public void testForceDeleteFile1() 
          throws Exception 
      {
          final File destination = new File( m_testDirectory, "copy1.txt" );
          FileUtil.forceDelete( destination );
          assert( "Check No Exist", !destination.exists() );
      }
      
      public void testForceDeleteFile2() 
          throws Exception 
      {
          final File destination = new File( m_testDirectory, "copy2.txt" );
          FileUtil.forceDelete( destination );
          assert( "Check No Exist", !destination.exists() );
      }
      
      public void testCopyFile1ToDir() 
          throws Exception 
      {
          final File directory = new File( m_testDirectory, "subdir" );
          if( !directory.exists() ) directory.mkdirs();
          final File destination = new File( directory, "file1-test.txt" );
          FileUtil.copyFileToDirectory( m_testFile1, directory );
          assert( "Check Exist", destination.exists() );
          assert( "Check Full copy", destination.length() == FILE1_SIZE );
      }
      
      public void testCopyFile2ToDir() 
          throws Exception 
      {
          final File directory = new File( m_testDirectory, "subdir" );
          if( !directory.exists() ) directory.mkdirs();
          final File destination = new File( directory, "file2-test.txt" );
          FileUtil.copyFileToDirectory( m_testFile2, directory );
          assert( "Check Exist", destination.exists() );
          assert( "Check Full copy", destination.length() == FILE2_SIZE );
      }  
  
      public void testForceDeleteDir() 
          throws Exception 
      {
          FileUtil.forceDelete( m_testDirectory.getParentFile() );
          assert( "Check No Exist", !m_testDirectory.getParentFile().exists() );
      }
  
      public void testResolveFileDotDot()
          throws Exception
      {
          final File file = FileUtil.resolveFile( m_testDirectory, ".." );
          assertEquality( "Check .. operator", file, m_testDirectory.getParentFile() );
      }
      
      public void testResolveFileDot()
          throws Exception
      {
          final File file = FileUtil.resolveFile( m_testDirectory, "." );
          assertEquality( "Check . operator", file, m_testDirectory );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/test/org/apache/excalibur/pool/test/PoolProfile.java
  
  Index: PoolProfile.java
  ===================================================================
  /*
   * Copyright  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.excalibur.pool.test;
  
  import org.apache.avalon.Poolable;
  import org.apache.excalibur.pool.DefaultPool;
  import org.apache.excalibur.pool.Pool;
  import org.apache.excalibur.pool.HardResourceLimitingPool;
  import org.apache.testlet.*;
  
  /**
   * This is used to profile the Pool implementation.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class PoolProfile
      extends AbstractTestlet
  {
      public static class A
          implements Poolable
      {
          int a;
          int b;
          int c;
          float x;
          float y;
          float z;
      }
  
      public static class B
          implements Poolable
      {
          int a;
          int b;
          int c;
          float x;
          float y;
          float z;
          Object o1;
          Object o2;
          Object o3;
  
          public void recycle()
          {
              o1 = o2 = o3 = null;
          }
      }
  
      public static class C
          implements Poolable
      {
          int a;
          int b;
          int c;
          float x;
          float y;
          float z;
          Object o1;
          Object o2;
          Object o3;
          Object o4;
          Object o5;
          Object o6;
  
          public void build()
          {
              o1 = new Object();
              o2 = new Object();
              o3 = new Object();
              o4 = new Object();
              o5 = new Object();
              o6 = new Object();
          }
  
          public void recycle()
          {
              o1 = o2 = o3 = o4 = o5 = o6 = null;
          }
      }
  
      protected static final int               TEST_SIZE          = 1000000;
  
      public void testSmallObjects()
          throws Exception
      {
          System.out.println("SMALL Sized Objects");
  
          final DefaultPool pool1 = new DefaultPool( A.class, 5, 10 );
          final long pool1Start = System.currentTimeMillis();
          final int pool1Factor = 1;
          final int pool1Loops = TEST_SIZE / pool1Factor;
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = pool1.get();
              pool1.put(a1);
          }
          final long pool1End = System.currentTimeMillis();
          final long pool1Duration = pool1End - pool1Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool2 = new DefaultPool( A.class, 5, 10 );
          final long pool2Start = System.currentTimeMillis();
          final int pool2Factor = 10;
          final int pool2Loops = TEST_SIZE / pool2Factor;
          for( int i = 0; i < pool2Loops; i++ )
          {
              final Poolable a1 = pool2.get();
              final Poolable a2 = pool2.get();
              final Poolable a3 = pool2.get();
              final Poolable a4 = pool2.get();
              final Poolable a5 = pool2.get();
              final Poolable a6 = pool2.get();
              final Poolable a7 = pool2.get();
              final Poolable a8 = pool2.get();
              final Poolable a9 = pool2.get();
              final Poolable a0 = pool2.get();
              pool2.put(a1);
              pool2.put(a2);
              pool2.put(a3);
              pool2.put(a4);
              pool2.put(a5);
              pool2.put(a6);
              pool2.put(a7);
              pool2.put(a8);
              pool2.put(a9);
              pool2.put(a0);
          }
          final long pool2End = System.currentTimeMillis();
          final long pool2Duration = pool2End - pool2Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool3 = new DefaultPool( A.class, 5, 10 );
          final long pool3Start = System.currentTimeMillis();
          final int pool3Factor = 15;
          final int pool3Loops = TEST_SIZE / pool3Factor;
          for( int i = 0; i < pool3Loops; i++ )
          {
              final Poolable a1 = pool3.get();
              final Poolable a2 = pool3.get();
              final Poolable a3 = pool3.get();
              final Poolable a4 = pool3.get();
              final Poolable a5 = pool3.get();
              final Poolable a6 = pool3.get();
              final Poolable a7 = pool3.get();
              final Poolable a8 = pool3.get();
              final Poolable a9 = pool3.get();
              final Poolable a10 = pool3.get();
              final Poolable a11 = pool3.get();
              final Poolable a12 = pool3.get();
              final Poolable a13 = pool3.get();
              final Poolable a14 = pool3.get();
              final Poolable a15 = pool3.get();
              pool3.put(a1);
              pool3.put(a2);
              pool3.put(a3);
              pool3.put(a4);
              pool3.put(a5);
              pool3.put(a6);
              pool3.put(a7);
              pool3.put(a8);
              pool3.put(a9);
              pool3.put(a10);
              pool3.put(a11);
              pool3.put(a12);
              pool3.put(a13);
              pool3.put(a14);
              pool3.put(a15);
          }
          final long pool3End = System.currentTimeMillis();
          final long pool3Duration = pool3End - pool3Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool4 = new DefaultPool( A.class, 5, 10 );
          final long pool4Start = System.currentTimeMillis();
          final int pool4Factor = 20;
          final int pool4Loops = TEST_SIZE / pool4Factor;
          for( int i = 0; i < pool4Loops; i++ )
          {
              final Poolable a1 = pool4.get();
              final Poolable a2 = pool4.get();
              final Poolable a3 = pool4.get();
              final Poolable a4 = pool4.get();
              final Poolable a5 = pool4.get();
              final Poolable a6 = pool4.get();
              final Poolable a7 = pool4.get();
              final Poolable a8 = pool4.get();
              final Poolable a9 = pool4.get();
              final Poolable a10 = pool4.get();
              final Poolable a11 = pool4.get();
              final Poolable a12 = pool4.get();
              final Poolable a13 = pool4.get();
              final Poolable a14 = pool4.get();
              final Poolable a15 = pool4.get();
              final Poolable a16 = pool4.get();
              final Poolable a17 = pool4.get();
              final Poolable a18 = pool4.get();
              final Poolable a19 = pool4.get();
              final Poolable a20 = pool4.get();
              pool4.put(a1);
              pool4.put(a2);
              pool4.put(a3);
              pool4.put(a4);
              pool4.put(a5);
              pool4.put(a6);
              pool4.put(a7);
              pool4.put(a8);
              pool4.put(a9);
              pool4.put(a10);
              pool4.put(a11);
              pool4.put(a12);
              pool4.put(a13);
              pool4.put(a14);
              pool4.put(a15);
              pool4.put(a16);
              pool4.put(a17);
              pool4.put(a18);
              pool4.put(a19);
              pool4.put(a20);
          }
          final long pool4End = System.currentTimeMillis();
          final long pool4Duration = pool4End - pool4Start;
  
          System.out.println("FreeMem post 4: " + Runtime.getRuntime().freeMemory() );
  
          final long createStart = System.currentTimeMillis();
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = new C();
          }
          final long createEnd = System.currentTimeMillis();
          final long createDuration = createEnd - createStart;
  
          //System.out.println("Create Duration: " + createDuration + "ms ");
          System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
  
          final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
          final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
          final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
          final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
  
          //System.out.println("Pool Duration for 100% hits: " + pool1Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
          //System.out.println("Pool Duration for 100% hits and saturated: " + pool2Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
          //System.out.println("Pool Duration for 60% hits: " + pool3Duration + "ms ");
          System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
          //System.out.println("Pool Duration for 50% hits: " + pool4Duration + "ms ");
          System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
      }
  
      public void testMediumObjects()
          throws Exception
      {
          System.out.println("MEDIUM Sized Objects");
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          final DefaultPool pool1 = new DefaultPool( B.class, 5, 10 );
          final long pool1Start = System.currentTimeMillis();
          final int pool1Factor = 1;
          final int pool1Loops = TEST_SIZE / pool1Factor;
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = pool1.get();
              pool1.put(a1);
          }
          final long pool1End = System.currentTimeMillis();
          final long pool1Duration = pool1End - pool1Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool2 = new DefaultPool( B.class, 5, 10 );
          final long pool2Start = System.currentTimeMillis();
          final int pool2Factor = 10;
          final int pool2Loops = TEST_SIZE / pool2Factor;
          for( int i = 0; i < pool2Loops; i++ )
          {
              final Poolable a1 = pool2.get();
              final Poolable a2 = pool2.get();
              final Poolable a3 = pool2.get();
              final Poolable a4 = pool2.get();
              final Poolable a5 = pool2.get();
              final Poolable a6 = pool2.get();
              final Poolable a7 = pool2.get();
              final Poolable a8 = pool2.get();
              final Poolable a9 = pool2.get();
              final Poolable a10 = pool2.get();
              pool2.put(a1);
              pool2.put(a2);
              pool2.put(a3);
              pool2.put(a4);
              pool2.put(a5);
              pool2.put(a6);
              pool2.put(a7);
              pool2.put(a8);
              pool2.put(a9);
              pool2.put(a10);
          }
          final long pool2End = System.currentTimeMillis();
          final long pool2Duration = pool2End - pool2Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool3 = new DefaultPool( B.class, 5, 10 );
          final long pool3Start = System.currentTimeMillis();
          final int pool3Factor = 15;
          final int pool3Loops = TEST_SIZE / pool3Factor;
          for( int i = 0; i < pool3Loops; i++ )
          {
              final Poolable a1 = pool3.get();
              final Poolable a2 = pool3.get();
              final Poolable a3 = pool3.get();
              final Poolable a4 = pool3.get();
              final Poolable a5 = pool3.get();
              final Poolable a6 = pool3.get();
              final Poolable a7 = pool3.get();
              final Poolable a8 = pool3.get();
              final Poolable a9 = pool3.get();
              final Poolable a10 = pool3.get();
              final Poolable a11 = pool3.get();
              final Poolable a12 = pool3.get();
              final Poolable a13 = pool3.get();
              final Poolable a14 = pool3.get();
              final Poolable a15 = pool3.get();
              pool3.put(a1);
              pool3.put(a2);
              pool3.put(a3);
              pool3.put(a4);
              pool3.put(a5);
              pool3.put(a6);
              pool3.put(a7);
              pool3.put(a8);
              pool3.put(a9);
              pool3.put(a10);
              pool3.put(a11);
              pool3.put(a12);
              pool3.put(a13);
              pool3.put(a14);
              pool3.put(a15);
          }
          final long pool3End = System.currentTimeMillis();
          final long pool3Duration = pool3End - pool3Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool4 = new DefaultPool( B.class, 5, 10 );
          final long pool4Start = System.currentTimeMillis();
          final int pool4Factor = 20;
          final int pool4Loops = TEST_SIZE / pool4Factor;
          for( int i = 0; i < pool4Loops; i++ )
          {
              final Poolable a1 = pool4.get();
              final Poolable a2 = pool4.get();
              final Poolable a3 = pool4.get();
              final Poolable a4 = pool4.get();
              final Poolable a5 = pool4.get();
              final Poolable a6 = pool4.get();
              final Poolable a7 = pool4.get();
              final Poolable a8 = pool4.get();
              final Poolable a9 = pool4.get();
              final Poolable a10 = pool4.get();
              final Poolable a11 = pool4.get();
              final Poolable a12 = pool4.get();
              final Poolable a13 = pool4.get();
              final Poolable a14 = pool4.get();
              final Poolable a15 = pool4.get();
              final Poolable a16 = pool4.get();
              final Poolable a17 = pool4.get();
              final Poolable a18 = pool4.get();
              final Poolable a19 = pool4.get();
              final Poolable a20 = pool4.get();
              pool4.put(a1);
              pool4.put(a2);
              pool4.put(a3);
              pool4.put(a4);
              pool4.put(a5);
              pool4.put(a6);
              pool4.put(a7);
              pool4.put(a8);
              pool4.put(a9);
              pool4.put(a10);
              pool4.put(a11);
              pool4.put(a12);
              pool4.put(a13);
              pool4.put(a14);
              pool4.put(a15);
              pool4.put(a16);
              pool4.put(a17);
              pool4.put(a18);
              pool4.put(a19);
              pool4.put(a20);
          }
          final long pool4End = System.currentTimeMillis();
          final long pool4Duration = pool4End - pool4Start;
  
          final long createStart = System.currentTimeMillis();
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = new C();
          }
          final long createEnd = System.currentTimeMillis();
          final long createDuration = createEnd - createStart;
  
          //System.out.println("Create Duration: " + createDuration + "ms ");
          System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
  
          final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
          final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
          final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
          final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
  
          //System.out.println("Pool Duration for 100% hits: " + pool1Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
          //System.out.println("Pool Duration for 100% hits and saturated: " + pool2Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
          //System.out.println("Pool Duration for 60% hits: " + pool3Duration + "ms ");
          System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
          //System.out.println("Pool Duration for 50% hits: " + pool4Duration + "ms ");
          System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
      }
  
      public void testLargeObjects()
          throws Exception
      {
          System.out.println("LARGE Sized Objects");
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          final DefaultPool pool1 = new DefaultPool( C.class, 5, 10 );
          final long pool1Start = System.currentTimeMillis();
          final int pool1Factor = 1;
          final int pool1Loops = TEST_SIZE / pool1Factor;
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = pool1.get();
              pool1.put(a1);
          }
          final long pool1End = System.currentTimeMillis();
          final long pool1Duration = pool1End - pool1Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool2 = new DefaultPool( C.class, 5, 10 );
          final long pool2Start = System.currentTimeMillis();
          final int pool2Factor = 10;
          final int pool2Loops = TEST_SIZE / pool2Factor;
          for( int i = 0; i < pool2Loops; i++ )
          {
              final Poolable a1 = pool2.get();
              final Poolable a2 = pool2.get();
              final Poolable a3 = pool2.get();
              final Poolable a4 = pool2.get();
              final Poolable a5 = pool2.get();
              final Poolable a6 = pool2.get();
              final Poolable a7 = pool2.get();
              final Poolable a8 = pool2.get();
              final Poolable a9 = pool2.get();
              final Poolable a10 = pool2.get();
              pool2.put(a1);
              pool2.put(a2);
              pool2.put(a3);
              pool2.put(a4);
              pool2.put(a5);
              pool2.put(a6);
              pool2.put(a7);
              pool2.put(a8);
              pool2.put(a9);
              pool2.put(a10);
          }
          final long pool2End = System.currentTimeMillis();
          final long pool2Duration = pool2End - pool2Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool3 = new DefaultPool( C.class, 5, 10 );
          final long pool3Start = System.currentTimeMillis();
          final int pool3Factor = 15;
          final int pool3Loops = TEST_SIZE / pool3Factor;
          for( int i = 0; i < pool3Loops; i++ )
          {
              final Poolable a1 = pool3.get();
              final Poolable a2 = pool3.get();
              final Poolable a3 = pool3.get();
              final Poolable a4 = pool3.get();
              final Poolable a5 = pool3.get();
              final Poolable a6 = pool3.get();
              final Poolable a7 = pool3.get();
              final Poolable a8 = pool3.get();
              final Poolable a9 = pool3.get();
              final Poolable a10 = pool3.get();
              final Poolable a11 = pool3.get();
              final Poolable a12 = pool3.get();
              final Poolable a13 = pool3.get();
              final Poolable a14 = pool3.get();
              final Poolable a15 = pool3.get();
              pool3.put(a1);
              pool3.put(a2);
              pool3.put(a3);
              pool3.put(a4);
              pool3.put(a5);
              pool3.put(a6);
              pool3.put(a7);
              pool3.put(a8);
              pool3.put(a9);
              pool3.put(a10);
              pool3.put(a11);
              pool3.put(a12);
              pool3.put(a13);
              pool3.put(a14);
              pool3.put(a15);
          }
          final long pool3End = System.currentTimeMillis();
          final long pool3Duration = pool3End - pool3Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
  
          final DefaultPool pool4 = new DefaultPool( C.class, 5, 10 );
          final long pool4Start = System.currentTimeMillis();
          final int pool4Factor = 20;
          final int pool4Loops = TEST_SIZE / pool4Factor;
          for( int i = 0; i < pool4Loops; i++ )
          {
              final Poolable a1 = pool4.get();
              final Poolable a2 = pool4.get();
              final Poolable a3 = pool4.get();
              final Poolable a4 = pool4.get();
              final Poolable a5 = pool4.get();
              final Poolable a6 = pool4.get();
              final Poolable a7 = pool4.get();
              final Poolable a8 = pool4.get();
              final Poolable a9 = pool4.get();
              final Poolable a10 = pool4.get();
              final Poolable a11 = pool4.get();
              final Poolable a12 = pool4.get();
              final Poolable a13 = pool4.get();
              final Poolable a14 = pool4.get();
              final Poolable a15 = pool4.get();
              final Poolable a16 = pool4.get();
              final Poolable a17 = pool4.get();
              final Poolable a18 = pool4.get();
              final Poolable a19 = pool4.get();
              final Poolable a20 = pool4.get();
              pool4.put(a1);
              pool4.put(a2);
              pool4.put(a3);
              pool4.put(a4);
              pool4.put(a5);
              pool4.put(a6);
              pool4.put(a7);
              pool4.put(a8);
              pool4.put(a9);
              pool4.put(a10);
              pool4.put(a11);
              pool4.put(a12);
              pool4.put(a13);
              pool4.put(a14);
              pool4.put(a15);
              pool4.put(a16);
              pool4.put(a17);
              pool4.put(a18);
              pool4.put(a19);
              pool4.put(a20);
          }
          final long pool4End = System.currentTimeMillis();
          final long pool4Duration = pool4End - pool4Start;
  
          System.out.println("FreeMem post 4: " + Runtime.getRuntime().freeMemory() );
  
          final long createStart = System.currentTimeMillis();
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = new C();
          }
          final long createEnd = System.currentTimeMillis();
          final long createDuration = createEnd - createStart;
  
          System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
  
          final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
          final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
          final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
          final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
  
          System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
          System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
          System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
          System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
      }
  
  
      public void testThreadedSmallObjects()
          throws Exception
      {
          System.out.println("SMALL Sized Objects with thread safe pools");
  
          final HardResourceLimitingPool pool1 = new HardResourceLimitingPool( A.class, 5, 10 );
          final long pool1Start = System.currentTimeMillis();
          final int pool1Factor = 1;
          final int pool1Loops = TEST_SIZE / pool1Factor;
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = pool1.get();
              pool1.put(a1);
          }
          final long pool1End = System.currentTimeMillis();
          final long pool1Duration = pool1End - pool1Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool2 = new HardResourceLimitingPool( A.class, 5, 10 );
          final long pool2Start = System.currentTimeMillis();
          final int pool2Factor = 10;
          final int pool2Loops = TEST_SIZE / pool2Factor;
          for( int i = 0; i < pool2Loops; i++ )
          {
              final Poolable a1 = pool2.get();
              final Poolable a2 = pool2.get();
              final Poolable a3 = pool2.get();
              final Poolable a4 = pool2.get();
              final Poolable a5 = pool2.get();
              final Poolable a6 = pool2.get();
              final Poolable a7 = pool2.get();
              final Poolable a8 = pool2.get();
              final Poolable a9 = pool2.get();
              final Poolable a0 = pool2.get();
              pool2.put(a1);
              pool2.put(a2);
              pool2.put(a3);
              pool2.put(a4);
              pool2.put(a5);
              pool2.put(a6);
              pool2.put(a7);
              pool2.put(a8);
              pool2.put(a9);
              pool2.put(a0);
          }
          final long pool2End = System.currentTimeMillis();
          final long pool2Duration = pool2End - pool2Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool3 = new HardResourceLimitingPool( A.class, 5, 10 );
          final long pool3Start = System.currentTimeMillis();
          final int pool3Factor = 15;
          final int pool3Loops = TEST_SIZE / pool3Factor;
          for( int i = 0; i < pool3Loops; i++ )
          {
              final Poolable a1 = pool3.get();
              final Poolable a2 = pool3.get();
              final Poolable a3 = pool3.get();
              final Poolable a4 = pool3.get();
              final Poolable a5 = pool3.get();
              final Poolable a6 = pool3.get();
              final Poolable a7 = pool3.get();
              final Poolable a8 = pool3.get();
              final Poolable a9 = pool3.get();
              final Poolable a10 = pool3.get();
              final Poolable a11 = pool3.get();
              final Poolable a12 = pool3.get();
              final Poolable a13 = pool3.get();
              final Poolable a14 = pool3.get();
              final Poolable a15 = pool3.get();
              pool3.put(a1);
              pool3.put(a2);
              pool3.put(a3);
              pool3.put(a4);
              pool3.put(a5);
              pool3.put(a6);
              pool3.put(a7);
              pool3.put(a8);
              pool3.put(a9);
              pool3.put(a10);
              pool3.put(a11);
              pool3.put(a12);
              pool3.put(a13);
              pool3.put(a14);
              pool3.put(a15);
          }
          final long pool3End = System.currentTimeMillis();
          final long pool3Duration = pool3End - pool3Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool4 = new HardResourceLimitingPool( A.class, 5, 10 );
          final long pool4Start = System.currentTimeMillis();
          final int pool4Factor = 20;
          final int pool4Loops = TEST_SIZE / pool4Factor;
          for( int i = 0; i < pool4Loops; i++ )
          {
              final Poolable a1 = pool4.get();
              final Poolable a2 = pool4.get();
              final Poolable a3 = pool4.get();
              final Poolable a4 = pool4.get();
              final Poolable a5 = pool4.get();
              final Poolable a6 = pool4.get();
              final Poolable a7 = pool4.get();
              final Poolable a8 = pool4.get();
              final Poolable a9 = pool4.get();
              final Poolable a10 = pool4.get();
              final Poolable a11 = pool4.get();
              final Poolable a12 = pool4.get();
              final Poolable a13 = pool4.get();
              final Poolable a14 = pool4.get();
              final Poolable a15 = pool4.get();
              final Poolable a16 = pool4.get();
              final Poolable a17 = pool4.get();
              final Poolable a18 = pool4.get();
              final Poolable a19 = pool4.get();
              final Poolable a20 = pool4.get();
              pool4.put(a1);
              pool4.put(a2);
              pool4.put(a3);
              pool4.put(a4);
              pool4.put(a5);
              pool4.put(a6);
              pool4.put(a7);
              pool4.put(a8);
              pool4.put(a9);
              pool4.put(a10);
              pool4.put(a11);
              pool4.put(a12);
              pool4.put(a13);
              pool4.put(a14);
              pool4.put(a15);
              pool4.put(a16);
              pool4.put(a17);
              pool4.put(a18);
              pool4.put(a19);
              pool4.put(a20);
          }
          final long pool4End = System.currentTimeMillis();
          final long pool4Duration = pool4End - pool4Start;
  
          System.out.println("FreeMem post 4: " + Runtime.getRuntime().freeMemory() );
  
          final long createStart = System.currentTimeMillis();
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = new C();
          }
          final long createEnd = System.currentTimeMillis();
          final long createDuration = createEnd - createStart;
  
          //System.out.println("Create Duration: " + createDuration + "ms ");
          System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
  
          final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
          final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
          final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
          final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
  
          //System.out.println("Pool Duration for 100% hits: " + pool1Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
          //System.out.println("Pool Duration for 100% hits and saturated: " + pool2Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
          //System.out.println("Pool Duration for 60% hits: " + pool3Duration + "ms ");
          System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
          //System.out.println("Pool Duration for 50% hits: " + pool4Duration + "ms ");
          System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
      }
  
      public void testThreadedMediumObjects()
          throws Exception
      {
          System.out.println("MEDIUM Sized Objects with thread safe pools");
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          final HardResourceLimitingPool pool1 = new HardResourceLimitingPool( B.class, 5, 10 );
          final long pool1Start = System.currentTimeMillis();
          final int pool1Factor = 1;
          final int pool1Loops = TEST_SIZE / pool1Factor;
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = pool1.get();
              pool1.put(a1);
          }
          final long pool1End = System.currentTimeMillis();
          final long pool1Duration = pool1End - pool1Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool2 = new HardResourceLimitingPool( B.class, 5, 10 );
          final long pool2Start = System.currentTimeMillis();
          final int pool2Factor = 10;
          final int pool2Loops = TEST_SIZE / pool2Factor;
          for( int i = 0; i < pool2Loops; i++ )
          {
              final Poolable a1 = pool2.get();
              final Poolable a2 = pool2.get();
              final Poolable a3 = pool2.get();
              final Poolable a4 = pool2.get();
              final Poolable a5 = pool2.get();
              final Poolable a6 = pool2.get();
              final Poolable a7 = pool2.get();
              final Poolable a8 = pool2.get();
              final Poolable a9 = pool2.get();
              final Poolable a10 = pool2.get();
              /*
                a1.build();
                a2.build();
                a3.build();
                a4.build();
                a5.build();
                a6.build();
                a7.build();
                a8.build();
                a9.build();
                a10.build();
              */
              pool2.put(a1);
              pool2.put(a2);
              pool2.put(a3);
              pool2.put(a4);
              pool2.put(a5);
              pool2.put(a6);
              pool2.put(a7);
              pool2.put(a8);
              pool2.put(a9);
              pool2.put(a10);
          }
          final long pool2End = System.currentTimeMillis();
          final long pool2Duration = pool2End - pool2Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool3 = new HardResourceLimitingPool( B.class, 5, 10 );
          final long pool3Start = System.currentTimeMillis();
          final int pool3Factor = 15;
          final int pool3Loops = TEST_SIZE / pool3Factor;
          for( int i = 0; i < pool3Loops; i++ )
          {
              final Poolable a1 = pool3.get();
              final Poolable a2 = pool3.get();
              final Poolable a3 = pool3.get();
              final Poolable a4 = pool3.get();
              final Poolable a5 = pool3.get();
              final Poolable a6 = pool3.get();
              final Poolable a7 = pool3.get();
              final Poolable a8 = pool3.get();
              final Poolable a9 = pool3.get();
              final Poolable a10 = pool3.get();
              final Poolable a11 = pool3.get();
              final Poolable a12 = pool3.get();
              final Poolable a13 = pool3.get();
              final Poolable a14 = pool3.get();
              final Poolable a15 = pool3.get();
              /*
                a1.build();
                a2.build();
                a3.build();
                a4.build();
                a5.build();
                a6.build();
                a7.build();
                a8.build();
                a9.build();
                a10.build();
                a11.build();
                a12.build();
                a13.build();
                a14.build();
                a15.build();
              */
              pool3.put(a1);
              pool3.put(a2);
              pool3.put(a3);
              pool3.put(a4);
              pool3.put(a5);
              pool3.put(a6);
              pool3.put(a7);
              pool3.put(a8);
              pool3.put(a9);
              pool3.put(a10);
              pool3.put(a11);
              pool3.put(a12);
              pool3.put(a13);
              pool3.put(a14);
              pool3.put(a15);
          }
          final long pool3End = System.currentTimeMillis();
          final long pool3Duration = pool3End - pool3Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool4 = new HardResourceLimitingPool( B.class, 5, 10 );
          final long pool4Start = System.currentTimeMillis();
          final int pool4Factor = 20;
          final int pool4Loops = TEST_SIZE / pool4Factor;
          for( int i = 0; i < pool4Loops; i++ )
          {
              final Poolable a1 = pool4.get();
              final Poolable a2 = pool4.get();
              final Poolable a3 = pool4.get();
              final Poolable a4 = pool4.get();
              final Poolable a5 = pool4.get();
              final Poolable a6 = pool4.get();
              final Poolable a7 = pool4.get();
              final Poolable a8 = pool4.get();
              final Poolable a9 = pool4.get();
              final Poolable a10 = pool4.get();
              final Poolable a11 = pool4.get();
              final Poolable a12 = pool4.get();
              final Poolable a13 = pool4.get();
              final Poolable a14 = pool4.get();
              final Poolable a15 = pool4.get();
              final Poolable a16 = pool4.get();
              final Poolable a17 = pool4.get();
              final Poolable a18 = pool4.get();
              final Poolable a19 = pool4.get();
              final Poolable a20 = pool4.get();
              /*
                a1.build();
                a2.build();
                a3.build();
                a4.build();
                a5.build();
                a6.build();
                a7.build();
                a8.build();
                a9.build();
                a10.build();
                a11.build();
                a12.build();
                a13.build();
                a14.build();
                a15.build();
                a16.build();
                a17.build();
                a18.build();
                a19.build();
                a20.build();
              */
              pool4.put(a1);
              pool4.put(a2);
              pool4.put(a3);
              pool4.put(a4);
              pool4.put(a5);
              pool4.put(a6);
              pool4.put(a7);
              pool4.put(a8);
              pool4.put(a9);
              pool4.put(a10);
              pool4.put(a11);
              pool4.put(a12);
              pool4.put(a13);
              pool4.put(a14);
              pool4.put(a15);
              pool4.put(a16);
              pool4.put(a17);
              pool4.put(a18);
              pool4.put(a19);
              pool4.put(a20);
          }
          final long pool4End = System.currentTimeMillis();
          final long pool4Duration = pool4End - pool4Start;
  
          final long createStart = System.currentTimeMillis();
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = new C();
          }
          final long createEnd = System.currentTimeMillis();
          final long createDuration = createEnd - createStart;
  
          //System.out.println("Create Duration: " + createDuration + "ms ");
          System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
  
          final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
          final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
          final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
          final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
  
          //System.out.println("Pool Duration for 100% hits: " + pool1Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
          //System.out.println("Pool Duration for 100% hits and saturated: " + pool2Duration + "ms ");
          System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
          //System.out.println("Pool Duration for 60% hits: " + pool3Duration + "ms ");
          System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
          //System.out.println("Pool Duration for 50% hits: " + pool4Duration + "ms ");
          System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
      }
  
      public void testThreadedLargeObjects()
          throws Exception
      {
          System.out.println("LARGE Sized Objects with thread safe pools");
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          final HardResourceLimitingPool pool1 = new HardResourceLimitingPool( C.class, 5, 10 );
          final long pool1Start = System.currentTimeMillis();
          final int pool1Factor = 1;
          final int pool1Loops = TEST_SIZE / pool1Factor;
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = pool1.get();
              //a1.build();
              pool1.put(a1);
          }
          final long pool1End = System.currentTimeMillis();
          final long pool1Duration = pool1End - pool1Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool2 = new HardResourceLimitingPool( C.class, 5, 10 );
          final long pool2Start = System.currentTimeMillis();
          final int pool2Factor = 10;
          final int pool2Loops = TEST_SIZE / pool2Factor;
          for( int i = 0; i < pool2Loops; i++ )
          {
              final Poolable a1 = pool2.get();
              final Poolable a2 = pool2.get();
              final Poolable a3 = pool2.get();
              final Poolable a4 = pool2.get();
              final Poolable a5 = pool2.get();
              final Poolable a6 = pool2.get();
              final Poolable a7 = pool2.get();
              final Poolable a8 = pool2.get();
              final Poolable a9 = pool2.get();
              final Poolable a10 = pool2.get();
              /*
                a1.build();
                a2.build();
                a3.build();
                a4.build();
                a5.build();
                a6.build();
                a7.build();
                a8.build();
                a9.build();
                a10.build();
              */
              pool2.put(a1);
              pool2.put(a2);
              pool2.put(a3);
              pool2.put(a4);
              pool2.put(a5);
              pool2.put(a6);
              pool2.put(a7);
              pool2.put(a8);
              pool2.put(a9);
              pool2.put(a10);
          }
          final long pool2End = System.currentTimeMillis();
          final long pool2Duration = pool2End - pool2Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool3 = new HardResourceLimitingPool( C.class, 5, 10 );
          final long pool3Start = System.currentTimeMillis();
          final int pool3Factor = 15;
          final int pool3Loops = TEST_SIZE / pool3Factor;
          for( int i = 0; i < pool3Loops; i++ )
          {
              final Poolable a1 = pool3.get();
              final Poolable a2 = pool3.get();
              final Poolable a3 = pool3.get();
              final Poolable a4 = pool3.get();
              final Poolable a5 = pool3.get();
              final Poolable a6 = pool3.get();
              final Poolable a7 = pool3.get();
              final Poolable a8 = pool3.get();
              final Poolable a9 = pool3.get();
              final Poolable a10 = pool3.get();
              final Poolable a11 = pool3.get();
              final Poolable a12 = pool3.get();
              final Poolable a13 = pool3.get();
              final Poolable a14 = pool3.get();
              final Poolable a15 = pool3.get();
              /*
                a1.build();
                a2.build();
                a3.build();
                a4.build();
                a5.build();
                a6.build();
                a7.build();
                a8.build();
                a9.build();
                a10.build();
                a11.build();
                a12.build();
                a13.build();
                a14.build();
                a15.build();
              */
              pool3.put(a1);
              pool3.put(a2);
              pool3.put(a3);
              pool3.put(a4);
              pool3.put(a5);
              pool3.put(a6);
              pool3.put(a7);
              pool3.put(a8);
              pool3.put(a9);
              pool3.put(a10);
              pool3.put(a11);
              pool3.put(a12);
              pool3.put(a13);
              pool3.put(a14);
              pool3.put(a15);
          }
          final long pool3End = System.currentTimeMillis();
          final long pool3Duration = pool3End - pool3Start;
  
          System.gc();
          System.gc();
          Thread.currentThread().sleep(2);
  
          System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
  
          final HardResourceLimitingPool pool4 = new HardResourceLimitingPool( C.class, 5, 10 );
          final long pool4Start = System.currentTimeMillis();
          final int pool4Factor = 20;
          final int pool4Loops = TEST_SIZE / pool4Factor;
          for( int i = 0; i < pool4Loops; i++ )
          {
              final Poolable a1 = pool4.get();
              final Poolable a2 = pool4.get();
              final Poolable a3 = pool4.get();
              final Poolable a4 = pool4.get();
              final Poolable a5 = pool4.get();
              final Poolable a6 = pool4.get();
              final Poolable a7 = pool4.get();
              final Poolable a8 = pool4.get();
              final Poolable a9 = pool4.get();
              final Poolable a10 = pool4.get();
              final Poolable a11 = pool4.get();
              final Poolable a12 = pool4.get();
              final Poolable a13 = pool4.get();
              final Poolable a14 = pool4.get();
              final Poolable a15 = pool4.get();
              final Poolable a16 = pool4.get();
              final Poolable a17 = pool4.get();
              final Poolable a18 = pool4.get();
              final Poolable a19 = pool4.get();
              final Poolable a20 = pool4.get();
              pool4.put(a1);
              pool4.put(a2);
              pool4.put(a3);
              pool4.put(a4);
              pool4.put(a5);
              pool4.put(a6);
              pool4.put(a7);
              pool4.put(a8);
              pool4.put(a9);
              pool4.put(a10);
              pool4.put(a11);
              pool4.put(a12);
              pool4.put(a13);
              pool4.put(a14);
              pool4.put(a15);
              pool4.put(a16);
              pool4.put(a17);
              pool4.put(a18);
              pool4.put(a19);
              pool4.put(a20);
          }
          final long pool4End = System.currentTimeMillis();
          final long pool4Duration = pool4End - pool4Start;
  
          System.out.println("FreeMem post 4: " + Runtime.getRuntime().freeMemory() );
  
          final long createStart = System.currentTimeMillis();
          for( int i = 0; i < TEST_SIZE; i++ )
          {
              final Poolable a1 = new C();
          }
          final long createEnd = System.currentTimeMillis();
          final long createDuration = createEnd - createStart;
  
          System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
  
          final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
          final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
          final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
          final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
  
          System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
          System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
          System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
          System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: avalon-dev-help@jakarta.apache.org


Mime
View raw message