You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by do...@apache.org on 2001/02/24 04:59:43 UTC
cvs commit: jakarta-avalon/src/java/org/apache/avalon/util/thread DefaultThreadManager.java ThreadContext.java ThreadManager.java ThreadPool.java WorkerThread.java
donaldp 01/02/23 19:59:43
Added: src/java/org/apache/avalon/util ArrayEnumeration.java
ArrayStack.java BinaryHeap.java Circuit.java
CircularBuffer.java
CircularDependencyException.java
DependencyGraph.java Enum.java
IteratorEnumeration.java ListUtils.java Lock.java
LockException.java ObjectUtil.java Primes.java
PriorityQueue.java PropertyException.java
PropertyUtil.java ProxyClassLoader.java
ProxyGenerator.java StringUtil.java ValuedEnum.java
Version.java
src/java/org/apache/avalon/util/cli AbstractMain.java
AbstractParserControl.java CLArgsParser.java
CLOption.java CLOptionDescriptor.java CLUtil.java
ParserControl.java
src/java/org/apache/avalon/util/cli/test ClutilTestlet.java
src/java/org/apache/avalon/util/datasource
DataSourceComponent.java J2eeDataSource.java
JdbcConnection.java JdbcConnectionPool.java
JdbcDataSource.java
src/java/org/apache/avalon/util/datasource/test
DataSourceTestlet.java
src/java/org/apache/avalon/util/i18n ResourceGroup.java
XMLResourceBundle.java
XMLResourceBundleFactory.java XPathAPI.java
src/java/org/apache/avalon/util/internet
CRLFInputStream.java CRLFOutputStream.java
InternetException.java InternetReply.java
InternetStream.java LineReader.java LineWriter.java
src/java/org/apache/avalon/util/io
ByteTerminatedInputStream.java
DirectoryFileFilter.java ExtensionFileFilter.java
FileUtil.java IOUtil.java MergedInputStreams.java
ResettableFileInputStream.java
src/java/org/apache/avalon/util/io/test FileUtilTestlet.java
src/java/org/apache/avalon/util/lang ThreadManager.java
src/java/org/apache/avalon/util/log AvalonLogFormatter.java
DefaultLogManager.java
src/java/org/apache/avalon/util/pool AbstractPool.java
DefaultObjectFactory.java DefaultPool.java
ObjectFactory.java Pool.java PoolController.java
ThreadSafePool.java
src/java/org/apache/avalon/util/pool/test PoolProfile.java
src/java/org/apache/avalon/util/security AbstractPolicy.java
DefaultPolicy.java PolicyClassLoader.java
src/java/org/apache/avalon/util/test BinaryHeapTestlet.java
DependencyGraphTestlet.java
PropertyUtilTestlet.java ProxyGeneratorTestlet.java
StringUtilTestlet.java
src/java/org/apache/avalon/util/thread
DefaultThreadManager.java ThreadContext.java
ThreadManager.java ThreadPool.java
WorkerThread.java
Log:
Rechecked in util sub-directory
Revision Changes Path
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ArrayEnumeration.java
Index: ArrayEnumeration.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.Enumeration;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Enumeration wrapper for array.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class ArrayEnumeration
implements Enumeration
{
protected Object[] m_elements;
protected int m_index;
public ArrayEnumeration( final List elements )
{
m_elements = elements.toArray();
}
public ArrayEnumeration( final Object[] elements )
{
m_elements = elements;
}
public boolean hasMoreElements()
{
return ( m_index < m_elements.length );
}
public Object nextElement()
{
if( !hasMoreElements() )
{
throw new NoSuchElementException("No more elements exist");
}
return m_elements[ m_index++ ];
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ArrayStack.java
Index: ArrayStack.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.ArrayList;
import java.util.EmptyStackException;
/**
* Unsynchronized stakc.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ArrayStack
extends ArrayList
{
public void setSize( final int size )
{
if( 0 == size ) clear();
else
{
removeRange( size, size() - 1 );
}
}
/**
* Adds the object to the top of the stack.
*
* @param element object to add to stack
* @return the object
*/
public Object push( final Object element )
{
add( element );
return element;
}
/**
* Remove element from top of stack and return it
*
* @return the element from stack
* @exception EmptyStackException if no elements left on stack
*/
public Object pop()
throws EmptyStackException
{
final int size = size();
if( 0 == size ) throw new EmptyStackException();
return remove( size - 1 );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/BinaryHeap.java
Index: BinaryHeap.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.NoSuchElementException;
/**
* Iterface for priority queues.
* This interface does not dictate whether it is min or max heap.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class BinaryHeap
implements PriorityQueue
{
protected final static int DEFAULT_CAPACITY = 13;
protected int m_size;
protected Comparable[] m_elements;
protected boolean m_isMinHeap;
public BinaryHeap()
{
this( DEFAULT_CAPACITY, true );
}
public BinaryHeap( final int capacity )
{
this( capacity, true );
}
public BinaryHeap( final boolean isMinHeap )
{
this( DEFAULT_CAPACITY, isMinHeap );
}
public BinaryHeap( final int capacity, final boolean isMinHeap )
{
m_isMinHeap = isMinHeap;
//+1 as 0 is noop
m_elements = new Comparable[ capacity + 1 ];
}
/**
* Clear all elements from queue.
*/
public void clear()
{
m_size = 0;
}
/**
* Test if queue is empty.
*
* @return true if queue is empty else false.
*/
public boolean isEmpty()
{
return ( 0 == m_size );
}
/**
* Test if queue is full.
*
* @return true if queue is full else false.
*/
public boolean isFull()
{
return ( m_elements.length == m_size );
}
/**
* Insert an element into queue.
*
* @param element the element to be inserted
*/
public void insert( final Comparable element )
{
if( isFull() ) grow();
//percolate element to it's place in tree
if( m_isMinHeap ) percolateUpMinHeap( element );
else percolateUpMaxHeap( element );
}
/**
* Return element on top of heap but don't remove it.
*
* @return the element at top of heap
* @exception NoSuchElementException if isEmpty() == true
*/
public Comparable peek() throws NoSuchElementException
{
if( isEmpty() ) throw new NoSuchElementException();
else return m_elements[ 1 ];
}
/**
* Return element on top of heap and remove it.
*
* @return the element at top of heap
* @exception NoSuchElementException if isEmpty() == true
*/
public Comparable pop() throws NoSuchElementException
{
final Comparable result = peek();
m_elements[ 1 ] = m_elements[ m_size-- ];
if( m_size != 0 )
{
//percolate top element to it's place in tree
if( m_isMinHeap ) percolateDownMinHeap( 1 );
else percolateDownMaxHeap( 1 );
}
return result;
}
/**
* Percolate element down heap from top.
* Assume it is a maximum heap.
*
* @param element the element
*/
protected void percolateDownMinHeap( final int index )
{
final Comparable element = m_elements[ index ];
int hole = index;
while( (hole * 2) <= m_size )
{
int child = hole * 2;
//if we have a right child and that child can not be percolated
//up then move onto other child
if( child != m_size &&
m_elements[ child + 1 ].compareTo( m_elements[ child ] ) < 0 )
{
child++;
}
//if we found resting place of bubble then terminate search
if( m_elements[ child ].compareTo( element ) >= 0 )
{
break;
}
m_elements[ hole ] = m_elements[ child ];
hole = child;
}
m_elements[ hole ] = element;
}
/**
* Percolate element down heap from top.
* Assume it is a maximum heap.
*
* @param element the element
*/
protected void percolateDownMaxHeap( final int index )
{
final Comparable element = m_elements[ index ];
int hole = index;
while( (hole * 2) <= m_size )
{
int child = hole * 2;
//if we have a right child and that child can not be percolated
//up then move onto other child
if( child != m_size &&
m_elements[ child + 1 ].compareTo( m_elements[ child ] ) > 0 )
{
child++;
}
//if we found resting place of bubble then terminate search
if( m_elements[ child ].compareTo( element ) <= 0 )
{
break;
}
m_elements[ hole ] = m_elements[ child ];
hole = child;
}
m_elements[ hole ] = element;
}
/**
* Percolate element up heap from bottom.
* Assume it is a maximum heap.
*
* @param element the element
*/
protected void percolateUpMinHeap( final Comparable element )
{
int hole = ++m_size;
m_elements[ hole ] = element;
while( hole > 1 &&
element.compareTo( m_elements[ hole / 2 ] ) < 0 )
{
//save element that is being pushed down
//as the element "bubble" is percolated up
final int next = hole / 2;
m_elements[ hole ] = m_elements[ next ];
hole = next;
}
m_elements[ hole ] = element;
}
/**
* Percolate element up heap from bottom.
* Assume it is a maximum heap.
*
* @param element the element
*/
protected void percolateUpMaxHeap( final Comparable element )
{
int hole = ++m_size;
while( hole > 1 &&
element.compareTo( m_elements[ hole / 2 ] ) > 0 )
{
//save element that is being pushed down
//as the element "bubble" is percolated up
final int next = hole / 2;
m_elements[ hole ] = m_elements[ next ];
hole = next;
}
m_elements[ hole ] = element;
}
protected void grow()
{
final Comparable[] elements =
new Comparable[ m_elements.length * 2 ];
System.arraycopy( m_elements, 0, elements, 0, m_elements.length );
m_elements = elements;
}
public String toString()
{
final StringBuffer sb = new StringBuffer();
sb.append( "[ " );
for( int i = 1; i < m_size + 1; i++ )
{
if( i != 1 ) sb.append( ", " );
sb.append( m_elements[ i ] );
}
sb.append( " ]" );
return sb.toString();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/Circuit.java
Index: Circuit.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
*
* @version 0.0.20, 04/07/1998
* @author Federico Barbieri <fe...@apache.org>
* @author Stefano Mazzocchi <ma...@mbox.systemy.it>
*/
public class Circuit
{
protected Hashtable m_map;
public Circuit()
{
m_map = new Hashtable();
}
public void addNode( final String name )
{
if( null == m_map.get( name ) )
{
m_map.put( name, new Node( name ) );
}
}
public void removeNode( final String name )
{
String tmp = null;
Enumeration e = m_map.keys();
while( e.hasMoreElements() )
{
tmp = (String)e.nextElement();
if( !tmp.equals( name ) )
{
try { unlink( tmp, name ); }
catch( final CircuitException ce) {}
try { unlink( name, tmp ); }
catch( final CircuitException ce ) {}
}
}
m_map.remove( name );
}
public void link( final String parent, final String child )
throws CircuitException
{
Node tempNode = null;
Node pnode = (Node)m_map.get( parent );
Node cnode = (Node)m_map.get( child );
if( null == pnode )
{
throw new CircuitException( "Unknown node " + parent );
}
else if( null == cnode )
{
throw new CircuitException( "Unknown node " + child );
}
else if( pnode.isChildOf( cnode ) )
{
throw new CircuitException( "Loop! Node " + parent +
" is already child of node " + child );
}
else
{
final Enumeration e = m_map.elements();
while( e.hasMoreElements() )
{
tempNode = (Node)e.nextElement();
if( tempNode.isChildOf( cnode ) )
{
tempNode.m_parents.addAll( pnode.m_parents );
}
}
}
}
public void unlink( final String parent, final String child )
throws CircuitException
{
Node cnode = (Node)m_map.get( child );
Node pnode = (Node)m_map.get( parent );
if( cnode.m_parents.contains( pnode ) )
{
Node tempNode = null;
Enumeration e = m_map.elements();
while( e.hasMoreElements() )
{
tempNode = (Node)e.nextElement();
if( tempNode.m_parents.contains( cnode ) )
{
tempNode.m_parents.removeAll( pnode.m_parents );
}
}
}
else
{
throw new CircuitException( "Node " + parent + " is not parent of node " + child );
}
}
public Vector getAncestors()
{
Vector ancestors = new Vector();
String name = null;
Node tempNode = null;
Enumeration e = m_map.keys();
while( e.hasMoreElements() )
{
name = (String)e.nextElement();
tempNode = (Node)m_map.get( name );
if( 1 == tempNode.m_parents.size() )
{
ancestors.addElement( name );
}
}
return ancestors;
}
public String getAncestor()
{
String name = null;
Node tempNode = null;
Enumeration e = m_map.keys();
while( e.hasMoreElements() )
{
name = (String)e.nextElement();
tempNode = (Node)m_map.get( name );
if( 1 == tempNode.m_parents.size() )
{
return name;
}
}
return null;
}
public boolean isEmpty()
{
return m_map.isEmpty();
}
protected final class Node
{
protected Vector m_parents;
protected String m_name;
protected Node( final String name )
{
m_parents = new Vector( 5 );
m_parents.addElement( this );
m_name = name;
}
protected boolean isChildOf( final Node parent )
{
return m_parents.contains( parent );
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
Enumeration e = m_parents.elements();
buffer.append( m_name + "[" );
while( e.hasMoreElements() )
{
buffer.append(((Node) e.nextElement()).m_name + " ");
}
buffer.append("]");
return buffer.toString();
}
}
public final class CircuitException
extends RuntimeException
{
public CircuitException()
{
}
public CircuitException( final String message )
{
super( message );
}
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
String name = null;
Node tempNode = null;
Enumeration e = m_map.keys();
while( e.hasMoreElements() )
{
name = (String)e.nextElement();
tempNode = (Node)m_map.get( name );
buffer.append( name + "(" + ( tempNode.m_parents.size() - 1 ) + ") " );
}
return buffer.toString();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/CircularBuffer.java
Index: CircularBuffer.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
/**
*
* @author Federico Barbieri <fe...@apache.org>
*/
public class CircularBuffer
{
protected Object[] m_buffer;
protected int m_bufferSize;
protected int m_contentSize;
protected int m_head;
protected int m_tail;
public CircularBuffer( int size )
{
m_buffer = new Object[size];
m_bufferSize = size;
m_contentSize = 0;
m_head = 0;
m_tail = 0;
}
public CircularBuffer()
{
this( 32 );
}
public boolean isEmpty()
{
return (m_contentSize == 0);
}
public int getContentSize()
{
return m_contentSize;
}
public int getBufferSize()
{
return m_bufferSize;
}
public void append( final Object o )
{
if( m_contentSize >= m_bufferSize )
{
int j = 0;
int i = m_tail;
Object[] tmp = new Object[ m_bufferSize * 2 ];
while( m_contentSize > 0 )
{
i++;
i %= m_bufferSize;
j++;
m_contentSize--;
tmp[ j ] = m_buffer[ i ];
}
m_buffer = tmp;
m_tail = 0;
m_head = j;
m_contentSize = j;
m_bufferSize *= 2;
}
m_buffer[ m_head ] = o;
m_head++;
m_head %= m_bufferSize;
m_contentSize++;
}
public Object get()
{
if( m_contentSize <= 0 )
{
return null;
}
Object o = m_buffer[ m_tail ];
m_tail++;
m_tail %= m_bufferSize;
m_contentSize--;
return o;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/CircularDependencyException.java
Index: CircularDependencyException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.List;
import org.apache.avalon.CascadingException;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class CircularDependencyException
extends CascadingException
{
protected List m_stack;
public CircularDependencyException( final String dependee,
final String dependent,
final List stack )
{
super( dependee + " depends upon " + dependent + " which depends upong " + dependee );
m_stack = stack;
}
public List getStack()
{
return m_stack;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/DependencyGraph.java
Index: DependencyGraph.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/**
* DirectedGraph is a acyclic Directed graph implementation.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DependencyGraph
{
protected final HashMap m_map = new HashMap();
protected boolean m_allowCircularity = true;
public void setAllowCircularity( final boolean allowCircularity )
{
m_allowCircularity = allowCircularity;
}
public void add( final String name, final String[] dependencies )
{
m_map.put( name, new GraphNode( name, dependencies ) );
}
public void remove( final String name )
{
m_map.remove( name );
}
public Dependency[] getDependencyList( final String name )
throws CircularDependencyException
{
final ArrayList list = new ArrayList();
final Dependency dependency = new Dependency( name , null );
list.add( dependency );
if( null != m_map.get( name ) )
{
final ArrayList stack = new ArrayList();
stack.add( name );
buildDependencyList( name, list, new ArrayList(), stack );
}
return (Dependency[])list.toArray( new Dependency[ 0 ] );
}
protected void buildDependencyList( final String name,
final ArrayList list,
final ArrayList done,
final ArrayList stack )
throws CircularDependencyException
{
if( done.contains( name ) ) return;
done.add( name );
final GraphNode node = (GraphNode)m_map.get( name );
if( null == node ) return;
final String[] dependencies = node.getDependencies();
for( int i = 0; i < dependencies.length; i++ )
{
if( stack.contains( dependencies[ i ] ) )
{
if( m_allowCircularity ) continue;
else
{
throw new CircularDependencyException( dependencies[ i ], name, stack );
}
}
if( done.contains( dependencies[ i ] ) ) continue;
final Dependency dependency = new Dependency( dependencies[ i ], name );
list.add( dependency );
stack.add( dependencies[ i ] );
buildDependencyList( dependencies[ i ], list, done, stack );
stack.remove( stack.size() - 1 );
}
}
public final static class Dependency
{
protected final String m_name;
protected final String m_requiredBy;
protected Dependency( final String name, final String requiredBy )
{
m_name = name;
m_requiredBy = requiredBy;
}
public String getName()
{
return m_name;
}
public String getRequiredBy()
{
return m_requiredBy;
}
public String toString()
{
return getName();
}
}
protected final static class GraphNode
{
protected final String m_name;
protected final String[] m_dependencies;
protected GraphNode( final String name, final String[] dependencies )
{
m_name = name;
m_dependencies = dependencies;
}
public String getName()
{
return m_name;
}
public String[] getDependencies()
{
return m_dependencies;
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/Enum.java
Index: Enum.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.Map;
/**
* Basic enum class for type-safe enums. Should be used as an abstract base.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public abstract class Enum
{
protected final String m_name;
public Enum( final String name )
{
this( name, null );
}
public Enum( final String name, final Map map )
{
m_name = name;
if( null != map )
{
map.put( name, this );
}
}
public final String getName()
{
return m_name;
}
public String toString()
{
return getClass().getName() + "[" + m_name + "]";
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/IteratorEnumeration.java
Index: IteratorEnumeration.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Enumeration wrapper for iterator.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class IteratorEnumeration
implements Enumeration
{
protected Iterator m_iterator;
public IteratorEnumeration( final Iterator iterator )
{
m_iterator = iterator;
}
public boolean hasMoreElements()
{
return m_iterator.hasNext();
}
public Object nextElement()
{
return m_iterator.next();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ListUtils.java
Index: ListUtils.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Miscelaneous utilities to manipulate Lists.
*
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ListUtils
{
public static List intersection( final List list1, final List list2 )
{
final ArrayList result = new ArrayList();
final Iterator iterator = list2.iterator();
while( iterator.hasNext() )
{
final Object o = iterator.next();
if ( list1.contains( o ) )
{
result.add( o );
}
}
return result;
}
public static List subtract( final List list1, final List list2 )
{
final ArrayList result = new ArrayList( list1 );
final Iterator iterator = list2.iterator();
while( iterator.hasNext() )
{
result.remove( iterator.next() );
}
return result;
}
public static List sum( final List list1, final List list2 )
{
return subtract( union( list1, list2 ),
intersection( list1, list2 ) );
}
public static List union( final List list1, final List list2 )
{
final ArrayList result = new ArrayList( list1 );
result.addAll( list2 );
return result;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/Lock.java
Index: Lock.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.Hashtable;
/**
* @author Federico Barbieri <fe...@apache.org>
*/
public class Lock
{
private Hashtable locks = new Hashtable();
public boolean isLocked( final Object key )
{
return (locks.get(key) != null);
}
public boolean canI( final Object key )
{
Object o = locks.get( key );
if( null == o || o == this.getCallerId() )
{
return true;
}
return false;
}
public boolean lock( final Object key )
{
Object theLock;
synchronized( this )
{
theLock = locks.get( key );
}
if( null == theLock )
{
locks.put( key, getCallerId() );
return true;
}
else if( getCallerId() == theLock )
{
return true;
}
else
{
return false;
}
}
public boolean unlock( final Object key )
{
Object theLock;
synchronized( this )
{
theLock = locks.get( key );
}
if( null == theLock )
{
return true;
}
else if( getCallerId() == theLock )
{
locks.remove( key );
return true;
}
else
{
return false;
}
}
private Object getCallerId()
{
return Thread.currentThread();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/LockException.java
Index: LockException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
public class LockException
extends RuntimeException
{
public LockException( final String message )
{
super( message );
}
public LockException()
{
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ObjectUtil.java
Index: ObjectUtil.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
/**
* This class provides basic facilities for manipulating objects.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class ObjectUtil
{
/**
* Private constructor to prevent instantiation.
*/
private ObjectUtil()
{
}
public static boolean isEqual( final Object o1, final Object o2 )
{
if( null == o1 )
{
if( null == o2 )
{
return true;
}
else
{
return false;
}
}
else if( null == o2 )
{
return false;
}
else
{
return o1.equals( o2 );
}
}
public static Object createObject( final ClassLoader classLoader, final String classname )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
final Class clazz = classLoader.loadClass( classname );
return clazz.newInstance();
}
public static Object createObject( final String classname )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
final Class clazz = Class.forName( classname );
return clazz.newInstance();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/Primes.java
Index: Primes.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
/**
*
* @author Federico Barbieri <fe...@apache.org>
* @author Stefano Mazzocchi <ma...@mbox.systemy.it>
*/
public class Primes
{
/**
* Last prime found.
*
*/
protected static long c_lastPrime = 1;
/**
* Return next prime.
*
*/
public static long nextPrime()
{
long l = c_lastPrime + 1;
long v = 2;
while( true )
{
l++;
while( v < l )
{
v++;
if( (l % v) == 0 )
{
v = 0;
break;
}
} // while v < l
if( v == l )
{
c_lastPrime = l;
return l;
} // if v is l
} // while true (break is used to escape)
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/PriorityQueue.java
Index: PriorityQueue.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.util.NoSuchElementException;
/**
* Iterface for priority queues.
* This interface does not dictate whether it is min or max heap.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface PriorityQueue
{
/**
* Clear all elements from queue.
*/
void clear();
/**
* Test if queue is empty.
*
* @return true if queue is empty else false.
*/
boolean isEmpty();
/**
* Insert an element into queue.
*
* @param element the element to be inserted
*/
void insert( Comparable element );
/**
* Return element on top of heap but don't remove it.
*
* @return the element at top of heap
* @exception NoSuchElementException if isEmpty() == true
*/
Comparable peek() throws NoSuchElementException;
/**
* Return element on top of heap and remove it.
*
* @return the element at top of heap
* @exception NoSuchElementException if isEmpty() == true
*/
Comparable pop() throws NoSuchElementException;
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/PropertyException.java
Index: PropertyException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import org.apache.avalon.CascadingException;
/**
* Thrown when a property can not be resolved properly.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class PropertyException
extends CascadingException
{
/**
* Construct a new <code>PropertyException</code> instance.
*
* @param message The detail message for this exception.
*/
public PropertyException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>PropertyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public PropertyException( final String message, final Throwable throwable )
{
super( message, throwable );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/PropertyUtil.java
Index: PropertyUtil.java
===================================================================
package org.apache.avalon.util;
import org.apache.avalon.Context;
import org.apache.avalon.Resolvable;
/**
* This provides utility methods for properties.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class PropertyUtil
{
private PropertyUtil()
{
}
/**
* Resolve property.
* This evaluates all property substitutions based on current context.
*
* @param property the property to resolve
* @param context the context in which to resolve property
* @param ignoreUndefined if false will throw an PropertyException if property is not found
* @return the reolved property
* @exception PropertyException if an error occurs
*/
public static Object resolveProperty( final String property,
final Context context,
final boolean ignoreUndefined )
throws PropertyException
{
int start = property.indexOf( "${" );
if( -1 == start ) return property;
int end = property.indexOf( '}', start );
if( -1 == end ) return property;
final int length = property.length();
if( 0 == start && end == (length - 1) )
{
return resolveValue( property.substring( start + 2, end ),
context,
ignoreUndefined );
}
final StringBuffer sb = new StringBuffer();
int lastPlace = 0;
while( true )
{
final Object value =
resolveValue( property.substring( start + 2, end ),
context,
ignoreUndefined );
sb.append( property.substring( lastPlace, start ) );
sb.append( value );
lastPlace = end + 1;
start = property.indexOf( "${", end );
if( -1 == start ) break;
end = property.indexOf( '}', start );
if( -1 == end ) break;
}
sb.append( property.substring( lastPlace, length ) );
return sb.toString();
}
protected static Object resolveValue( final String key,
final Context context,
final boolean ignoreUndefined )
throws PropertyException
{
Object value = context.get( key );
while( null != value && value instanceof Resolvable )
{
value = ((Resolvable)value).resolve( context );
}
if( null == value )
{
if( ignoreUndefined )
{
return "";
}
else
{
throw new PropertyException( "Unable to find " + key + " to expand during " +
"property resolution." );
}
}
return value;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ProxyClassLoader.java
Index: ProxyClassLoader.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
/**
* Utility class to help load dynamically generated classes.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ProxyClassLoader
extends ClassLoader
{
public ProxyClassLoader( final ClassLoader parent )
{
super( parent );
}
public Class loadClass( final String name,
final boolean resolve,
final byte[] classData )
throws ClassNotFoundException
{
final Class result =
defineClass( name, classData, 0, classData.length );
if( resolve )
{
resolveClass( result );
}
return result;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ProxyGenerator.java
Index: ProxyGenerator.java
===================================================================
/**
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import gnu.bytecode.Access;
import gnu.bytecode.ClassType;
import gnu.bytecode.ClassTypeWriter;
import gnu.bytecode.CodeAttr;
import gnu.bytecode.Field;
import gnu.bytecode.Scope;
import gnu.bytecode.Type;
import gnu.bytecode.Variable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.log.LogKit;
import org.apache.log.Logger;
/**
* A class to generate proxies for objects.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class ProxyGenerator
{
protected final static boolean DEBUG = false;
protected final static Logger LOGGER =
( DEBUG ) ? LogKit.getLoggerFor( "ProxyGenerator" ) : null;
protected final static Object MONITOR = new Object();
protected final static ClassType BASE_CLASS =
(ClassType)Type.getType( "java.lang.Object" );
protected static long c_currentId;
/**
* Private constructor to block subclassing.
*
*/
private ProxyGenerator()
{
}
/**
* Way to generate unique id for each class.
*
* @return a unique id
*/
protected static long getNextId()
{
synchronized( MONITOR )
{
return c_currentId++;
}
}
/**
* Generate a proxy for object with certain interfaces.
*
* @param object the object
* @param interfaces[] the interfaces
* @return the proxy object
* @exception IllegalArgumentException if an error occurs
*/
public static Object generateProxy( final Object object,
final Class[] interfaces )
throws IllegalArgumentException
{
if( DEBUG )
{
LOGGER.debug( "Generating proxy for " + object.getClass().getName() );
LOGGER.debug( "Interfaces generating:" );
for( int i = 0; i < interfaces.length; i++ )
{
LOGGER.debug( interfaces[ i ].getName() );
}
}
for( int i = 0; i < interfaces.length; i++ )
{
if( !interfaces[ i ].isInterface() )
{
throw new IllegalArgumentException( "Class " + interfaces[ i ].getName() +
" is not an interface" );
}
else if( !interfaces[ i ].isInstance( object ) )
{
throw new IllegalArgumentException( "Object does not implement interface " +
interfaces[ i ].getName() );
}
}
final HashMap methodSet = determineMethods( interfaces );
final String classname = "org.apache.avalon.tmp.Proxy" + getNextId();
if( DEBUG ) { LOGGER.debug( "Generating proxy named " + classname ); }
final ClassType proxy = createProxyType( classname );
//generate all interface declarations
generateInterfaces( proxy, interfaces );
final ClassType target =
(ClassType)Type.make( object.getClass() );
target.doFixups();
//generate variables/constructor
generateBase( proxy, target );
//generate methods
final Iterator methods = methodSet.values().iterator();
while( methods.hasNext() )
{
generateMethod( proxy, target, (Method)methods.next() );
}
if( DEBUG )
{
//help while debugging
//ClassTypeWriter.print( target, System.out, 0 );
//try { proxy.writeToFile( "/tmp/" + classname.replace('.','/') + ".class" ); }
//catch( final Throwable throwable ) { throwable.printStackTrace(); }
}
proxy.doFixups();
Class proxyClass = null;
try
{
final byte[] classData = proxy.writeToArray();
//extremely inneficient - must fix in future
final ProxyClassLoader classLoader =
new ProxyClassLoader( object.getClass().getClassLoader() );
proxyClass = classLoader.loadClass( classname, true, classData );
final Constructor ctor =
proxyClass.getConstructor( new Class[] { object.getClass() } );
return ctor.newInstance( new Object[] { object } );
}
catch( final Throwable throwable ) { throwable.printStackTrace(); }
return null;
}
/**
* Create Proxy class.
*
* @param classname name of class
* @return the proxy class
*/
protected static ClassType createProxyType( final String classname )
{
final ClassType proxy = new ClassType( classname );
proxy.setModifiers( Access.PUBLIC | /*ACC_SUPER*/ 0x0020 | Access.FINAL );
proxy.setSuper( BASE_CLASS );
return proxy;
}
/**
* generate the list of Interfaces class implements.
*
* @param proxy the proxy class
* @param interfaces[] the interfaces to add
*/
protected static void generateInterfaces( final ClassType proxy,
final Class[] interfaces )
{
final ClassType[] interfaceTypes = new ClassType[ interfaces.length ];
for( int i = 0; i < interfaceTypes.length; i++ )
{
interfaceTypes[ i ] = (ClassType)Type.getType( interfaces[ i ].getName() );
}
proxy.setInterfaces( interfaceTypes );
}
/**
* Generate code for wrapper method.
*
* @param proxy the class to add to
* @param target the class wrapping
* @param method the method to wrap
*/
protected static void generateMethod( final ClassType proxy,
final ClassType target,
final Method method )
{
final Class[] parameters = method.getParameterTypes();
final Type[] parameterTypes = new Type[ parameters.length ];
for( int i = 0; i < parameterTypes.length; i++ )
{
parameterTypes[ i ] = Type.getType( parameters[ i ].getName() );
}
final Type returnType =
Type.getType( method.getReturnType().getName() );
final gnu.bytecode.Method newMethod =
proxy.addMethod( method.getName(),
Access.PUBLIC,
parameterTypes,
returnType );
newMethod.init_param_slots();
newMethod.pushScope();
final CodeAttr code = newMethod.getCode();
//put m_core on stack;
final Field field = proxy.getField( "m_core" );
code.emitPushThis();
code.emitGetField( field );
for( int i = 0; i < parameterTypes.length; i++ )
{
code.emitLoad( code.getArg( 1 + i ) );
}
//call target method
final gnu.bytecode.Method targetMethod =
target.getMethod( method.getName(), parameterTypes );
code.emitInvokeVirtual( targetMethod );
//return
code.emitReturn();
newMethod.popScope();
}
/**
* Generate constructor code and field data.
*
* @param proxy the representation of class so far
* @param target the type that is wrapped
*/
protected static void generateBase( final ClassType proxy,
final Type target )
{
final Field field = proxy.addField( "m_core", target );
field.flags |= Access.PRIVATE;
final gnu.bytecode.Method constructor =
proxy.addMethod( "<init>",
Access.PUBLIC,
new Type[] { target },
Type.void_type );
final gnu.bytecode.Method superConstructor
= proxy.getSuperclass().addMethod( "<init>",
Access.PUBLIC,
null,
Type.void_type );
constructor.init_param_slots();
constructor.pushScope();
final CodeAttr code = constructor.getCode();
//super();
code.emitPushThis();
code.emitInvokeSpecial( superConstructor );
//m_core = param1;
code.emitPushThis();
code.emitLoad( code.getArg( 1 ) );
code.emitPutField( field );
//return
code.emitReturn();
constructor.popScope();
}
/**
* Determine the methods that must be implemented to
* implement interface, eliminating duplicates.
*
* @param interfaces[] the interfaces to extract methods from
* @return methods
*/
protected static HashMap determineMethods( final Class[] interfaces )
{
final HashMap methodSet = new HashMap();
final StringBuffer sb = new StringBuffer();
for( int i = 0; i < interfaces.length; i++ )
{
if( DEBUG )
{
LOGGER.debug( "Scanning interface " + interfaces[ i ].getName() +
" for methods" );
}
final Method[] methods = interfaces[ i ].getMethods();
//for each method generate a pseudo signature
//Add the method to methodSet under that signature.
//This is to ensure that only one version of a method is
//entered into set even if multiple interfaces declare it
for( int j = 0; j < methods.length; j++ )
{
sb.append( methods[ j ].getName() );
sb.append( '(' );
final Class[] parameters = methods[ j ].getParameterTypes();
for( int k = 0; k < parameters.length; k++ )
{
sb.append( parameters[ k ].getName() );
sb.append( ' ' );
}
sb.append( ";)" );
if( DEBUG )
{
LOGGER.debug( "Found method with pseudo-signature " + sb );
}
methodSet.put( sb.toString(), methods[ j ] );
sb.setLength( 0 );
}
}
return methodSet;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/StringUtil.java
Index: StringUtil.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.apache.avalon.CascadingThrowable;
/**
* This class provides basic facilities for manipulating strings.
*
* Some exception handling stuff thieved from Turbine...
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
*/
public final class StringUtil
{
/**
* Private constructor to prevent instantiation.
*/
private StringUtil()
{
}
/**
* Replace substrings of one string with another string and return altered string.
*
* @param original input string
* @param oldString the substring section to replace
* @param newString the new substring replacing old substring section
* @return converted string
*/
public static String replaceSubString( final String original,
final String oldString,
final String newString )
{
final StringBuffer sb = new StringBuffer();
int end = original.indexOf( oldString );
int start = 0;
final int stringSize = oldString.length();
while( end != -1 )
{
sb.append( original.substring( start, end ) );
sb.append( newString );
start = end + stringSize;
end = original.indexOf( oldString, start );
}
end = original.length();
sb.append( original.substring( start, end ) );
return sb.toString();
}
public static String printStackTrace( final Throwable throwable )
{
return printStackTrace( throwable, 0, true );
}
public static String printStackTrace( final Throwable throwable,
final boolean printCascading )
{
return printStackTrace( throwable, 0, printCascading );
}
public static String printStackTrace( final Throwable throwable, int depth )
{
final String[] lines = captureStackTrace( throwable );
if( 0 == depth || depth > lines.length ) depth = lines.length;
final StringBuffer sb = new StringBuffer();
for( int i = 0; i < depth; i++ )
{
sb.append( lines[ i ] );
sb.append( '\n' );
}
return sb.toString();
}
public static String printStackTrace( Throwable throwable,
final int depth,
final boolean printCascading )
{
final String result = printStackTrace( throwable, depth );
if( !printCascading || !(throwable instanceof CascadingThrowable) )
{
return result;
}
else
{
final StringBuffer sb = new StringBuffer();
sb.append( result );
throwable = ((CascadingThrowable)throwable).getCause();
while( null != throwable )
{
sb.append( "rethrown from\n" );
sb.append( printStackTrace( throwable, depth ) );
if( throwable instanceof CascadingThrowable )
{
throwable = ((CascadingThrowable)throwable).getCause();
}
else
{
throwable = null;
}
}
return sb.toString();
}
}
/**
* Captures the stack trace associated with this exception.
*
* @return an array of Strings describing stack frames.
*/
public static String[] captureStackTrace( final Throwable throwable )
{
final StringWriter sw = new StringWriter();
throwable.printStackTrace( new PrintWriter( sw, true ) );
return splitString( sw.toString(), "\n" );
}
/**
* Splits the string on every token into an array of stack frames.
*
* @param string the string
* @param onToken the token
* @return the resultant array
*/
public static String[] splitString( final String string, final String onToken )
{
final StringTokenizer tokenizer = new StringTokenizer( string, onToken );
final ArrayList lines = new ArrayList();
while( tokenizer.hasMoreTokens() )
{
lines.add( tokenizer.nextToken() );
}
return (String[])lines.toArray( new String[ 0 ] );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/ValuedEnum.java
Index: ValuedEnum.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
/**
* Basic enum class for type-safe enums with values. Should be used as an abstract base.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public abstract class ValuedEnum
extends Enum
{
protected final int m_value;
public ValuedEnum( final String name, final int value )
{
super( name );
m_value = value;
}
public final int getValue()
{
return m_value;
}
public final boolean isEqualTo( final ValuedEnum enum )
{
return m_value == enum.m_value;
}
public final boolean isGreaterThan( final ValuedEnum enum )
{
return m_value > enum.m_value;
}
public final boolean isGreaterThanOrEqual( final ValuedEnum enum )
{
return m_value >= enum.m_value;
}
public final boolean isLessThan( final ValuedEnum enum )
{
return m_value < enum.m_value;
}
public final boolean isLessThanOrEqual( final ValuedEnum enum )
{
return m_value <= enum.m_value;
}
public String toString()
{
return getClass().getName() + "[" + m_name + "=" + m_value + "]";
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/Version.java
Index: Version.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util;
/**
* This document is NOT RIGHT.
* <p />
*
* The version number of a <code>Block</code> is made up of three
* dot-separated fields:
* <p />
* "<b>major.minor.patchlevel</b>"
* <p />
* and (optionally) by a fourth field (always <b>"-dev"</b>)
* specifying that this version is under development.
* <p />
* The <b>major</b>, <b>minor</b> and <b>patchlevel</b> fields are
* <i>integer</i> numbers represented in decimal notation and have the
* following meaning:
* <ul>
* <p /><li><b>major</b> - When the major version changes (in ex. from
* "1.5.12" to "2.0.0"), then backward compatibility
* with previous releases is not granted (this usually happens this
* <code>Block</code> is implementing a new major version of an interface
* specified in <b>org.apache.avalon.blocks</b> package).
* </li><p />
* <p /><li><b>minor</b> - When the minor version changes (in ex. from
* "1.5.12" to "1.6.0"), then backward compatibility
* with previous releases is granted, but something changed in the
* implementation (in ex. new features were added, the configuration
* syntax may be different, or the <code>Block</code> is implementing a
* new minor version of an interface specified in
* <b>org.apache.avalon.blocks</b> package).
* </li><p />
* <p /><li><b>patchlevel</b> - When the patchlevel version changes (in ex.
* from "1.5.12" to "1.5.13"), then the only changed
* things are fixes in the code implementation, but no new features or
* changes were made to the behaviour of the code.
* </li>
* </ul>
* <p />
* The fourth field, optional and always "<b>-dev</b>" (in ex.
* "1.5.12-dev") specifies that current <code>Block</code>
* implementation is under development, and so may contain not-working
* code or not all features were implemented.
* <p />
* <p />
* <b>NOTE: The absence of the "-dev" tag does not endorse
* any warranty of particular stability, safety or compliancy.
* The only source for such informations is the (usually provided) license
* file accompaining the block itself.</b>
*
* The class defining versioning pattern.
* <p />
* <p />
* Any interface in <b>org.apache.avalon.blocks</b> package <b>MUST</b> provides
* a Version instance containing versioning informations on this interface.<p />
* Any BlockInfo returned by a Block implementation <b>MUST</b> provides a
* Version instances containing versioning informations on this implementation.
* <p /><p />
* Version numbers are:<p />
* "<b>major.minor.revision.dev</b>"
* <p />
* The <b>major</b> , <b>minor</b> and <b>revision</b>fields are <i>integer</i>
* numbers represented in decimal notation and have the following meaning:
* <ul><b> - Refering to an interface</b>
* <ul>
* <li><b>major</b> - When the major version changes (in ex. from
* "1.5" to "2.0"), then backward compatibility with
* previous releases is not granted.
* </li><p />
* <p /><li><b>minor</b> - When the minor version changes (in ex. from
* "1.5" to "1.6"), then backward compatibility
* with previous releases is granted, but something changed in the
* interface (in ex. new methods were added).
* </li><p />
* <li><b>revision</b> - When refering to an interface may represent a change
* in documentation or other minor changes. If some methods are modified a minor
* version changes is needed.<p />
* - When refering to a Block implementation this represent minor changes in
* implementation like bugs fix.
* </li><p />
* <li><b>dev</b> - The boolean dev field specify if this Block or interface
* is under development and not yet approved by the Java Apache org.apache.avalon.interfaces;
* developers group (mailing-list).
* </li><p />
* </ul>
* </ul>
* <ul><b> - Refering to a Block</b>
* <ul>
* <li><b>major</b> - When the major version changes (in ex. from
* "1.5" to "2.0"), then backward compatibility with
* previous releases is not granted.
* </li><p />
* <p /><li><b>minor</b> - When the minor version changes (in ex. from
* "1.5" to "1.6"), then backward compatibility
* with previous releases is granted, but something changed in the
* interface (in ex. new methods were added).
* </li><p />
* <li><b>revision</b> - When refering to an interface may represent a change
* in documentation or other minor changes. If some methods are modified a minor
* version changes is needed.<p />
* - When refering to a Block implementation this represent minor changes in
* implementation like bugs fix.
* </li><p />
* <li><b>dev</b> - The boolean dev field specify if this Block or interface
* is under development and not yet approved by the Java Apache org.apache.avalon.interfaces;
* developers group (mailing-list).
* </li><p />
* </ul>
* </ul>
* The third field, optional and always "<b>-dev</b>" (in ex.
* "1.5-dev") specifies that the interface is currently under
* development, or it was not yet approved by the Java Apache org.apache.avalon.interfaces;
* developers group (mailing-list) and so, not yet integrated with the
* org.apache.avalon.interfaces; distributions.
*
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
* @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:rlogiacco@mail.com">Roberto Lo Giacco</a>
* @author <a href="http://java.apache.org/">Java Apache Project</a>
*/
public final class Version
{
protected int m_major;
protected int m_minor;
protected int m_revision;
/**
* Create a new instance of a <code>Version</code> object with the
* specified version numbers.
*
* @param major This <code>Version</code> major number.
* @param minor This <code>Version</code> minor number.
* @param rev This <code>Version</code> revision number.
*/
public Version( final int major, final int minor, final int revision )
{
m_major = major;
m_minor = minor;
m_revision = revision;
}
/**
* Check this <code>Version</code> against another for equality.
* <p />
* If this <code>Version</code> is compatible with the specified one, then
* <b>true</b> is returned, otherwise <b>false</b>.
*
* @param other The other <code>Version</code> object to be compared with this
* for equality.
*/
public boolean equals( final Version other )
{
if( m_major != other.m_major) return false;
else if( m_minor != other.m_minor) return false;
else if( m_revision != other.m_revision ) return false;
else return true;
}
/**
* Check this <code>Version</code> against another for compliancy
* (compatibility).
* <p />
* If this <code>Version</code> is compatible with the specified one, then
* <b>true</b> is returned, otherwise <b>false</b>. Be careful when using
* this method since, in example, version 1.3.7 is compliant to version
* 1.3.6, while the opposite is not.
*
* @param v The other <code>Version</code> object to be compared with this
* for compliancy (compatibility).
*/
public boolean complies( final Version other )
{
if( m_major != other.m_major) return false;
else if( m_minor < other.m_minor) return false;
else return true;
}
/**
* Overload toString to report version correctly.
*
* @return the dot seperated version string
*/
public String toString()
{
return m_major + "." + m_minor + "." + m_revision;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/AbstractMain.java
Index: AbstractMain.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
import java.util.List;
import org.apache.avalon.AbstractLoggable;
/**
* Abstract main entry point.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public abstract class AbstractMain
extends AbstractLoggable
{
protected CLOptionDescriptor[] m_options;
/**
* Return string describing how command is executed.
*
* @return the string describing exectution command
*/
protected String getExecutionCommand()
{
return "java " + getClass().getName() + " [options]";
}
/**
* Display usage report.
*
*/
protected void usage()
{
System.out.println( getExecutionCommand() );
System.out.println( "\tAvailable options:");
System.out.println( CLUtil.describeOptions( m_options ) );
}
/**
* Initialise the options for command line parser.
*
*/
protected abstract CLOptionDescriptor[] createCLOptions();
/**
* Main entry point.
*
* @param args[] the command line arguments
* @Throwable Throwable if an error occurs
*/
public void execute( final String[] args )
throws Exception
{
m_options = createCLOptions();
final CLArgsParser parser = new CLArgsParser( args, m_options );
if( null != parser.getErrorString() )
{
System.err.println( "Error: " + parser.getErrorString() );
return;
}
execute( parser.getArguments() );
}
/**
* Overide this method to provide functionality for your application.
*
* @param clOptions the list of command line options
*/
protected abstract void execute( final List clOptions )
throws Exception;
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/AbstractParserControl.java
Index: AbstractParserControl.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
/**
* Class to inherit from so when in future when new controls are added
* clients will no have to implement them.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class AbstractParserControl
implements ParserControl
{
public boolean isFinished( int lastOptionCode )
{
return false;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/CLArgsParser.java
Index: CLArgsParser.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Vector;
/**
* Parser for command line arguments.
*
* This parses command lines according to the standard (?) of
* gnu utilities.
*
* Note: This is still used in 1.1 libraries so do not add 1.2+ dependancies.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class CLArgsParser
{
protected class Token
{
protected final int m_type;
protected final String m_value;
public Token( final int type, final String value )
{
m_type = type;
m_value = value;
}
public String getValue()
{
return m_value;
}
public int getType()
{
return m_type;
}
public String toString()
{
return "" + m_type + ":" + m_value;
}
}
private final static int STATE_NORMAL = 0;
private final static int STATE_REQUIRE_2ARGS = 1;
private final static int STATE_REQUIRE_ARG = 2;
private final static int STATE_OPTIONAL_ARG = 3;
private final static int STATE_NO_OPTIONS = 4;
private final static int STATE_OPTION_MODE = 5;
protected final static int TOKEN_SEPERATOR = 0;
protected final static int TOKEN_STRING = 1;
protected final static char[] ARG2_SEPERATORS =
new char[] { (char)0, '=', '-' };
protected final static char[] ARG_SEPERATORS =
new char[] { (char)0, '=' };
protected final static char[] NULL_SEPERATORS =
new char[] { (char)0 };
protected final CLOptionDescriptor[] m_optionDescriptors;
protected final Vector m_options;
protected final ParserControl m_control;
protected String m_errorMessage;
protected String[] m_unparsedArgs = new String[] {};
//variables used while parsing options.
protected char ch;
protected String[] args;
protected boolean isLong;
protected int argIndex;
protected int stringIndex;
protected int stringLength;
//cached character == Integer.MAX_VALUE when invalid
protected final static int INVALID = Integer.MAX_VALUE;
protected int m_lastChar = INVALID;
protected int m_lastOptionId;
protected CLOption m_option;
protected int m_state = STATE_NORMAL;
public String[] getUnparsedArgs()
{
return m_unparsedArgs;
}
/**
* Retrieve a list of options that were parsed from command list.
*
* @return the list of options
*/
public Vector getArguments()
{
//System.out.println( "Arguments: " + m_options );
return m_options;
}
/**
* Get Descriptor for option id.
*
* @param id the id
* @return the descriptor
*/
private CLOptionDescriptor getDescriptorFor( final int id )
{
for( int i = 0; i < m_optionDescriptors.length; i++ )
{
if( m_optionDescriptors[i].getId() == id )
{
return m_optionDescriptors[i];
}
}
return null;
}
/**
* Retrieve a descriptor by name.
*
* @param name the name
* @return the descriptor
*/
private CLOptionDescriptor getDescriptorFor( final String name )
{
for( int i = 0; i < m_optionDescriptors.length; i++ )
{
if( m_optionDescriptors[i].getName().equals( name ) )
{
return m_optionDescriptors[i];
}
}
return null;
}
/**
* Retrieve an error message that occured during parsing if one existed.
*
* @return the error string
*/
public String getErrorString()
{
//System.out.println( "ErrorString: " + m_errorMessage );
return m_errorMessage;
}
/**
* Requier state to be placed in for option.
*
* @param descriptor the Option Descriptor
* @return the state
*/
private int getStateFor( final CLOptionDescriptor descriptor )
{
int flags = descriptor.getFlags();
if( ( flags & CLOptionDescriptor.ARGUMENTS_REQUIRED_2 ) ==
CLOptionDescriptor.ARGUMENTS_REQUIRED_2 )
{
return STATE_REQUIRE_2ARGS;
}
else if( ( flags & CLOptionDescriptor.ARGUMENT_REQUIRED ) ==
CLOptionDescriptor.ARGUMENT_REQUIRED )
{
return STATE_REQUIRE_ARG;
}
else if( ( flags & CLOptionDescriptor.ARGUMENT_OPTIONAL ) ==
CLOptionDescriptor.ARGUMENT_OPTIONAL )
{
return STATE_OPTIONAL_ARG;
}
else
{
return STATE_NORMAL;
}
}
/**
* Create a parser that can deals with options and parses certain args.
*
* @param args[] the args
* @param optionDescriptors[] the option descriptors
*/
public CLArgsParser( final String[] args,
final CLOptionDescriptor[] optionDescriptors,
final ParserControl control )
{
m_optionDescriptors = optionDescriptors;
m_control = control;
m_options = new Vector();
this.args = args;
try
{
parse();
checkIncompatabilities( m_options );
}
catch( final ParseException pe )
{
m_errorMessage = pe.getMessage();
}
//System.out.println( "Built : " + m_options );
//System.out.println( "From : " + Arrays.asList( args ) );
}
/**
* Check for duplicates of an option.
* It is an error to have duplicates unless appropriate flags is set in descriptor.
*
* @param arguments the arguments
*/
protected void checkIncompatabilities( final Vector arguments )
throws ParseException
{
final int size = arguments.size();
for( int i = 0; i < size; i++ )
{
final CLOption option = (CLOption)arguments.elementAt( i );
final int id = option.getId();
final CLOptionDescriptor descriptor = getDescriptorFor( id );
//this occurs when id == 0 and user has not supplied a descriptor
//for arguments
if( null == descriptor ) continue;
final int[] incompatable = descriptor.getIncompatble();
checkIncompatable( arguments, incompatable, i );
}
}
protected void checkIncompatable( final Vector arguments,
final int[] incompatable,
final int original )
throws ParseException
{
final int size = arguments.size();
for( int i = 0; i < size; i++ )
{
if( original == i ) continue;
final CLOption option = (CLOption)arguments.elementAt( i );
final int id = option.getId();
final CLOptionDescriptor descriptor = getDescriptorFor( id );
for( int j = 0; j < incompatable.length; j++ )
{
if( id == incompatable[ j ] )
{
final CLOption originalOption = (CLOption)arguments.elementAt( original );
final int originalId = originalOption.getId();
String message = null;
if( id == originalId )
{
message =
"Duplicate options for " + describeDualOption( originalId ) +
" found.";
}
else
{
message = "Incompatable options -" +
describeDualOption( id ) + " and " +
describeDualOption( originalId ) + " found.";
}
throw new ParseException( message, 0 );
}
}
}
}
protected String describeDualOption( final int id )
{
final CLOptionDescriptor descriptor = getDescriptorFor( id );
if( null == descriptor ) return "<parameter>";
else
{
final StringBuffer sb = new StringBuffer();
boolean hasCharOption = false;
if( Character.isLetter( (char)id ) )
{
sb.append( '-' );
sb.append( (char)id );
hasCharOption = true;
}
final String longOption = descriptor.getName();
if( null != longOption )
{
if( hasCharOption ) sb.append( '/' );
sb.append( "--" );
sb.append( longOption );
}
return sb.toString();
}
}
/**
* Create a parser that can deals with options and parses certain args.
*
* @param args[] the args
* @param optionDescriptors[] the option descriptors
*/
public CLArgsParser( final String[] args,
final CLOptionDescriptor[] optionDescriptors )
{
this( args, optionDescriptors, null );
}
/**
* Create a string array that is subset of input array.
* The sub-array should start at array entry indicated by index. That array element
* should only include characters from charIndex onwards.
*
* @param array[] the original array
* @param index the cut-point in array
* @param charIndex the cut-point in element of array
* @return the result array
*/
protected String[] subArray( final String[] array,
final int index,
final int charIndex )
{
final int remaining = array.length - index;
final String[] result = new String[ remaining ];
if( remaining > 1 )
{
System.arraycopy( array, index + 1, result, 1, remaining - 1 );
}
result[0] = array[ index ].substring( charIndex - 1 );
return result;
}
/**
* Actually parse arguments
*
* @param args[] arguments
*/
protected void parse()
throws ParseException
{
if( 0 == args.length ) return;
stringLength = args[ argIndex ].length();
//ch = peekAtChar();
while( true )
{
ch = peekAtChar();
if( argIndex >= args.length ) break;
if( null != m_control && m_control.isFinished( m_lastOptionId ) )
{
//this may need mangling due to peeks
m_unparsedArgs = subArray( args, argIndex, stringIndex );
return;
}
//System.out.println( "State=" + m_state );
//System.out.println( "Char=" + (char)ch );
if( STATE_OPTION_MODE == m_state )
{
//if get to an arg barrier then return to normal mode
//else continue accumulating options
if( 0 == ch )
{
getChar(); //strip the null
m_state = STATE_NORMAL;
}
else parseShortOption();
}
else if( STATE_NORMAL == m_state )
{
parseNormal();
}
else if( STATE_NO_OPTIONS == m_state )
{
//should never get to here when stringIndex != 0
addOption( new CLOption( args[ argIndex++ ] ) );
}
else if( STATE_OPTIONAL_ARG == m_state && '-' == ch )
{
m_state = STATE_NORMAL;
addOption( m_option );
}
else
{
parseArguments();
}
}
if( m_option != null )
{
if( STATE_OPTIONAL_ARG == m_state )
{
m_options.addElement( m_option );
}
else if( STATE_REQUIRE_ARG == m_state )
{
final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
final String message =
"Missing argument to option " + getOptionDescription( descriptor );
throw new ParseException( message, 0 );
}
else if( STATE_REQUIRE_2ARGS == m_state )
{
if( 1 == m_option.getArgumentCount() )
{
m_option.addArgument( "" );
m_options.addElement( m_option );
}
else
{
final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
final String message =
"Missing argument to option " + getOptionDescription( descriptor );
throw new ParseException( message, 0 );
}
}
else
{
throw new ParseException( "IllegalState " + m_state + ": " + m_option, 0 );
}
}
}
protected final String getOptionDescription( final CLOptionDescriptor descriptor )
{
if( isLong ) return "--" + descriptor.getName();
else return "-" + (char)descriptor.getId();
}
protected final char peekAtChar()
{
if( INVALID == m_lastChar ) m_lastChar = readChar();
return (char)m_lastChar;
}
protected final char getChar()
{
if( INVALID != m_lastChar )
{
final char result = (char)m_lastChar;
m_lastChar = INVALID;
return result;
}
else return readChar();
}
private final char readChar()
{
if( stringIndex >= stringLength )
{
argIndex++;
stringIndex = 0;
if( argIndex < args.length ) stringLength = args[ argIndex ].length();
else stringLength = 0;
return 0;
}
if( argIndex >= args.length ) return 0;
return args[ argIndex ].charAt( stringIndex++ );
}
protected final Token nextToken( final char[] seperators )
{
ch = getChar();
if( isSeperator( ch, seperators ) )
{
ch = getChar();
return new Token( TOKEN_SEPERATOR, null );
}
final StringBuffer sb = new StringBuffer();
do
{
sb.append( ch );
ch = getChar();
}
while( !isSeperator( ch, seperators ) );
return new Token( TOKEN_STRING, sb.toString() );
}
private final boolean isSeperator( final char ch, final char[] seperators )
{
for( int i = 0; i < seperators.length; i++ )
{
if( ch == seperators[ i ] ) return true;
}
return false;
}
protected void addOption( final CLOption option )
{
m_options.addElement( option );
m_lastOptionId = option.getId();
m_option = null;
}
protected void parseOption( final CLOptionDescriptor descriptor,
final String optionString )
throws ParseException
{
if( null == descriptor )
{
throw new ParseException( "Unknown option " + optionString, 0 );
}
m_state = getStateFor( descriptor );
m_option = new CLOption( descriptor.getId() );
if( STATE_NORMAL == m_state ) addOption( m_option );
}
protected void parseShortOption()
throws ParseException
{
ch = getChar();
final CLOptionDescriptor descriptor = getDescriptorFor( (int)ch );
isLong = false;
parseOption( descriptor, "-" + ch );
if( STATE_NORMAL == m_state ) m_state = STATE_OPTION_MODE;
}
protected boolean parseArguments()
throws ParseException
{
if( STATE_REQUIRE_ARG == m_state )
{
if( '=' == ch || 0 == ch ) getChar();
final Token token = nextToken( NULL_SEPERATORS );
m_option.addArgument( token.getValue() );
addOption( m_option );
m_state = STATE_NORMAL;
}
else if( STATE_REQUIRE_2ARGS == m_state )
{
if( 0 == m_option.getArgumentCount() )
{
final Token token = nextToken( ARG_SEPERATORS );
if( TOKEN_SEPERATOR == token.getType() )
{
final CLOptionDescriptor descriptor = getDescriptorFor( m_option.getId() );
final String message =
"Unable to parse first argument for option " +
getOptionDescription( descriptor );
throw new ParseException( message, 0 );
}
else
{
m_option.addArgument( token.getValue() );
}
}
else //2nd argument
{
final StringBuffer sb = new StringBuffer();
ch = getChar();
if( '-' == ch ) m_lastChar = ch;
while( !isSeperator( ch, ARG2_SEPERATORS ) )
{
sb.append( ch );
ch = getChar();
}
final String argument = sb.toString();
//System.out.println( "Arguement:" + argument );
m_option.addArgument( argument );
addOption( m_option );
m_option = null;
m_state = STATE_NORMAL;
}
}
return true;
}
/**
* Parse Options from Normal mode.
*/
protected void parseNormal()
throws ParseException
{
if( '-' != ch )
{
//Parse the arguments that are not options
final String argument = nextToken( NULL_SEPERATORS ).getValue();
addOption( new CLOption( argument ) );
m_state = STATE_NORMAL;
}
else
{
getChar(); // strip the -
if( 0 == peekAtChar() )
{
throw new ParseException( "Malformed option -", 0 );
}
else
{
ch = peekAtChar();
//if it is a short option then parse it else ...
if( '-' != ch ) parseShortOption();
else
{
getChar(); // strip the -
//-- sequence .. it can either mean a change of state
//to STATE_NO_OPTIONS or else a long option
if( 0 == peekAtChar() )
{
getChar();
m_state = STATE_NO_OPTIONS;
}
else
{
//its a long option
final String optionName = nextToken( ARG_SEPERATORS ).getValue();
final CLOptionDescriptor descriptor = getDescriptorFor( optionName );
isLong = true;
parseOption( descriptor, "--" + optionName );
}
}
}
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/CLOption.java
Index: CLOption.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
import java.util.Arrays;
/**
* Basic class describing an instance of option.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class CLOption
{
protected final int m_id;
protected String[] m_arguments;
/**
* Retrieve argument to option if it takes arguments.
*
* @return the argument
*/
public final String getArgument()
{
return getArgument( 0 );
}
/**
* Retrieve argument to option if it takes arguments.
*
* @return the argument
*/
public final String getArgument( final int index )
{
if( null == m_arguments || index < 0 || index >= m_arguments.length )
{
return null;
}
else return m_arguments[ index ];
}
/**
* Retrieve id of option.
*
* The id is eqivelent to character code if it can be a single letter option.
*
* @return the id
*/
public final int getId()
{
return m_id;
}
/**
* Constructor taking an id (that must be a proper character code)
*
* @param id the new id
*/
public CLOption( final int id )
{
m_id = id;
}
/**
* Constructor taking argument for option.
*
* @param argument the argument
*/
public CLOption( final String argument )
{
this( 0 );
addArgument( argument );
}
/**
* Mutator fo Argument property.
*
* @param argument the argument
*/
public final void addArgument( final String argument )
{
if( null == m_arguments ) m_arguments = new String[] { argument };
else
{
final String[] arguments = new String[ m_arguments.length + 1 ];
System.arraycopy( m_arguments, 0, arguments, 0, m_arguments.length );
arguments[ m_arguments.length ] = argument;
m_arguments = arguments;
}
}
public int getArgumentCount()
{
if( null == m_arguments ) return 0;
else return m_arguments.length;
}
/**
* Convert to String.
*
* @return the string value
*/
public String toString()
{
final StringBuffer sb = new StringBuffer();
sb.append( "[Option " );
sb.append( (char)m_id );
if( null != m_arguments )
{
sb.append( ", " );
sb.append( Arrays.asList( m_arguments ) );
}
sb.append( " ]" );
return sb.toString();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/CLOptionDescriptor.java
Index: CLOptionDescriptor.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
/**
* Basic class describing an type of option.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class CLOptionDescriptor
{
public final static int ARGUMENT_REQUIRED = 1 << 1;
public final static int ARGUMENT_OPTIONAL = 1 << 2;
public final static int ARGUMENT_DISALLOWED = 1 << 3;
public final static int ARGUMENTS_REQUIRED_2 = 1 << 4;
protected final int m_id;
protected final int m_flags;
protected final String m_name;
protected final String m_description;
protected final int[] m_incompatable;
/**
* Constructor.
*
* @param name the name/long option
* @param flags the flags
* @param id the id/character option
* @param description description of option usage
*/
public CLOptionDescriptor( final String name,
final int flags,
final int id,
final String description )
{
this( name, flags, id, description, new int[] { id } );
}
/**
* Constructor.
*
* @param name the name/long option
* @param flags the flags
* @param id the id/character option
* @param description description of option usage
*/
public CLOptionDescriptor( final String name,
final int flags,
final int id,
final String description,
final int[] incompatable )
{
m_id = id;
m_name = name;
m_flags = flags;
m_description = description;
m_incompatable = incompatable;
}
protected int[] getIncompatble()
{
return m_incompatable;
}
/**
* Retrieve textual description.
*
* @return the description
*/
public final String getDescription()
{
return m_description;
}
/**
* Retrieve flags about option.
* Flags include details such as whether it allows parameters etc.
*
* @return the flags
*/
public final int getFlags()
{
return m_flags;
}
/**
* Retrieve the id for option.
* The id is also the character if using single character options.
*
* @return the id
*/
public final int getId()
{
return m_id;
}
/**
* Retrieve name of option which is also text for long option.
*
* @return name/long option
*/
public final String getName()
{
return m_name;
}
/**
* Convert to String.
*
* @return the converted value to string.
*/
public String toString()
{
return
"[OptionDescriptor " + m_name +
", " + m_id + ", " + m_flags +
", " + m_description + " ]";
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/CLUtil.java
Index: CLUtil.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
/**
* CLUtil offers basic utility operations for use both internal and external to package.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class CLUtil
{
protected static int MAX_DESCRIPTION_COLUMN_LENGTH = 60;
/**
* Format options into StringBuffer and return.
*
* @param options[] the option descriptors
* @return the formatted description/help for options
*/
public static StringBuffer describeOptions( final CLOptionDescriptor[] options )
{
StringBuffer sb = new StringBuffer();
for (int i = 0; i < options.length; i++)
{
final char ch = (char) options[i].getId();
final String name = options[i].getName();
String description = options[i].getDescription();
boolean needComma = false;
sb.append('\t');
if( Character.isLetter(ch) )
{
sb.append("-");
sb.append(ch);
needComma = true;
}
if (null != name)
{
if( needComma ) sb.append(", ");
sb.append("--");
sb.append(name);
sb.append('\n');
}
if( null != description )
{
while( description.length() > MAX_DESCRIPTION_COLUMN_LENGTH )
{
final String descriptionPart =
description.substring( 0, MAX_DESCRIPTION_COLUMN_LENGTH );
description =
description.substring( MAX_DESCRIPTION_COLUMN_LENGTH );
sb.append( "\t\t" );
sb.append( descriptionPart );
sb.append( '\n' );
}
sb.append( "\t\t" );
sb.append( description );
sb.append( '\n' );
}
}
return sb;
}
/**
* Private Constructor so that no instance can ever be created.
*
*/
private CLUtil()
{
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/cli/ParserControl.java
Index: ParserControl.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.cli;
/**
* ParserControl is used to control particular behaviour of the parser.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface ParserControl
{
boolean isFinished( int lastOptionCode );
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/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.avalon.util.cli.test;
import java.util.List;
import org.apache.avalon.util.cli.AbstractParserControl;
import org.apache.avalon.util.cli.CLArgsParser;
import org.apache.avalon.util.cli.CLOption;
import org.apache.avalon.util.cli.CLOptionDescriptor;
import org.apache.avalon.util.cli.ParserControl;
import org.apache.testlet.AbstractTestlet;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class ClutilTestlet
extends AbstractTestlet
{
protected final static String[] ARGLIST1 =
{
"--you","are","--all","-cler","kid"
};
protected final static String[] ARGLIST2 =
{
"-Dstupid=idiot","are","--all","here"
};
protected final static String[] ARGLIST3 =
{
//duplicates
"-Dstupid=idiot","are","--all","--all","here"
};
protected final static String[] ARGLIST4 =
{
//incompatable (blee/all)
"-Dstupid=idiot","are","--all","--blee","here"
};
protected final static String[] ARGLIST5 =
{
"-f","myfile.txt"
};
private static final int DEFINE_OPT = 'D';
private static final int YOU_OPT = 'y';
private static final int ALL_OPT = 'a';
private static final int CLEAR1_OPT = 'c';
private static final int CLEAR2_OPT = 'l';
private static final int CLEAR3_OPT = 'e';
private static final int CLEAR5_OPT = 'r';
private static final int BLEE_OPT = 'b';
private static final int FILE_OPT = 'f';
protected final static CLOptionDescriptor DEFINE =
new CLOptionDescriptor( "define",
CLOptionDescriptor.ARGUMENTS_REQUIRED_2,
DEFINE_OPT,
"define" );
protected final static CLOptionDescriptor YOU =
new CLOptionDescriptor( "you", CLOptionDescriptor.ARGUMENT_DISALLOWED, YOU_OPT, "you" );
protected final static CLOptionDescriptor ALL =
new CLOptionDescriptor( "all",
CLOptionDescriptor.ARGUMENT_DISALLOWED,
ALL_OPT,
"all",
new int[] { BLEE_OPT } );
protected final static CLOptionDescriptor CLEAR1 =
new CLOptionDescriptor( "c", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR1_OPT, "c" );
protected final static CLOptionDescriptor CLEAR2 =
new CLOptionDescriptor( "l", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR2_OPT, "l" );
protected final static CLOptionDescriptor CLEAR3 =
new CLOptionDescriptor( "e", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR3_OPT, "e" );
protected final static CLOptionDescriptor CLEAR5 =
new CLOptionDescriptor( "r", CLOptionDescriptor.ARGUMENT_DISALLOWED, CLEAR5_OPT, "r" );
protected final static CLOptionDescriptor BLEE =
new CLOptionDescriptor( "blee",
CLOptionDescriptor.ARGUMENT_DISALLOWED,
BLEE_OPT,
"blee" );
protected final static CLOptionDescriptor FILE =
new CLOptionDescriptor( "file",
CLOptionDescriptor.ARGUMENT_REQUIRED,
FILE_OPT,
"the build file." );
public void testFullParse()
{
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
YOU, ALL, CLEAR1, CLEAR2, CLEAR3, CLEAR5
};
final CLArgsParser parser = new CLArgsParser( ARGLIST1, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 8 );
assertEquality( ((CLOption)clOptions.get( 0 )).getId(), YOU_OPT );
assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions.get( 3 )).getId(), CLEAR1_OPT );
assertEquality( ((CLOption)clOptions.get( 4 )).getId(), CLEAR2_OPT );
assertEquality( ((CLOption)clOptions.get( 5 )).getId(), CLEAR3_OPT );
assertEquality( ((CLOption)clOptions.get( 6 )).getId(), CLEAR5_OPT );
assertEquality( ((CLOption)clOptions.get( 7 )).getId(), 0 );
}
public void testDuplicateOptions()
{
//"-Dstupid=idiot","are","--all","--all","here"
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
DEFINE, ALL, CLEAR1
};
final CLArgsParser parser = new CLArgsParser( ARGLIST3, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 5 );
assertEquality( ((CLOption)clOptions.get( 0 )).getId(), DEFINE_OPT );
assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions.get( 3 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions.get( 4 )).getId(), 0 );
}
public void testIncompatableOptions()
{
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
DEFINE, ALL, CLEAR1, BLEE
};
final CLArgsParser parser = new CLArgsParser( ARGLIST4, options );
assertNotNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 5 );
assertEquality( ((CLOption)clOptions.get( 0 )).getId(), DEFINE_OPT );
assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions.get( 3 )).getId(), BLEE_OPT );
assertEquality( ((CLOption)clOptions.get( 4 )).getId(), 0 );
}
public void testSingleArg()
{
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
FILE
};
final CLArgsParser parser = new CLArgsParser( ARGLIST5, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 1 );
assertEquality( ((CLOption)clOptions.get( 0 )).getId(), FILE_OPT );
assertEquality( ((CLOption)clOptions.get( 0 )).getArgument(), "myfile.txt" );
}
public void test2ArgsParse()
{
//"-Dstupid=idiot","are","--all","here"
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
DEFINE, ALL, CLEAR1
};
final CLArgsParser parser = new CLArgsParser( ARGLIST2, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 4 );
assertEquality( ((CLOption)clOptions.get( 0 )).getId(), DEFINE_OPT );
assertEquality( ((CLOption)clOptions.get( 1 )).getId(), 0 );
assertEquality( ((CLOption)clOptions.get( 2 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions.get( 3 )).getId(), 0 );
final CLOption option = (CLOption)clOptions.get( 0 );
assertEquality( "stupid", option.getArgument( 0 ) );
assertEquality( "idiot", option.getArgument( 1 ) );
}
public void testPartParse()
{
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
YOU
};
final ParserControl control = new AbstractParserControl()
{
public boolean isFinished( int lastOptionCode )
{
return (lastOptionCode == YOU_OPT);
}
};
final CLArgsParser parser = new CLArgsParser( ARGLIST1, options, control );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 1 );
assertEquality( ((CLOption)clOptions.get( 0 )).getId(), YOU_OPT );
}
public void test2PartParse()
{
final CLOptionDescriptor[] options1 = new CLOptionDescriptor[]
{
YOU
};
final CLOptionDescriptor[] options2 = new CLOptionDescriptor[]
{
ALL, CLEAR1, CLEAR2, CLEAR3, CLEAR5
};
final ParserControl control1 = new AbstractParserControl()
{
public boolean isFinished( int lastOptionCode )
{
return (lastOptionCode == YOU_OPT);
}
};
final CLArgsParser parser1 = new CLArgsParser( ARGLIST1, options1, control1 );
assertNull( parser1.getErrorString() );
final List clOptions1 = parser1.getArguments();
final int size1 = clOptions1.size();
assertEquality( size1, 1 );
assertEquality( ((CLOption)clOptions1.get( 0 )).getId(), YOU_OPT );
final CLArgsParser parser2 =
new CLArgsParser( parser1.getUnparsedArgs(), options2 );
assertNull( parser2.getErrorString() );
final List clOptions2 = parser2.getArguments();
final int size2 = clOptions2.size();
assertEquality( size2, 7 );
assertEquality( ((CLOption)clOptions2.get( 0 )).getId(), 0 );
assertEquality( ((CLOption)clOptions2.get( 1 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions2.get( 2 )).getId(), CLEAR1_OPT );
assertEquality( ((CLOption)clOptions2.get( 3 )).getId(), CLEAR2_OPT );
assertEquality( ((CLOption)clOptions2.get( 4 )).getId(), CLEAR3_OPT );
assertEquality( ((CLOption)clOptions2.get( 5 )).getId(), CLEAR5_OPT );
assertEquality( ((CLOption)clOptions2.get( 6 )).getId(), 0 );
}
public void test2PartPartialParse()
{
final CLOptionDescriptor[] options1 = new CLOptionDescriptor[]
{
YOU, ALL, CLEAR1
};
final CLOptionDescriptor[] options2 = new CLOptionDescriptor[] {};
final ParserControl control1 = new AbstractParserControl()
{
public boolean isFinished( final int lastOptionCode )
{
return (lastOptionCode == CLEAR1_OPT);
}
};
final CLArgsParser parser1 = new CLArgsParser( ARGLIST1, options1, control1 );
assertNull( parser1.getErrorString() );
final List clOptions1 = parser1.getArguments();
final int size1 = clOptions1.size();
assertEquality( size1, 4 );
assertEquality( ((CLOption)clOptions1.get( 0 )).getId(), YOU_OPT );
assertEquality( ((CLOption)clOptions1.get( 1 )).getId(), 0 );
assertEquality( ((CLOption)clOptions1.get( 2 )).getId(), ALL_OPT );
assertEquality( ((CLOption)clOptions1.get( 3 )).getId(), CLEAR1_OPT );
assert( parser1.getUnparsedArgs()[0].equals("ler") );
final CLArgsParser parser2 =
new CLArgsParser( parser1.getUnparsedArgs(), options2 );
assertNull( parser2.getErrorString() );
final List clOptions2 = parser2.getArguments();
final int size2 = clOptions2.size();
assertEquality( size2, 2 );
assertEquality( ((CLOption)clOptions2.get( 0 )).getId(), 0 );
assertEquality( ((CLOption)clOptions2.get( 1 )).getId(), 0 );
}
public void testDuplicatesFail()
{
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
YOU, ALL, CLEAR1, CLEAR2, CLEAR3, CLEAR5
};
//duplicate as
final String[] DUPLICATE_ARGLIST =
{
"--you","are","--all","-clear","kid"
};
final CLArgsParser parser = new CLArgsParser( ARGLIST1, options );
assertNull( parser.getErrorString() );
}
public void testIncomplete2Args()
{
//"-Dstupid="
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
DEFINE
};
final CLArgsParser parser = new CLArgsParser( new String[] { "-Dstupid=" }, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 1 );
final CLOption option = (CLOption)clOptions.get( 0 );
assertEquality( option.getId(), DEFINE_OPT );
assertEquality( option.getArgument( 0 ), "stupid" );
assertEquality( option.getArgument( 1 ), "" );
}
public void testIncomplete2ArgsMixed()
{
//"-Dstupid=","-c"
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
DEFINE, CLEAR1
};
final String[] args = new String[] { "-Dstupid=", "-c" };
final CLArgsParser parser = new CLArgsParser( args, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 2 );
assertEquality( ((CLOption)clOptions.get( 1 )).getId(), CLEAR1_OPT );
final CLOption option = (CLOption)clOptions.get( 0 );
assertEquality( option.getId(), DEFINE_OPT );
assertEquality( option.getArgument( 0 ), "stupid" );
assertEquality( option.getArgument( 1 ), "" );
}
public void fail_testIncomplete2ArgsMixedNoEq()
{
//"-Dstupid","-c"
final CLOptionDescriptor[] options = new CLOptionDescriptor[]
{
DEFINE, CLEAR1
};
final String[] args = new String[] { "-Dstupid", "-c" };
final CLArgsParser parser = new CLArgsParser( args, options );
assertNull( parser.getErrorString() );
final List clOptions = parser.getArguments();
final int size = clOptions.size();
assertEquality( size, 2 );
assertEquality( ((CLOption)clOptions.get( 1 )).getId(), CLEAR1_OPT );
final CLOption option = (CLOption)clOptions.get( 0 );
assertEquality( option.getId(), DEFINE_OPT );
assertEquality( option.getArgument( 0 ), "stupid" );
assertEquality( option.getArgument( 1 ), "" );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/datasource/DataSourceComponent.java
Index: DataSourceComponent.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.datasource;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.avalon.Component;
import org.apache.avalon.Configurable;
import org.apache.avalon.ThreadSafe;
/**
* The standard interface for DataSources in Avalon.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/02/24 03:59:38 $
*/
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/avalon/util/datasource/J2eeDataSource.java
Index: J2eeDataSource.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.datasource;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.avalon.Configuration;
import org.apache.avalon.ConfigurationException;
import org.apache.avalon.AbstractLoggable;
/**
* The J2EE implementation for DataSources in Cocoon. This uses the
* <code>javax.sql.DataSource</code> object and assumes that the
* J2EE container pools the datasources properly.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/02/24 03:59:38 $
*/
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/avalon/util/datasource/JdbcConnection.java
Index: JdbcConnection.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.datasource;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.Map;
import org.apache.avalon.AbstractLoggable;
import org.apache.avalon.Recyclable;
import org.apache.avalon.util.pool.Pool;
/**
* The Connection object used in conjunction with the JdbcDataSource
* object.
*
* TODO: Implement a configurable closed end Pool, where the Connection
* acts like JDBC PooledConnections work. That means we can limit the
* total number of Connection objects that are created.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/02/24 03:59:38 $
*/
public class JdbcConnection
extends AbstractLoggable
implements Connection, Recyclable
{
private Connection m_connection;
private Pool m_pool;
public JdbcConnection( final Connection connection, final Pool pool )
{
m_connection = connection;
m_pool = pool;
}
public Statement createStatement()
throws SQLException
{
return m_connection.createStatement();
}
public PreparedStatement prepareStatement( final String sql )
throws SQLException
{
return m_connection.prepareStatement( sql );
}
public CallableStatement prepareCall( final String sql )
throws SQLException
{
return m_connection.prepareCall( sql );
}
public String nativeSQL( final String sql )
throws SQLException
{
return m_connection.nativeSQL( sql );
}
public void setAutoCommit( final boolean autoCommit )
throws SQLException
{
m_connection.setAutoCommit( autoCommit );
}
public boolean getAutoCommit()
throws SQLException
{
return m_connection.getAutoCommit();
}
public void commit()
throws SQLException
{
m_connection.commit();
}
public void rollback()
throws SQLException
{
m_connection.rollback();
}
public void close()
throws SQLException
{
setAutoCommit( false );
m_pool.put( this );
}
public void recycle()
{
try { m_connection.close(); }
catch( final SQLException se )
{
getLogger().warn( "Could not close connection", se );
}
}
public boolean isClosed()
throws SQLException
{
return m_connection.isClosed();
}
public DatabaseMetaData getMetaData()
throws SQLException
{
return m_connection.getMetaData();
}
public void setReadOnly( final boolean readOnly )
throws SQLException
{
m_connection.setReadOnly( readOnly );
}
public boolean isReadOnly()
throws SQLException
{
return m_connection.isReadOnly();
}
public void setCatalog( final String catalog )
throws SQLException
{
m_connection.setCatalog( catalog );
}
public String getCatalog()
throws SQLException
{
return m_connection.getCatalog();
}
public void setTransactionIsolation( final int level )
throws SQLException
{
m_connection.setTransactionIsolation(level);
}
public int getTransactionIsolation()
throws SQLException
{
return m_connection.getTransactionIsolation();
}
public SQLWarning getWarnings()
throws SQLException
{
return m_connection.getWarnings();
}
public void clearWarnings()
throws SQLException
{
m_connection.clearWarnings();
}
public Statement createStatement( final int resultSetType,
final int resultSetConcurrency )
throws SQLException
{
return m_connection.createStatement(resultSetType, resultSetConcurrency);
}
public PreparedStatement prepareStatement( final String sql,
final int resultSetType,
final int resultSetConcurrency )
throws SQLException
{
return m_connection.prepareStatement( sql, resultSetType, resultSetConcurrency );
}
public CallableStatement prepareCall( final String sql,
final int resultSetType,
final int resultSetConcurrency )
throws SQLException
{
return m_connection.prepareCall( sql, resultSetType, resultSetConcurrency );
}
public Map getTypeMap()
throws SQLException
{
return m_connection.getTypeMap();
}
public void setTypeMap( final Map map )
throws SQLException
{
m_connection.setTypeMap( map );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcConnectionPool.java
Index: JdbcConnectionPool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.datasource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.avalon.AbstractLoggable;
import org.apache.avalon.Disposable;
import org.apache.avalon.Initializable;
import org.apache.avalon.Poolable;
import org.apache.avalon.Recyclable;
import org.apache.avalon.util.pool.Pool;
/**
* The Pool implementation for JdbcConnections. It uses a background
* thread to manage the number of SQL Connections.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/02/24 03:59:38 $
*/
public class JdbcConnectionPool
extends AbstractLoggable
implements Pool, Runnable, Disposable, Initializable
{
private final String m_dburl;
private final String m_username;
private final String m_password;
private final int m_min;
private final int m_max;
private int m_currentCount;
private List m_active = new ArrayList();
private List m_ready = new ArrayList();
private boolean m_monitoring = true;
public JdbcConnectionPool( final String url,
final String username,
final String password,
final int min,
final int max )
{
m_dburl = url;
m_username = username;
m_password = password;
if( min < 0 )
{
getLogger().warn( "Minumum number of connections specified is " +
"less than 0, using 0" );
m_min = 0;
}
else
{
m_min = min;
}
if( ( max < min ) || ( max < 1 ) )
{
getLogger().warn( "Maximum number of connections specified must be at " +
"least 1 and must be greater than the minumum number " +
"of connections" );
m_max = ( min > 1 ) ? min : 1;
}
else
{
m_max = max;
}
}
public void init()
{
for( int i = 0; i < m_min; i++ )
{
m_ready.add( createJdbcConnection() );
}
new Thread( this );
}
private JdbcConnection createJdbcConnection()
{
JdbcConnection connection = null;
try
{
if( null == m_username )
{
connection = new JdbcConnection( DriverManager.getConnection( m_dburl ), this );
connection.setLogger(getLogger());
m_currentCount++;
}
else
{
connection =
new JdbcConnection( DriverManager.getConnection( m_dburl,
m_username,
m_password ),
this);
connection.setLogger(getLogger());
m_currentCount++;
}
}
catch( final SQLException se )
{
getLogger().error( "Could not create connection to database", se );
}
getLogger().debug( "JdbcConnection object created" );
return connection;
}
private void recycle( final Recyclable obj )
{
getLogger().debug( "JdbcConnection object recycled" );
obj.recycle();
}
public Poolable get()
throws Exception
{
Poolable obj = null;
if( 0 == m_ready.size() )
{
if( m_currentCount < m_max )
{
synchronized( m_active )
{
obj = createJdbcConnection();
m_active.add( obj );
}
}
else
{
throw new SQLException("There are no more Connections available");
}
}
else
{
synchronized( m_active )
{
obj = (Poolable)m_ready.remove( 0 );
m_active.add( obj );
}
}
getLogger().debug( "JdbcConnection '" + m_dburl +
"' has been requested from pool." );
return obj;
}
public synchronized void put( final Poolable obj )
{
int location = m_active.indexOf( obj );
m_active.remove( obj );
if( m_monitoring )
{
m_ready.add( obj );
}
getLogger().debug( "JdbcConnection '" + m_dburl + "' has been returned to the pool." );
}
public void run()
{
while( m_monitoring )
{
synchronized( m_ready )
{
if( m_ready.size() < m_min )
{
getLogger().debug( "There are not enough Connections for pool: " + m_dburl );
while( ( m_ready.size() < m_min ) && ( m_currentCount < m_max ) )
{
m_ready.add( createJdbcConnection() );
}
}
else
{
getLogger().debug( "Trimming excess fat from pool: " + m_dburl );
while( m_ready.size() > m_min )
{
recycle( (Recyclable)m_ready.remove( 0 ) );
}
}
}
try
{
Thread.sleep( 1 * 60 * 1000 );
}
catch( final InterruptedException ie )
{
getLogger().warn( "Caught an InterruptedException", ie );
}
}
}
public void dispose()
{
m_monitoring = false;
synchronized (m_ready)
{
while( !m_ready.isEmpty() )
{
recycle( (Recyclable)m_ready.remove( 0 ) );
}
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcDataSource.java
Index: JdbcDataSource.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.datasource;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.avalon.Configuration;
import org.apache.avalon.ConfigurationException;
import org.apache.avalon.Disposable;
import org.apache.avalon.AbstractLoggable;
/**
* The Default implementation for DataSources in Avalon. This uses the
* normal <code>java.sql.Connection</code> object and
* <code>java.sql.DriverManager</code>.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/02/24 03:59:38 $
*/
public class JdbcDataSource
extends AbstractLoggable
implements DataSourceComponent
{
protected JdbcConnectionPool m_pool;
/**
* Configure and set up DB connection. Here we set the connection
* information needed to create the Connection objects. It must
* be called only once.
*
* @param conf The Configuration object needed to describe the
* connection.
*
* @throws ConfigurationException
*/
public void configure( final Configuration configuration )
throws ConfigurationException
{
if( null == m_pool )
{
final String dburl = configuration.getChild( "dburl" ).getValue();
final String user = configuration.getChild( "user" ).getValue( null );
final String passwd = configuration.getChild( "password" ).getValue( null );
final Configuration controler = configuration.getChild( "pool-controller" );
final int min = controler.getAttributeAsInt( "min", 0 );
final int max = controler.getAttributeAsInt( "max", 3 );
m_pool = new JdbcConnectionPool( dburl, user, passwd, min, max );
m_pool.setLogger(getLogger());
m_pool.init();
}
}
/** Get the database connection */
public Connection getConnection()
throws SQLException
{
try { return (Connection) m_pool.get(); }
catch( final Exception e )
{
getLogger().error( "Could not return Connection", e );
throw new SQLException( e.getMessage() );
}
}
/** Dispose properly of the pool */
public void dispose()
{
m_pool.dispose();
m_pool = null;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/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.avalon.util.datasource.test;
import org.apache.testlet.AbstractTestlet;
import org.apache.avalon.Configuration;
import org.apache.avalon.ConfigurationException;
import org.apache.avalon.DefaultConfiguration;
import org.apache.avalon.util.datasource.DataSourceComponent;
import org.apache.avalon.util.datasource.JdbcDataSource;
import org.apache.log.LogKit;
import java.sql.SQLException;
import java.sql.Connection;
import java.util.Random;
/**
* Test the DataSource Component. I don't know how to make this generic,
* so I'll throw some bones out there, and hope someone can set this up
* better.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
*/
public class DataSourceTestlet extends AbstractTestlet {
static final Configuration conf;
static final String LOCATION = "Testlet Framework";
static {
DefaultConfiguration dc = new DefaultConfiguration("", LOCATION);
DefaultConfiguration pool = new DefaultConfiguration("pool-controller", LOCATION);
DefaultConfiguration dburl = new DefaultConfiguration("dburl", LOCATION);
DefaultConfiguration user = new DefaultConfiguration("user", LOCATION);
DefaultConfiguration password = new DefaultConfiguration("password", LOCATION);
pool.addAttribute("min", "5");
pool.addAttribute("max", "10");
dc.addChild(pool);
dburl.appendValueData("jdbc:odbc://test");
dc.addChild(dburl);
user.appendValueData("test");
dc.addChild(user);
password.appendValueData("test");
dc.addChild(password);
conf = dc;
LogKit.setGlobalPriority(org.apache.log.Priority.INFO);
try {
Class.forName("Your Driver Class Here");
} catch (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 (ConfigurationException ce) {
assert("Over Allocation Test", false);
}
try {
for (int i = 0; i < 11; i++) {
ds.getConnection();
}
} catch (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 (ConfigurationException ce) {
LogKit.getLoggerFor("test").error(ce.getMessage(), ce);
assert("Over Allocation Test", false);
}
Thread one = new Thread(new ConnectionThread(ds));
Thread two = new Thread(new ConnectionThread(ds));
one.start();
two.start();
while (one.isAlive() || two.isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
// Ignore
}
}
LogKit.getLoggerFor("test").info("If you saw no failure messages, then the test passed");
assert("Normal Use Test", result);
}
class ConnectionThread implements Runnable {
DataSourceComponent datasource;
ConnectionThread(DataSourceComponent dc) {
this.datasource = dc;
}
public void run() {
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 (SQLException se) {
LogKit.getLoggerFor("test").info("Failed to get Connection, test failed");
assert("Normal Use Test", false);
} catch (InterruptedException ie) {
// Ignore
}
}
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/i18n/ResourceGroup.java
Index: ResourceGroup.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.i18n;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Random;
import java.util.ResourceBundle;
/**
* A class used to manage resource bundles.
*/
public class ResourceGroup
{
protected final static Random RANDOM = new Random();
protected final HashMap m_bundles = new HashMap();
protected final Locale m_locale;
/**
* Create a ResourceGroup to manage resource bundles for a particular locale.
*
* @param locale the locale
*/
public ResourceGroup( final Locale locale )
{
m_locale = locale;
}
public Locale getLocale()
{
return m_locale;
}
public String format( final String base, final String key, final Object[] args )
{
final String pattern = getPattern( base, key );
final MessageFormat messageFormat = new MessageFormat( pattern );
messageFormat.setLocale( m_locale );
return messageFormat.format( args );
}
public ResourceBundle getBundle( final String base )
throws MissingResourceException
{
ResourceBundle result = (ResourceBundle) m_bundles.get( base );
if( null != result ) return result;
// bundle wasn't cached, so load it, cache it, and return it.
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
result = ResourceBundle.getBundle( base, m_locale, classLoader );
m_bundles.put( base, result );
return result;
}
public String getPattern( final String base, final String key )
throws MissingResourceException
{
final ResourceBundle bundle = getBundle( base );
final Object object = bundle.getObject( key );
// is the resource a single string
if( object instanceof String )
{
return (String)object;
}
else if( object instanceof String[] )
{
//if string array then randomly pick one
final String[] strings = (String[])object;
return strings[ RANDOM.nextInt( strings.length ) ];
}
else
{
throw new MissingResourceException( "Unable to find resource of appropriate type.",
"java.lang.String",
key );
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/i18n/XMLResourceBundle.java
Index: XMLResourceBundle.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.i18n;
/**
* @author <a href="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
* @author <a href="mailto:neeme@one.lv">Neeme Praks</a>
* @author <a href="mailto:oleg@one.lv">Oleg Podolsky</a>
* @version $Id: XMLResourceBundle.java,v 1.1 2001/02/24 03:59:39 donaldp Exp $
*/
/** JDK classes **/
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.Hashtable;
import java.util.Locale;
import java.util.MissingResourceException;
/** W3C DOM classes **/
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
/** Xerces classes **/
import org.apache.xerces.dom.DocumentImpl;
import org.apache.xerces.dom.TextImpl;
import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.SAXException;
/** Xalan classes **/
import org.apache.xalan.xpath.XPathSupport;
import org.apache.xalan.xpath.XPath;
import org.apache.xalan.xpath.XPathProcessorImpl;
import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
import org.apache.xalan.xpath.xml.PrefixResolverDefault;
import org.apache.xalan.xpath.XObject;
public class XMLResourceBundle {
// Cache for storing string values for existing XPaths
private Hashtable cacheIS = new Hashtable();
// Cache for storing non-existing XPaths
private Hashtable cacheNO = new Hashtable();
private Document resource;
public String bundleName = ""; //used by getLocale()
protected XMLResourceBundle parent = null;
public XMLResourceBundle( Document doc, String name, XMLResourceBundle p ) {
System.out.print( "Constructing XMLResourceBundle: " + name );
if ( p != null )
System.out.println( " --> parent: " + p.bundleName );
else
System.out.println( " --> parent: " + p );
this.resource = doc;
this.bundleName = name;
this.parent = p;
}
public void addToCache( String key, String value ) {
cacheIS.put( key, value );
}
public Document getResource() {
return this.resource;
}
// gets string without throwing an exception, returns empty string instead
public String getStringSimple( String xPathKey ) {
String result = "";
try {
result = getString( xPathKey );
} catch ( MissingResourceException e ) {
// do nothing
}
return result;
}
public String getString( String xPathKey ) throws MissingResourceException {
if ( cacheIS.containsKey( xPathKey ) )
return ( String ) cacheIS.get( xPathKey );
if ( cacheNO.containsKey( xPathKey ) )
new MissingResourceException( "Unable to locate resource: " + xPathKey, "XMLResourceBundle", xPathKey );
Node root = this.resource.getDocumentElement();
try {
Node node = XPathAPI.selectSingleNode( root, xPathKey );
if ( node != null ) {
String temp = getTextNodeAsString( node );
addToCache( xPathKey, temp );
return temp;
} else {
if ( this.parent != null )
return this.parent.getString( xPathKey );
else
throw new Exception();
}
} catch ( Exception e ) {
// no nodes returned??
cacheNO.put( xPathKey, "" );
throw new MissingResourceException( "Unable to locate resource: " + xPathKey, "XMLResourceBundle", xPathKey );
}
}
public String getString( Node role, String key ) throws MissingResourceException {
try {
Node node = XPathAPI.selectSingleNode( role, key );
if ( node != null )
return getTextNodeAsString( node );
else
throw new Exception();
} catch ( Exception e ) {
// no nodes returned??
throw new MissingResourceException( "Unable to locate resource: " + key, "XMLResourceBundle", key );
}
}
private String getTextNodeAsString( Node node ) throws MissingResourceException {
node = node.getFirstChild();
if ( node.getNodeType() == Node.TEXT_NODE )
return ( ( TextImpl ) node ).getData();
else
throw new MissingResourceException( "Unable to locate XMLResourceBundle", "XMLResourceBundleFactory", "" );
}
public Node getRole( String xPath ) {
Node root = resource.getDocumentElement();
try {
Node node = XPathAPI.selectSingleNode( root, xPath );
if ( node != null )
return node;
else
throw new Exception();
} catch ( Exception e ) {
// no nodes returned??
throw new MissingResourceException( "Unable to locate resource: " + xPath, "XMLResourceBundle", xPath );
}
}
public Node getRole( Node role, String xPath ) {
try {
Node node = XPathAPI.selectSingleNode( role, xPath );
if ( node != null )
return node;
else
throw new Exception();
} catch ( Exception e ) {
// no nodes returned??
throw new MissingResourceException( "Unable to locate resource: " + xPath, "XMLResourceBundle", xPath );
}
}
public XPath createXPath( String str, Node namespaceNode ) throws SAXException {
XPathSupport xpathSupport = new XMLParserLiaisonDefault();
if ( null == namespaceNode )
throw new SAXException( "A namespace node is required to resolve prefixes!" );
PrefixResolverDefault prefixResolver = new PrefixResolverDefault( ( namespaceNode.getNodeType() == Node.DOCUMENT_NODE ) ? ( ( Document ) namespaceNode ).getDocumentElement() : namespaceNode );
// Create the XPath object.
XPath xpath = new XPath();
// Create a XPath parser.
XPathProcessorImpl parser = new XPathProcessorImpl( xpathSupport );
parser.initXPath( xpath, str, prefixResolver );
return xpath;
}
public Locale getLocale() {
String bundle = bundleName.substring( 0, bundleName.indexOf( ".xml" ) );
int localeStart = bundle.indexOf( "_" );
if ( localeStart == -1 )
return new Locale( "", "", "" );
bundle = bundle.substring( localeStart + 1 );
localeStart = bundle.indexOf( "_" );
if ( localeStart == -1 )
return new Locale( bundle, "", "" );
String lang = bundle.substring( 0, localeStart );
bundle = bundle.substring( localeStart + 1 );
localeStart = bundle.indexOf( "_" );
if ( localeStart == -1 )
return new Locale( lang, bundle, "" );
String country = bundle.substring( 0, localeStart );
bundle = bundle.substring( localeStart + 1 );
return new Locale( lang, country, bundle );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/i18n/XMLResourceBundleFactory.java
Index: XMLResourceBundleFactory.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.i18n;
/**
* @author <a href="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
* @author <a href="mailto:neeme@one.lv">Neeme Praks</a>
* @author <a href="mailto:oleg@one.lv">Oleg Podolsky</a>
* @version $Id: XMLResourceBundleFactory.java,v 1.1 2001/02/24 03:59:39 donaldp Exp $
*/
/** JDK classes **/
/** W3C DOM classes **/
/** Xerces-J classes **/
//import java.lang.ref.SoftReference;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Vector;
import org.apache.xerces.dom.DocumentImpl;
import org.apache.xerces.dom.TextImpl;
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLResourceBundleFactory {
protected static Hashtable cache = new Hashtable();
protected static String directory;
protected XMLResourceBundleFactory() {}
public static XMLResourceBundle getBundle( String name ) throws MissingResourceException {
return getBundle( name, Locale.getDefault() );
}
public static XMLResourceBundle getBundle( String name, Locale loc ) throws MissingResourceException {
return getBundle( name, loc, false );
}
public static XMLResourceBundle getBundle( String name, Locale loc, boolean cacheAtStartup ) throws MissingResourceException {
XMLResourceBundle parent = null;
String bundleName = getBundleName( name, loc );
// first look in the cache - if there grab it
XMLResourceBundle bundle = getCachedBundle( bundleName );
if ( bundle != null )
return bundle;
// if bundle is not in cache try loading the bundle using the given name and locale bundleName
Document doc = null;
doc = loadResourceBundle( bundleName );
if ( doc != null ) {
if ( ! loc.getLanguage().equals( "" ) )
parent = getParentBundle( name, loc, cacheAtStartup );
bundle = new XMLResourceBundle( doc, bundleName, parent );
if ( cacheAtStartup )
storeTextElements( bundle, bundle.getResource(), "" );
updateCache( bundleName, bundle );
return bundle;
}
// if the locale's language is "" then we've already tried to load the default resource and it's not available
while ( ! loc.getLanguage().equals( "" ) ) {
// if the given bundle name is not found, then try loading using a shortened Locale
loc = getParentLocale( loc );
bundleName = getBundleName( name, loc );
// first look in the cache - if there grab it and return
bundle = getCachedBundle( bundleName );
if ( bundle != null )
return bundle;
// try loading the bundle using the given name and locale bundleName
doc = loadResourceBundle( bundleName );
if ( doc != null ) {
if ( ! loc.getLanguage().equals( "" ) )
parent = getParentBundle( name, loc, cacheAtStartup );
bundle = new XMLResourceBundle( doc, bundleName, parent );
if ( cacheAtStartup )
storeTextElements( bundle, bundle.getResource(), "" );
updateCache( bundleName, bundle );
return bundle;
}
}
throw new MissingResourceException( "Unable to locate resource: " + bundleName, "XMLResourceBundleFactory", "" );
}
protected synchronized static XMLResourceBundle getParentBundle( String name, Locale loc ) {
return getParentBundle( name, loc, false );
}
protected synchronized static XMLResourceBundle getParentBundle( String name, Locale loc, boolean cacheAtStartup ) {
loc = getParentLocale( loc );
String bundleName = getBundleName( name, loc );
Document doc = loadResourceBundle( bundleName );
XMLResourceBundle bundle = null;
if ( doc != null ) {
if ( ! loc.getLanguage().equals( "" ) )
bundle = getParentBundle( name, loc );
bundle = new XMLResourceBundle( doc, bundleName, bundle );
if ( cacheAtStartup )
storeTextElements( bundle, bundle.getResource(), "" );
updateCache( bundleName, bundle );
}
return bundle;
}
// this method returns the next locale up the parent hierarchy
// e.g.; the parent of new Locale("en","us","mac")
// would be new Locale("en", "us", "");
protected static Locale getParentLocale( Locale loc ) {
if ( loc.getVariant().equals( "" ) ) {
if ( loc.getCountry().equals( "" ) )
loc = new Locale( "", "", "" );
else
loc = new Locale( loc.getLanguage(), "", "" );
} else
loc = new Locale( loc.getLanguage(), loc.getCountry(), "" );
return loc;
}
protected synchronized static XMLResourceBundle getCachedBundle( String bundleName ) {
/*
SoftReference ref = (SoftReference)(cache.get(bundleName));
if (ref != null)
return (XMLResourceBundle) ref.get();
else
return null;
*/
return ( XMLResourceBundle ) ( cache.get( bundleName ) );
}
protected synchronized static void updateCache( String bundleName, XMLResourceBundle bundle ) {
cache.put( bundleName, bundle );
}
/* protected static String getBundleName(String name, Locale loc)
{
StringBuffer sb = new StringBuffer(name);
if (! loc.getLanguage().equals(""))
{
sb.append("_");
sb.append(loc.getLanguage());
}
if (! loc.getCountry().equals(""))
{
sb.append("_");
sb.append(loc.getCountry());
}
if (! loc.getVariant().equals(""))
{
sb.append("_");
sb.append(loc.getVariant());
}
// should all the files have an extension of .xml? Seems reasonable
sb.append(".xml");
return sb.toString();
}
*/
protected static String getBundleName( String name, Locale loc ) {
String lang = loc.getLanguage();
StringBuffer sb = new StringBuffer( getDirectory() );
if ( lang.length() > 0 ) sb.append( "/" ).append( lang );
sb.append( "/" ).append( name ).append( ".xml" );
return sb.toString();
}
public static XMLResourceBundle getBundle( String fileName, String localeName ) throws MissingResourceException {
return getBundle( fileName, new Locale( localeName, localeName ) );
}
public static XMLResourceBundle getBundleFromFilename( String bundleName ) throws MissingResourceException {
return getBundleFromFilename( bundleName, true );
}
public static XMLResourceBundle getBundleFromFilename( String bundleName, boolean cacheAtStartup ) throws MissingResourceException {
Document doc = null;
doc = loadResourceBundle( getDirectory() + "/" + bundleName );
XMLResourceBundle bundle = getCachedBundle( bundleName );
if ( bundle != null )
return bundle;
if ( doc != null ) {
bundle = new XMLResourceBundle( doc, bundleName, null );
if ( cacheAtStartup )
storeTextElements( bundle, bundle.getResource(), "" );
updateCache( bundleName, bundle );
return bundle;
}
throw new MissingResourceException( "Unable to locate resource: " + bundleName, "XMLResourceBundleFactory", "" );
}
// Load the XML document based on bundleName
protected static Document loadResourceBundle( String bundleName ) {
try {
DOMParser parser = new DOMParser();
parser.parse( bundleName );
return parser.getDocument();
} catch ( IOException e ) {
return null;
}
catch ( SAXException e ) {
return null;
}
}
public static void setDirectory( String dir ) {
directory = dir;
}
public static String getDirectory() {
return ( directory != null ? directory : "" );
}
// Steps through the bundle tree and stores all text element values
// in bundle's cache, and also stores attributes for all element nodes.
// Parent must be am element-type node.
private static void storeTextElements( XMLResourceBundle bundle, Node parent, String pathToParent ) {
NodeList children = parent.getChildNodes();
int childnum = children.getLength();
for ( int i = 0; i < childnum; i++ ) {
Node child = children.item( i );
if ( child.getNodeType() == Node.ELEMENT_NODE ) {
String pathToChild = pathToParent + '/' + child.getNodeName();
NamedNodeMap attrs = child.getAttributes();
if ( attrs != null ) {
Node temp = null;
String pathToAttr = null;
int attrnum = attrs.getLength();
for ( int j = 0; j < attrnum; j++ ) {
temp = attrs.item( j );
pathToAttr = "/@" + temp.getNodeName();
bundle.addToCache( pathToChild + pathToAttr, temp.getNodeValue() );
}
}
String childValue = getTextValue( child );
if ( childValue != null )
bundle.addToCache( pathToChild, childValue );
else
storeTextElements( bundle, child, pathToChild );
}
}
}
private static String getTextValue( Node element ) {
NodeList list = element.getChildNodes();
int listsize = list.getLength();
Node item = null;
String itemValue = null;
for ( int i = 0; i < listsize; i++ ) {
item = list.item( i );
if ( item.getNodeType() != Node.TEXT_NODE ) return null;
itemValue = item.getNodeValue(); if ( itemValue == null ) return null;
itemValue = itemValue.trim(); if ( itemValue.length() == 0 ) return null;
return itemValue;
}
return null;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/i18n/XPathAPI.java
Index: XPathAPI.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.i18n;
import org.xml.sax.SAXException;
import org.w3c.dom.Node;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.apache.xalan.xpath.XPathSupport;
import org.apache.xalan.xpath.XPath;
import org.apache.xalan.xpath.XPathProcessorImpl;
import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
import org.apache.xalan.xpath.xml.PrefixResolverDefault;
import org.apache.xalan.xpath.XObject;
/**
* The methods in this class are convenience methods into the
* low-level XPath API. We would like to eventually move these
* methods into the XPath core, but would like to do some peer
* review first to make sure we have it right.
* Please note that these methods execute pure XPaths. They do not
* implement those parts of XPath extended by XSLT, such as the
* document() function). If you want to install XSLT functions, you
* have to use the low-level API.
* These functions tend to be a little slow, since a number of objects must be
* created for each evaluation. A faster way is to precompile the
* XPaths using the low-level API, and then just use the XPaths
* over and over.
*
* @author <a href="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
* @see http://www.w3.org/TR/xpath
* @version $Id: XPathAPI.java,v 1.1 2001/02/24 03:59:39 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.
* @see org.apache.xalan.xpath.XObject
* @see org.apache.xalan.xpath.XNull
* @see org.apache.xalan.xpath.XBoolean
* @see org.apache.xalan.xpath.XNumber
* @see org.apache.xalan.xpath.XString
* @see org.apache.xalan.xpath.XRTreeFrag
*/
public static XObject eval( Node contextNode, String str )
throws SAXException {
return eval( contextNode, str, contextNode );
}
/**
* Evaluate XPath string to an XObject.
* XPath namespace prefixes are resolved from the namespaceNode.
* The implementation of this is a little slow, since it creates
* a number of objects each time it is called. This could be optimized
* to keep the same objects around, but then thread-safety issues would arise.
*
* @param contextNode The node to start searching from.
* @param str A valid XPath string.
* @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
* @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
* @see org.apache.xalan.xpath.XObject
* @see org.apache.xalan.xpath.XNull
* @see org.apache.xalan.xpath.XBoolean
* @see org.apache.xalan.xpath.XNumber
* @see org.apache.xalan.xpath.XString
* @see org.apache.xalan.xpath.XRTreeFrag */
public static XObject eval( Node contextNode, String str, Node namespaceNode )
throws SAXException {
// Since we don't have a XML Parser involved here, install some default support
// for things like namespaces, etc.
// (Changed from: XPathSupportDefault xpathSupport = new XPathSupportDefault();
// because XPathSupportDefault is weak in a number of areas... perhaps
// XPathSupportDefault should be done away with.)
XPathSupport xpathSupport = new XMLParserLiaisonDefault();
if ( null == namespaceNode )
namespaceNode = contextNode;
// Create an object to resolve namespace prefixes.
// XPath namespaces are resolved from the input context node's document element
// if it is a root node, or else the current context node (for lack of a better
// resolution space, given the simplicity of this sample code).
PrefixResolverDefault prefixResolver = new PrefixResolverDefault( ( namespaceNode.getNodeType() == Node.DOCUMENT_NODE )
? ( ( Document ) namespaceNode ).getDocumentElement() :
namespaceNode );
// Create the XPath object.
XPath xpath = new XPath();
// Create a XPath parser.
XPathProcessorImpl parser = new XPathProcessorImpl( xpathSupport );
parser.initXPath( xpath, str, prefixResolver );
// Execute the XPath, and have it return the result
return xpath.execute( xpathSupport, contextNode, prefixResolver );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/CRLFInputStream.java
Index: CRLFInputStream.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Transform line endings to CRLF in input stream.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class CRLFInputStream
extends FilterInputStream
{
protected int m_lastChar;
public CRLFInputStream( final InputStream inputStream )
{
super( inputStream );
m_lastChar = -1;
}
public int read()
throws IOException
{
if( '\r' != m_lastChar )
{
final int result = m_lastChar;
m_lastChar = -1;
return result;
}
final int data = in.read();
if( -1 == data )
{
if( -1 != m_lastChar ) return m_lastChar;
else return data;
}
else if( '\r' == data )
{
m_lastChar = data;
return read();
}
else if( '\n' != data )
{
if( -1 != m_lastChar )
{
final int result = m_lastChar;
m_lastChar = -1;
return result;
}
else return data;
}
else return data;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/CRLFOutputStream.java
Index: CRLFOutputStream.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Transform line endings to CRLF in output stream.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class CRLFOutputStream
extends FilterOutputStream
{
public CRLFOutputStream( final OutputStream outputStream )
{
super( outputStream );
}
public void write( final int data )
throws IOException
{
if( '\n' == data ) out.write( '\r' );
out.write( data );
}
public void write( final byte data[], final int offset, final int len )
throws IOException
{
for( int i = 0; i < len; i++)
{
final byte element = data[ offset + i ];
if( '\n' == element ) out.write( '\r' );
out.write( element );
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/InternetException.java
Index: InternetException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
import org.apache.avalon.CascadingException;
/**
* Connection thrown during various internet related protocol handling.
* The code field will handle the common 3 digit code + message
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class InternetException
extends CascadingException
{
protected InternetReply m_reply;
public InternetException( final int code, final String description )
{
this( code, description, null );
}
public InternetException( final int code,
final String description,
final Throwable throwable )
{
super( description, throwable );
m_reply = new InternetReply( code, description );
}
public InternetReply getReply()
{
return m_reply;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/InternetReply.java
Index: InternetReply.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
/**
* This is for holding Internet reply codes + descriptions.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class InternetReply
{
protected int m_code;
protected String m_description;
public InternetReply( final int code, final String description )
{
m_code = code;
m_description = description;
}
public int getCode()
{
return m_code;
}
public String getDescription()
{
return m_description;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/InternetStream.java
Index: InternetStream.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ProtocolException;
/**
* This is the Internet output/input stream.
* Used for such things as SMTP, NNTP, FTP? etc.
*
* TODO: Need to be able to set a flag to allow lax input-reading
* to cope with some non-compliant sources
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class InternetStream
{
protected final static int MAX_OUTGOING_LINE_LENGTH = 512;
protected LineReader m_reader;
protected LineWriter m_writer;
protected String m_lastLine;
protected String m_responseText;
protected int m_responseCode;
protected String m_requestVerb;
protected String m_requestParameter;
/**
* Constructor taking an input and output.
*
* @param input the InputStream
* @param output the OutputStream
*/
public InternetStream( final InputStream input, final OutputStream output )
{
m_reader = new LineReader( input );
m_writer = new LineWriter( output );
}
/**
* Retrieve request verb last received.
*
* @return the request verb
*/
public String getRequestVerb()
{
return m_requestVerb;
}
/**
* Retrieve request parameter
*
* @return the request parameter
*/
public String getRequestParameter()
{
return m_requestParameter;
}
public String getResponseText()
{
return m_responseText;
}
public int getResponseCode()
{
return m_responseCode;
}
/**
* Retrieve last line received from connection.
*
* @return the last line received
*/
public String getLastLine()
{
return m_lastLine;
}
/**
* Send a request to server.
*
* @param verb the request verb
* @exception IOException if an error occurs
*/
public void sendRequest( final String verb )
throws IOException
{
sendRequest( verb, null );
}
/**
* Send a Request to server.
*
* @param verb the request verb
* @param parameter the parameter (or null if none)
* @exception IOException if an error occurs
*/
public void sendRequest( final String verb, final String parameter )
throws IOException
{
final StringBuffer sb = new StringBuffer();
sb.append( verb );
if( null != parameter )
{
sb.append( ' ' );
sb.append( parameter );
}
m_writer.println( sb.toString() );
}
/**
* Send a response.
* Format the message so that it conforms to line length/contents rules.
*
* @param responseCode the response code
* @param message the message
* @exception IOException if an error occurs
*/
public void sendResponse( final int responseCode, final String message )
throws IOException
{
int start = 0;
int end = message.indexOf( '\n' );
while( -1 != end )
{
sendResponseLines( responseCode, false, message.substring( start, end ) );
start = end + 1;
end = message.indexOf( '\n', start );
}
end = message.length();
sendResponseLines( responseCode, true, message.substring( start, end ) );
}
/**
* Receive a Request from client.
*
* @exception IOException if an error occurs
*/
public void receiveRequest()
throws IOException
{
m_requestVerb = null;
m_requestParameter = null;
final String line = m_reader.readln();
int space = line.indexOf( ' ' );
if( -1 == space )
{
m_requestVerb = line.toUpperCase();
}
else
{
m_requestVerb = line.substring( 0, space ).toUpperCase();
m_requestParameter = line.substring( space + 1 ).trim();
if( m_requestParameter.equals( "" ) )
{
m_requestParameter = null;
}
}
}
/**
* receive a response from server.
*
* @exception IOException if an error occurs
*/
public void receiveResponse()
throws IOException
{
boolean lastLine = false;
m_responseCode = 0;
m_responseText = null;
while( !lastLine )
{
final String line = m_reader.readln();
int responseCode = Integer.parseInt( line.substring( 0, 3 ) );
if( 0 != m_responseCode && responseCode != m_responseCode )
{
throw new ProtocolException( "Badly formed response with differing codes" );
}
m_responseCode = responseCode;
lastLine = ( ' ' == line.charAt( 3 ) );
final String messagePart = line.substring( 4, line.length() );
if( null == m_responseText ) m_responseText = messagePart;
else m_responseText += '\n' + messagePart;
}
}
/**
* Helper method to build a response line.
* If message is greater than MAX_OUTGOING_LINE_LENGTH it is broken into multiple lines.
*
* @param responseCode the response code.
* @param isLastLine true if this is last line in response
* @param message the message
* @exception IOException if an error occurs
*/
protected void sendResponseLines( final int responseCode,
final boolean isLastLine,
final String message )
throws IOException
{
final int size = message.length();
if( size < MAX_OUTGOING_LINE_LENGTH )
{
sendResponseLine( responseCode, isLastLine, message );
}
else
{
int start = 0;
int end = MAX_OUTGOING_LINE_LENGTH;
while( end < size )
{
sendResponseLine( responseCode, false, message.substring( start, end ) );
start = end + 1;
end = end + MAX_OUTGOING_LINE_LENGTH;
}
sendResponseLine( responseCode, isLastLine, message.substring( start, size ) );
}
}
/**
* Helper method to build a response line.
*
* @param responseCode the response code.
* @param isLastLine true if this is last line in response
* @param message the message
* @exception IOException if an error occurs
*/
protected void sendResponseLine( final int responseCode,
final boolean isLastLine,
final String message )
throws IOException
{
final char seperator = ( isLastLine ) ? ' ' : '-';
final String responseLine = Integer.toString( responseCode ) + seperator + message;
sendLine( responseLine );
}
/**
* Send a raw line and terminate it with a \r\n.
* This assumes thaat the parameters does not have \r\n
* sequence in it (or \n byitself).
*
* @param line the line
* @exception IOException if an error occurs
*/
public final void sendLine( final String line )
throws IOException
{
m_writer.println( line );
}
/**
* Receive a line.
*
* @return the line received
* @exception IOException if an error occurs
*/
public final String receiveLine()
throws IOException
{
m_lastLine = m_reader.readln();
return m_lastLine;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/LineReader.java
Index: LineReader.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
import java.io.IOException;
import java.io.InputStream;
import java.net.ProtocolException;
/**
* Used to write lines with appropriate line endings.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class LineReader
{
protected final static byte[] LINE_TERMINATOR = { (byte)'\r', (byte)'\n' };
protected InputStream m_input;
protected boolean m_laxLineFormat;
public LineReader( final InputStream input )
{
m_input = input;
}
public void setLaxLineFormat( final boolean laxLineFormat )
{
m_laxLineFormat = laxLineFormat;
}
public String readln()
throws IOException
{
final StringBuffer sb = new StringBuffer();
int data = m_input.read();
int last = -1;
while( LINE_TERMINATOR[ 1 ] != data )
{
if( last == LINE_TERMINATOR[ 0 ] )
{
if( data == LINE_TERMINATOR[ 1 ] ) break;
else sb.append( (char)last );
}
else if( data == LINE_TERMINATOR[ 1 ] )
{
break;
}
else
{
last = data;
if( data != LINE_TERMINATOR[ 0 ] ) sb.append( (char)data );
}
data = m_input.read();
}
return sb.toString();
}
public void close()
throws IOException
{
m_input.close();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/internet/LineWriter.java
Index: LineWriter.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.internet;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ProtocolException;
/**
* Used to write lines with appropriate line endings.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class LineWriter
{
protected final static byte[] LINE_TERMINATOR = { (byte)'\r', (byte)'\n' };
protected OutputStream m_output;
public LineWriter( final OutputStream output )
{
m_output = output;
}
public void println( final String data )
throws IOException
{
m_output.write( data.getBytes() );
m_output.write( LINE_TERMINATOR );
m_output.flush();
}
public void close()
throws IOException
{
m_output.close();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/ByteTerminatedInputStream.java
Index: ByteTerminatedInputStream.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author Federico Barbieri <fe...@apache.org>
*/
public class ByteTerminatedInputStream
extends InputStream
{
protected final boolean m_includeTerminator;
protected final InputStream m_inputStream;
protected final byte[] m_terminator;
protected final int m_matchLength;
protected int m_match;
public ByteTerminatedInputStream( final InputStream inputStream,
final byte[] terminator,
final boolean includeTerminator )
{
m_includeTerminator = includeTerminator;
m_matchLength = terminator.length;
m_terminator = terminator;
m_inputStream = inputStream;
m_match = 0;
}
public int read()
throws IOException
{
if( m_match == m_matchLength ) return -1;
int next = getNext();
if( !m_includeTerminator && 0 != m_match )
{
m_inputStream.mark( m_matchLength );
int matchTest = next;
while( -1 != matchTest )
{
matchTest = getNext();
if( m_match == m_matchLength ) return -1;
else if( m_match == 0 ) break;
}
m_match = 0;
m_inputStream.reset();
}
return next;
}
protected final int getNext()
throws IOException
{
final int next = m_inputStream.read();
if( next == m_terminator[ m_match ] ) m_match++;
else if( next == m_terminator[ 0 ] ) m_match = 1;
else m_match = 0;
return next;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/DirectoryFileFilter.java
Index: DirectoryFileFilter.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.File;
import java.io.FilenameFilter;
/**
* This filters files based if not a directory.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DirectoryFileFilter
implements FilenameFilter
{
public boolean accept( final File file, final String name )
{
return file.isDirectory();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/ExtensionFileFilter.java
Index: ExtensionFileFilter.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.File;
import java.io.FilenameFilter;
/**
* This filters files based on the extension (what the filename
* ends with). This is used in retrieving all the files of a
* particular type.
*
* @author Federico Barbieri <fe...@apache.org>
* @author Serge Knystautas <se...@lokitech.com>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ExtensionFileFilter
implements FilenameFilter
{
private String[] m_extensions;
public ExtensionFileFilter( final String[] extensions )
{
m_extensions = extensions;
}
public ExtensionFileFilter( final String extension )
{
m_extensions = new String[] { extension };
}
public boolean accept( final File file, final String name )
{
for( int i = 0; i < m_extensions.length; i++ )
{
if( name.endsWith( m_extensions[ i ] ) ) return true;
}
return false;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/FileUtil.java
Index: FileUtil.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.*;
import java.net.URL;
import org.apache.avalon.util.StringUtil;
/**
* This class provides basic facilities for manipulating files.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class FileUtil
{
/**
* Private constructor to prevent instantiation.
*
*/
private FileUtil()
{
}
public static File toFile( final URL url )
{
if( !url.getProtocol().equals( "file" ) )
{
return null;
}
else
{
final String filename = url.getFile().replace( '/', File.separatorChar );
return new File( filename );
}
}
/**
* Remove extention from filename.
* ie
* fo.txt --> foo
* a\b\c.jpg --> a\b\c
* a\b\c --> a\b\c
*
* @param filename the filename
* @return the filename minus extention
*/
public static String removeExtention( final String filename )
{
final int index = filename.lastIndexOf( '.' );
if( -1 == index )
{
return filename;
}
else
{
return filename.substring( 0, index );
}
}
/**
* remove path from filename.
* ie.
* a/b/c.txt --> c.txt
* a.txt --> a.txt
*
* @param filepath the filepath
* @return the filename minus path
*/
public static String removePath( final String filepath )
{
final int index = filepath.lastIndexOf( File.separator );
if( -1 == index )
{
return filepath;
}
else
{
return filepath.substring( index + 1 );
}
}
/**
* Copy file from source to destination.
*/
public static void copyFileToDirectory( final String source,
final String destinationDirectory )
throws IOException
{
copyFileToDirectory( new File( source ), new File( destinationDirectory ) );
}
/**
* Copy file from source to destination.
*/
public static void copyFileToDirectory( final File source,
final File destinationDirectory )
throws IOException
{
if( destinationDirectory.exists() && !destinationDirectory.isDirectory() )
{
throw new IllegalArgumentException( "Destination is not a directory" );
}
copyFile( source, new File( destinationDirectory, source.getName() ) );
}
/**
* Copy file from source to destination.
*/
public static void copyFile( final File source, final File destination )
throws IOException
{
//check source exists
if( !source.exists() )
{
throw new IOException( "File " + source + " does not exist" );
}
//does destinations directory exist ?
if( !destination.getParentFile().exists() )
{
destination.mkdirs();
}
//make sure we can write to destination
if( destination.exists() && !destination.canWrite() )
{
throw new IOException( "Unable to open file " + destination + " for writing." );
}
IOUtil.copy( new FileInputStream( source ), new FileOutputStream( destination ) );
if( source.length() != destination.length() )
{
throw new IOException( "Failed to copy full contents from " + source +
" to " + destination );
}
}
public static void copyURLToFile( final URL source, final File destination )
throws IOException
{
//does destinations directory exist ?
if( !destination.getParentFile().exists() )
{
destination.mkdirs();
}
//make sure we can write to destination
if( destination.exists() && !destination.canWrite() )
{
throw new IOException( "Unable to open file " + destination + " for writing." );
}
IOUtil.copy( source.openStream(), new FileOutputStream( destination ) );
}
public static String normalize( String location )
{
location = StringUtil.replaceSubString( location, "/./", "/" );
final StringBuffer sb = new StringBuffer();
int trail = 0;
int end = location.indexOf( "/../" );
int start = 0;
while( end != -1 )
{
//TODO: fix when starts with /../
trail = location.lastIndexOf( "/", end - 1 );
sb.append( location.substring( start, trail ) );
sb.append( '/' );
start = end + 4;
end = location.indexOf( "/../", start );
}
end = location.length();
sb.append( location.substring( start, end ) );
return sb.toString();
}
/** Will concatenate 2 paths, dealing with ..
* ( /a/b/c + d = /a/b/d, /a/b/c + ../d = /a/d )
*
* Thieved from Tomcat sources...
*
* @return null if error occurs
*/
public static String catPath( String lookupPath, String path )
{
// Cut off the last slash and everything beyond
int index = lookupPath.lastIndexOf( "/" );
lookupPath = lookupPath.substring( 0, index );
// Deal with .. by chopping dirs off the lookup path
while( path.startsWith( "../" ) )
{
if( lookupPath.length() > 0 )
{
index = lookupPath.lastIndexOf( "/" );
lookupPath = lookupPath.substring( 0, index );
}
else
{
// More ..'s than dirs, return null
return null;
}
index = path.indexOf( "../" ) + 3;
path = path.substring( index );
}
return lookupPath + "/" + path;
}
public static File resolveFile( final File baseFile, String filename )
{
if( '/' != File.separatorChar )
{
filename = filename.replace( '/', File.separatorChar );
}
if( '\\' != File.separatorChar )
{
filename = filename.replace( '\\', File.separatorChar );
}
// deal with absolute files
if( filename.startsWith( File.separator ) )
{
File file = new File( filename );
try { file = file.getCanonicalFile(); }
catch( final IOException ioe ) {}
return file;
}
final char[] chars = filename.toCharArray();
final StringBuffer sb = new StringBuffer();
//remove duplicate file seperators in succession - except
//on win32 as UNC filenames can be \\AComputer\AShare\myfile.txt
int start = 0;
if( '\\' == File.separatorChar )
{
sb.append( filename.charAt( 0 ) );
start++;
}
for( int i = start; i < chars.length; i++ )
{
final boolean doubleSeperator =
File.separatorChar == chars[ i ] && File.separatorChar == chars[ i - 1 ];
if( !doubleSeperator ) sb.append( chars[ i ] );
}
filename = sb.toString();
//must be relative
File file = (new File( baseFile, filename )).getAbsoluteFile();
try { file = file.getCanonicalFile(); }
catch( final IOException ioe ) {}
return file;
}
/**
* Delete a file. If file is directory delete it and all sub-directories.
*/
public static void forceDelete( final String file )
throws IOException
{
forceDelete( new File( file ) );
}
/**
* Delete a file. If file is directory delete it and all sub-directories.
*/
public static void forceDelete( final File file )
throws IOException
{
if( file.isDirectory() ) deleteDirectory( file );
else
{
if( false == file.delete() )
{
throw new IOException( "File " + file + " unable to be deleted." );
}
}
}
/**
* Recursively delete a directory.
*/
public static void deleteDirectory( final String directory )
throws IOException
{
deleteDirectory( new File( directory ) );
}
/**
* Recursively delete a directory.
*/
public static void deleteDirectory( final File directory )
throws IOException
{
if( !directory.exists() ) return;
cleanDirectory( directory );
if( false == directory.delete() )
{
throw new IOException( "Directory " + directory + " unable to be deleted." );
}
}
/**
* Clean a directory without deleting it.
*/
public static void cleanDirectory( final String directory )
throws IOException
{
cleanDirectory( new File( directory ) );
}
/**
* Clean a directory without deleting it.
*/
public static void cleanDirectory( final File directory )
throws IOException
{
if( !directory.exists() )
{
throw new IllegalArgumentException( directory + " does not exist" );
}
if( !directory.isDirectory() )
{
throw new IllegalArgumentException( directory + " is not a directory" );
}
final File[] files = directory.listFiles();
for( int i = 0; i < files.length; i++ )
{
final File file = files[ i ];
if( file.isFile() ) file.delete();
else if( file.isDirectory() )
{
cleanDirectory( file );
if( false == file.delete() )
{
throw new IOException( "Directory " + file + " unable to be deleted." );
}
}
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/IOUtil.java
Index: IOUtil.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.*;
/**
* This class provides basic facilities for manipulating io streams.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class IOUtil
{
/**
* Private constructor to prevent instantiation.
*/
private IOUtil()
{
}
public static void shutdownStream( final OutputStream output )
{
if( null == output ) return;
try { output.close(); }
catch( final IOException ioe ) {}
}
public static void shutdownStream( final InputStream input )
{
if( null == input ) return;
try { input.close(); }
catch( final IOException ioe ) {}
}
/**
* Copy stream-data from source to destination.
*/
public static void copy( final InputStream source, final OutputStream destination )
throws IOException
{
try
{
final BufferedInputStream input = new BufferedInputStream( source );
final BufferedOutputStream output = new BufferedOutputStream( destination );
final int BUFFER_SIZE = 1024 * 4;
final byte[] buffer = new byte[ BUFFER_SIZE ];
while( true )
{
final int count = input.read( buffer, 0, BUFFER_SIZE );
if( -1 == count ) break;
// write out those same bytes
output.write( buffer, 0, count );
}
//needed to flush cache
output.flush();
}
finally
{
shutdownStream( source );
shutdownStream( destination );
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/MergedInputStreams.java
Index: MergedInputStreams.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.IOException;
import java.io.InputStream;
/**
* Merges multiple input streams into one.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class MergedInputStreams
extends InputStream
{
protected final InputStream[] m_streams;
protected int m_index;
public MergedInputStreams( final InputStream[] inputStreams )
{
super();
m_streams = inputStreams;
}
public int read()
throws IOException
{
if( m_index >= m_streams.length ) return -1;
int returnVal = m_streams[ m_index ].read();
if( -1 == returnVal && (++m_index) < m_streams.length )
{
returnVal = m_streams[ m_index ].read();
}
return returnVal;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/io/ResettableFileInputStream.java
Index: ResettableFileInputStream.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.io;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Federico Barbieri <fe...@apache.org>
*/
public class ResettableFileInputStream
extends InputStream
{
protected static final int DEFAULT_BUFFER_SIZE = 1024;
protected final String m_filename;
protected int m_bufferSize;
protected InputStream m_inputStream;
protected long m_position;
protected long m_mark;
protected boolean m_isMarkSet;
public ResettableFileInputStream( final File file )
throws IOException
{
this( file.getCanonicalPath() );
}
public ResettableFileInputStream( final String filename )
throws IOException
{
this( filename, DEFAULT_BUFFER_SIZE );
}
public ResettableFileInputStream( final String filename, final int bufferSize )
throws IOException
{
m_bufferSize = bufferSize;
m_filename = filename;
m_position = 0;
m_inputStream = newStream();
}
public void mark( final int readLimit )
{
m_isMarkSet = true;
m_mark = m_position;
m_inputStream.mark( readLimit );
}
public boolean markSupported()
{
return true;
}
public void reset()
throws IOException
{
if( !m_isMarkSet )
{
throw new IOException( "Unmarked Stream" );
}
try
{
m_inputStream.reset();
}
catch( final IOException ioe )
{
try
{
m_inputStream.close();
m_inputStream = newStream();
m_inputStream.skip( m_mark );
m_position = m_mark;
}
catch( final Exception e )
{
throw new IOException( "Cannot reset current Stream: " + e.getMessage() );
}
}
}
protected InputStream newStream()
throws IOException
{
return new BufferedInputStream( new FileInputStream( m_filename ), m_bufferSize );
}
public int available()
throws IOException
{
return m_inputStream.available();
}
public void close() throws IOException
{
m_inputStream.close();
}
public int read() throws IOException
{
m_position++;
return m_inputStream.read();
}
public int read( final byte[] bytes, final int offset, final int length )
throws IOException
{
final int count = m_inputStream.read( bytes, offset, length );
m_position += count;
return count;
}
public long skip( final long count )
throws IOException
{
m_position += count;
return m_inputStream.skip( count );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/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.avalon.util.io.test;
import java.io.*;
import org.apache.avalon.util.io.FileUtil;
import org.apache.testlet.AbstractTestlet;
import org.apache.testlet.TestFailedException;
/**
* This is used to test FileUtil for correctness.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class FileUtilTestlet
extends AbstractTestlet
{
protected final int FILE1_SIZE = 1;
protected final int FILE2_SIZE = 1024 * 4 + 1;
protected final File m_testDirectory;
protected final File m_testFile1;
protected final File m_testFile2;
public FileUtilTestlet()
throws IOException
{
m_testDirectory = (new File( "test/io/" )).getAbsoluteFile();
if( !m_testDirectory.exists() )
{
m_testDirectory.mkdirs();
}
m_testFile1 = new File( m_testDirectory, "file1-test.txt" );
m_testFile2 = new File( m_testDirectory, "file2-test.txt" );
createFile( m_testFile1, FILE1_SIZE );
createFile( m_testFile2, FILE2_SIZE );
}
protected void createFile( final File file, final long size )
throws IOException
{
final BufferedOutputStream output =
new BufferedOutputStream( new FileOutputStream( file ) );
for( int i = 0; i < size; i++ )
{
output.write( (byte)'X' );
}
output.close();
}
public void testCopyFile1()
throws Exception
{
final File destination = new File( m_testDirectory, "copy1.txt" );
FileUtil.copyFile( m_testFile1, destination );
assert( "Check Exist", destination.exists() );
assert( "Check Full copy", destination.length() == FILE1_SIZE );
}
public void testCopyFile2()
throws Exception
{
final File destination = new File( m_testDirectory, "copy2.txt" );
FileUtil.copyFile( m_testFile2, destination );
assert( "Check Exist", destination.exists() );
assert( "Check Full copy", destination.length() == FILE2_SIZE );
}
public void testForceDeleteFile1()
throws Exception
{
final File destination = new File( m_testDirectory, "copy1.txt" );
FileUtil.forceDelete( destination );
assert( "Check No Exist", !destination.exists() );
}
public void testForceDeleteFile2()
throws Exception
{
final File destination = new File( m_testDirectory, "copy2.txt" );
FileUtil.forceDelete( destination );
assert( "Check No Exist", !destination.exists() );
}
public void testCopyFile1ToDir()
throws Exception
{
final File directory = new File( m_testDirectory, "subdir" );
if( !directory.exists() ) directory.mkdirs();
final File destination = new File( directory, "file1-test.txt" );
FileUtil.copyFileToDirectory( m_testFile1, directory );
assert( "Check Exist", destination.exists() );
assert( "Check Full copy", destination.length() == FILE1_SIZE );
}
public void testCopyFile2ToDir()
throws Exception
{
final File directory = new File( m_testDirectory, "subdir" );
if( !directory.exists() ) directory.mkdirs();
final File destination = new File( directory, "file2-test.txt" );
FileUtil.copyFileToDirectory( m_testFile2, directory );
assert( "Check Exist", destination.exists() );
assert( "Check Full copy", destination.length() == FILE2_SIZE );
}
public void testForceDeleteDir()
throws Exception
{
FileUtil.forceDelete( m_testDirectory.getParentFile() );
assert( "Check No Exist", !m_testDirectory.getParentFile().exists() );
}
public void testResolveFileDotDot()
throws Exception
{
final File file = FileUtil.resolveFile( m_testDirectory, ".." );
assertEquality( "Check .. operator", file, m_testDirectory.getParentFile() );
}
public void testResolveFileDot()
throws Exception
{
final File file = FileUtil.resolveFile( m_testDirectory, "." );
assertEquality( "Check . operator", file, m_testDirectory );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/lang/ThreadManager.java
Index: ThreadManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.lang;
import org.apache.avalon.util.thread.ThreadContext;
import org.apache.avalon.util.thread.ThreadPool;
/**
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
*/
public final class ThreadManager
{
/**
* @deprecated This will be removed in future iterations and is legacy from old time
*/
public static ThreadPool getWorkerPool( final String name )
{
return ThreadContext.getCurrentThreadPool();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/log/AvalonLogFormatter.java
Index: AvalonLogFormatter.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.log;
import java.util.Date;
import org.apache.avalon.util.StringUtil;
import org.apache.log.format.PatternFormatter;
/**
* Specialized formatter that knows about CascadingThrowables.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class AvalonLogFormatter
extends PatternFormatter
{
protected String getStackTrace( final Throwable throwable, final String format )
{
if( null == throwable ) return "";
return StringUtil.printStackTrace( throwable, 8, true );
}
/**
* Utility method to format time.
*
* @param time the time
* @param format ancilliary format parameter - allowed to be null
* @return the formatted string
*/
protected String getTime( final long time, final String format )
{
return new Date().toString();
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/log/DefaultLogManager.java
Index: DefaultLogManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.log;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.apache.avalon.AbstractLoggable;
import org.apache.avalon.Component;
import org.apache.avalon.configuration.Configurable;
import org.apache.avalon.configuration.Configuration;
import org.apache.avalon.configuration.ConfigurationException;
import org.apache.avalon.Context;
import org.apache.avalon.Contextualizable;
import org.apache.log.Category;
import org.apache.log.LogKit;
import org.apache.log.LogTarget;
import org.apache.log.output.FileOutputLogTarget;
/**
* Component responsible for managing logs.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultLogManager
extends AbstractLoggable
implements Component, Contextualizable, Configurable
{
protected String m_baseName;
protected File m_baseDirectory;
public void contextualize( final Context context )
{
m_baseName = (String)context.get( "name" );
if( null == m_baseName ) m_baseName = "<base>";
m_baseDirectory = (File)context.get( "directory" );
if( null == m_baseDirectory ) m_baseDirectory = new File( "." );
}
public void configure( final Configuration configuration )
throws ConfigurationException
{
final Configuration[] targets = configuration.getChildren( "log-target" );
configureTargets( m_baseName, m_baseDirectory, targets );
final Configuration[] categories = configuration.getChildren( "category" );
configureCategories( m_baseName, categories );
/*
final String logPriority = configuration.getChild( "global-priority" ).getValue();
final Priority.Enum priority = LogKit.getPriorityForName( logPriority );
LogKit.setGlobalPriority( priority );
*/
}
protected void configureTargets( final String baseName,
final File baseDirectory,
final Configuration[] targets )
throws ConfigurationException
{
for( int i = 0; i < targets.length; i++ )
{
final Configuration target = targets[ i ];
final String name = baseName + '.' + target.getAttribute( "name" );
String location = target.getAttribute( "location" ).trim();
final String format = target.getAttribute( "format", null );
if( '/' == location.charAt( 0 ) )
{
location = location.substring( 1 );
}
final File file = new File( baseDirectory, location );
final FileOutputLogTarget logTarget = new FileOutputLogTarget();
final AvalonLogFormatter formatter = new AvalonLogFormatter();
formatter.setFormat( "%{time} [%7.7{priority}] <<%{category}>> " +
"(%{context}): %{message}\\n%{throwable}" );
logTarget.setFormatter( formatter );
try { logTarget.setFilename( file.getAbsolutePath() ); }
catch( final IOException ioe )
{
throw new ConfigurationException( "Error initializing log files", ioe );
}
if( null != format )
{
logTarget.setFormat( format );
}
LogKit.addLogTarget( name, logTarget );
}
}
protected void configureCategories( final String baseName, final Configuration[] categories )
throws ConfigurationException
{
for( int i = 0; i < categories.length; i++ )
{
final Configuration category = categories[ i ];
String name = category.getAttribute( "name" );
final String target = baseName + '.' + category.getAttribute( "target" );
final String priority = category.getAttribute( "priority" );
if( name.trim().equals( "" ) )
{
name = baseName;
}
else
{
name = baseName + '.' + name;
}
final Category logCategory =
LogKit.createCategory( name, LogKit.getPriorityForName( priority ) );
final LogTarget logTarget = LogKit.getLogTarget( target );
LogTarget logTargets[] = null;
if( null != target ) logTargets = new LogTarget[] { logTarget };
LogKit.createLogger( logCategory, logTargets );
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/AbstractPool.java
Index: AbstractPool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
import org.apache.avalon.Poolable;
import org.apache.avalon.Recyclable;
import org.apache.avalon.Initializable;
/**
* This is an <code>Pool</code> that caches Poolable objects for reuse.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class AbstractPool
implements Pool, Initializable
{
protected int m_count;
protected Poolable[] m_pool;
protected ObjectFactory m_factory;
protected PoolController m_controller;
protected int m_maximum;
protected int m_initial;
public AbstractPool( final ObjectFactory factory,
final PoolController controller,
final int initial,
final int maximum )
{
m_count = 0;
m_factory = factory;
m_controller = controller;
m_maximum = maximum;
m_initial = initial;
}
public void init()
throws Exception
{
grow( m_maximum );
fill( m_initial );
}
/**
* Retrieve an object from pool.
*
* @return an object from Pool
*/
public Poolable get() throws Exception
{
if( null == m_pool && null != m_controller )
{
final int increase = m_controller.grow();
if( increase > 0 ) grow( increase );
}
if( 0 == m_count )
{
return m_factory.newInstance();
}
m_count--;
final Poolable poolable = m_pool[ m_count ];
m_pool[ m_count ] = null;
return poolable;
}
/**
* Place an object in pool.
*
* @param poolable the object to be placed in pool
*/
public void put( final Poolable poolable )
{
if( poolable instanceof Recyclable )
{
((Recyclable)poolable).recycle();
}
if( m_pool.length == (m_count + 1) && null != m_controller )
{
final int decrease = m_controller.shrink();
if( decrease > 0 ) shrink( decrease );
}
if ( m_pool.length > m_count + 1 )
{
m_pool[ m_count++ ] = poolable;
}
}
/**
* Return the total number of slots in Pool
*
* @return the total number of slots
*/
public final int getCapacity()
{
return m_pool.length;
}
/**
* Get the number of used slots in Pool
*
* @return the number of used slots
*/
public final int getSize()
{
return m_count;
}
/**
* This fills the pool to the size specified in parameter.
*/
public final void fill( final int fillSize ) throws Exception
{
final int size = Math.min( m_pool.length, fillSize );
for( int i = m_count; i < size; i++ )
{
m_pool[i] = m_factory.newInstance();
}
m_count = size;
}
/**
* This fills the pool by the size specified in parameter.
*/
public final void grow( final int increase )
{
if( null == m_pool )
{
m_pool = new Poolable[ increase ];
return;
}
final Poolable[] poolables = new Poolable[ increase + m_pool.length ];
System.arraycopy( m_pool, 0, poolables, 0, m_pool.length );
m_pool = poolables;
}
/**
* This shrinks the pool by parameter size.
*/
public final void shrink( final int decrease )
{
final Poolable[] poolables = new Poolable[ m_pool.length - decrease ];
System.arraycopy( m_pool, 0, poolables, 0, poolables.length );
m_pool = poolables;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/DefaultObjectFactory.java
Index: DefaultObjectFactory.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
import java.lang.reflect.Constructor;
import org.apache.avalon.Poolable;
import org.apache.avalon.Recyclable;
/**
* This is the default for factory that is used to create objects for Pool.
*
* It creates objects via reflection and constructor.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultObjectFactory
implements ObjectFactory
{
protected Constructor m_constructor;
protected Object[] m_arguements;
public DefaultObjectFactory( final Constructor constructor, final Object[] arguements )
{
m_arguements = arguements;
m_constructor = constructor;
}
public DefaultObjectFactory( final Class clazz,
final Class[] arguementClasses,
final Object[] arguements )
throws NoSuchMethodException
{
this( clazz.getConstructor( arguementClasses ), arguements );
}
public DefaultObjectFactory( final Class clazz )
throws NoSuchMethodException
{
this( clazz, null, null );
}
public Class getCreatedClass()
{
return m_constructor.getDeclaringClass();
}
public Poolable newInstance()
{
try
{
return (Poolable)m_constructor.newInstance( m_arguements );
}
catch( final Exception e )
{
throw new Error( "Failed to instantiate the class " +
m_constructor.getDeclaringClass().getName() + " due to " + e );
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/DefaultPool.java
Index: DefaultPool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
import org.apache.avalon.Poolable;
import org.apache.avalon.Recyclable;
/**
* This is an <code>Pool</code> that caches Poolable objects for reuse.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultPool
extends AbstractPool
{
public final static int DEFAULT_POOL_SIZE = 8;
public DefaultPool( final ObjectFactory factory,
final PoolController controller )
throws Exception
{
super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
}
public DefaultPool( final ObjectFactory factory )
throws Exception
{
this( factory, null );
}
public DefaultPool( final Class clazz, final int initial, final int maximum )
throws NoSuchMethodException, Exception
{
super( new DefaultObjectFactory( clazz ), null, initial, maximum );
}
public DefaultPool( final Class clazz, final int initial )
throws NoSuchMethodException, Exception
{
this( clazz, initial, initial );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/ObjectFactory.java
Index: ObjectFactory.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
import org.apache.avalon.Component;
import org.apache.avalon.Poolable;
/**
* This is the interface for factory that is used to create objects for Pool.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface ObjectFactory
extends Component
{
Poolable newInstance() throws Exception;
Class getCreatedClass();
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/Pool.java
Index: Pool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
import org.apache.avalon.Component;
import org.apache.avalon.Poolable;
/**
* This is an <code>Pool</code> that caches Poolable objects for reuse.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@mad.scientist.com">Peter Donald</a>
*/
public interface Pool
extends Component
{
Poolable get() throws Exception;
void put( Poolable poolable );
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/PoolController.java
Index: PoolController.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
/**
* This is the interface you implement if you want to control how Pools capacity
* changes overtime.
*
* It gets called everytime that a Pool tries to go below or above it's minimum or maximum.
*
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
*/
public interface PoolController
{
/**
* Called when a Pool reaches it's minimum.
*
* Return the number of elements to increase minimum and maximum by.
*
* @return the element increase
*/
int grow();
/**
* Called when a pool reaches it's maximum.
*
* Returns the number of elements to decrease mi and max by.
*
* @return the element decrease
*/
int shrink();
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/pool/ThreadSafePool.java
Index: ThreadSafePool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.pool;
import org.apache.avalon.Poolable;
import org.apache.avalon.Recyclable;
import org.apache.avalon.ThreadSafe;
/**
* This is a implementation of <code>Pool</code> that is thread safe.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ThreadSafePool
extends AbstractPool
implements ThreadSafe
{
public final static int DEFAULT_POOL_SIZE = 8;
protected boolean m_blocking = false;
public ThreadSafePool( final ObjectFactory factory, final PoolController controller )
throws Exception
{
super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
}
public ThreadSafePool( final ObjectFactory factory )
throws Exception
{
this( factory, null );
}
public ThreadSafePool( final ObjectFactory factory,
final int initial,
final int maximum )
throws Exception
{
super( factory, null, initial, maximum );
}
public ThreadSafePool( final ObjectFactory factory, final int initial )
throws Exception
{
this( factory, initial, initial );
}
public ThreadSafePool( final Class clazz, final int initial, final int maximum )
throws NoSuchMethodException, Exception
{
this( new DefaultObjectFactory( clazz ), initial, maximum );
}
public ThreadSafePool( final Class clazz, final int initial )
throws NoSuchMethodException, Exception
{
this( clazz, initial, initial );
}
public final boolean isBlocking()
{
return m_blocking;
}
/**
* Set whether this pool is blocking.
*
* If this pool is blocking and empties the Pool then the thread will block until
* an object is placed back in the pool. This has to be used with care as an errant
* thread who never does a put will force blocked clients to wait forever.
*
* @param blocking a boolean indicating if it is blocking or not
*/
public final void setBlocking( final boolean blocking )
{
m_blocking = blocking;
}
/**
* Retrieve an object from pool.
*
* @return an object from Pool
*/
public final Poolable get() throws Exception
{
//Require this or else the wait later will cause
final Poolable[] pool = m_pool;
synchronized( pool )
{
if( 0 == m_count )
{
if( !m_blocking )
{
return m_factory.newInstance();
}
else
{
while( 0 == m_count )
{
try { pool.wait(); }
catch( final InterruptedException ie ) { }
}
}
}
m_count--;
final Poolable poolable = m_pool[ m_count ];
m_pool[ m_count ] = null;
return poolable;
}
}
/**
* Place an object in pool.
*
* @param poolable the object to be placed in pool
*/
public final void put( final Poolable poolable )
{
final Poolable[] pool = m_pool;
synchronized( pool )
{
super.put( poolable );
//if someone was waiting on the old pool then we have to notify them
pool.notifyAll();
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/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.avalon.util.pool.test;
import org.apache.avalon.Poolable;
import org.apache.avalon.util.pool.DefaultPool;
import org.apache.avalon.util.pool.Pool;
import org.apache.avalon.util.pool.ThreadSafePool;
import org.apache.testlet.*;
/**
* This is used to profile the Pool implementation.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class PoolProfile
extends AbstractTestlet
{
public static class A
implements Poolable
{
int a;
int b;
int c;
float x;
float y;
float z;
}
public static class B
implements Poolable
{
int a;
int b;
int c;
float x;
float y;
float z;
Object o1;
Object o2;
Object o3;
public void recycle()
{
o1 = o2 = o3 = null;
}
}
public static class C
implements Poolable
{
int a;
int b;
int c;
float x;
float y;
float z;
Object o1;
Object o2;
Object o3;
Object o4;
Object o5;
Object o6;
public void build()
{
o1 = new Object();
o2 = new Object();
o3 = new Object();
o4 = new Object();
o5 = new Object();
o6 = new Object();
}
public void recycle()
{
o1 = o2 = o3 = o4 = o5 = o6 = null;
}
}
protected static final int TEST_SIZE = 1000000;
public void testSmallObjects()
throws Exception
{
System.out.println("SMALL Sized Objects");
final DefaultPool pool1 = new DefaultPool( A.class, 5, 10 );
final long pool1Start = System.currentTimeMillis();
final int pool1Factor = 1;
final int pool1Loops = TEST_SIZE / pool1Factor;
for( int i = 0; i < TEST_SIZE; i++ )
{
final Poolable a1 = pool1.get();
pool1.put(a1);
}
final long pool1End = System.currentTimeMillis();
final long pool1Duration = pool1End - pool1Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool2 = new DefaultPool( A.class, 5, 10 );
final long pool2Start = System.currentTimeMillis();
final int pool2Factor = 10;
final int pool2Loops = TEST_SIZE / pool2Factor;
for( int i = 0; i < pool2Loops; i++ )
{
final Poolable a1 = pool2.get();
final Poolable a2 = pool2.get();
final Poolable a3 = pool2.get();
final Poolable a4 = pool2.get();
final Poolable a5 = pool2.get();
final Poolable a6 = pool2.get();
final Poolable a7 = pool2.get();
final Poolable a8 = pool2.get();
final Poolable a9 = pool2.get();
final Poolable a0 = pool2.get();
pool2.put(a1);
pool2.put(a2);
pool2.put(a3);
pool2.put(a4);
pool2.put(a5);
pool2.put(a6);
pool2.put(a7);
pool2.put(a8);
pool2.put(a9);
pool2.put(a0);
}
final long pool2End = System.currentTimeMillis();
final long pool2Duration = pool2End - pool2Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool3 = new DefaultPool( A.class, 5, 10 );
final long pool3Start = System.currentTimeMillis();
final int pool3Factor = 15;
final int pool3Loops = TEST_SIZE / pool3Factor;
for( int i = 0; i < pool3Loops; i++ )
{
final Poolable a1 = pool3.get();
final Poolable a2 = pool3.get();
final Poolable a3 = pool3.get();
final Poolable a4 = pool3.get();
final Poolable a5 = pool3.get();
final Poolable a6 = pool3.get();
final Poolable a7 = pool3.get();
final Poolable a8 = pool3.get();
final Poolable a9 = pool3.get();
final Poolable a10 = pool3.get();
final Poolable a11 = pool3.get();
final Poolable a12 = pool3.get();
final Poolable a13 = pool3.get();
final Poolable a14 = pool3.get();
final Poolable a15 = pool3.get();
pool3.put(a1);
pool3.put(a2);
pool3.put(a3);
pool3.put(a4);
pool3.put(a5);
pool3.put(a6);
pool3.put(a7);
pool3.put(a8);
pool3.put(a9);
pool3.put(a10);
pool3.put(a11);
pool3.put(a12);
pool3.put(a13);
pool3.put(a14);
pool3.put(a15);
}
final long pool3End = System.currentTimeMillis();
final long pool3Duration = pool3End - pool3Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool4 = new DefaultPool( A.class, 5, 10 );
final long pool4Start = System.currentTimeMillis();
final int pool4Factor = 20;
final int pool4Loops = TEST_SIZE / pool4Factor;
for( int i = 0; i < pool4Loops; i++ )
{
final Poolable a1 = pool4.get();
final Poolable a2 = pool4.get();
final Poolable a3 = pool4.get();
final Poolable a4 = pool4.get();
final Poolable a5 = pool4.get();
final Poolable a6 = pool4.get();
final Poolable a7 = pool4.get();
final Poolable a8 = pool4.get();
final Poolable a9 = pool4.get();
final Poolable a10 = pool4.get();
final Poolable a11 = pool4.get();
final Poolable a12 = pool4.get();
final Poolable a13 = pool4.get();
final Poolable a14 = pool4.get();
final Poolable a15 = pool4.get();
final Poolable a16 = pool4.get();
final Poolable a17 = pool4.get();
final Poolable a18 = pool4.get();
final Poolable a19 = pool4.get();
final Poolable a20 = pool4.get();
pool4.put(a1);
pool4.put(a2);
pool4.put(a3);
pool4.put(a4);
pool4.put(a5);
pool4.put(a6);
pool4.put(a7);
pool4.put(a8);
pool4.put(a9);
pool4.put(a10);
pool4.put(a11);
pool4.put(a12);
pool4.put(a13);
pool4.put(a14);
pool4.put(a15);
pool4.put(a16);
pool4.put(a17);
pool4.put(a18);
pool4.put(a19);
pool4.put(a20);
}
final long pool4End = System.currentTimeMillis();
final long pool4Duration = pool4End - pool4Start;
System.out.println("FreeMem post 4: " + Runtime.getRuntime().freeMemory() );
final long createStart = System.currentTimeMillis();
for( int i = 0; i < TEST_SIZE; i++ )
{
final Poolable a1 = new C();
}
final long createEnd = System.currentTimeMillis();
final long createDuration = createEnd - createStart;
//System.out.println("Create Duration: " + createDuration + "ms ");
System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
//System.out.println("Pool Duration for 100% hits: " + pool1Duration + "ms ");
System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
//System.out.println("Pool Duration for 100% hits and saturated: " + pool2Duration + "ms ");
System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
//System.out.println("Pool Duration for 60% hits: " + pool3Duration + "ms ");
System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
//System.out.println("Pool Duration for 50% hits: " + pool4Duration + "ms ");
System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
}
public void testMediumObjects()
throws Exception
{
System.out.println("MEDIUM Sized Objects");
System.gc();
System.gc();
Thread.currentThread().sleep(2);
final DefaultPool pool1 = new DefaultPool( B.class, 5, 10 );
final long pool1Start = System.currentTimeMillis();
final int pool1Factor = 1;
final int pool1Loops = TEST_SIZE / pool1Factor;
for( int i = 0; i < TEST_SIZE; i++ )
{
final Poolable a1 = pool1.get();
pool1.put(a1);
}
final long pool1End = System.currentTimeMillis();
final long pool1Duration = pool1End - pool1Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool2 = new DefaultPool( B.class, 5, 10 );
final long pool2Start = System.currentTimeMillis();
final int pool2Factor = 10;
final int pool2Loops = TEST_SIZE / pool2Factor;
for( int i = 0; i < pool2Loops; i++ )
{
final Poolable a1 = pool2.get();
final Poolable a2 = pool2.get();
final Poolable a3 = pool2.get();
final Poolable a4 = pool2.get();
final Poolable a5 = pool2.get();
final Poolable a6 = pool2.get();
final Poolable a7 = pool2.get();
final Poolable a8 = pool2.get();
final Poolable a9 = pool2.get();
final Poolable a10 = pool2.get();
pool2.put(a1);
pool2.put(a2);
pool2.put(a3);
pool2.put(a4);
pool2.put(a5);
pool2.put(a6);
pool2.put(a7);
pool2.put(a8);
pool2.put(a9);
pool2.put(a10);
}
final long pool2End = System.currentTimeMillis();
final long pool2Duration = pool2End - pool2Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool3 = new DefaultPool( B.class, 5, 10 );
final long pool3Start = System.currentTimeMillis();
final int pool3Factor = 15;
final int pool3Loops = TEST_SIZE / pool3Factor;
for( int i = 0; i < pool3Loops; i++ )
{
final Poolable a1 = pool3.get();
final Poolable a2 = pool3.get();
final Poolable a3 = pool3.get();
final Poolable a4 = pool3.get();
final Poolable a5 = pool3.get();
final Poolable a6 = pool3.get();
final Poolable a7 = pool3.get();
final Poolable a8 = pool3.get();
final Poolable a9 = pool3.get();
final Poolable a10 = pool3.get();
final Poolable a11 = pool3.get();
final Poolable a12 = pool3.get();
final Poolable a13 = pool3.get();
final Poolable a14 = pool3.get();
final Poolable a15 = pool3.get();
pool3.put(a1);
pool3.put(a2);
pool3.put(a3);
pool3.put(a4);
pool3.put(a5);
pool3.put(a6);
pool3.put(a7);
pool3.put(a8);
pool3.put(a9);
pool3.put(a10);
pool3.put(a11);
pool3.put(a12);
pool3.put(a13);
pool3.put(a14);
pool3.put(a15);
}
final long pool3End = System.currentTimeMillis();
final long pool3Duration = pool3End - pool3Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool4 = new DefaultPool( B.class, 5, 10 );
final long pool4Start = System.currentTimeMillis();
final int pool4Factor = 20;
final int pool4Loops = TEST_SIZE / pool4Factor;
for( int i = 0; i < pool4Loops; i++ )
{
final Poolable a1 = pool4.get();
final Poolable a2 = pool4.get();
final Poolable a3 = pool4.get();
final Poolable a4 = pool4.get();
final Poolable a5 = pool4.get();
final Poolable a6 = pool4.get();
final Poolable a7 = pool4.get();
final Poolable a8 = pool4.get();
final Poolable a9 = pool4.get();
final Poolable a10 = pool4.get();
final Poolable a11 = pool4.get();
final Poolable a12 = pool4.get();
final Poolable a13 = pool4.get();
final Poolable a14 = pool4.get();
final Poolable a15 = pool4.get();
final Poolable a16 = pool4.get();
final Poolable a17 = pool4.get();
final Poolable a18 = pool4.get();
final Poolable a19 = pool4.get();
final Poolable a20 = pool4.get();
pool4.put(a1);
pool4.put(a2);
pool4.put(a3);
pool4.put(a4);
pool4.put(a5);
pool4.put(a6);
pool4.put(a7);
pool4.put(a8);
pool4.put(a9);
pool4.put(a10);
pool4.put(a11);
pool4.put(a12);
pool4.put(a13);
pool4.put(a14);
pool4.put(a15);
pool4.put(a16);
pool4.put(a17);
pool4.put(a18);
pool4.put(a19);
pool4.put(a20);
}
final long pool4End = System.currentTimeMillis();
final long pool4Duration = pool4End - pool4Start;
final long createStart = System.currentTimeMillis();
for( int i = 0; i < TEST_SIZE; i++ )
{
final Poolable a1 = new C();
}
final long createEnd = System.currentTimeMillis();
final long createDuration = createEnd - createStart;
//System.out.println("Create Duration: " + createDuration + "ms ");
System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
//System.out.println("Pool Duration for 100% hits: " + pool1Duration + "ms ");
System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
//System.out.println("Pool Duration for 100% hits and saturated: " + pool2Duration + "ms ");
System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
//System.out.println("Pool Duration for 60% hits: " + pool3Duration + "ms ");
System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
//System.out.println("Pool Duration for 50% hits: " + pool4Duration + "ms ");
System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
}
public void testLargeObjects()
throws Exception
{
System.out.println("LARGE Sized Objects");
System.gc();
System.gc();
Thread.currentThread().sleep(2);
final DefaultPool pool1 = new DefaultPool( C.class, 5, 10 );
final long pool1Start = System.currentTimeMillis();
final int pool1Factor = 1;
final int pool1Loops = TEST_SIZE / pool1Factor;
for( int i = 0; i < TEST_SIZE; i++ )
{
final Poolable a1 = pool1.get();
pool1.put(a1);
}
final long pool1End = System.currentTimeMillis();
final long pool1Duration = pool1End - pool1Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 1: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool2 = new DefaultPool( C.class, 5, 10 );
final long pool2Start = System.currentTimeMillis();
final int pool2Factor = 10;
final int pool2Loops = TEST_SIZE / pool2Factor;
for( int i = 0; i < pool2Loops; i++ )
{
final Poolable a1 = pool2.get();
final Poolable a2 = pool2.get();
final Poolable a3 = pool2.get();
final Poolable a4 = pool2.get();
final Poolable a5 = pool2.get();
final Poolable a6 = pool2.get();
final Poolable a7 = pool2.get();
final Poolable a8 = pool2.get();
final Poolable a9 = pool2.get();
final Poolable a10 = pool2.get();
pool2.put(a1);
pool2.put(a2);
pool2.put(a3);
pool2.put(a4);
pool2.put(a5);
pool2.put(a6);
pool2.put(a7);
pool2.put(a8);
pool2.put(a9);
pool2.put(a10);
}
final long pool2End = System.currentTimeMillis();
final long pool2Duration = pool2End - pool2Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 2: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool3 = new DefaultPool( C.class, 5, 10 );
final long pool3Start = System.currentTimeMillis();
final int pool3Factor = 15;
final int pool3Loops = TEST_SIZE / pool3Factor;
for( int i = 0; i < pool3Loops; i++ )
{
final Poolable a1 = pool3.get();
final Poolable a2 = pool3.get();
final Poolable a3 = pool3.get();
final Poolable a4 = pool3.get();
final Poolable a5 = pool3.get();
final Poolable a6 = pool3.get();
final Poolable a7 = pool3.get();
final Poolable a8 = pool3.get();
final Poolable a9 = pool3.get();
final Poolable a10 = pool3.get();
final Poolable a11 = pool3.get();
final Poolable a12 = pool3.get();
final Poolable a13 = pool3.get();
final Poolable a14 = pool3.get();
final Poolable a15 = pool3.get();
pool3.put(a1);
pool3.put(a2);
pool3.put(a3);
pool3.put(a4);
pool3.put(a5);
pool3.put(a6);
pool3.put(a7);
pool3.put(a8);
pool3.put(a9);
pool3.put(a10);
pool3.put(a11);
pool3.put(a12);
pool3.put(a13);
pool3.put(a14);
pool3.put(a15);
}
final long pool3End = System.currentTimeMillis();
final long pool3Duration = pool3End - pool3Start;
System.gc();
System.gc();
Thread.currentThread().sleep(2);
System.out.println("FreeMem post 3: " + Runtime.getRuntime().freeMemory() );
final DefaultPool pool4 = new DefaultPool( C.class, 5, 10 );
final long pool4Start = System.currentTimeMillis();
final int pool4Factor = 20;
final int pool4Loops = TEST_SIZE / pool4Factor;
for( int i = 0; i < pool4Loops; i++ )
{
final Poolable a1 = pool4.get();
final Poolable a2 = pool4.get();
final Poolable a3 = pool4.get();
final Poolable a4 = pool4.get();
final Poolable a5 = pool4.get();
final Poolable a6 = pool4.get();
final Poolable a7 = pool4.get();
final Poolable a8 = pool4.get();
final Poolable a9 = pool4.get();
final Poolable a10 = pool4.get();
final Poolable a11 = pool4.get();
final Poolable a12 = pool4.get();
final Poolable a13 = pool4.get();
final Poolable a14 = pool4.get();
final Poolable a15 = pool4.get();
final Poolable a16 = pool4.get();
final Poolable a17 = pool4.get();
final Poolable a18 = pool4.get();
final Poolable a19 = pool4.get();
final Poolable a20 = pool4.get();
pool4.put(a1);
pool4.put(a2);
pool4.put(a3);
pool4.put(a4);
pool4.put(a5);
pool4.put(a6);
pool4.put(a7);
pool4.put(a8);
pool4.put(a9);
pool4.put(a10);
pool4.put(a11);
pool4.put(a12);
pool4.put(a13);
pool4.put(a14);
pool4.put(a15);
pool4.put(a16);
pool4.put(a17);
pool4.put(a18);
pool4.put(a19);
pool4.put(a20);
}
final long pool4End = System.currentTimeMillis();
final long pool4Duration = pool4End - pool4Start;
System.out.println("FreeMem post 4: " + Runtime.getRuntime().freeMemory() );
final long createStart = System.currentTimeMillis();
for( int i = 0; i < TEST_SIZE; i++ )
{
final Poolable a1 = new C();
}
final long createEnd = System.currentTimeMillis();
final long createDuration = createEnd - createStart;
System.out.println("FreeMem post create: " + Runtime.getRuntime().freeMemory() );
final double pool1Efficiancy = (double)createDuration/(double)pool1Duration * 100.0;
final double pool2Efficiancy = (double)createDuration/(double)pool2Duration * 100.0;
final double pool3Efficiancy = (double)createDuration/(double)pool3Duration * 100.0;
final double pool4Efficiancy = (double)createDuration/(double)pool4Duration * 100.0;
System.out.println("Pool Efficiancy for 100% hits: " + pool1Efficiancy + "ms ");
System.out.println("Pool Efficiancy for 100% hits and saturated: " + pool2Efficiancy + "ms ");
System.out.println("Pool Efficiancy for 60% hits: " + pool3Efficiancy + "ms ");
System.out.println("Pool Efficiancy for 50% hits: " + pool4Efficiancy + "ms ");
}
public void testThreadedSmallObjects()
throws Exception
{
System.out.println("SMALL Sized Objects with thread safe pools");
final ThreadSafePool pool1 = new ThreadSafePool( 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 ThreadSafePool pool2 = new ThreadSafePool( 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 ThreadSafePool pool3 = new ThreadSafePool( 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 ThreadSafePool pool4 = new ThreadSafePool( 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 ThreadSafePool pool1 = new ThreadSafePool( 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 ThreadSafePool pool2 = new ThreadSafePool( 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 ThreadSafePool pool3 = new ThreadSafePool( 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 ThreadSafePool pool4 = new ThreadSafePool( 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 ThreadSafePool pool1 = new ThreadSafePool( 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 ThreadSafePool pool2 = new ThreadSafePool( 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 ThreadSafePool pool3 = new ThreadSafePool( 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 ThreadSafePool pool4 = new ThreadSafePool( 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 ");
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/security/AbstractPolicy.java
Index: AbstractPolicy.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.security;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.PropertyPermission;
import org.apache.avalon.Component;
import org.apache.avalon.Loggable;
import org.apache.avalon.util.io.FileUtil;
import org.apache.log.Logger;
/**
* Abstract policy extended in avalon.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public abstract class AbstractPolicy
extends Policy
implements Component, Loggable
{
protected final static boolean DEBUG = true;
protected final ArrayList m_entries = new ArrayList();
protected Logger m_logger;
/**
* Internal Policy Entry holder class.
*/
protected final static class PolicyEntry
{
CodeSource m_codeSource;
Permissions m_permissions;
}
public void setLogger( final Logger logger )
{
m_logger = logger;
}
/**
* Overide so we can have a per-application security policy with
* no side-effects to other applications.
*
* @param codeSource the codeSource to get permissions for
* @return the PermissionCollection
*/
public PermissionCollection getPermissions( CodeSource codeSource )
{
codeSource = normalize( codeSource );
getLogger().debug( "getPermissions(" + codeSource.getLocation() + ");" );
final Permissions permissions = new Permissions();
final int size = m_entries.size();
for( int i = 0; i < size; i++ )
{
final PolicyEntry entry = (PolicyEntry)m_entries.get( i );
if( entry.m_codeSource.implies( codeSource ) )
{
if( DEBUG )
{
getLogger().debug( entry.m_codeSource.getLocation() + " implies " +
codeSource.getLocation() );
}
copyPermissions( permissions, entry.m_permissions );
}
}
if( DEBUG )
{
getLogger().debug( codeSource.getLocation() + " permissions = " + permissions );
}
return permissions;
}
/**
* Refresh policy. Ignored in this implementation.
*/
public void refresh()
{
}
/**
* Normalizing CodeSource involves removing relative addressing
* (like .. and .) for file urls.
*
* @param codeSource the codeSource to be normalized
* @return the normalized codeSource
*/
protected CodeSource normalize( final CodeSource codeSource )
{
final URL initialLocation = codeSource.getLocation();
// This is a bit of a hack. I don't know why CodeSource should behave like this
// Fear not, this only seems to be a problem for home grown classloaders.
// - Paul Hammant, Nov 2000
if( null == initialLocation ) return codeSource;
String location = null;
if( !initialLocation.getProtocol().equalsIgnoreCase( "file" ) )
{
location = initialLocation.getFile();
location = FileUtil.normalize( location );
}
else
{
final File file = new File( initialLocation.getFile() );
location = file.getAbsoluteFile().toString().replace( File.separatorChar, '/' );
location = FileUtil.normalize( location );
}
URL finalLocation = null;
try
{
finalLocation = new URL( initialLocation.getProtocol(),
initialLocation.getHost(),
initialLocation.getPort(),
location );
}
catch( final MalformedURLException mue )
{
getLogger().warn( "Error building codeBase", mue );
}
return new CodeSource( finalLocation, codeSource.getCertificates() );
}
protected void copyPermissions( final Permissions destination, final Permissions src )
{
final Enumeration enum = src.elements();
while( enum.hasMoreElements() )
{
destination.add( (Permission)enum.nextElement() );
}
}
/**
* Create a permission set for a codeBase.
* These are read-write permissions and can be written till until the
* time in which they are applied to code.
*
* @param location the location of codes to apply permission set to.
* @param signers a comma seperated string of thos who signed codebase
* @return the new permission set
* @exception MalformedURLException if location string is malformed
*/
protected Permissions createPermissionSetFor( final String location,
final Certificate[] signers )
throws MalformedURLException
{
final PolicyEntry entry = new PolicyEntry();
entry.m_codeSource = new CodeSource( new URL( location ), signers );
entry.m_codeSource = normalize( entry.m_codeSource );
getLogger().debug( "createPermissionSetFor(" +
entry.m_codeSource.getLocation() + ");" );
entry.m_permissions = new Permissions();
m_entries.add( entry );
return entry.m_permissions;
}
protected final Logger getLogger()
{
return m_logger;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/security/DefaultPolicy.java
Index: DefaultPolicy.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.security;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.UnresolvedPermission;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.PropertyPermission;
import java.util.StringTokenizer;
import org.apache.avalon.Component;
import org.apache.avalon.configuration.Configurable;
import org.apache.avalon.configuration.Configuration;
import org.apache.avalon.configuration.ConfigurationException;
import org.apache.avalon.Context;
import org.apache.avalon.Contextualizable;
import org.apache.avalon.DefaultContext;
import org.apache.avalon.Initializable;
import org.apache.avalon.util.PropertyException;
import org.apache.avalon.util.PropertyUtil;
import org.apache.avalon.util.security.AbstractPolicy;
/**
* Policy that extracts information from policy files.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultPolicy
extends AbstractPolicy
implements Component, Contextualizable, Configurable, Initializable
{
protected DefaultContext m_context;
public void contextualize( final Context context )
{
m_context = new DefaultContext( System.getProperties(), context );
m_context.put( "/", File.separator );
}
public void configure( final Configuration configuration )
throws ConfigurationException
{
final Configuration[] keyStoreConfigurations = configuration.getChildren( "keystore" );
final HashMap keyStores = configureKeyStores( keyStoreConfigurations );
final Configuration[] grants = configuration.getChildren( "grant" );
configureGrants( grants, keyStores );
}
public void init()
throws Exception
{
//these properties straight out ot ${java.home}/lib/security/java.policy
final Permissions permissions = createPermissionSetFor( "file:/-", null );
permissions.add( new PropertyPermission( "os.name", "read" ) );
permissions.add( new PropertyPermission( "os.arch", "read" ) );
permissions.add( new PropertyPermission( "os.version", "read" ) );
permissions.add( new PropertyPermission( "file.separator", "read" ) );
permissions.add( new PropertyPermission( "path.separator", "read" ) );
permissions.add( new PropertyPermission( "line.separator", "read" ) );
permissions.add( new PropertyPermission( "java.version", "read" ) );
permissions.add( new PropertyPermission( "java.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.vendor.url", "read" ) );
permissions.add( new PropertyPermission( "java.class.version", "read" ) );
permissions.add( new PropertyPermission( "java.vm.version", "read" ) );
permissions.add( new PropertyPermission( "java.vm.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.vm.name", "read" ) );
permissions.add( new PropertyPermission( "java.specification.version", "read" ) );
permissions.add( new PropertyPermission( "java.specification.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.specification.name", "read" ) );
permissions.add( new PropertyPermission( "java.vm.specification.version", "read" ) );
permissions.add( new PropertyPermission( "java.vm.specification.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.vm.specification.name", "read" ) );
}
protected HashMap configureKeyStores( final Configuration[] configurations )
throws ConfigurationException
{
final HashMap keyStores = new HashMap();
for( int i = 0; i < configurations.length; i++ )
{
final Configuration configuration = configurations[ i ];
final String type = configuration.getAttribute( "type" );
final String location = configuration.getAttribute( "location" );
final String name = configuration.getAttribute( "name" );
try
{
final KeyStore keyStore = KeyStore.getInstance( type );
final URL url = new URL( location );
final InputStream ins = url.openStream();
keyStore.load( ins, null );
keyStores.put( name, keyStore );
}
catch( final Exception e )
{
throw new ConfigurationException( "Error configuring keystore " + name, e );
}
}
return keyStores;
}
protected void configureGrants( final Configuration[] configurations,
final HashMap keyStores )
throws ConfigurationException
{
for( int i = 0; i < configurations.length; i++ )
{
configureGrant( configurations[ i ], keyStores );
}
}
protected void configureGrant( final Configuration configuration, final HashMap keyStores )
throws ConfigurationException
{
//<grant signed-by="Fred" code-base="file:${sar.home}/blocks/*" key-store="foo-keystore">
//<permission class="java.io.FilePermission" target="/tmp/*" action="read,write" />
//</grant>
final String signedBy = configuration.getAttribute( "signed-by", null );
final String keyStoreName = configuration.getAttribute( "key-store", null );
String codeBase = configuration.getAttribute( "code-base", null );
if( null != codeBase )
{
codeBase = expand( codeBase );
}
final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
Permissions permissions = null;
try { permissions = createPermissionSetFor( codeBase, signers ); }
catch( final MalformedURLException mue )
{
throw new ConfigurationException( "Malformed code-base " + codeBase, mue );
}
configurePermissions( configuration.getChildren( "permission" ),
permissions,
keyStores );
}
protected void configurePermissions( final Configuration[] configurations,
final Permissions permissions,
final HashMap keyStores )
throws ConfigurationException
{
for( int i = 0; i < configurations.length; i++ )
{
configurePermission( configurations[ i ], permissions, keyStores );
}
}
protected void configurePermission( final Configuration configuration,
final Permissions permissions,
final HashMap keyStores )
throws ConfigurationException
{
final String type = configuration.getAttribute( "class" );
final String actions = configuration.getAttribute( "actions", null );
final String signedBy = configuration.getAttribute( "signed-by", null );
final String keyStoreName = configuration.getAttribute( "key-store", null );
String target = configuration.getAttribute( "target", null );
if( null != target )
{
target = expand( target );
}
final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
final Permission permission = createPermission( type, target, actions, signers );
permissions.add( permission );
}
protected String expand( final String value )
throws ConfigurationException
{
try
{
final Object resolvedValue = PropertyUtil.resolveProperty( value, m_context, false );
return resolvedValue.toString();
}
catch( final PropertyException pe )
{
throw new ConfigurationException( "Error resolving property " + value, pe );
}
}
protected Permission createPermission( final String type,
final String target,
final String actions,
final Certificate[] signers )
throws ConfigurationException
{
if( null != signers )
{
return createUnresolvedPermission( type, target, actions, signers );
}
try
{
final Class c = Class.forName( type );
Class paramClasses[] = null;
Object params[] = null;
if( null == actions && null == target )
{
paramClasses = new Class[ 0 ];
params = new Object[ 0 ];
}
else if( null == actions )
{
paramClasses = new Class[1];
paramClasses[0] = String.class;
params = new Object[1];
params[0] = target;
}
else
{
paramClasses = new Class[2];
paramClasses[0] = String.class;
paramClasses[1] = String.class;
params = new Object[2];
params[0] = target;
params[1] = actions;
}
final Constructor constructor = c.getConstructor( paramClasses );
final Object o = constructor.newInstance( params );
return (Permission)o;
}
catch( final ClassNotFoundException cnfe )
{
return createUnresolvedPermission( type, target, actions, signers );
}
catch( final Exception e )
{
throw new ConfigurationException( "Failed to create permission " + type +
" due to " + e, e );
}
}
protected Permission createUnresolvedPermission( final String type,
final String target,
final String actions,
final Certificate[] signers )
{
return new UnresolvedPermission( type, target, actions, signers );
}
protected Certificate[] getSigners( final String signedBy,
String keyStoreName,
final HashMap keyStores )
throws ConfigurationException
{
if( null != signedBy && null == keyStoreName )
{
keyStoreName = "default";
}
Certificate[] signers = null;
if( null != signedBy )
{
signers = getCertificates( signedBy, keyStoreName, keyStores );
}
return signers;
}
protected Certificate[] getCertificates( final String signedBy,
final String keyStoreName,
final HashMap keyStores )
throws ConfigurationException
{
final KeyStore keyStore = (KeyStore)keyStores.get( keyStoreName );
if( null == keyStore )
{
throw new ConfigurationException( "Unable to aquire keyStore " + keyStoreName );
}
final ArrayList certificateSet = new ArrayList();
final StringTokenizer tokenizer = new StringTokenizer( signedBy, "," );
while( tokenizer.hasMoreTokens() )
{
final String alias = ((String)tokenizer.nextToken()).trim();
Certificate certificate = null;
try { certificate = keyStore.getCertificate( alias ); }
catch( final KeyStoreException kse )
{
throw new ConfigurationException( "Error aquiring certificate " + alias,
kse );
}
if( null == certificate )
{
throw new ConfigurationException( "Unable to locate alias " + alias +
" in keystore named " + keyStoreName );
}
if( !certificateSet.contains( certificate ) )
{
if( DEBUG ) getLogger().debug( "Certificate " + certificate );
certificateSet.add( certificate );
}
}
return (Certificate[])certificateSet.toArray( new Certificate[ 0 ] );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/security/PolicyClassLoader.java
Index: PolicyClassLoader.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.security;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
/**
* Classloader that applies correct policy information.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class PolicyClassLoader
extends URLClassLoader
{
protected Policy m_policy;
public PolicyClassLoader( final URL[] urls,
final ClassLoader classLoader,
final Policy policy )
{
super( urls, classLoader );
m_policy = policy;
}
/**
* Overide so we can have a per-application security policy with
* no side-effects to other applications.
*
* @param codeSource the codeSource to get permissions for
* @return the PermissionCollection
*/
protected PermissionCollection getPermissions( final CodeSource codeSource )
{
if( null == m_policy )
{
final Permissions permissions = new Permissions();
permissions.add( new java.security.AllPermission() );
return permissions;
}
else
{
return m_policy.getPermissions( codeSource );
}
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/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.avalon.util.test;
import org.apache.avalon.util.BinaryHeap;
import org.apache.testlet.AbstractTestlet;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class BinaryHeapTestlet
extends AbstractTestlet
{
protected final static Integer VAL1 = new Integer( 1 );
protected final static Integer VAL2 = new Integer( 2 );
protected final static Integer VAL3 = new Integer( 3 );
protected final static Integer VAL4 = new Integer( 4 );
protected final static Integer VAL5 = new Integer( 5 );
protected final static Integer VAL6 = new Integer( 6 );
protected final static Integer VAL7 = new Integer( 7 );
public void testSimpleOrder()
{
final BinaryHeap heap = new BinaryHeap();
heap.clear();
heap.insert( VAL1 );
heap.insert( VAL2 );
heap.insert( VAL3 );
heap.insert( VAL4 );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL4 == heap.pop() );
}
public void testReverseOrder()
{
final BinaryHeap heap = new BinaryHeap();
heap.clear();
heap.insert( VAL4 );
heap.insert( VAL3 );
heap.insert( VAL2 );
heap.insert( VAL1 );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL4 == heap.pop() );
}
public void testMixedOrder()
{
final BinaryHeap heap = new BinaryHeap();
heap.clear();
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL4 == heap.pop() );
}
public void testDuplicates()
{
final BinaryHeap heap = new BinaryHeap();
heap.clear();
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL4 == heap.pop() );
}
public void testMixedInsertPopOrder()
{
final BinaryHeap heap = new BinaryHeap();
heap.clear();
heap.insert( VAL1 );
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL4 == heap.pop() );
assert( VAL4 == heap.pop() );
}
public void testReverseSimpleOrder()
{
final BinaryHeap heap = new BinaryHeap( false );
heap.clear();
heap.insert( VAL1 );
heap.insert( VAL2 );
heap.insert( VAL3 );
heap.insert( VAL4 );
assert( VAL4 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
}
public void testReverseReverseOrder()
{
final BinaryHeap heap = new BinaryHeap( false );
heap.clear();
heap.insert( VAL4 );
heap.insert( VAL3 );
heap.insert( VAL2 );
heap.insert( VAL1 );
assert( VAL4 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
}
public void testReverseMixedOrder()
{
final BinaryHeap heap = new BinaryHeap( false );
heap.clear();
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL4 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
}
public void testReverseDuplicates()
{
final BinaryHeap heap = new BinaryHeap( false );
heap.clear();
heap.insert( VAL4 );
heap.insert( VAL3 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
assert( VAL4 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
}
public void testReverseMixedInsertPopOrder()
{
final BinaryHeap heap = new BinaryHeap( false );
heap.clear();
heap.insert( VAL1 );
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL4 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL2 == heap.pop() );
heap.insert( VAL4 );
heap.insert( VAL2 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL1 );
heap.insert( VAL3 );
assert( VAL4 == heap.pop() );
assert( VAL3 == heap.pop() );
assert( VAL2 == heap.pop() );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.peek() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
assert( VAL1 == heap.pop() );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/test/DependencyGraphTestlet.java
Index: DependencyGraphTestlet.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.test;
import java.util.List;
import org.apache.avalon.util.CircularDependencyException;
import org.apache.avalon.util.DependencyGraph;
import org.apache.testlet.AbstractTestlet;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class DependencyGraphTestlet
extends AbstractTestlet
{
protected final String[][] DEPENDENCY_TREE =
{
{ "A" }, { "B", "C", "D" },
{ "B" }, { "E" },
{ "C" }, {},
{ "D" }, { "F" },
{ "E" }, { "F" },
{ "F" }, { },
{ "G" }, { "H" },
{ "H" }, { "G" },
{ "I" }, { "I" }
};
protected DependencyGraph m_graph;
public void initialize()
{
m_graph = new DependencyGraph();
for( int i = 0; i < DEPENDENCY_TREE.length; i += 2 )
{
m_graph.add( DEPENDENCY_TREE[ i ][0], DEPENDENCY_TREE[ i + 1 ] );
}
}
protected boolean contains( final DependencyGraph.Dependency[] list, final String name )
{
for( int i = 0; i < list.length; i++ )
{
if( list[ i ].getName().equals( name ) )
{
return true;
}
}
return false;
}
public void testNoDependency()
throws Exception
{
final DependencyGraph.Dependency[] list = m_graph.getDependencyList( "F" );
assertEquality( "Graph for F", list.length, 1 );
assertEquality( "Graph for F[1]", list[ 0 ].getName(), "F" );
assertEquality( "Graph for F[1]", list[ 0 ].getRequiredBy(), null );
}
public void test1LevelDependency()
throws Exception
{
final DependencyGraph.Dependency[] list = m_graph.getDependencyList( "E" );
assertEquality( "Graph for E", list.length, 2 );
assert( "Graph for E[1]", contains( list, "E" ) );
assert( "Graph for E[2]", contains( list, "F" ) );
}
public void test2LevelDependency()
throws Exception
{
final DependencyGraph.Dependency[] list = m_graph.getDependencyList( "B" );
assertEquality( "Graph for E", list.length, 3 );
assert( "Graph for E[1]", contains( list, "E" ) );
assert( "Graph for E[2]", contains( list, "F" ) );
assert( "Graph for E[3]", contains( list, "B" ) );
}
public void testNLevelDependency()
throws Exception
{
final DependencyGraph.Dependency[] list = m_graph.getDependencyList( "A" );
assertEquality( "Graph for A", list.length, 6 );
assert( "Graph for A[1]", contains( list, "A" ) );
assert( "Graph for A[2]", contains( list, "B" ) );
assert( "Graph for A[3]", contains( list, "C" ) );
assert( "Graph for A[4]", contains( list, "D" ) );
assert( "Graph for A[5]", contains( list, "E" ) );
assert( "Graph for A[6]", contains( list, "F" ) );
}
public void testAllowableCircularDependency()
throws Exception
{
m_graph.setAllowCircularity( true );
final DependencyGraph.Dependency[] list = m_graph.getDependencyList( "G" );
assertEquality( "Graph for G", list.length, 2 );
assert( "Graph for G[1]", contains( list, "G" ) );
assert( "Graph for H[2]", contains( list, "H" ) );
}
public void testUnallowableCircularDependency()
throws Exception
{
try
{
m_graph.setAllowCircularity( false );
m_graph.getDependencyList( "G" );
}
catch( final CircularDependencyException cde )
{
return;
}
fail( "Expected CircularDependencyException" );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/test/PropertyUtilTestlet.java
Index: PropertyUtilTestlet.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.test;
import org.apache.avalon.Context;
import org.apache.avalon.DefaultContext;
import org.apache.avalon.Resolvable;
import org.apache.avalon.util.PropertyException;
import org.apache.avalon.util.PropertyUtil;
import org.apache.testlet.AbstractTestlet;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class PropertyUtilTestlet
extends AbstractTestlet
{
protected static final class ResolveTest
implements Resolvable
{
protected int m_count;
protected int m_current;
public ResolveTest( final int count )
{
m_count = count;
}
public Object resolve( final Context context )
{
m_current++;
if( m_current >= m_count ) return new Integer( m_count );
else return this;
}
}
protected final static Object OBJ1 = new Object();
protected final static Object OBJ2 = new Object();
protected DefaultContext m_context;
public void initialize()
{
m_context = new DefaultContext();
m_context.put( "obj1", OBJ1 );
m_context.put( "obj2", OBJ2 );
m_context.put( "res1", new ResolveTest( 1 ) );
m_context.put( "res2", new ResolveTest( 2 ) );
m_context.put( "res3", new ResolveTest( 3 ) );
m_context.put( "res4", new ResolveTest( 4 ) );
}
public void testNoResolve()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( "blah", m_context, false );
assertEquality( result, "blah" );
}
public void testObjResolve()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( "${obj1}", m_context, false );
assertEquality( result, OBJ1 );
}
public void testObjResolveToText()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( "${obj1} ", m_context, false );
assertEquality( result, OBJ1 + " " );
}
public void testDualObjResolve()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( " ${obj1} ${obj2} ", m_context, false );
assertEquality( result, " " + OBJ1 + " " + OBJ2 + " " );
}
public void testRecurseObjResolve()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( "${res1}", m_context, false );
assertEquality( result, new Integer( 1 ) );
}
public void testRecurseObjResolve2()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( "${res2}", m_context, false );
assertEquality( result, new Integer( 2 ) );
}
public void testNullObjResolve()
throws PropertyException
{
final Object result =
PropertyUtil.resolveProperty( "${blahaaa}", m_context, true );
assertEquality( result, "" );
}
public void testNullObjResolveForException()
throws PropertyException
{
try
{
final Object result =
PropertyUtil.resolveProperty( "${blahaaa}", m_context, false );
}
catch( final PropertyException pe )
{
return;
}
fail( "NUll resolve occured without exception" );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/test/ProxyGeneratorTestlet.java
Index: ProxyGeneratorTestlet.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.avalon.util.test;
import org.apache.avalon.util.ProxyGenerator;
import org.apache.testlet.AbstractTestlet;
import org.apache.testlet.TestFailedException;
/**
* This is used to test Proxy generation for correctness.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class ProxyGeneratorTestlet
extends AbstractTestlet
{
public interface Interface1
{
void method1();
}
public interface Interface2 extends Interface1
{
void method2();
}
public interface Interface3
{
void method3( int x );
}
public interface Interface4
{
void method4( String x );
}
public interface Interface5
{
void method3( String x );
}
public interface Interface6
{
void method2();
}
public interface Interface7
{
void method3( double x );
}
public interface Interface8
{
void method3( double x, double y );
}
public interface Interface9
{
int method4( double x, double y );
}
public interface Interface10
{
double method10( double x, double y );
}
public static class ClassA
implements Interface1, Interface3, Interface4, Interface5, Interface9, Interface10
{
public void method1() {}
public void method3( int x ) {}
public void method3( String x ) {}
public void method4( String x ) {}
public int method4( double x, double y ) { return 0; }
public double method10( double x, double y ) { return 0.0; }
}
public static class ClassB implements Interface2, Interface6, Interface7, Interface8
{
public void method1() {}
public void method2() {}
public void method3( double x ) {}
public void method3( double x, double y ) {}
}
public void testNoParamMethod()
throws Exception
{
final Class[] interfaces = new Class[] { Interface1.class };
final Object object = new ClassA();
final Object result = doTest( object, interfaces );
((Interface1)result).method1();
}
public void testExtendedInterfaceHidden()
throws Exception
{
final Class[] interfaces = new Class[] { Interface1.class };
final Object object = new ClassB();
final Object result = doTest( object, interfaces );
((Interface1)result).method1();
assert( !(result instanceof Interface2) );
}
public void testExtendedInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface1.class, Interface2.class };
final Object object = new ClassB();
final Object result = doTest( object, interfaces );
((Interface1)result).method1();
((Interface2)result).method1();
((Interface2)result).method2();
}
public void testIntParamInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface3.class };
final Object object = new ClassA();
final Object result = doTest( object, interfaces );
((Interface3)result).method3(2);
}
public void testStringParamInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface4.class };
final Object object = new ClassA();
final Object result = doTest( object, interfaces );
((Interface4)result).method4("Hello");
}
public void testOverloadedStringParamInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface5.class };
final Object object = new ClassA();
final Object result = doTest( object, interfaces );
((Interface5)result).method3("Hello");
}
public void testDuplicateMethodInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface2.class, Interface6.class };
final Object object = new ClassB();
final Object result = doTest( object, interfaces );
((Interface6)result).method2();
((Interface2)result).method2();
}
public void testDoubleParamInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface7.class };
final Object object = new ClassB();
final Object result = doTest( object, interfaces );
((Interface7)result).method3(2.0);
}
public void test2DoubleParamInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface8.class };
final Object object = new ClassB();
final Object result = doTest( object, interfaces );
((Interface8)result).method3(2.0,2.0);
}
public void testIntReturnInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface9.class };
final Object object = new ClassA();
final Object result = doTest( object, interfaces );
final int x = ((Interface9)result).method4(2.0,2.0);
}
public void testDoubleReturnInterface()
throws Exception
{
final Class[] interfaces = new Class[] { Interface10.class };
final Object object = new ClassA();
final Object result = doTest( object, interfaces );
final double x = ((Interface10)result).method10(2.0,2.0);
}
protected Object doTest( final Object object, final Class[] interfaces )
throws Exception
{
final Object result =
ProxyGenerator.generateProxy( object, interfaces );
if( null == result )
{
throw new TestFailedException( "Proxy object failed to be created." );
}
for( int i = 0; i < interfaces.length; i++ )
{
if( !interfaces[ i ].isInstance( result ) )
{
throw new TestFailedException( "Interface " + interfaces[ i ] +
" not implemented by proxy." );
}
}
return result;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/test/StringUtilTestlet.java
Index: StringUtilTestlet.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.test;
import org.apache.avalon.util.StringUtil;
import org.apache.testlet.AbstractTestlet;
/**
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class StringUtilTestlet
extends AbstractTestlet
{
public void testNoReplace()
{
final String result =
StringUtil.replaceSubString("blah", "not-there", "ignored" );
assertEquality( result, "blah" );
}
public void testMidReplace()
{
final String result =
StringUtil.replaceSubString("blah", "la", "le" );
assertEquality( result, "bleh" );
}
public void testStartReplace()
{
final String result =
StringUtil.replaceSubString("blah", "bla", "ble" );
assertEquality( result, "bleh" );
}
public void testEndReplace()
{
final String result =
StringUtil.replaceSubString("blah", "lah", "leh" );
assertEquality( result, "bleh" );
}
public void testDoubleReplace()
{
final String result =
StringUtil.replaceSubString("blahblah", "la", "le" );
assertEquality( result, "blehbleh" );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/thread/DefaultThreadManager.java
Index: DefaultThreadManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.thread;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.avalon.AbstractLoggable;
import org.apache.avalon.configuration.Configurable;
import org.apache.avalon.configuration.Configuration;
import org.apache.avalon.configuration.ConfigurationException;
/**
*
*
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultThreadManager
extends AbstractLoggable
implements ThreadManager, Configurable
{
protected final Hashtable m_pools = new Hashtable();
public void configure( final Configuration configuration )
throws ConfigurationException
{
final Configuration[] groups = configuration.getChildren( "thread-group" );
for( int i = 0; i < groups.length; i++ )
{
final Configuration group = groups[ i ];
final String name = group.getChild( "name" ).getValue();
final int priority = group.getChild( "priority" ).getValueAsInt( 5 );
final boolean isDaemon = group.getChild( "is-daemon" ).getValueAsBoolean( false );
final int minThreads = group.getChild( "min-threads" ).getValueAsInt( 5 );
final int maxThreads = group.getChild( "max-threads" ).getValueAsInt( 10 );
final int minSpareThreads = group.getChild( "min-spare-threads" ).
getValueAsInt( maxThreads - minThreads );
try
{
final ThreadPool threadPool = new ThreadPool( name, maxThreads );
threadPool.setDaemon( isDaemon );
setupLogger( threadPool );
m_pools.put( name, threadPool );
}
catch( final Exception e )
{
throw new ConfigurationException( "Error creating thread pool " + name,
e );
}
}
}
public ThreadPool getDefaultThreadPool()
{
return getThreadPool( "default" );
}
public ThreadPool getThreadPool( final String name )
{
final ThreadPool threadPool = (ThreadPool)m_pools.get( name );
if( null == threadPool )
{
//Should this be a ComponentNotFoundException ????
throw new IllegalArgumentException( "No such thread group " + name );
}
return threadPool;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/thread/ThreadContext.java
Index: ThreadContext.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.thread;
import org.apache.avalon.Poolable;
import org.apache.avalon.util.pool.ObjectFactory;
import org.apache.avalon.util.pool.ThreadSafePool;
/**
* To deal with *current* ThreadContext.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class ThreadContext
{
protected final static InheritableThreadLocal c_context = new InheritableThreadLocal();
public static ThreadPool getCurrentThreadPool()
{
return (ThreadPool)c_context.get();
}
public static void setCurrentThreadPool( final ThreadPool threadPool )
{
//TODO: protect by a permission guard
c_context.set( threadPool );
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/thread/ThreadManager.java
Index: ThreadManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.thread;
import org.apache.avalon.Component;
/**
* Interface for component that hands out thread pools.
*
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface ThreadManager
extends Component
{
ThreadPool getThreadPool( String name );
ThreadPool getDefaultThreadPool();
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/thread/ThreadPool.java
Index: ThreadPool.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.thread;
import org.apache.avalon.Loggable;
import org.apache.avalon.Poolable;
import org.apache.avalon.util.pool.ObjectFactory;
import org.apache.avalon.util.pool.ThreadSafePool;
import org.apache.log.Logger;
/**
* This class is the public frontend for the thread pool code.
*
* TODO: Should this be configured with min threads, max threads and min spare threads ?
*
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ThreadPool
extends ThreadGroup
implements ObjectFactory, Loggable
{
protected final ThreadSafePool m_pool;
protected int m_level;
protected Logger m_logger;
public ThreadPool( final int capacity )
throws Exception
{
this( "Worker Pool", capacity );
}
public ThreadPool( final String name, final int capacity )
throws Exception
{
super( name );
m_pool = new ThreadSafePool( this, 0 );
m_pool.init();
m_pool.grow( capacity );
}
public void setLogger( final Logger logger )
{
m_logger = logger;
}
public Poolable newInstance()
{
final WorkerThread worker =
new WorkerThread( this, m_pool, getName() + " Worker #" + m_level++ );
worker.setLogger( m_logger );
worker.start();
return worker;
}
public Class getCreatedClass()
{
return WorkerThread.class;
}
public void execute( final Runnable work )
throws Exception
{
execute( work, Thread.NORM_PRIORITY );
}
public void execute( final Runnable work, final int priority )
throws Exception
{
final WorkerThread worker = getWorker( priority );
worker.execute( work );
}
public void executeAndWait( final Runnable work )
throws Exception
{
executeAndWait( work, Thread.NORM_PRIORITY );
}
public void executeAndWait( final Runnable work, final int priority )
throws Exception
{
final WorkerThread worker = getWorker( priority );
worker.executeAndWait( work );
}
protected WorkerThread getWorker( final int priority )
throws Exception
{
final WorkerThread worker = (WorkerThread)m_pool.get();
worker.setContextClassLoader( Thread.currentThread().getContextClassLoader() );
worker.setPriority( priority );
return worker;
}
}
1.1 jakarta-avalon/src/java/org/apache/avalon/util/thread/WorkerThread.java
Index: WorkerThread.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.util.thread;
import org.apache.avalon.Loggable;
import org.apache.avalon.Poolable;
import org.apache.avalon.util.pool.ThreadSafePool;
import org.apache.log.Logger;
/**
* This class extends the Thread class to add recyclable functionalities.
*
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
class WorkerThread
extends Thread
implements Poolable, Loggable
{
protected final static boolean DEBUG = false;
protected Logger m_logger;
protected ThreadPool m_threadPool;
protected ThreadSafePool m_pool;
protected Runnable m_work;
protected boolean m_alive;
/**
* Allocates a new <code>Worker</code> object.
*/
protected WorkerThread( final ThreadPool threadPool,
final ThreadSafePool pool,
final String name )
{
super( threadPool, name );
m_threadPool = threadPool;
m_pool = pool;
m_work = null;
m_alive = true;
setDaemon( false );
}
public void setLogger( final Logger logger )
{
m_logger = logger;
}
/**
* The main execution loop.
*/
public final synchronized void run()
{
ThreadContext.setCurrentThreadPool( m_threadPool );
if( DEBUG ) m_logger.info( getName() + ": starting." );
// Notify the pool this worker started running.
//notifyAll();
while( m_alive )
{
waitUntilCondition( true );
if( DEBUG ) m_logger.debug( getName() + ": running." );
try
{
m_work.run();
}
catch( final ThreadDeath td )
{
if ( DEBUG ) m_logger.debug( getName() + ": thread has died." );
// This is to let the thread death propagate to the runtime
// enviroment to let it know it must kill this worker
throw td;
}
catch( final Throwable t )
{
// Error thrown while working.
if( DEBUG ) m_logger.debug( getName() + ": error caught: " + t );
// XXX: what should we do when this happens?
}
if( DEBUG ) m_logger.debug( getName() + ": done." );
m_work = null;
//should this be just notify or notifyAll ???
//It seems to resource intensive option to use notify()
//notifyAll();
notify();
// recycle ourselves
if( null != m_pool )
{
m_pool.put( this );
}
else
{
m_alive = false;
}
}
}
/**
* Set the <code>Work</code> code this <code>Worker</code> must
* execute and <i>notifies</i> its thread to do it.
*/
protected synchronized void executeAndWait( final Runnable work )
{
execute( work );
waitUntilCondition( false );
}
protected synchronized void waitUntilCondition( final boolean hasWork )
{
while( hasWork == (null == m_work) )
{
try
{
if( DEBUG ) m_logger.debug( getName() + ": waiting." );
wait();
if( DEBUG ) m_logger.debug( getName() + ": notified." );
}
catch( final InterruptedException ie ) {}
}
}
protected synchronized void execute( final Runnable work )
{
if( DEBUG ) m_logger.debug( getName() + ": notifying this worker." );
m_work = work;
notify();
}
/**
* Set the <code>alive</code> variable to false causing the worker to die.
* If the worker is stalled and a timeout generated this call, this method
* does not change the state of the worker (that must be destroyed in other
* ways).
*/
public void dispose()
{
if( DEBUG ) m_logger.debug( getName() + ": destroying." );
m_alive = false;
}
}