Author: olamy
Date: Thu Sep 22 13:47:58 2011
New Revision: 1174134

URL: http://svn.apache.org/viewvc?rev=1174134&view=rev
Log:
[WAGON-328] Allow putDirectory to continue even if an individual file transfer 
fails
Submitted by Andrew Phillips.

Modified:
    
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
    
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
    
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java

Modified: 
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
URL: 
http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java?rev=1174134&r1=1174133&r2=1174134&view=diff
==============================================================================
--- 
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
 (original)
+++ 
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
 Thu Sep 22 13:47:58 2011
@@ -721,7 +721,6 @@ public abstract class AbstractWagon
     protected void fireTransferError( Resource resource, Exception e, int 
requestType )
     {
         TransferEvent transferEvent = new TransferEvent( this, resource, e, 
requestType );
-
         transferEventSupport.fireTransferError( transferEvent );
     }
 

Modified: 
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
URL: 
http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java?rev=1174134&r1=1174133&r2=1174134&view=diff
==============================================================================
--- 
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
 (original)
+++ 
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
 Thu Sep 22 13:47:58 2011
@@ -19,12 +19,6 @@ package org.apache.maven.wagon.providers
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.jackrabbit.webdav.DavConstants;
@@ -48,6 +42,12 @@ import org.codehaus.plexus.util.FileUtil
 import org.codehaus.plexus.util.StringUtils;
 import org.w3c.dom.Node;
 
+import java.io.File;
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * <p>WebDavWagon</p>
  * <p/>
@@ -57,30 +57,32 @@ import org.w3c.dom.Node;
  * @author <a href="mailto:[email protected]";>Joakim Erdfelt</a>
  * @author <a href="mailto:[email protected]";>Carlos Sanchez</a>
  * @author <a href="mailto:[email protected]";>James William Dumay</a>
- *
  * @plexus.component role="org.apache.maven.wagon.Wagon"
- *   role-hint="dav"
- *   instantiation-strategy="per-lookup"
+ * role-hint="dav"
+ * instantiation-strategy="per-lookup"
  */
 public class WebDavWagon
     extends AbstractHttpClientWagon
 {
+    protected static final String CONTINUE_ON_FAILURE_PROPERTY = 
"wagon.webdav.continueOnFailure";
+
+    private final boolean continueOnFailure = Boolean.getBoolean( 
CONTINUE_ON_FAILURE_PROPERTY );
+
     /**
      * Defines the protocol mapping to use.
-     *
+     * <p/>
      * First string is the user definition way to define a webdav url,
      * the second string is the internal representation of that url.
-     *
+     * <p/>
      * NOTE: The order of the mapping becomes the search order.
      */
-    private static final String[][] protocolMap = new String[][] {
-        { "dav:http://";, "http://"; },    /* maven 2.0.x url string format. 
(violates URI spec) */
-        { "dav:https://";, "https://"; },  /* maven 2.0.x url string format. 
(violates URI spec) */
-        { "dav+http://";, "http://"; },    /* URI spec compliant 
(protocol+transport) */
-        { "dav+https://";, "https://"; },  /* URI spec compliant 
(protocol+transport) */
-        { "dav://", "http://"; },         /* URI spec compliant (protocol only) 
*/
-        { "davs://", "https://"; }        /* URI spec compliant (protocol only) 
*/
-    };
+    private static final String[][] protocolMap =
+        new String[][]{ { "dav:http://";, "http://"; },    /* maven 2.0.x url 
string format. (violates URI spec) */
+            { "dav:https://";, "https://"; },  /* maven 2.0.x url string format. 
(violates URI spec) */
+            { "dav+http://";, "http://"; },    /* URI spec compliant 
(protocol+transport) */
+            { "dav+https://";, "https://"; },  /* URI spec compliant 
(protocol+transport) */
+            { "dav://", "http://"; },         /* URI spec compliant (protocol 
only) */
+            { "davs://", "https://"; }        /* URI spec compliant (protocol 
only) */ };
 
     /**
      * This wagon supports directory copying
@@ -112,7 +114,7 @@ public class WebDavWagon
         {
             baseUrl += ":" + repository.getPort();
         }
-        
+
         // create relative path that will always have a leading and trailing 
slash
         String relpath = FileUtils.normalize( getPath( basedir, dir ) + "/" );
 
@@ -252,7 +254,7 @@ public class WebDavWagon
 
                         MultiStatusResponse response = 
multiStatus.getResponses()[i];
 
-                        String entryUrl =  response.getHref();
+                        String entryUrl = response.getHref();
                         String fileName = PathUtils.filename( 
URLDecoder.decode( entryUrl ) );
                         if ( entryUrl.endsWith( "/" ) )
                         {
@@ -298,8 +300,8 @@ public class WebDavWagon
                 method.releaseConnection();
             }
         }
-        throw new ResourceDoesNotExistException( "Destination path exists but 
is not a "
-                        + "WebDAV collection (directory): " + url );
+        throw new ResourceDoesNotExistException(
+            "Destination path exists but is not a " + "WebDAV collection 
(directory): " + url );
     }
 
     public String getURL( Repository repository )
@@ -319,4 +321,28 @@ public class WebDavWagon
         // No mapping trigger? then just return as-is.
         return url;
     }
+
+
+    public void put( File source, String resourceName )
+        throws TransferFailedException, ResourceDoesNotExistException, 
AuthorizationException
+    {
+        try
+        {
+            super.put( source, resourceName );
+        }
+        catch ( TransferFailedException e )
+        {
+            if ( continueOnFailure )
+            {
+                // TODO use a logging mechanism here or a fireTransferWarning
+                System.out.println(
+                    "WARN: Skip unable to transfer '" + resourceName + "' from 
'" + source.getPath() + "' due to "
+                        + e.getMessage() );
+            }
+            else
+            {
+                throw e;
+            }
+        }
+    }
 }

Modified: 
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
URL: 
http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java?rev=1174134&r1=1174133&r2=1174134&view=diff
==============================================================================
--- 
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
 (original)
+++ 
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
 Thu Sep 22 13:47:58 2011
@@ -16,8 +16,11 @@ package org.apache.maven.wagon.providers
  */
 
 import it.could.webdav.DAVServlet;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
 import org.apache.maven.wagon.ResourceDoesNotExistException;
 import org.apache.maven.wagon.StreamingWagon;
+import org.apache.maven.wagon.TransferFailedException;
 import org.apache.maven.wagon.Wagon;
 import org.apache.maven.wagon.http.HttpWagonTestCase;
 import org.apache.maven.wagon.repository.Repository;
@@ -28,6 +31,7 @@ import org.mortbay.jetty.servlet.Servlet
 
 import java.io.File;
 import java.io.IOException;
+import java.net.SocketTimeoutException;
 import java.util.List;
 import java.util.Properties;
 
@@ -68,7 +72,7 @@ public class WebDavWagonTest
         return ( file.lastModified() / 1000 ) * 1000;
     }
 
