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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Peter Donald</a> * @author <a href="mailto:[EMAIL PROTECTED]">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 <[EMAIL PROTECTED]> */ 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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Federico Barbieri</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Federico Barbieri</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Mike Engelhart</a> * @author <a href="mailto:[EMAIL PROTECTED]">Neeme Praks</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Mike Engelhart</a> * @author <a href="mailto:[EMAIL PROTECTED]">Neeme Praks</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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 <[EMAIL PROTECTED]> */ 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:[EMAIL PROTECTED]">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 <[EMAIL PROTECTED]> * @author Serge Knystautas <[EMAIL PROTECTED]> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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 <[EMAIL PROTECTED]> */ 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 <[EMAIL PROTECTED]> */ 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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]