akarasulu 2003/11/05 20:03:49
Added: repository/impl/src/java/org/apache/avalon/repository/impl
DefaultAuthenticator.java DefaultBlockManifest.java
DefaultFactory.java DefaultFileRepository.java
HttpController.java package.html
Log:
Checking in a snapshot of the repository
Revision Changes Path
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultAuthenticator.java
Index: DefaultAuthenticator.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact [EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.repository.impl;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
/**
* Default authenticator that provides support for username password
* based authentication in conjunction with the repository proxy settings.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
*/
public final class DefaultAuthenticator extends Authenticator
{
/**
* Proxy username.
*/
private String m_username;
/**
* Proxy password.
*/
private char[] m_password;
/**
* Creation of a new simple authenticator.
* @param username the username
* @param password a passsword
* @exception NullPointerException if the supplied username or password is null
*/
public DefaultAuthenticator( String username, String password ) throws
NullPointerException
{
if( username == null ) throw new NullPointerException( "username" );
if( password == null ) throw new NullPointerException( "password" );
m_username = username;
m_password = password.toCharArray();
}
/**
* Returns the password authenticator.
* @return the password authenticator
*/
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication( m_username, m_password );
}
}
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultBlockManifest.java
Index: DefaultBlockManifest.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact [EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.repository.impl;
import java.util.jar.Manifest;
import org.apache.avalon.repository.BlockManifest;
/**
* An extended manifest that provides a set of convinience operations
* to access block related attributes.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
*/
public final class DefaultBlockManifest implements BlockManifest
{
/**
* Group identifier.
*/
private final String m_group;
/**
* Name.
*/
private final String m_name;
/**
* Version identifier.
*/
private final String m_version;
/**
* Creation of a new block manifest
* @param manifest the jar manifest
*/
public DefaultBlockManifest( Manifest manifest ) throws NullPointerException
{
m_group = (String) manifest.getMainAttributes().getValue( BLOCK_GROUP_KEY );
m_name = (String) manifest.getMainAttributes().getValue( BLOCK_NAME_KEY );
m_version = (String) manifest.getMainAttributes().getValue(
BLOCK_VERSION_KEY );
}
public String getBlockGroup()
{
return m_group;
}
public String getBlockName()
{
return m_name;
}
public String getBlockVersion()
{
return m_version;
}
}
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFactory.java
Index: DefaultFactory.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact [EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.repository.impl ;
import java.io.File ;
import java.io.IOException ;
import java.io.InputStream ;
import java.io.FileInputStream ;
import java.util.Properties ;
import java.net.Authenticator ;
import java.net.MalformedURLException ;
import java.net.PasswordAuthentication ;
import org.apache.avalon.defaults.Defaults ;
import org.apache.avalon.defaults.DefaultsFinder ;
import org.apache.avalon.defaults.SimpleDefaultsFinder ;
import org.apache.avalon.defaults.SystemDefaultsFinder ;
import org.apache.avalon.repository.Repository ;
import org.apache.avalon.repository.ProxyContext ;
import org.apache.avalon.repository.RepositoryConfig ;
import org.apache.avalon.repository.RepositoryFactory ;
import org.apache.avalon.repository.RepositoryException ;
/**
* The default repository factory implementation.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Alex Karasulu</a>
* @author $Author: akarasulu $
* @version $Revision: 1.1 $
*/
public class DefaultFactory implements RepositoryFactory
{
/** properties file where we pull defaults from */
public static final String DEFAULTS = "repository.properties" ;
/** single valued properties */
private static final String [] s_singles = {
"cache.dir",
"proxyHost",
"proxyPort",
"proxyUsername",
"proxyPassword"
} ;
/** the local repository base key where we download files into */
public static final String CACHE_DIR = s_singles[0] ;
/** the proxy host key */
public static final String PROXY_HOST = s_singles[1] ;
/** the proxy port key */
public static final String PROXY_PORT = s_singles[2] ;
/** the proxy username key */
public static final String PROXY_USERNAME = s_singles[3] ;
/** the proxy password key */
public static final String PROXY_PASSWORD = s_singles[4] ;
/** enumerated (multivalued) properties */
public static final String [] s_multiple = {
"remote.repository.url"
} ;
/** the key base for the remote repo enumerated property */
public static final String REMOTE_REPO_BASE = s_multiple[0] ;
/**
* Creates a repository configuration and populates it with parameters
* obtained from a default bootstrap properties file, a hidden form of the
* same properties file (dot '.' prefixed), and the system properties in
* that order. Support property key macro expansion.
*
* @see org.apache.avalon.repository.RepositoryFactory#getDefaultConfig()
*/
public RepositoryConfig getDefaultConfig()
throws RepositoryException
{
Properties l_bootstrap = new Properties() ;
ProxyContext l_proxy = null ;
RepositoryConfig l_config = new RepositoryConfig() ;
InputStream l_in = Repository.class.getResourceAsStream( DEFAULTS ) ;
/*
* Load the jar relative default properties file first. Then load into
* the same properties the dot prefixed version of the defaults file
* within the user's home directory.
*/
try
{
l_bootstrap.load( l_in ) ;
String l_userHome = System.getProperty( "user.home" ) ;
File l_user = new File( l_userHome, "." + DEFAULTS ) ;
if ( l_user.exists() )
{
l_in = new FileInputStream( l_user ) ;
l_bootstrap.load( l_in ) ;
}
}
catch( IOException e )
{
throw new RepositoryException( "Failed to load defaults", e ) ;
}
/*
* Create the finder (discovery policy), construct the defaults, and
* macro expand the values.
*/
final DefaultsFinder [] l_finders = {
new SimpleDefaultsFinder( new Properties[] { l_bootstrap }, false ),
new SystemDefaultsFinder()
} ;
final Defaults l_defaults =
new Defaults( s_singles, s_multiple, l_finders ) ;
Defaults.macroExpand( l_defaults, null ) ;
/*
* Here we start to populate the empty repository configuration using
* the values stored in the defaults.
*/
l_config.setCacheDir( l_defaults.getProperty( CACHE_DIR ) ) ;
try
{
l_config.setRemoteRepositoryUrls(
l_defaults.getEnumerated( REMOTE_REPO_BASE ) ) ;
}
catch ( MalformedURLException e )
{
throw new RepositoryException( "Failed to set remote repos", e ) ;
}
if ( l_defaults.containsKey( PROXY_HOST ) )
{
int l_port = Integer
.parseInt( l_defaults.getProperty( PROXY_PORT ) ) ;
String l_host = l_defaults.getProperty( PROXY_HOST ) ;
Authenticator l_authenticator = new Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
PasswordAuthentication l_pwdAuth =
new PasswordAuthentication(
l_defaults.getProperty( PROXY_USERNAME ),
l_defaults.getProperty( PROXY_PASSWORD )
.toCharArray() ) ;
return l_pwdAuth ;
}
} ;
l_proxy = new ProxyContext( l_host, l_port, l_authenticator) ;
}
l_config.setProxyContext( l_proxy ) ;
return l_config ;
}
/**
* Creates a file repository using the properties of a configuration bean.
*
* @see org.apache.avalon.repository.RepositoryFactory
* create(org.apache.avalon.repository.RepositoryConfig)
*/
public Repository create( RepositoryConfig a_config )
{
Repository l_repository = null ;
File l_base = new File( a_config.getCacheDir() ) ;
if ( null == a_config.getProxyContext() &&
null == a_config.getRemoteRepositories() )
{
l_repository = new DefaultFileRepository( l_base ) ;
}
else if ( null == a_config.getProxyContext() )
{
l_repository = new DefaultFileRepository( l_base,
a_config.getRemoteRepositories() ) ;
}
l_repository = new DefaultFileRepository( l_base,
a_config.getProxyContext(),
a_config.getRemoteRepositories() ) ;
return l_repository ;
}
}
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFileRepository.java
Index: DefaultFileRepository.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact [EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.repository.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.Authenticator;
import java.net.JarURLConnection;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
import org.apache.avalon.repository.Repository;
import org.apache.avalon.repository.RepositoryException;
import org.apache.avalon.repository.ProxyContext;
import org.apache.avalon.repository.BlockManifest;
/**
* A component that provides access to versioned resources based on
* an underlying file system.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
*/
public class DefaultFileRepository implements Repository
{
//------------------------------------------------------------------
// immutable state
//------------------------------------------------------------------
/**
* The directory referencing the local repository cache.
*/
private final File m_base;
/**
* Sequence of remote hosts.
*/
private final URL[] m_hosts;
//------------------------------------------------------------------
// constructor
//------------------------------------------------------------------
public DefaultFileRepository( File base )
{
this( base, null, new URL[0] );
}
public DefaultFileRepository( File base, URL[] hosts )
{
this( base, null, hosts );
}
public DefaultFileRepository( File base, ProxyContext context, URL[] hosts )
{
if( base == null ) throw new NullPointerException( "base" );
m_base = base;
if( hosts == null )
{
m_hosts = new URL[0];
}
else
{
m_hosts = new URL[ hosts.length ];
for( int i=0; i<hosts.length; i++ )
{
URL url = hosts[i];
final String path = url.toString();
if( !path.endsWith( "/" ) )
{
try
{
m_hosts[i] = new URL( path + "/" );
}
catch( Throwable e )
{
final String error =
"Could not coerce supplied URL to a directory reference: "
+ path;
throw new IllegalArgumentException( error );
}
}
else
{
m_hosts[i] = hosts[i];
}
}
}
if( context != null )
{
System.getProperties().put( "proxySet", "true" );
System.getProperties().put( "proxyHost", context.getHost() );
System.getProperties().put( "proxyPort", context.getPort() );
if( context.getAuthenticator() != null )
{
Authenticator.setDefault( context.getAuthenticator() );
}
}
}
//------------------------------------------------------------------
// implementation
//------------------------------------------------------------------
/**
* Return the repository location.
*
* @return the location
*/
public String getLocation()
{
return m_base.toString();
}
/**
* Install a block archive into the repository.
* @param url the block archive url
* @param buffer a string buffer against which messages may be logged
* @return the block manifest
*/
public BlockManifest install( URL url, StringBuffer buffer ) throws
RepositoryException
{
String path = url.getFile();
try
{
File temp = File.createTempFile( "avalon-", "-bar" );
temp.delete();
HttpController.getFile( url.toString(), temp, true );
temp.deleteOnExit();
return expand( temp.toURL(), buffer );
}
catch( RepositoryException e )
{
throw e;
}
catch( Throwable e )
{
final String error =
"Cannot install target: " + url;
throw new RepositoryException( error, e );
}
}
/**
* Expand a block archive into the repository.
* @param url the block archive url
* @param buffer a string buffer against which messages may be logged
* @return the block manifest
*/
private BlockManifest expand( URL url, StringBuffer buffer ) throws
RepositoryException
{
try
{
URL jurl = new URL( "jar:" + url.toString() + "!/" );
JarURLConnection connection = (JarURLConnection) jurl.openConnection();
BlockManifest manifest =
new DefaultBlockManifest( connection.getManifest() );
final String group = manifest.getBlockGroup();
buffer.append( "\nBlock Group: " + group );
final File root = new File( m_base, group );
buffer.append( "\nLocal target: " + root );
JarFile jar = connection.getJarFile();
Enumeration entries = jar.entries();
while( entries.hasMoreElements() )
{
ZipEntry entry = (ZipEntry) entries.nextElement();
if( !entry.getName().startsWith( "META-INF" ) )
{
installEntry( buffer, root, jar, entry );
}
}
buffer.append( "\nInstall successful." );
return manifest;
}
catch( Throwable e )
{
final String error =
"Could not install block: " + url;
throw new RepositoryException( error, e );
}
}
/**
* Get a resource relative to the supplied artifact name where the artifact name
* is equivalent to the group and resource name seperated by a colon.
*
* @param artifact the artifact name
* @param version the version identifier
* @param type the resource type
* @return the resource
*/
public URL getArtifact(
final String artifact, final String version, final String type )
throws RepositoryException
{
int n = verify( artifact );
final String group = getGroupName( artifact, n );
final String name = getResourceName( artifact, n );
return getArtifact( group, name, version, type );
}
/**
* Get a resource relative to the supplied application name,
* resource name, version and resource type.
*
* @param group the application or group name
* @param name the resource name
* @param version the version identifier
* @param type the resource type
* @return the resource
*/
public URL getArtifact(
final String group, final String name, final String version, final String type
)
throws RepositoryException
{
if( m_hosts == null )
{
throw new IllegalStateException( "hosts" );
}
if( group == null )
{
throw new NullPointerException( "group" );
}
if( name == null )
{
throw new NullPointerException( "name" );
}
if( type == null )
{
throw new NullPointerException( "type" );
}
String path = group + "/" + type + "s/" + name;
if( ( version != null ) && ( version.length() != 0 ) )
{
path = path + "-" + version;
}
path = path + "." + type;
RepositoryException repositoryException = null;
try
{
return getLocalArtifact( group, name, version, type );
}
catch( RepositoryException e )
{
repositoryException = e;
for( int i=0; i<m_hosts.length; i++ )
{
final URL source = m_hosts[i];
final String host = source.toString();
final File local = new File( m_base, path );
final String url = host + path;
try
{
if( HttpController.getFile( url, local, true ) )
{
return getLocalArtifact( group, name, version, type );
}
}
catch( Throwable anything )
{
// continue
}
}
}
catch( Throwable e )
{
final String error =
"Unexpected error while attempting to resolve artifact: " + path;
throw new RepositoryException( error, e );
}
//
// fallback to throwing a local repository error
//
throw repositoryException;
}
/**
* Get a resource relative to the supplied application name,
* resource name, version and resource type from the local cache.
*
* @param group the application or group name
* @param name the resource name
* @param version the version identifier
* @param type the resource type
* @return the resource
*/
private URL getLocalArtifact(
final String group, final String name,
final String version, final String type )
throws RepositoryException
{
File application = new File( m_base, group );
if( !application.exists() )
{
final String error =
"Unknown group: '" + group
+ "' relative to the repository base: '" + m_base + "'.";
throw new RepositoryException( error );
}
File types = new File( application, type + "s" );
if( !types.exists() )
{
final String error =
"No resources of the type: '" + type
+ "' in the group: '" + group
+ "'. File: '" + types + "'.";
throw new RepositoryException( error );
}
//
// we only append the version identifier if the version
// value is not null and more than 0 characters
//
String resourceName = name;
if( ( version != null ) && ( version.length() != 0 ) )
{
resourceName = resourceName + "-" + version;
}
File resource = new File( types, resourceName + "." + type );
if( !resource.exists() )
{
final String error =
"No resources of the type: '" + type
+ "' in the group: '" + group
+ "' with the name: '" + name
+ "' and version: '" + version
+ ". File: '" + resource + "'.";
throw new RepositoryException( error );
}
try
{
return resource.toURL();
}
catch( Throwable e )
{
final String error =
"Unable to resolve URL for resource: " + resource;
throw new RepositoryException( error );
}
}
private int verify( final String artifact ) throws RepositoryException
{
int n = artifact.indexOf( SEPERATOR );
if( n < 1 )
{
final String error =
"Invalid artifact name: " + artifact;
throw new RepositoryException( error );
}
return n;
}
private String getGroupName( String artifact, int index )
{
return artifact.substring( 0, index );
}
private String getResourceName( String artifact, int index )
{
return artifact.substring( index + 1 );
}
/**
* Internal utility to install a entry from a jar file into the local repository.
* @param buffer the buffer to log messages to
* @param root the root directory corresponding to the bar group
* @param jar the block archive
* @param entry the entry from the archive to install
*/
private void installEntry(
StringBuffer buffer, File root, JarFile jar, ZipEntry entry ) throws Exception
{
if( entry.isDirectory() ) return;
final String name = entry.getName();
File file = new File( root, name );
long timestamp = entry.getTime();
if( file.exists() )
{
if( file.lastModified() == timestamp )
{
buffer.append( "\nEntry: " + name + " (already exists)" );
return;
}
else if( file.lastModified() > timestamp )
{
buffer.append( "\nEntry: " + name + " (local version is more
recent)" );
return;
}
else
{
buffer.append( "\nEntry: " + name + " (updating local version)" );
}
}
else
{
buffer.append( "\nEntry: " + name );
}
InputStream is = jar.getInputStream( entry );
if ( is == null )
{
final String error =
"Entry returned a null input stream: " + name;
buffer.append( "\n " + error );
throw new IOException( error );
}
file.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream( file );
byte[] buf = new byte[100 * 1024];
int length;
while ( ( length = is.read( buf ) ) >= 0 )
{
fos.write( buf, 0, length );
}
fos.close();
is.close();
if ( timestamp < 0 )
{
file.setLastModified( System.currentTimeMillis() );
}
else
{
file.setLastModified( timestamp );
}
}
}
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/HttpController.java
Index: HttpController.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact [EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.repository.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
/**
* Class supporting the retrival of remotely located resources.
* Implementation is based on original code from the Maven project
* refactored to seperate static proxy establishment from transport
* concerns.
*
* @author [EMAIL PROTECTED]
* @author [EMAIL PROTECTED] (Added Java 1.1 style HTTP basic auth)
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
*/
class HttpController
{
/**
* Retrieve a remote file. Returns true if the file was updated, false
* if the existing cached resource was not modified.
*
* @param url the of the file to retrieve
* @param destinationFile where to store it
* @param useTimestamp whether to check the modified timestamp on the
* <code>destinationFile</code> against the remote <code>source</code>
* @param useChecksum Flag to indicate the use of the checksum for the retrieved
* artifact if it is available.
*/
public static boolean getFile(
String url, File destinationFile, boolean useTimestamp, boolean useChecksum )
throws Exception
{
// Get the requested file.
boolean result = getFile( url, destinationFile, useTimestamp );
// Get the checksum if requested.
if ( useChecksum )
{
File checksumFile = new File( destinationFile + ".md5" );
try
{
getFile( url + ".md5", checksumFile, useTimestamp );
}
catch ( Exception e )
{
// do nothing we will check later in the process
// for the checksums.
}
}
return result;
}
/**
* Retrieve a remote file. Returns true if the file was successfully
* retrieved or if it is up to date (when the useTimestamp flag is set).
*
* @param url the of the file to retrieve
* @param destinationFile where to store it
* @param useTimestamp whether to check the modified timestamp on the
* <code>destinationFile</code> against the remote <code>source</code>
* @return TRUE if the file was updated else FALSE
*/
public static boolean getFile( String url,
File destinationFile,
boolean useTimestamp )
throws Exception
{
String[] s = parseUrl( url );
String username = s[0];
String password = s[1];
String parsedUrl = s[2];
URL source = new URL( parsedUrl );
//set the timestamp to the file date.
long timestamp = 0;
boolean hasTimestamp = false;
if ( useTimestamp && destinationFile.exists() )
{
timestamp = destinationFile.lastModified();
hasTimestamp = true;
}
//set up the URL connection
URLConnection connection = source.openConnection();
//modify the headers
//NB: things like user authentication could go in here too.
if ( useTimestamp && hasTimestamp )
{
connection.setIfModifiedSince( timestamp );
}
//connect to the remote site (may take some time)
connection.connect();
//next test for a 304 result (HTTP only)
if ( connection instanceof HttpURLConnection )
{
HttpURLConnection httpConnection = (HttpURLConnection) connection;
if ( httpConnection.getResponseCode() ==
HttpURLConnection.HTTP_NOT_MODIFIED )
{
return false;
}
// test for 401 result (HTTP only)
if ( httpConnection.getResponseCode() ==
HttpURLConnection.HTTP_UNAUTHORIZED )
{
throw new Exception( "Not authorized." );
}
}
// REVISIT: at this point even non HTTP connections may support the
// if-modified-since behaviour - we just check the date of the
// content and skip the write if it is not newer.
// Some protocols (FTP) dont include dates, of course.
InputStream is = null;
for ( int i = 0; i < 3; i++ )
{
try
{
is = connection.getInputStream();
break;
}
catch ( IOException ex )
{
// do nothing
}
}
if ( is == null )
{
final String error =
"Connection returned a null input stream: " + url;
throw new IOException( error );
}
File parent = destinationFile.getParentFile();
parent.mkdirs();
FileOutputStream fos = new FileOutputStream( destinationFile );
byte[] buffer = new byte[100 * 1024];
int length;
System.out.print( "Source: " + source + "\n");
while ( ( length = is.read( buffer ) ) >= 0 )
{
fos.write( buffer, 0, length );
System.out.print( "." );
}
System.out.println( "" );
fos.close();
is.close();
// if (and only if) the use file time option is set, then the
// saved file now has its timestamp set to that of the downloaded
// file
if ( useTimestamp )
{
long remoteTimestamp = connection.getLastModified();
if ( remoteTimestamp != 0 )
{
touchFile( destinationFile, remoteTimestamp );
}
}
return true;
}
/**
* Parse an url which might contain a username and password. If the
* given url doesn't contain a username and password then return the
* origin url unchanged.
*
* @param url The url to parse.
* @return The username, password and url.
*/
static String[] parseUrl( String url )
{
String[] parsedUrl = new String[3];
parsedUrl[0] = null;
parsedUrl[1] = null;
parsedUrl[2] = url;
// We want to be able to deal with Basic Auth where the username
// and password are part of the URL. An example of the URL string
// we would like to be able to parse is like the following:
//
// http://username:[EMAIL PROTECTED]
int i = url.indexOf( "@" );
if ( i > 0 )
{
String s = url.substring( 7, i );
int j = s.indexOf( ":" );
parsedUrl[0] = s.substring( 0, j );
parsedUrl[1] = s.substring( j + 1 );
parsedUrl[2] = "http://" + url.substring( i + 1 );
}
return parsedUrl;
}
/**
* set the timestamp of a named file to a specified time.
*
* @param file the file to touch
* @param timemillis in milliseconds since the start of the era
* @return true if it succeeded. False means that this is a java1.1 system
* and that file times can not be set
* @exception Exception Thrown in unrecoverable error. Likely this
* comes from file access failures.
*/
private static boolean touchFile( File file, long timemillis )
throws Exception
{
long modifiedTime;
if ( timemillis < 0 )
{
modifiedTime = System.currentTimeMillis();
}
else
{
modifiedTime = timemillis;
}
file.setLastModified( modifiedTime );
return true;
}
}
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/package.html
Index: package.html
===================================================================
<body>
<p>
The repository impl package contains an implementation of a file based repository.
</p>
</body>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]