-    
+
     private File getDavRepository()
     {
         return getTestFile( 
"target/test-output/http-repository/newfolder/folder2" );
@@ -134,8 +138,9 @@ public class WebDavWagonTest
         assertURL( "dav+https://localhost:"; + getTestRepositoryPort() + 
"/dav/",
                    "https://localhost:"; + getTestRepositoryPort() + "/dav/" );
     }
-    
-    public void testMkdirs() throws Exception
+
+    public void testMkdirs()
+        throws Exception
     {
         setupRepositories();
 
@@ -143,33 +148,33 @@ public class WebDavWagonTest
 
         WebDavWagon wagon = (WebDavWagon) getWagon();
         wagon.connect( testRepository, getAuthInfo() );
-        
+
         try
         {
             File dir = getRepositoryDirectory();
-            
+
             // check basedir also doesn't exist and will need to be created
             dir = new File( dir, testRepository.getBasedir() );
             assertFalse( dir.exists() );
-            
+
             // test leading /
             assertFalse( new File( dir, "foo" ).exists() );
             wagon.mkdirs( "/foo" );
             assertTrue( new File( dir, "foo" ).exists() );
-            
+
             // test trailing /
             assertFalse( new File( dir, "bar" ).exists() );
             wagon.mkdirs( "bar/" );
             assertTrue( new File( dir, "bar" ).exists() );
-            
+
             // test when already exists
             wagon.mkdirs( "bar" );
-            
+
             // test several parts
             assertFalse( new File( dir, "1/2/3/4" ).exists() );
             wagon.mkdirs( "1/2/3/4" );
             assertTrue( new File( dir, "1/2/3/4" ).exists() );
-            
+
             // test additional part and trailing /
             assertFalse( new File( dir, "1/2/3/4/5" ).exists() );
             wagon.mkdirs( "1/2/3/4/5/" );
@@ -178,12 +183,13 @@ public class WebDavWagonTest
         finally
         {
             wagon.disconnect();
-            
+
             tearDownWagonTestingFixtures();
         }
     }
 
-    public void testMkdirsWithNoBasedir() throws Exception
+    public void testMkdirsWithNoBasedir()
+        throws Exception
     {
         // WAGON-244
         setupRepositories();
@@ -191,29 +197,29 @@ public class WebDavWagonTest
         setupWagonTestingFixtures();
 
         // reconstruct with no basedir
-        testRepository.setUrl( testRepository.getProtocol() + "://" + 
testRepository.getHost() + ":"
-            + testRepository.getPort() );
+        testRepository.setUrl(
+            testRepository.getProtocol() + "://" + testRepository.getHost() + 
":" + testRepository.getPort() );
 
         WebDavWagon wagon = (WebDavWagon) getWagon();
         wagon.connect( testRepository, getAuthInfo() );
-        
+
         try
         {
             File dir = getRepositoryDirectory();
-            
+
             // check basedir also doesn't exist and will need to be created
             dir = new File( dir, testRepository.getBasedir() );
             assertTrue( dir.exists() );
-            
+
             // test leading /
             assertFalse( new File( dir, "foo" ).exists() );
             wagon.mkdirs( "/foo" );
-            assertTrue( new File( dir, "foo" ).exists() );            
+            assertTrue( new File( dir, "foo" ).exists() );
         }
         finally
         {
             wagon.disconnect();
-            
+
             tearDownWagonTestingFixtures();
         }
     }
@@ -225,6 +231,7 @@ public class WebDavWagonTest
 
     /**
      * Make sure wagon webdav can detect remote directory
+     *
      * @throws Exception
      */
     public void testWagonWebDavGetFileList()
@@ -236,20 +243,15 @@ public class WebDavWagonTest
 
         String dirName = "file-list";
 
-        String filenames[] = new String[] {
-            "test-resource.txt",
-            "test-resource.pom",
-            "test-resource b.txt",
-            "more-resources.dat" };
+        String filenames[] =
+            new String[]{ "test-resource.txt", "test-resource.pom", 
"test-resource b.txt", "more-resources.dat" };
 
         for ( int i = 0; i < filenames.length; i++ )
         {
             putFile( dirName + "/" + filenames[i], dirName + "/" + 
filenames[i], filenames[i] + "\n" );
         }
 
-        String dirnames[] = new String[] {
-            "test-dir1",
-            "test-dir2"};
+        String dirnames[] = new String[]{ "test-dir1", "test-dir2" };
 
         for ( int i = 0; i < dirnames.length; i++ )
         {
@@ -293,11 +295,10 @@ public class WebDavWagonTest
         }
         catch ( ResourceDoesNotExistException e )
         {
-        
+
         }
-        
+
         wagon.disconnect();
-        
 
         tearDownWagonTestingFixtures();
     }
