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