*/
import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.manager.ChecksumFailedException;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.repository.ArtifactUtils;
+import org.apache.maven.repository.digest.DefaultDigester;
+import org.apache.maven.repository.digest.Digester;
import org.apache.maven.repository.proxy.configuration.ProxyConfiguration;
-import org.apache.maven.repository.proxy.files.Checksum;
-import org.apache.maven.repository.proxy.files.DefaultRepositoryFileManager;
import org.apache.maven.repository.proxy.repository.ProxyRepository;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.observers.ChecksumObserver;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
/**
* @author Edwin Punzalan
+ * @plexus.component role="org.apache.maven.repository.proxy.ProxyManager"
*/
public class DefaultProxyManager
- //implements ProxyManager
+ extends AbstractLogEnabled
+ implements ProxyManager
{
- /* @plexus.requirement */
+ /**
+ * @plexus.requirement
+ */
private WagonManager wagon;
+ /**
+ * @plexus.requirement
+ */
+ private ArtifactFactory artifactFactory;
+
private ProxyConfiguration config;
public DefaultProxyManager( ProxyConfiguration configuration )
public File get( String path )
throws ProxyException
{
+ //@todo use wagon for cache use file:// as URL
String cachePath = config.getRepositoryCachePath();
File cachedFile = new File( cachePath, path );
if ( !cachedFile.exists() )
{
try
{
- if ( path.indexOf( "/jars/" ) >= 0 )
+ Artifact artifact = ArtifactUtils.buildArtifact( path, artifactFactory );
+
+ File remoteFile;
+ if ( artifact != null )
{
- //@todo maven 1 repo request
- throw new ProxyException( "Maven 1 repository requests not yet supported." );
+ remoteFile = getArtifactFile( artifact );
}
- else if ( path.indexOf( "/poms/" ) >= 0 )
+ else if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) )
{
- //@todo maven 1 repo request
- throw new ProxyException( "Maven 1 repository requests not yet supported." );
+ remoteFile = getRepositoryFile( path, false );
}
else
{
- //maven 2 repo request
- Object obj = new DefaultRepositoryFileManager().getRequestedObjectFromPath( path );
-
- if ( obj == null )
- {
- //right now, only metadata is known to fit here
- return getRepositoryFile( path );
- }
- else if ( obj instanceof Checksum )
- {
- return getRepositoryFile( path, false );
- }
- else if ( obj instanceof Artifact )
- {
- Artifact artifact = (Artifact) obj;
- return getArtifactFile( artifact );
- }
- else
- {
- throw new ProxyException( "Could not hande repository object: " + obj.getClass() );
- }
+ // as of now, only metadata fits here
+ remoteFile = getRepositoryFile( path );
}
+
+ return remoteFile;
}
catch ( TransferFailedException e )
{
//@todo configure wagon
- ChecksumObserver listener = null;
- try
- {
- listener = repository.getChecksumObserver();
-
- if ( listener != null )
- {
- wagon.addTransferListener( listener );
- }
- }
- catch ( NoSuchAlgorithmException e )
+ Map checksums = null;
+ if ( useChecksum )
{
- System.out.println(
- "Skipping checksum validation for unsupported algorithm: " + repository.getChecksum() );
+ checksums = prepareChecksums( wagon );
}
if ( connectToRepository( wagon, repository ) )
if ( useChecksum )
{
- success = doChecksumCheck( listener, repository, path, wagon );
+ releaseChecksums( wagon, checksums );
+ success = doChecksumCheck( checksums, repository, path, wagon );
}
else
{
}
catch ( TransferFailedException e )
{
- System.out.println( "Skipping repository " + repository.getUrl() + ": " + e.getMessage() );
+ getLogger().info( "Skipping repository " + repository.getUrl() + ": " + e.getMessage() );
}
catch ( ResourceDoesNotExistException e )
{
}
catch ( AuthorizationException e )
{
- System.out.println( "Skipping repository " + repository.getUrl() + ": " + e.getMessage() );
+ getLogger().info( "Skipping repository " + repository.getUrl() + ": " + e.getMessage() );
}
catch ( UnsupportedProtocolException e )
{
- System.out.println( "Skipping repository " + repository.getUrl() +
- ": no wagon configured for protocol " + repository.getProtocol() );
+ getLogger().info( "Skipping repository " + repository.getUrl() + ": no wagon configured for protocol " +
+ repository.getProtocol() );
}
}
throw new ProxyException( "Could not find " + path + " in any of the repositories." );
}
+ private Map prepareChecksums( Wagon wagon )
+ {
+ Map checksums = new HashMap();
+ try
+ {
+ ChecksumObserver checksum = new ChecksumObserver( "SHA-1" );
+ wagon.addTransferListener( checksum );
+ checksums.put( "sha1", checksum );
+
+ checksum = new ChecksumObserver( "MD5" );
+ wagon.addTransferListener( checksum );
+ checksums.put( "md5", checksum );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ getLogger().info( "An error occurred while preparing checksum observers", e );
+ }
+ return checksums;
+ }
+
+ private void releaseChecksums( Wagon wagon, Map checksumMap )
+ {
+ for ( Iterator checksums = checksumMap.values().iterator(); checksums.hasNext(); )
+ {
+ ChecksumObserver listener = (ChecksumObserver) checksums.next();
+ wagon.removeTransferListener( listener );
+ }
+ }
+
private boolean connectToRepository( Wagon wagon, ProxyRepository repository )
{
boolean connected = false;
}
catch ( ConnectionException e )
{
- System.out.println( "Could not connect to " + repository.getId() + ": " + e.getMessage() );
+ getLogger().info( "Could not connect to " + repository.getId() + ": " + e.getMessage() );
}
catch ( AuthenticationException e )
{
- System.out.println( "Could not connect to " + repository.getId() + ": " + e.getMessage() );
+ getLogger().info( "Could not connect to " + repository.getId() + ": " + e.getMessage() );
}
return connected;
}
- private boolean doChecksumCheck( ChecksumObserver listener, ProxyRepository repository, String path, Wagon wagon )
- //throws ChecksumFailedException
+ private boolean doChecksumCheck( Map checksumMap, ProxyRepository repository, String path, Wagon wagon )
{
- boolean success = false;
-
- try
+ for ( Iterator checksums = checksumMap.keySet().iterator(); checksums.hasNext(); )
{
- String checksumExt = repository.getChecksum().getFileExtension();
+ String checksumExt = (String) checksums.next();
+ ChecksumObserver checksum = (ChecksumObserver) checksumMap.get( checksumExt );
String remotePath = path + "." + checksumExt;
File checksumFile = new File( config.getRepositoryCache().getBasedir(), remotePath );
- verifyChecksum( listener.getActualChecksum(), checksumFile, remotePath, checksumExt, wagon );
+ try
+ {
+ File tempChecksumFile = new File( checksumFile.getAbsolutePath() + "." + checksumExt );
+
+ wagon.get( remotePath + "." + checksumExt, tempChecksumFile );
- wagon.removeTransferListener( listener );
+ String algorithm;
+ if ( "md5".equals( checksumExt ) )
+ {
+ algorithm = "MD5";
+ }
+ else
+ {
+ algorithm = "SHA-1";
+ }
- success = true;
- }
- catch ( ChecksumFailedException e )
- {
- System.out.println( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" );
+ Digester digester = new DefaultDigester();
+ try
+ {
+ return digester.verifyChecksum( tempChecksumFile, checksum.getActualChecksum(), algorithm );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ getLogger().info( "Failed to initialize checksum: " + algorithm + "\n " + e.getMessage() );
+ return false;
+ }
+ catch ( IOException e )
+ {
+ getLogger().info( "Failed to verify checksum: " + algorithm + "\n " + e.getMessage() );
+ return false;
+ }
+
+ }
+ catch ( ChecksumFailedException e )
+ {
+ return false;
+ }
+ catch ( TransferFailedException e )
+ {
+ getLogger().warn( "An error occurred during the download of " + remotePath + ": " + e.getMessage() );
+ // do nothing try the next checksum
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ getLogger().warn( "An error occurred during the download of " + remotePath + ": " + e.getMessage() );
+ // do nothing try the next checksum
+ }
+ catch ( AuthorizationException e )
+ {
+ getLogger().warn( "An error occurred during the download of " + remotePath + ": " + e.getMessage() );
+ // do nothing try the next checksum
+ }
}
- return success;
+ getLogger().info( "Skipping checksum validation for " + path + ": No remote checksums available." );
+
+ return true;
}
private void verifyChecksum( String actualChecksum, File destination, String remotePath,
String checksumFileExtension, Wagon wagon )
- throws ChecksumFailedException
+ throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
{
try
{
"'; remote = '" + expectedChecksum + "'" );
}
}
- catch ( TransferFailedException e )
- {
- System.out.println( "Skipping checksum validation for " + remotePath + ": " + e.getMessage() );
- }
- catch ( ResourceDoesNotExistException e )
- {
- System.out.println( "Skipping checksum validation for " + remotePath + ": " + e.getMessage() );
- }
- catch ( AuthorizationException e )
- {
- System.out.println( "Skipping checksum validation for " + remotePath + ": " + e.getMessage() );
- }
catch ( IOException e )
{
throw new ChecksumFailedException( "Invalid checksum file", e );
}
catch ( ConnectionException e )
{
- System.err.println( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
+ getLogger().error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
}
}
}
+++ /dev/null
-package org.apache.maven.repository.proxy.files;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.factory.ArtifactFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * @author Edwin Punzalan
- */
-public class DefaultRepositoryFileManager
-{
- /* @plexus.requirement */
- private ArtifactFactory factory;
-
- public Object getRequestedObjectFromPath( String path )
- {
- if ( path.endsWith( ".pom" ) )
- {
- return getArtifactFromPath( path );
- }
- else if ( path.endsWith( "ar" ) )
- {
- return getArtifactFromPath( path );
- }
- else if ( path.endsWith( ".md5" ) )
- {
- return new Checksum( "MD5" );
- }
- else if ( path.endsWith( ".sha1" ) )
- {
- return new Checksum( "SHA-1" );
- }
- else
- {
- //@todo handle metadata file requests
- return null;
- }
- }
-
- private Artifact getArtifactFromPath( String path )
- {
- List pathInfo = getReversedPathInfo( path );
- String filename = getPathToken( pathInfo );
- String version = getPathToken( pathInfo );
- String artifactId = getPathToken( pathInfo );
- String groupId = "";
- while ( pathInfo.size() > 0 )
- {
- if ( groupId.length() == 0 )
- {
- groupId = "." + groupId;
- }
- else
- {
- groupId = getPathToken( pathInfo ) + "." + groupId;
- }
- }
-
- return factory.createBuildArtifact( groupId, artifactId, version, getFileExtension( filename ) );
- }
-
- private List getReversedPathInfo( String path )
- {
- List reversedPath = new ArrayList();
-
- StringTokenizer tokenizer = new StringTokenizer( path, "/" );
- while ( tokenizer.hasMoreTokens() )
- {
- reversedPath.add( 0, tokenizer.nextToken() );
- }
-
- return reversedPath;
- }
-
- private String getPathToken( List path )
- {
- if ( path.size() > 0 )
- {
- return (String) path.remove( 0 );
- }
- else
- {
- return null;
- }
- }
-
- private String getFileExtension( String filename )
- {
- int idx = filename.lastIndexOf( '.' );
- return filename.substring( idx + 1 );
- }
-}
--- /dev/null
+package org.apache.maven.repository.proxy.configuration;\r
+\r
+/*\r
+ * Copyright 2005-2006 The Apache Software Foundation.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+import org.apache.maven.artifact.repository.ArtifactRepository;\r
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;\r
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;\r
+import org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout;\r
+import org.apache.maven.repository.proxy.repository.ProxyRepository;\r
+import org.codehaus.plexus.PlexusTestCase;\r
+\r
+import java.io.File;\r
+import java.util.List;\r
+import java.util.ArrayList;\r
+\r
+public class ProxyConfigurationTest\r
+ extends PlexusTestCase\r
+{\r
+ private ProxyConfiguration config;\r
+\r
+ protected void setUp()\r
+ throws Exception\r
+ {\r
+ super.setUp();\r
+\r
+ config = (ProxyConfiguration) container.lookup( ProxyConfiguration.ROLE );\r
+ }\r
+\r
+ public void testBrowsable()\r
+ {\r
+ assertFalse( config.isBrowsable() );\r
+ config.setBrowsable( true );\r
+ assertTrue( config.isBrowsable() );\r
+ }\r
+\r
+ public void testRepositoryCache()\r
+ {\r
+ File cacheFile = new File( "target/proxy-cache" );\r
+ config.setRepositoryCachePath( "file://" + cacheFile.getAbsolutePath() );\r
+ ArtifactRepository cache = config.getRepositoryCache();\r
+ System.out.println( cache.getUrl() );\r
+ assertEquals( cacheFile.getAbsolutePath(), cache.getBasedir() );\r
+ assertEquals( config.getRepositoryCachePath(), cache.getBasedir() );\r
+ }\r
+\r
+ public void testRepositories()\r
+ {\r
+ ArtifactRepositoryLayout defLayout = new DefaultRepositoryLayout();\r
+ ProxyRepository repo1 = new ProxyRepository( "repo1", "http://www.ibiblio.org/maven2", defLayout );\r
+ config.addRepository( repo1 );\r
+ assertEquals( 1, config.getRepositories().size() );\r
+\r
+ ArtifactRepositoryLayout legacyLayout = new LegacyRepositoryLayout();\r
+ ProxyRepository repo2 = new ProxyRepository( "repo2", "http://www.ibiblio.org/maven", legacyLayout );\r
+ config.addRepository( repo2 );\r
+ assertEquals( 2, config.getRepositories().size() );\r
+\r
+ List repositories = config.getRepositories();\r
+ ProxyRepository repo = (ProxyRepository) repositories.get( 0 );\r
+ assertEquals( repo1, repo );\r
+\r
+ repo = (ProxyRepository) repositories.get( 1 );\r
+ assertEquals( repo2, repo );\r
+\r
+ try\r
+ {\r
+ repositories.add( new ProxyRepository( "repo", "url", defLayout ) );\r
+ fail( "Expected UnsupportedOperationException not thrown." );\r
+ }\r
+ catch ( java.lang.UnsupportedOperationException e )\r
+ {\r
+ assertTrue( true );\r
+ }\r
+\r
+ repositories = new ArrayList();\r
+ repositories.add( repo1 );\r
+ repositories.add( repo2 );\r
+ config.setRepositories( repositories );\r
+ assertEquals( repositories, config.getRepositories() );\r
+ }\r
+\r
+ protected void tearDown()\r
+ throws Exception\r
+ {\r
+ config = null;\r
+\r
+ super.tearDown();\r
+ }\r
+}
\ No newline at end of file