@@ -328,4 +329,99 @@ public class WebDavWagonTest
 
         }
     }
+
+    public void testWagonFailsOnPutFailureByDefault()
+        throws Exception
+    {
+        setupRepositories();
+
+        setupWagonTestingFixtures();
+
+        File testFile = getTempFile();
+
+        System.clearProperty( WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY );
+
+        WebDavWagon wagon = new TimeoutSimulatingWagon();
+        wagon.connect( testRepository, getAuthInfo() );
+
+        try
+        {
+            String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
+
+            try
+            {
+                wagon.put( testFile, filename );
+                fail( "Exception expected" );
+            }
+            catch ( TransferFailedException e )
+            {
+
+            }
+        }
+        finally
+        {
+            wagon.disconnect();
+
+            tearDownWagonTestingFixtures();
+        }
+    }
+
+    private File getTempFile()
+        throws IOException
+    {
+        File inputFile = File.createTempFile( "test-resource", ".txt" );
+        inputFile.deleteOnExit();
+        return inputFile;
+    }
+
+    private static class TimeoutSimulatingWagon
+        extends WebDavWagon
+    {
+        private static final String TIMEOUT_TRIGGER = "timeout";
+
+        protected int execute( HttpMethod httpMethod )
+            throws HttpException, IOException
+        {
+            if ( httpMethod.getPath().contains( TIMEOUT_TRIGGER ) )
+            {
+                throw new SocketTimeoutException( "Timeout triggered by 
request for '" + httpMethod.getPath() + "'" );
+            }
+            else
+            {
+                return super.execute( httpMethod );
+            }
+        }
+    }
+
+    public void testWagonContinuesOnPutFailureIfPropertySet()
+        throws Exception
+    {
+        setupRepositories();
+
+        setupWagonTestingFixtures();
+
+        File testFile = getTempFile();
+
+        String continueOnFailureProperty = 
WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY;
+        System.setProperty( continueOnFailureProperty, "true" );
+
+        WebDavWagon wagon = new TimeoutSimulatingWagon();
+        wagon.connect( testRepository, getAuthInfo() );
+
+        try
+        {
+            String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
+
+            wagon.put( testFile, filename );
+        }
+        finally
+        {
+            wagon.disconnect();
+
+            System.clearProperty( continueOnFailureProperty );
+
+            tearDownWagonTestingFixtures();
+        }
+    }
+
 }


Reply via email to