You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by cz...@apache.org on 2002/04/19 11:05:38 UTC
cvs commit: jakarta-avalon-excalibur/all/src/scratchpad/org/apache/avalon/excalibur/source/validity AggregatedValidity.java NOPValidity.java TimeStampValidity.java
cziegeler 02/04/19 02:05:38
Added: all/src/java/org/apache/avalon/excalibur/monitor
Monitorable.java SourceResource.java
all/src/java/org/apache/excalibur/source Source.java
SourceFactory.java SourceParameters.java
SourceResolver.java SourceUtil.java
SourceValidity.java
all/src/java/org/apache/excalibur/source/impl
ResourceSource.java ResourceSourceFactory.java
SourceResolverImpl.java URLSource.java
all/src/java/org/apache/excalibur/source/impl/validity
AggregatedValidity.java NOPValidity.java
TimeStampValidity.java
Removed: all/src/scratchpad/org/apache/avalon/excalibur/monitor
Monitorable.java SourceResource.java
all/src/scratchpad/org/apache/avalon/excalibur/source
ResourceSource.java ResourceSourceFactory.java
Source.java SourceFactory.java
SourceParameters.java SourceResolver.java
SourceResolverImpl.java SourceUtil.java
SourceValidity.java URLSource.java
all/src/scratchpad/org/apache/avalon/excalibur/source/validity
AggregatedValidity.java NOPValidity.java
TimeStampValidity.java
Log:
Moving things from scratchpad
Revision Changes Path
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/avalon/excalibur/monitor/Monitorable.java
Index: Monitorable.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.monitor;
/**
* Describes an object which can be monitored.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
*/
public interface Monitorable
{
/**
* Get the corresponding Resource object for monitoring.
*/
Resource getResource()
throws Exception;
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/avalon/excalibur/monitor/SourceResource.java
Index: SourceResource.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.monitor;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceValidity;
/**
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version $Id: SourceResource.java,v 1.1 2002/04/19 09:05:37 cziegeler Exp $
*/
public final class SourceResource extends StreamResource
{
/** The wrapped source object */
private final Source source;
/** The last validity object */
private SourceValidity validity;
/**
* Instantiate the SourceResource
*/
public SourceResource( Source source )
throws Exception
{
super( source.getSystemId() );
this.source = source;
m_previousModified = System.currentTimeMillis();
this.validity = source.getValidity();
}
/**
* Determines the last time this resource was modified
*/
public long lastModified()
{
if( this.validity == null )
{
return System.currentTimeMillis();
}
else
{
SourceValidity newVal = this.source.getValidity();
if( newVal != null && this.validity.isValid( newVal ) == true )
{
return m_previousModified;
}
else
{
this.validity = newVal;
return System.currentTimeMillis();
}
}
}
/**
* Sets the resource value with an OutputStream
*/
public InputStream getResourceAsStream() throws IOException
{
return this.source.getInputStream();
}
/**
* Sets the resource value with a Writer
*/
public Reader getResourceAsReader() throws IOException
{
return new InputStreamReader( this.getResourceAsStream() );
}
/**
* Sets the resource value with an OutputStream
*/
public OutputStream setResourceAsStream() throws IOException
{
throw new IOException( "setResourceAsStream() not supported for URLResource" );
}
/**
* Sets the resource value with a Writer
*/
public Writer setResourceAsWriter() throws IOException
{
throw new IOException( "setResourceAsWriter() not supported for URLResource" );
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/Source.java
Index: Source.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source;
import java.io.IOException;
import java.io.InputStream;
/**
* Description of a source. This interface provides a simple interface
* for accessing a source of data.
*
* When the <code>Source</code> object is no longer needed
* it must be released using the resolver. This is very similar like
* looking up components from a <code>ComponentManager</code>.
* In fact a source object can implement most lifecycle interfaces
* like Composable, Initializable, Disposable etc.
*
* Thee data content can be constant or change over time.
* Using the getInputStream() method you get always the upto-date content.
* When you're done with using the source object, you have to release it.
* If you want to track changes of the source object, this interface
* offers you some support for it by providing a SourceValidity object.
*
* How does the caching work?
* The first time you get a Source object, you simply ask
* it for it's content via getInputStream() and then get the validity
* object by invoking getValidity. (Further calls to getValidity always
* return the same object! This is not updated!)
* The caching algorithm can now store this validity object together
* with the system identifier of the source.
* The next time, the caching algorithm wants to check if the cached
* content is still valid. It has a validity object already to check
* against.
*
* If it is still the same Source than the first time, you
* have to call discardValidity() in order to discard the stored validity
* in the Source object. If it is a new Source object,
* calling discardValidity() should do no harm.
* After that an upto-date validity object can retrieved by calling
* getValidity(). This can be used to test if the content is still valid
* as discribed in the source validity documentation.
* If the content is still valid, the cache knows what to do, if not,
* the new content can be get using getInputStream().
* So either after a call to getValidity() or the getInputStream the
* validity object must be the same until discardValidity is called!
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public interface Source {
/**
* Return an <code>InputStream</code> object to read from the source.
* This is the data at the point of invocation of this method,
* so if this is an {@link ModifiableSource} object, you might get
* different content from two invocations.
*/
InputStream getInputStream()
throws IOException;
/**
* Return the unique identifer for this source
*/
String getSystemId();
/**
* Get the Validity object. This can either wrap the last modification
* date or the expires information or...
* If it is currently not possible to calculate such an information
* <code>null</code> is returned.
*/
SourceValidity getValidity();
/**
* Refresh the content of this object after the underlying data
* content has changed.
*/
void discardValidity();
/**
* The mime-type of the content described by this object.
* If the source is not able to determine the mime-type by itself
* this can be null.
*/
String getMimeType();
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/SourceFactory.java
Index: SourceFactory.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;
import org.apache.avalon.framework.component.Component;
/**
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version $Id: SourceFactory.java,v 1.1 2002/04/19 09:05:37 cziegeler Exp $
*/
public interface SourceFactory
extends Component
{
String ROLE = SourceFactory.class.getName();
/**
* Get a <code>Source</code> object.
* @param parameters This is optional.
*/
Source getSource( String location, Map parameters )
throws MalformedURLException, IOException;
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/SourceParameters.java
Index: SourceParameters.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
/**
* This class holds parameters for a <code>Source</code> object.
* It differs from the usual Parameters object because it can hold
* more than one value for a parameter.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version $Id: SourceParameters.java,v 1.1 2002/04/19 09:05:37 cziegeler Exp $
*/
public final class SourceParameters
implements Serializable, Cloneable
{
/** The parameter names are the keys and the value is a List object */
private Map names = new HashMap( 5 );
/**
* Decode the string
*/
private String parseName( String s )
{
StringBuffer sb = new StringBuffer();
for( int i = 0; i < s.length(); i++ )
{
char c = s.charAt( i );
switch( c )
{
case '+':
sb.append( ' ' );
break;
case '%':
try
{
sb.append( (char)Integer.parseInt( s.substring( i + 1, i + 3 ),
16 ) );
i += 2;
}
catch( NumberFormatException e )
{
throw new IllegalArgumentException();
}
catch( StringIndexOutOfBoundsException e )
{
String rest = s.substring( i );
sb.append( rest );
if( rest.length() == 2 )
i++;
}
break;
default:
sb.append( c );
break;
}
}
return sb.toString();
}
/**
* Create a new parameters object from the
* children of the configuration.
* If no children are available <code>null</code>
* is returned.
*/
public static SourceParameters create( Configuration conf )
{
Configuration[] children = conf.getChildren();
if( children != null && children.length > 0 )
{
SourceParameters pars = new SourceParameters();
String name;
String value;
for( int i = 0; i < children.length; i++ )
{
name = children[ i ].getName();
try
{
value = children[ i ].getValue();
}
catch( ConfigurationException local )
{
value = ""; // ignore exception
}
pars.setParameter( name, value );
}
return pars;
}
return null;
}
/**
* Standard Constructor creating an empty parameters object
*/
public SourceParameters()
{
}
/**
* Construct a new object from a queryString
*/
public SourceParameters( String queryString )
{
if( queryString != null )
{
StringTokenizer st = new StringTokenizer( queryString, "&" );
while( st.hasMoreTokens() )
{
String pair = (String)st.nextToken();
int pos = pair.indexOf( '=' );
if( pos != -1 )
{
this.setParameter( this.parseName( pair.substring( 0, pos ) ),
this.parseName( pair.substring( pos + 1, pair.length() ) ) );
}
}
}
}
/**
* Add a parameter.
* The parameter is added with the given value.
* @param name The name of the parameter.
* @param value The value of the parameter.
*/
public void setParameter( String name, String value )
{
ArrayList list;
if( names.containsKey( name ) == true )
{
list = (ArrayList)names.get( name );
}
else
{
list = new ArrayList( 3 );
names.put( name, list );
}
list.add( value );
}
/**
* Get the value of a parameter.
* @param name The name of the parameter.
* @return The value of the first parameter with the name
* or <CODE>null</CODE>
*/
public String getParameter( String name )
{
if( names.containsKey( name ) == true )
{
return (String)( (ArrayList)names.get( name ) ).get( 0 );
}
return null;
}
/**
* Get the value of a parameter.
* @param name The name of the parameter.
* @param defaultValue The default value if the parameter does not exist.
* @return The value of the first parameter with the name
* or <CODE>defaultValue</CODE>
*/
public String getParameter( String name, String defaultValue )
{
if( names.containsKey( name ) == true )
{
return (String)( (ArrayList)names.get( name ) ).get( 0 );
}
return defaultValue;
}
/**
* Get the integer value of a parameter.
* @param name The name of the parameter.
* @param defaultValue The default value if the parameter does not exist.
* @return The value of the first parameter with the name
* or <CODE>defaultValue</CODE>
*/
public int getParameterAsInteger( String name, int defaultValue )
{
if( names.containsKey( name ) == true )
{
return new Integer( (String)( (ArrayList)names.get( name ) ).get( 0 ) ).intValue();
}
return defaultValue;
}
/**
* Get the boolean value of a parameter.
* @param name The name of the parameter.
* @param defaultValue The default value if the parameter does not exist.
* @return The value of the first parameter with the name
* or <CODE>defaultValue</CODE>
*/
public boolean getParameterAsBoolean( String name, boolean defaultValue )
{
if( names.containsKey( name ) == true )
{
return new Boolean( (String)( (ArrayList)names.get( name ) ).get( 0 ) ).booleanValue();
}
return defaultValue;
}
/**
* Test if a value for this parameter exists.
* @param name The name of the parameter.
* @return <CODE>true</CODE> if a value exists, otherwise <CODE>false</CODE>
*/
public boolean containsParameter( String name )
{
return names.containsKey( name );
}
/**
* Get all values of a parameter.
* @param name The name of the parameter.
* @return Iterator for the (String) values or null if the parameter
* is not defined.
*/
public Iterator getParameterValues( String name )
{
if( names.containsKey( name ) == true )
{
ArrayList list = (ArrayList)names.get( name );
return list.iterator();
}
return null;
}
/**
* Get all parameter names.
* @return Iterator for the (String) parameter names.
*/
public Iterator getParameterNames()
{
return names.keySet().iterator();
}
/**
* Create a Parameters object.
* The first value of each parameter is added to the Parameters object.
* @return An Parameters object - if no parameters are defined this is an
* empty object.
*/
public Parameters getFirstParameters()
{
Parameters result = new Parameters();
Iterator iter = this.getParameterNames();
String parName;
while( iter.hasNext() )
{
parName = (String)iter.next();
result.setParameter( parName, this.getParameter( parName ) );
}
return result;
}
/**
* Build a query string.
* The query string can e.g. be used for http connections.
* @return A query string which contains for each parameter/value pair
* a part, like "parameter=value" separated by "&".
* If no parameter is defined <CODE>null</CODE> is returned.
*/
public String getQueryString()
{
StringBuffer result = new StringBuffer();
Iterator iter = this.names.keySet().iterator();
Iterator listIterator;
String key;
String value;
boolean first = true;
while( iter.hasNext() == true )
{
key = (String)iter.next();
listIterator = ( (ArrayList)names.get( key ) ).iterator();
while( listIterator.hasNext() == true )
{
if( first == false ) result.append( '&' );
value = (String)listIterator.next();
result.append( key ).append( '=' ).append( value );
first = false;
}
}
return ( result.length() == 0 ? null : result.toString() );
}
/**
* Build a query string and encode each parameter value.
* The query string can e.g. be used for http connections.
* @return A query string which contains for each parameter/value pair
* a part, like "parameter=value" separated by "&".
* If no parameter is defined <CODE>null</CODE> is returned.
*/
public String getEncodedQueryString()
{
StringBuffer result = new StringBuffer();
Iterator iter = this.names.keySet().iterator();
Iterator listIterator;
String key;
String value;
boolean first = true;
while( iter.hasNext() == true )
{
key = (String)iter.next();
listIterator = ( (ArrayList)names.get( key ) ).iterator();
while( listIterator.hasNext() == true )
{
if( first == false ) result.append( '&' );
value = (String)listIterator.next();
result.append( key ).append( '=' ).append( SourceUtil.encode( value ) );
first = false;
}
}
return ( result.length() == 0 ? null : result.toString() );
}
/**
* Add all parameters from the incoming parameters object.
*/
public void add( SourceParameters parameters )
{
if( null != parameters )
{
Iterator names = parameters.getParameterNames();
Iterator values;
String name;
String value;
while( names.hasNext() == true )
{
name = (String)names.next();
values = parameters.getParameterValues( name );
while( values.hasNext() == true )
{
value = (String)values.next();
this.setParameter( name, value );
}
}
}
}
/**
* Overriding toString
*/
public String toString()
{
StringBuffer buffer = new StringBuffer( "SourceParameters: {" );
Iterator names = this.getParameterNames();
String name;
boolean firstName = true;
Iterator values;
String value;
boolean firstValue;
while( names.hasNext() == true )
{
name = (String)names.next();
if( firstName == false )
{
buffer.append( ", " );
}
else
{
firstName = false;
}
buffer.append( name ).append( " = (" );
values = this.getParameterValues( name );
firstValue = true;
while( values.hasNext() == true )
{
value = (String)values.next();
if( firstValue == false )
{
buffer.append( ", " );
}
else
{
firstValue = false;
}
buffer.append( value );
}
buffer.append( ')' );
}
buffer.append( '}' );
return buffer.toString();
}
/**
* Returns a copy of the parameters object.
*/
public Object clone()
{
SourceParameters newObject = new SourceParameters();
Iterator names = this.getParameterNames();
Iterator values;
String name, value;
while( names.hasNext() )
{
name = (String)names.next();
values = this.getParameterValues( name );
while( values.hasNext() )
{
value = (String)values.next();
newObject.setParameter( name, value );
}
}
return newObject;
}
/**
* Test if there are any parameters.
*/
public boolean hasParameters()
{
return ( this.names.size() > 0 );
}
/**
* Set the value of this parameter to the given value.
* Remove all other values for this parameter.
*/
public void setSingleParameterValue( String name, String value )
{
this.removeParameter( name );
this.setParameter( name, value );
}
/**
* Remove all values for this parameter
*/
public void removeParameter( String name )
{
if( this.names.containsKey( name ) )
{
this.names.remove( name );
}
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/SourceResolver.java
Index: SourceResolver.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
/**
* Base interface for resolving a source by system identifiers.
* Instead of using the java.net.URL classes which prevent you
* from adding your own custom protocols in a server environment,
* you should use this resolver for all URLs.
*
* The resolver creates for each source a <code>Source</code>
* object, which could then be asked for an <code>InputStream</code>
* etc.
*
* When the <code>Source</code> object is no longer needed
* it must be released using the resolver. This is very similar like
* looking up components from a <code>ComponentManager</code>.
* In fact a source object can implement most lifecycle interfaces
* like Composable, Initializable, Disposable etc.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public interface SourceResolver
extends Component
{
String ROLE = SourceResolver.class.getName();
/**
* Get a <code>Source</code> object.
* This is a shortcut for <code>resolve(location, null, null)</code>
*/
Source resolveURI( String location )
throws MalformedURLException, IOException, ComponentException;
/**
* Get a <code>Source</code> object.
* @param location - the URI to resolve. If this is relative it is either
* resolved relative to the base parameter (if not null)
* or relative to a base setting of the source resolver
* itself.
* @param base - a base URI for resolving relative locations. This
* is optional and can be <code>null</code>.
* @param parameters - Additional parameters for the URI. The parameters
* are specific to the used protocol.
*/
Source resolveURI( String location,
String base,
Map parameters )
throws MalformedURLException, IOException, ComponentException;
/**
* Releases a resolved resource
*/
void release( Source source );
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/SourceUtil.java
Index: SourceUtil.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.BitSet;
import java.util.Iterator;
import org.apache.avalon.framework.parameters.Parameters;
/**
*
* Utility class for source resolving.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public final class SourceUtil
{
private static final char[] alphabet = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55
'4', '5', '6', '7', '8', '9', '+', '/'}; // 56 to 63
/**
* Append parameters to the uri.
* Each parameter is appended to the uri with "parameter=value",
* the parameters are separated by "&".
*/
public static String appendParameters( String uri,
Parameters parameters )
{
if( parameters != null )
{
StringBuffer buffer = new StringBuffer( uri );
String[] keys = parameters.getNames();
String current;
char separator = ( uri.indexOf( "?" ) == -1 ? '?' : '&' );
if( keys != null )
{
for( int i = 0; i < keys.length; i++ )
{
current = keys[ i ];
buffer.append( separator )
.append( current )
.append( '=' )
.append( SourceUtil.encode( parameters.getParameter( current, null ) ) );
separator = '&';
}
}
return buffer.toString();
}
return uri;
}
/**
* Append parameters to the uri
* Each parameter is appended to the uri with "parameter=value",
* the parameters are separated by "&".
*/
public static String appendParameters( String uri,
SourceParameters parameters )
{
if( parameters != null )
{
StringBuffer buffer = new StringBuffer( uri );
Iterator keys = parameters.getParameterNames();
String current;
char separator = ( uri.indexOf( "?" ) == -1 ? '?' : '&' );
Iterator values;
while( keys.hasNext() == true )
{
current = (String)keys.next();
values = parameters.getParameterValues( current );
while( values.hasNext() == true )
{
buffer.append( separator )
.append( current )
.append( '=' )
.append( SourceUtil.encode( (String)values.next() ) );
separator = '&';
}
}
return buffer.toString();
}
return uri;
}
/**
* BASE 64 encoding.
* See also RFC 1421
*/
public static String encodeBASE64( String s )
{
return encodeBASE64( s.getBytes() );
}
/**
* BASE 64 encoding.
* See also RFC 1421
*/
public static String encodeBASE64( byte[] octetString )
{
int bits24;
int bits6;
char[] out = new char[ ( ( octetString.length - 1 ) / 3 + 1 ) * 4 ];
int outIndex = 0;
int i = 0;
while( ( i + 3 ) <= octetString.length )
{
// store the octets
bits24 = ( octetString[ i++ ] & 0xFF ) << 16;
bits24 |= ( octetString[ i++ ] & 0xFF ) << 8;
bits24 |= ( octetString[ i++ ] & 0xFF ) << 0;
bits6 = ( bits24 & 0x00FC0000 ) >> 18;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0003F000 ) >> 12;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x00000FC0 ) >> 6;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0000003F );
out[ outIndex++ ] = alphabet[ bits6 ];
}
if( octetString.length - i == 2 )
{
// store the octets
bits24 = ( octetString[ i ] & 0xFF ) << 16;
bits24 |= ( octetString[ i + 1 ] & 0xFF ) << 8;
bits6 = ( bits24 & 0x00FC0000 ) >> 18;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0003F000 ) >> 12;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x00000FC0 ) >> 6;
out[ outIndex++ ] = alphabet[ bits6 ];
// padding
out[ outIndex++ ] = '=';
}
else if( octetString.length - i == 1 )
{
// store the octets
bits24 = ( octetString[ i ] & 0xFF ) << 16;
bits6 = ( bits24 & 0x00FC0000 ) >> 18;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0003F000 ) >> 12;
out[ outIndex++ ] = alphabet[ bits6 ];
// padding
out[ outIndex++ ] = '=';
out[ outIndex++ ] = '=';
}
return new String( out );
}
/** A BitSet defining the characters which don't need encoding */
static BitSet charactersDontNeedingEncoding;
static final int characterCaseDiff = ( 'a' - 'A' );
/** Initialize the BitSet */
static
{
charactersDontNeedingEncoding = new BitSet( 256 );
int i;
for( i = 'a'; i <= 'z'; i++ )
{
charactersDontNeedingEncoding.set( i );
}
for( i = 'A'; i <= 'Z'; i++ )
{
charactersDontNeedingEncoding.set( i );
}
for( i = '0'; i <= '9'; i++ )
{
charactersDontNeedingEncoding.set( i );
}
charactersDontNeedingEncoding.set( '-' );
charactersDontNeedingEncoding.set( '_' );
charactersDontNeedingEncoding.set( '.' );
charactersDontNeedingEncoding.set( '*' );
charactersDontNeedingEncoding.set( '"' );
}
/**
* Translates a string into <code>x-www-form-urlencoded</code> format.
*
* @param s <code>String</code> to be translated.
* @return the translated <code>String</code>.
*/
public static String encode( String s )
{
final StringBuffer out = new StringBuffer( s.length() );
final ByteArrayOutputStream buf = new ByteArrayOutputStream( 32 );
final OutputStreamWriter writer = new OutputStreamWriter( buf );
for( int i = 0; i < s.length(); i++ )
{
int c = (int)s.charAt( i );
if( charactersDontNeedingEncoding.get( c ) )
{
out.append( (char)c );
}
else
{
try
{
writer.write( c );
writer.flush();
}
catch( IOException e )
{
buf.reset();
continue;
}
byte[] ba = buf.toByteArray();
for( int j = 0; j < ba.length; j++ )
{
out.append( '%' );
char ch = Character.forDigit( ( ba[ j ] >> 4 ) & 0xF, 16 );
// converting to use uppercase letter as part of
// the hex value if ch is a letter.
if( Character.isLetter( ch ) )
{
ch -= characterCaseDiff;
}
out.append( ch );
ch = Character.forDigit( ba[ j ] & 0xF, 16 );
if( Character.isLetter( ch ) )
{
ch -= characterCaseDiff;
}
out.append( ch );
}
buf.reset();
}
}
return out.toString();
}
/**
* Return a <code>File</code> object associated with the <code>Source</code> object.
*
* @return The corresponding <code>File</code> object or null if the
* <code>Source</code> object does not point to a file URI.
*/
public static File getFile( Source source )
{
final String systemId = source.getSystemId();
if( systemId.startsWith( "file:" ) )
{
return new File( systemId.substring( 5 ) );
}
return null;
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/SourceValidity.java
Index: SourceValidity.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source;
/**
* A Validity object contains all information to check if a Source object is
* still valid.
* There are two possibilities: The validity object has all information
* to check by itself how long it is valid (e.g. given an expires date).
* The other possibility needs another (newer) validity object to compare
* against (e.g. to test a last modification date).
* To avoid testing, what the actual implementation of the validity object
* supports, the invocation order is to first call isValid() and only if
* this results in <code>false</code>, then to call isValid(SourceValidity).
* But remember to call the second isValid(SourceValidity) when <code>false</code>
* is returned by the first invocation!
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public interface SourceValidity
extends java.io.Serializable
{
/**
* Check if the component is still valid.
* If <code>false</code> is returned the isValid(SourceValidity) must be
* called afterwards!
*/
boolean isValid();
/**
* Check if the component is still valid.
* This is only true, if the incoming Validity is of the same
* type and has the same values.
* The invocation order is that the isValid method of the
* old Validity object is called with the new one as a parameter
*/
boolean isValid( SourceValidity newValidity );
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/ResourceSource.java
Index: ResourceSource.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl;
import java.io.IOException;
import java.io.InputStream;
import org.apache.excalibur.source.*;
import org.apache.excalibur.source.impl.validity.NOPValidity;
/**
* Description of a source which is described by the resource protocol
* which gets a resource from the classloader.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public final class ResourceSource
implements Source
{
/** The system identifier */
private String systemId;
/** Location of the resource */
private String location;
/**
* Constructor
*/
public ResourceSource( String systemId )
{
this.systemId = systemId;
final int pos = systemId.indexOf( "://" );
this.location = systemId.substring( pos + 3 );
}
/**
* Return an <code>InputStream</code> object to read from the source.
*/
public InputStream getInputStream()
throws IOException
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if( loader == null )
{
loader = this.getClass().getClassLoader();
}
return loader.getResourceAsStream( this.location );
}
/**
* Return the unique identifer for this source
*/
public String getSystemId()
{
return this.systemId;
}
/**
* Get the Validity object. This can either wrap the last modification
* date or the expires information or...
* If it is currently not possible to calculate such an information
* <code>null</code> is returned.
*/
public SourceValidity getValidity()
{
// we are always valid
return NOPValidity.SHARED_INSTANCE;
}
/**
* Refresh this object and update the last modified date
* and content length.
*/
public void discardValidity()
{
// nothing to do
}
/**
* The mime-type of the content described by this object.
* If the source is not able to determine the mime-type by itself
* this can be null.
*/
public String getMimeType()
{
// FIXME
return null;
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/ResourceSourceFactory.java
Index: ResourceSourceFactory.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.excalibur.source.*;
/**
* A factory for the Resource protocol
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version $Id: ResourceSourceFactory.java,v 1.1 2002/04/19 09:05:37 cziegeler Exp $
*/
public class ResourceSourceFactory
extends AbstractLogEnabled
implements SourceFactory, ThreadSafe
{
/**
* Get a <code>Source</code> object.
* @param parameters This is optional.
*/
public Source getSource( String location, Map parameters )
throws MalformedURLException, IOException
{
if( this.getLogger().isDebugEnabled() )
{
this.getLogger().debug( "Creating source object for " + location );
}
return new ResourceSource( location );
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/SourceResolverImpl.java
Index: SourceResolverImpl.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentSelector;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.excalibur.source.*;
/**
* Base interface for resolving a source by system identifiers.
* Instead of using the java.net.URL classes which prevent you
* to add your own custom protocols in a server environment,
* you should use this resolver for all URLs.
*
* The resolver creates for each source a <code>Source</code>
* object, which could then be asked for an <code>InputStream</code>
* etc.
*
* When the <code>Source</code> object is no longer needed
* it must be released using the resolver. This is very similar like
* looking up components from a <code>ComponentManager</code>
* and releasing them.
*
* It looks for the base URL in the <code>Context</code> object with
* the "container.rootDir" entry. If the entry does not exist, it is
* populated with the system property "user.dir".
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @version $Id: SourceResolverImpl.java,v 1.1 2002/04/19 09:05:37 cziegeler Exp $
*/
public class SourceResolverImpl
extends AbstractLogEnabled
implements Composable,
Contextualizable,
Disposable,
SourceResolver,
ThreadSafe
{
/** The component manager */
protected ComponentManager m_manager;
/** The special Source factories */
protected ComponentSelector m_factorySelector;
/** The context */
protected Context m_context;
/**
* The base URL
*/
protected URL m_baseURL;
/**
* Get the context
*/
public void contextualize( Context context )
throws ContextException
{
m_context = context;
try
{
m_baseURL = ( (File)m_context.get( "context-root" ) ).toURL();
}
catch( ContextException ce )
{
// set the base URL to the current directory
try
{
m_baseURL = new File( System.getProperty( "user.dir" ) ).toURL();
if( this.getLogger().isDebugEnabled() )
{
this.getLogger().debug( "SourceResolver: Using base URL: " + m_baseURL );
}
}
catch( MalformedURLException mue )
{
getLogger().warn( "Malformed URL for user.dir, and no container.rootDir exists", mue );
throw new ContextException( "Malformed URL for user.dir, and no container.rootDir exists", mue );
}
}
catch( MalformedURLException mue )
{
getLogger().warn( "Malformed URL for container.rootDir", mue );
throw new ContextException( "Malformed URL for container.rootDir", mue );
}
}
/**
* Set the current <code>ComponentManager</code> instance used by this
* <code>Composable</code>.
*/
public void compose( ComponentManager manager )
throws ComponentException
{
m_manager = manager;
m_factorySelector = (ComponentSelector)m_manager.lookup( SourceFactory.ROLE + "Selector" );
}
/**
* Dispose
*/
public void dispose()
{
if( m_manager != null )
{
m_manager.release( m_factorySelector );
m_factorySelector = null;
}
}
/**
* Get a <code>Source</code> object.
*/
public Source resolveURI( String location )
throws MalformedURLException, IOException, ComponentException
{
return this.resolveURI( location, null, null );
}
/**
* Get a <code>Source</code> object.
*/
public Source resolveURI( String location,
String baseURI,
Map parameters )
throws MalformedURLException, IOException, ComponentException
{
if( this.getLogger().isDebugEnabled() )
{
this.getLogger().debug( "Resolving '" + location + "' with base '" + baseURI + "' in context '" + m_baseURL + "'" );
}
if( location == null ) throw new MalformedURLException( "Invalid System ID" );
if( null != baseURI && baseURI.indexOf( ':' ) == -1 )
{
throw new MalformedURLException( "BaseURI is not valid, it must contain a protocol: " + baseURI );
}
// first step: create systemID
String systemID;
if( baseURI == null ) baseURI = m_baseURL.toExternalForm();
if( location.length() == 0 )
{
systemID = baseURI;
}
else if( location.charAt( 0 ) == '/' )
{
// windows: absolute paths can start with drive letter
if( location.length() > 2 && location.charAt( 2 ) == ':' )
{
systemID = new StringBuffer( "file:" ).append( location ).toString();
}
else
{
final int protocolEnd = baseURI.indexOf( ':' );
systemID = new StringBuffer( baseURI.substring( protocolEnd + 1 ) )
.append( location ).toString();
}
}
else if( location.indexOf( ":" ) > 1 )
{
systemID = location;
}
// windows: absolute paths can start with drive letter
else if( location.length() > 1 && location.charAt( 1 ) == ':' )
{
systemID = new StringBuffer( "file:/" ).append( location ).toString();
}
else
{
if( baseURI.startsWith( "file:" ) == true )
{
File temp = new File( baseURI.substring( "file:".length() ), location );
String path = temp.getAbsolutePath();
// windows paths starts with drive letter
if( path.charAt( 0 ) != File.separator.charAt( 0 ) )
{
systemID = "file:/" + path;
}
else
{
systemID = "file:" + path;
}
}
else
{
final StringBuffer buffer = new StringBuffer( baseURI );
if( !baseURI.endsWith( "/" ) ) buffer.append( '/' );
buffer.append( location );
systemID = buffer.toString();
}
}
if( this.getLogger().isDebugEnabled() )
{
this.getLogger().debug( "Resolved to systemID '" + systemID + "'" );
}
Source source = null;
// search for a SourceFactory implementing the protocol
final int protocolPos = systemID.indexOf( ':' );
if( protocolPos != -1 )
{
final String protocol = systemID.substring( 0, protocolPos );
if( m_factorySelector.hasComponent( protocol ) )
{
SourceFactory factory = null;
try
{
factory = (SourceFactory)m_factorySelector.select( protocol );
source = factory.getSource( systemID, parameters );
}
finally
{
m_factorySelector.release( factory );
}
}
}
if( null == source )
{
// no factory found, so usual url handling stuff...
try
{
if( this.getLogger().isDebugEnabled() == true )
{
getLogger().debug( "Making URL from " + systemID );
}
source = new URLSource( new URL( systemID ), parameters );
}
catch( MalformedURLException mue )
{
if( this.getLogger().isDebugEnabled() )
{
getLogger().debug( "Making URL - MalformedURLException in getURL:", mue );
getLogger().debug( "Making URL a File (assuming that it is full path):" + systemID );
}
source = new URLSource( ( new File( systemID ) ).toURL(), parameters );
}
}
if( source instanceof LogEnabled )
{
( (LogEnabled)source ).enableLogging( getLogger() );
}
try
{
if( source instanceof Contextualizable )
{
( (Contextualizable)source ).contextualize( m_context );
}
}
catch( ContextException ce )
{
throw new ComponentException( "ContextException occured during source resolving.", ce );
}
if( source instanceof Composable )
{
( (Composable)source ).compose( m_manager );
}
return source;
}
/**
* Releases a resolved resource
*/
public void release( Source source )
{
if( source == null ) return;
if( source instanceof Recyclable )
{
( (Recyclable)source ).recycle();
}
if( source instanceof Disposable )
{
( (Disposable)source ).dispose();
}
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/URLSource.java
Index: URLSource.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Map;
import org.apache.avalon.excalibur.monitor.FileResource;
import org.apache.avalon.excalibur.monitor.Monitorable;
import org.apache.avalon.excalibur.monitor.Resource;
import org.apache.avalon.excalibur.monitor.SourceResource;
import org.apache.excalibur.source.*;
import org.apache.excalibur.source.impl.validity.TimeStampValidity;
/**
* Description of a source which is described by an URL.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public final class URLSource
implements Source, Monitorable
{
/** With this parameter you can specify the method to use for a http request.
* Default is GET.
*/
public final String HTTP_METHOD = "org.apache.avalon.excalibur.source.Source.http.method";
/** With this parameter you can specify additional request parameters which are
* appended to the URI.
*/
public final String REQUEST_PARAMETERS = "org.apache.avalon.excalibur.source.Source.request.parameters";
/** Identifier for file urls */
private final String FILE = "file:";
/** The last modification date or 0 */
private long lastModificationDate;
/** The system id */
private String systemId;
/** The URL of the source */
private URL url;
/** The connection for a real URL */
private URLConnection connection;
/** Is this a file or a "real" URL */
private boolean isFile;
/** Are we initialized? */
private boolean gotInfos;
/** The <code>SourceParameters</code> used for a post*/
private SourceParameters parameters;
/** Is this a post? */
private boolean isPost = false;
/**
* Construct a new object from a <code>URL</code>.
* @param parameters This is optional
*/
public URLSource( URL url,
Map parameters )
throws IOException
{
this.systemId = url.toExternalForm();
this.isFile = systemId.startsWith( FILE );
this.url = url;
this.gotInfos = false;
this.isPost = false;
if( null != parameters )
{
this.parameters = (SourceParameters)parameters.get( REQUEST_PARAMETERS );
final String method = (String)parameters.get( HTTP_METHOD );
if( "POST".equalsIgnoreCase( method ) )
this.isPost = true;
}
if( !isFile
&& null != this.parameters
&& this.parameters.hasParameters()
&& !this.isPost )
{
StringBuffer urlBuffer = new StringBuffer( this.systemId );
String key;
final Iterator i = this.parameters.getParameterNames();
Iterator values;
String value;
boolean first = ( this.systemId.indexOf( '?' ) == -1 );
if( first == true ) urlBuffer.append( '?' );
while( i.hasNext() )
{
key = (String)i.next();
values = this.parameters.getParameterValues( key );
while( values.hasNext() == true )
{
value = SourceUtil.encode( (String)values.next() );
if( first == false ) urlBuffer.append( '&' );
first = false;
urlBuffer.append( key );
urlBuffer.append( '=' );
urlBuffer.append( value );
}
}
this.url = new URL( urlBuffer.toString() );
this.parameters = null;
}
}
/**
* Get the last modification date and content length of the source.
* Any exceptions are ignored.
*/
private void getInfos()
{
if( !this.gotInfos )
{
if( this.isFile )
{
File file = new File( this.systemId.substring( FILE.length() ) );
this.lastModificationDate = file.lastModified();
}
else
{
if( !this.isPost )
{
try
{
if( null == this.connection )
{
this.connection = this.url.openConnection();
String userInfo = this.getUserInfo();
if( this.url.getProtocol().startsWith( "http" ) && userInfo != null )
{
this.connection.setRequestProperty( "Authorization", "Basic " + SourceUtil.encodeBASE64( userInfo ) );
}
}
this.lastModificationDate = this.connection.getLastModified();
}
catch( IOException ignore )
{
this.lastModificationDate = 0;
}
}
else
{
// do not open connection when using post!
this.lastModificationDate = 0;
}
}
this.gotInfos = true;
}
}
/**
* Get the last modification date of the source or 0 if it
* is not possible to determine the date.
*/
public long getLastModified()
{
this.getInfos();
return this.lastModificationDate;
}
/**
* Get the corresponding Resource object for monitoring.
*/
public Resource getResource()
throws Exception
{
this.getInfos();
if( this.isFile == true )
{
return new FileResource( this.systemId.substring( FILE.length() ) );
}
else
{
return new SourceResource( this );
}
}
/**
* Return an <code>InputStream</code> object to read from the source.
*
* @throws ResourceNotFoundException if file not found or
* HTTP location does not exist.
* @throws IOException if I/O error occured.
*/
public InputStream getInputStream()
throws IOException
{
this.getInfos();
InputStream input = null;
if( this.isFile == true )
{
input = new FileInputStream( this.systemId.substring( FILE.length() ) );
}
else
{
if( this.connection == null )
{
this.connection = this.url.openConnection();
/* The following requires a jdk 1.3 */
String userInfo = this.getUserInfo();
if( this.url.getProtocol().startsWith( "http" ) && userInfo != null )
{
this.connection.setRequestProperty( "Authorization", "Basic " + SourceUtil.encodeBASE64( userInfo ) );
}
// do a post operation
if( this.connection instanceof HttpURLConnection
&& this.isPost )
{
StringBuffer buffer = new StringBuffer( 2000 );
String key;
Iterator i = this.parameters.getParameterNames();
Iterator values;
String value;
boolean first = true;
while( i.hasNext() )
{
key = (String)i.next();
values = this.parameters.getParameterValues( key );
while( values.hasNext() == true )
{
value = SourceUtil.encode( (String)values.next() );
if( first == false ) buffer.append( '&' );
first = false;
buffer.append( key.toString() );
buffer.append( '=' );
buffer.append( value );
}
}
HttpURLConnection httpCon = (HttpURLConnection)connection;
httpCon.setDoInput( true );
if( buffer.length() > 1 )
{ // only post if we have parameters
String postString = buffer.toString();
httpCon.setRequestMethod( "POST" ); // this is POST
httpCon.setDoOutput( true );
httpCon.setRequestProperty( "Content-type", "application/x-www-form-urlencoded" );
// A content-length header must be contained in a POST request
httpCon.setRequestProperty( "Content-length", Integer.toString( postString.length() ) );
java.io.OutputStream out = new java.io.BufferedOutputStream( httpCon.getOutputStream() );
out.write( postString.getBytes() );
out.close();
}
input = httpCon.getInputStream();
this.connection = null; // make sure a new connection is created next time
return input;
}
}
input = this.connection.getInputStream();
this.connection = null; // make sure a new connection is created next time
}
return input;
}
private static boolean checkedURLClass = false;
private static boolean urlSupportsGetUserInfo = false;
private static Method urlGetUserInfo = null;
private static Object[] emptyParams = new Object[ 0 ];
/**
* Check if the <code>URL</code> class supports the getUserInfo()
* method which is introduced in jdk 1.3
*/
private String getUserInfo()
{
if( URLSource.checkedURLClass == true )
{
if( URLSource.urlSupportsGetUserInfo == true )
{
try
{
return (String)URLSource.urlGetUserInfo.invoke( this.url, URLSource.emptyParams );
}
catch( Exception e )
{
// ignore this anyway
}
}
return null;
}
else
{
// test if the url class supports the getUserInfo method
try
{
URLSource.urlGetUserInfo = URL.class.getMethod( "getUserInfo", null );
String ui = (String)URLSource.urlGetUserInfo.invoke( this.url, URLSource.emptyParams );
URLSource.checkedURLClass = true;
URLSource.urlSupportsGetUserInfo = true;
return ui;
}
catch( Exception e )
{
}
URLSource.checkedURLClass = true;
URLSource.urlSupportsGetUserInfo = false;
URLSource.urlGetUserInfo = null;
return null;
}
}
/**
* Return the unique identifer for this source
*/
public String getSystemId()
{
return this.systemId;
}
/**
* Get the Validity object. This can either wrap the last modification
* date or the expires information or...
* If it is currently not possible to calculate such an information
* <code>null</code> is returned.
*/
public SourceValidity getValidity()
{
final long lm = this.getLastModified();
if( lm == -1 )
{
return null;
}
else
{
return new TimeStampValidity( lm );
}
}
/**
* Refresh this object and update the last modified date
* and content length.
*/
public void discardValidity()
{
// reset connection
this.connection = null;
this.gotInfos = false;
}
/**
* The mime-type of the content described by this object.
* If the source is not able to determine the mime-type by itself
* this can be null.
*/
public String getMimeType()
{
// FIXME
return null;
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/validity/AggregatedValidity.java
Index: AggregatedValidity.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl.validity;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.excalibur.source.SourceValidity;
/**
* A validation object using a List.
*
* @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public final class AggregatedValidity
implements SourceValidity
{
private List a;
public AggregatedValidity()
{
this.a = new ArrayList();
}
public void add( SourceValidity validity )
{
this.a.add( validity );
}
public boolean isValid()
{
for( Iterator i = a.iterator(); i.hasNext(); )
{
if( !( (SourceValidity)i.next() ).isValid() )
return false;
}
return true;
}
public boolean isValid( SourceValidity validity )
{
if( validity instanceof AggregatedValidity )
{
List b = ( (AggregatedValidity)validity ).a;
if( a.size() != b.size() )
return false;
for( Iterator i = a.iterator(), j = b.iterator(); i.hasNext(); )
{
final SourceValidity srcA = (SourceValidity)i.next();
final SourceValidity srcB = (SourceValidity)j.next();
if( !srcA.isValid() && !srcA.isValid( srcB ) )
return false;
}
return true;
}
return false;
}
public String toString()
{
StringBuffer b = new StringBuffer( "SourceValidity " );
for( Iterator i = a.iterator(); i.hasNext(); )
{
b.append( i.next() );
if( i.hasNext() ) b.append( ':' );
}
return b.toString();
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/validity/NOPValidity.java
Index: NOPValidity.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl.validity;
import org.apache.excalibur.source.SourceValidity;
/**
* A validation object which is always valid.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public final class NOPValidity
implements SourceValidity
{
public static final SourceValidity SHARED_INSTANCE = new NOPValidity();
/**
* Check if the component is still valid.
* If <code>false</code> is returned the isValid(SourceValidity) must be
* called afterwards!
*/
public boolean isValid()
{
return true;
}
public boolean isValid( SourceValidity newValidity )
{
return newValidity instanceof NOPValidity;
}
public String toString()
{
return "NOPValidity";
}
}
1.1 jakarta-avalon-excalibur/all/src/java/org/apache/excalibur/source/impl/validity/TimeStampValidity.java
Index: TimeStampValidity.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.source.impl.validity;
import org.apache.excalibur.source.SourceValidity;
/**
* A validation object for time-stamps.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/04/19 09:05:37 $
*/
public final class TimeStampValidity
implements SourceValidity
{
private long timeStamp;
public TimeStampValidity( long timeStamp )
{
this.timeStamp = timeStamp;
}
/**
* Check if the component is still valid.
* If <code>false</code> is returned the isValid(SourceValidity) must be
* called afterwards!
*/
public boolean isValid()
{
return false;
}
public boolean isValid( SourceValidity newValidity )
{
if( newValidity instanceof TimeStampValidity )
{
return this.timeStamp == ( (TimeStampValidity)newValidity ).getTimeStamp();
}
return false;
}
public long getTimeStamp()
{
return this.timeStamp;
}
public String toString()
{
return "TimeStampValidity: " + this.timeStamp;
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>