]> source.dussan.org Git - archiva.git/commitdiff
PR: MRM-43
authorEdwin L. Punzalan <epunzalan@apache.org>
Sat, 4 Feb 2006 02:26:29 +0000 (02:26 +0000)
committerEdwin L. Punzalan <epunzalan@apache.org>
Sat, 4 Feb 2006 02:26:29 +0000 (02:26 +0000)
Added digester usage from utils
Removed m1 client support from DefaultProxyManager.java (m1 support should be done in another class, maybe LegacyProxyManager)
Removed unused classes: Checksum.java and DefaultRepositoryFileManager.java
Added unit tests for configuration package

git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@374817 13f79535-47bb-0310-9956-ffa450edef68

maven-repository-proxy/pom.xml
maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/DefaultProxyManager.java
maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/ProxyManager.java
maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/files/Checksum.java [deleted file]
maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/files/DefaultRepositoryFileManager.java [deleted file]
maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/repository/ProxyRepository.java
maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java [new file with mode: 0644]

index a6201714bed14762f4b7fab4fe0b7c8994b0ce20..a0b22c33a1387c3a82fe94f692fb81696d522d37 100644 (file)
   <artifactId>maven-repository-proxy</artifactId>\r
   <name>Maven Repository Proxy</name>\r
   <dependencies>\r
+    <dependency>\r
+      <groupId>org.apache.maven.repository</groupId>\r
+      <artifactId>maven-repository-utils</artifactId>\r
+    </dependency>\r
     <dependency>\r
       <groupId>org.apache.maven</groupId>\r
       <artifactId>maven-artifact</artifactId>\r
index 4fe07d8a92307df8585ef408a7a348bb8f00589c..4004f4f3378d7f18da45f8af43d251a3c698cc48 100644 (file)
@@ -17,12 +17,14 @@ package org.apache.maven.repository.proxy;
  */
 
 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;
@@ -32,22 +34,34 @@ import org.apache.maven.wagon.Wagon;
 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 )
@@ -58,6 +72,7 @@ public class DefaultProxyManager
     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() )
@@ -72,40 +87,24 @@ public class DefaultProxyManager
     {
         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 )
         {
@@ -155,20 +154,10 @@ public class DefaultProxyManager
 
                 //@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 ) )
@@ -187,7 +176,8 @@ public class DefaultProxyManager
 
                         if ( useChecksum )
                         {
-                            success = doChecksumCheck( listener, repository, path, wagon );
+                            releaseChecksums( wagon, checksums );
+                            success = doChecksumCheck( checksums, repository, path, wagon );
                         }
                         else
                         {
@@ -207,7 +197,7 @@ public class DefaultProxyManager
             }
             catch ( TransferFailedException e )
             {
-                System.out.println( "Skipping repository " + repository.getUrl() + ": " + e.getMessage() );
+                getLogger().info( "Skipping repository " + repository.getUrl() + ": " + e.getMessage() );
             }
             catch ( ResourceDoesNotExistException e )
             {
@@ -215,18 +205,47 @@ public class DefaultProxyManager
             }
             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;
@@ -237,44 +256,87 @@ public class DefaultProxyManager
         }
         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
         {
@@ -323,18 +385,6 @@ public class DefaultProxyManager
                     "'; 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 );
@@ -349,7 +399,7 @@ public class DefaultProxyManager
         }
         catch ( ConnectionException e )
         {
-            System.err.println( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
+            getLogger().error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
         }
     }
 }
index c3b1d6ca16629fe6f11b151c3a38b8f68ca2ccdd..9463fd108e1b48e23f3aeced6a31bba167e922aa 100644 (file)
@@ -16,22 +16,16 @@ package org.apache.maven.repository.proxy;
  * limitations under the License.
  */
 
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-
 import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
 
 /**
  * @author Edwin Punzalan
  */
 public interface ProxyManager
 {
-    File getArtifactFile( Artifact artifact )
-        throws TransferFailedException, ResourceDoesNotExistException, IOException;
+    public File get( String path )
+        throws ProxyException;
 
-    InputStream getArtifactAsStream( Artifact artifact )
-        throws TransferFailedException, ResourceDoesNotExistException, IOException;
+    public File getRemoteFile( String path )
+        throws ProxyException;
 }
diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/files/Checksum.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/files/Checksum.java
deleted file mode 100644 (file)
index 1b2314f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-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.
- */
-
-/**
- * @author Edwin Punzalan
- */
-public class Checksum
-{
-    private String algorithm;
-
-    public Checksum( String algorithm )
-    {
-        this.setAlgorithm( algorithm );
-    }
-
-    public String getFileExtension()
-    {
-        if ( "MD5".equals( algorithm ) )
-        {
-            return "md5";
-        }
-        else
-        {
-            return "sha1";
-        }
-    }
-
-    public String getAlgorithm()
-    {
-        return algorithm;
-    }
-
-    public void setAlgorithm( String algorithm )
-    {
-        this.algorithm = algorithm;
-    }
-}
diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/files/DefaultRepositoryFileManager.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/files/DefaultRepositoryFileManager.java
deleted file mode 100644 (file)
index 2289286..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-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 );
-    }
-}
index fcea3456c8c4019f0db2a260e0ba792e740c6435..2d01b5be17df6bebea89bfec1d2dcc9e8ab3a2e1 100644 (file)
@@ -18,10 +18,6 @@ package org.apache.maven.repository.proxy.repository;
 
 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
-import org.apache.maven.repository.proxy.files.Checksum;
-import org.apache.maven.wagon.observers.ChecksumObserver;
-
-import java.security.NoSuchAlgorithmException;
 
 /**
  * @author Edwin Punzalan
@@ -29,26 +25,8 @@ import java.security.NoSuchAlgorithmException;
 public class ProxyRepository
     extends DefaultArtifactRepository
 {
-    private Checksum checksum;
-
     public ProxyRepository( String id, String url, ArtifactRepositoryLayout layout )
     {
         super( id, url, layout );
     }
-
-    public void setChecksum( String algorithm )
-    {
-        this.checksum = new Checksum( algorithm );
-    }
-
-    public Checksum getChecksum()
-    {
-        return checksum;
-    }
-
-    public ChecksumObserver getChecksumObserver()
-        throws NoSuchAlgorithmException
-    {
-        return new ChecksumObserver( checksum.getAlgorithm() );
-    }
 }
diff --git a/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java
new file mode 100644 (file)
index 0000000..a3103bd
--- /dev/null
@@ -0,0 +1,103 @@
+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