You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wagon-commits@maven.apache.org by br...@apache.org on 2008/06/02 15:04:11 UTC

svn commit: r662418 - in /maven/wagon/trunk: wagon-provider-api/src/main/java/org/apache/maven/wagon/ wagon-provider-test/src/main/java/org/apache/maven/wagon/ wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/ wagon-p...

Author: brett
Date: Mon Jun  2 06:04:10 2008
New Revision: 662418

URL: http://svn.apache.org/viewvc?rev=662418&view=rev
Log:
[WAGON-101] streaming ssh provider

Removed:
    maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/AbstractSshWagon.java
Modified:
    maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
    maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/StreamWagon.java
    maven/wagon/trunk/wagon-provider-test/src/main/java/org/apache/maven/wagon/StreamingWagonTestCase.java
    maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/LSParser.java
    maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/ScpHelper.java
    maven/wagon/trunk/wagon-providers/wagon-ssh-external/src/main/java/org/apache/maven/wagon/providers/ssh/external/ScpExternalWagon.java
    maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/AbstractJschWagon.java
    maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java
    maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagon.java
    maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonTest.java
    maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonWithSshPrivateKeySearchTest.java
    maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagonTest.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=662418&r1=662417&r2=662418&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 Mon Jun  2 06:04:10 2008
@@ -345,10 +345,6 @@
     protected void putTransfer( Resource resource, File source, OutputStream output, boolean closeOutput )
         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
     {
-        resource.setContentLength( source.length() );
-
-        resource.setLastModified( source.lastModified() );
-
         firePutStarted( resource, source );
 
         transfer( resource, source, output, closeOutput );
@@ -773,54 +769,6 @@
         return false;
     }
 
-    public void createZip( List files, File zipName, File basedir )
-        throws IOException
-    {
-        ZipOutputStream zos = new ZipOutputStream( new FileOutputStream( zipName ) );
-
-        try
-        {
-            for ( int i = 0; i < files.size(); i++ )
-            {
-                String file = (String) files.get( i );
-
-                file = file.replace( '\\', '/' );
-
-                writeZipEntry( zos, new File( basedir, file ), file );
-            }
-        }
-        finally
-        {
-            IOUtil.close( zos );
-        }
-    }
-
-    private void writeZipEntry( ZipOutputStream jar, File source, String entryName )
-        throws IOException
-    {
-        byte[] buffer = new byte[1024];
-
-        int bytesRead;
-
-        FileInputStream is = new FileInputStream( source );
-
-        try
-        {
-            ZipEntry entry = new ZipEntry( entryName );
-
-            jar.putNextEntry( entry );
-
-            while ( ( bytesRead = is.read( buffer ) ) != -1 )
-            {
-                jar.write( buffer, 0, bytesRead );
-            }
-        }
-        finally
-        {
-            is.close();
-        }
-    }
-
     protected static String getPath( String basedir, String dir )
     {
         String path;

Modified: maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/StreamWagon.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/StreamWagon.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/StreamWagon.java (original)
+++ maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/StreamWagon.java Mon Jun  2 06:04:10 2008
@@ -137,6 +137,10 @@
 
         firePutInitiated( resource, source );
 
+        resource.setContentLength( source.length() );
+
+        resource.setLastModified( source.lastModified() );
+
         OutputStream os = getOutputStream( resource );
 
         checkOutputStream( resource, os );
@@ -175,8 +179,7 @@
             throw e;
         }
 
-        OutputStream os = outputData.getOutputStream();
-        return os;
+        return outputData.getOutputStream();
     }
 
     public boolean getIfNewerToStream( String resourceName, OutputStream stream, long timestamp )

Modified: maven/wagon/trunk/wagon-provider-test/src/main/java/org/apache/maven/wagon/StreamingWagonTestCase.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-provider-test/src/main/java/org/apache/maven/wagon/StreamingWagonTestCase.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-provider-test/src/main/java/org/apache/maven/wagon/StreamingWagonTestCase.java (original)
+++ maven/wagon/trunk/wagon-provider-test/src/main/java/org/apache/maven/wagon/StreamingWagonTestCase.java Mon Jun  2 06:04:10 2008
@@ -100,37 +100,38 @@
     public void testWagonGetIfNewerToStreamIsNewer()
         throws Exception
     {
-        setupRepositories();
-
-        setupWagonTestingFixtures();
-
-        int expectedSize = putFile();
-
-        getIfNewerToStream( sourceFile.lastModified() + 30000, false, expectedSize );
+        if ( supportsGetIfNewer() )
+        {
+            setupRepositories();
+            setupWagonTestingFixtures();
+            int expectedSize = putFile();
+            getIfNewerToStream( sourceFile.lastModified() + 30000, false, expectedSize );
+        }
     }
 
     public void testWagonGetIfNewerToStreamIsOlder()
         throws Exception
     {
-        setupRepositories();
-
-        setupWagonTestingFixtures();
-
-        int expectedSize = putFile();
-
-        getIfNewerToStream( new SimpleDateFormat( "yyyy-MM-dd" ).parse( "2006-01-01" ).getTime(), true, expectedSize );
+        if ( supportsGetIfNewer() )
+        {
+            setupRepositories();
+            setupWagonTestingFixtures();
+            int expectedSize = putFile();
+            getIfNewerToStream( new SimpleDateFormat( "yyyy-MM-dd" ).parse( "2006-01-01" ).getTime(), true,
+                                expectedSize );
+        }
     }
 
     public void testWagonGetIfNewerToStreamIsSame()
         throws Exception
     {
-        setupRepositories();
-
-        setupWagonTestingFixtures();
-
-        int expectedSize = putFile();
-
-        getIfNewerToStream( sourceFile.lastModified(), false, expectedSize );
+        if ( supportsGetIfNewer() )
+        {
+            setupRepositories();
+            setupWagonTestingFixtures();
+            int expectedSize = putFile();
+            getIfNewerToStream( sourceFile.lastModified(), false, expectedSize );
+        }
     }
 
     private void getIfNewerToStream( long timestamp, boolean expectedResult, int expectedSize )

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/LSParser.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/LSParser.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/LSParser.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/LSParser.java Mon Jun  2 06:04:10 2008
@@ -19,9 +19,6 @@
  * under the License.
  */
 
-import org.apache.maven.wagon.TransferFailedException;
-import org.codehaus.plexus.util.StringUtils;
-
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.StringReader;
@@ -30,6 +27,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.maven.wagon.TransferFailedException;
+
 /**
  * LSParser 
  *

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/ScpHelper.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/ScpHelper.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/ScpHelper.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh-common/src/main/java/org/apache/maven/wagon/providers/ssh/ScpHelper.java Mon Jun  2 06:04:10 2008
@@ -19,19 +19,304 @@
  * under the License.
  */
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
 import org.apache.maven.wagon.CommandExecutionException;
 import org.apache.maven.wagon.CommandExecutor;
+import org.apache.maven.wagon.PathUtils;
 import org.apache.maven.wagon.PermissionModeUtils;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.Streams;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.repository.Repository;
 import org.apache.maven.wagon.repository.RepositoryPermissions;
+import org.apache.maven.wagon.resource.Resource;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
 
 public class ScpHelper
 {
-    private ScpHelper()
+    public static final char PATH_SEPARATOR = '/';
+
+    public static final int DEFAULT_SSH_PORT = 22;
+    
+    private final CommandExecutor executor;
+    
+    public ScpHelper( CommandExecutor executor )
+    {
+        this.executor = executor;
+    }
+
+    public static String getResourceDirectory( String resourceName )
+    {
+        String dir = PathUtils.dirname( resourceName );
+        dir = StringUtils.replace( dir, "\\", "/" );
+        return dir;
+    }
+
+    public static String getResourceFilename( String r )
+    {
+        String filename;
+        if ( r.lastIndexOf( PATH_SEPARATOR ) > 0 )
+        {
+            filename = r.substring( r.lastIndexOf( PATH_SEPARATOR ) + 1 );
+        }
+        else
+        {
+            filename = r;
+        }
+        return filename;
+    }
+
+    public static Resource getResource( String resourceName )
+    {
+        String r = StringUtils.replace( resourceName, "\\", "/" );
+        return new Resource( r );
+    }
+
+    public static File getPrivateKey( AuthenticationInfo authenticationInfo )
+        throws FileNotFoundException
+    {
+        // If user don't define a password, he want to use a private key
+        File privateKey = null;
+        if ( authenticationInfo.getPassword() == null )
+        {
+
+            if ( authenticationInfo.getPrivateKey() != null )
+            {
+                privateKey = new File( authenticationInfo.getPrivateKey() );
+                if ( !privateKey.exists() )
+                {
+                    throw new FileNotFoundException( "Private key '" + privateKey + "' not found" );
+                }
+            }
+            else
+            {
+                privateKey = findPrivateKey();
+            }
+
+            if ( privateKey != null && privateKey.exists() )
+            {
+                if ( authenticationInfo.getPassphrase() == null )
+                {
+                    authenticationInfo.setPassphrase( "" );
+                }
+            }
+        }
+        return privateKey;
+    }
+
+    private static File findPrivateKey()
+    {
+        String privateKeyDirectory = System.getProperty( "wagon.privateKeyDirectory" );
+
+        if ( privateKeyDirectory == null )
+        {
+            privateKeyDirectory = System.getProperty( "user.home" );
+        }
+
+        File privateKey = new File( privateKeyDirectory, ".ssh/id_dsa" );
+
+        if ( !privateKey.exists() )
+        {
+            privateKey = new File( privateKeyDirectory, ".ssh/id_rsa" );
+            if ( !privateKey.exists() )
+            {
+                privateKey = null;
+            }
+        }
+
+        return privateKey;
+    }
+    
+    public static void createZip( List files, File zipName, File basedir )
+        throws IOException
+    {
+        ZipOutputStream zos = new ZipOutputStream( new FileOutputStream( zipName ) );
+
+        try
+        {
+            for ( int i = 0; i < files.size(); i++ )
+            {
+                String file = (String) files.get( i );
+
+                file = file.replace( '\\', '/' );
+
+                writeZipEntry( zos, new File( basedir, file ), file );
+            }
+        }
+        finally
+        {
+            IOUtil.close( zos );
+        }
+    }
+
+    private static void writeZipEntry( ZipOutputStream jar, File source, String entryName )
+        throws IOException
+    {
+        byte[] buffer = new byte[1024];
+
+        int bytesRead;
+
+        FileInputStream is = new FileInputStream( source );
+
+        try
+        {
+            ZipEntry entry = new ZipEntry( entryName );
+
+            jar.putNextEntry( entry );
+
+            while ( ( bytesRead = is.read( buffer ) ) != -1 )
+            {
+                jar.write( buffer, 0, bytesRead );
+            }
+        }
+        finally
+        {
+            is.close();
+        }
+    }
+
+    protected static String getPath( String basedir, String dir )
+    {
+        String path;
+        path = basedir;
+        if ( !basedir.endsWith( "/" ) && !dir.startsWith( "/" ) )
+        {
+            path += "/";
+        }
+        path += dir;
+        return path;
+    }
+
+    public void putDirectory( Wagon wagon, File sourceDirectory, String destinationDirectory )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
+        Repository repository = wagon.getRepository();
+        
+        String basedir = repository.getBasedir();
+
+        String destDir = StringUtils.replace( destinationDirectory, "\\", "/" );
+
+        String path = getPath( basedir, destDir );
+        try
+        {
+            if ( repository.getPermissions() != null )
+            {
+                String dirPerms = repository.getPermissions().getDirectoryMode();
+
+                if ( dirPerms != null )
+                {
+                    String umaskCmd = "umask " + PermissionModeUtils.getUserMaskFor( dirPerms );
+                    executor.executeCommand( umaskCmd );
+                }
+            }
+
+            String mkdirCmd = "mkdir -p " + path;
+
+            executor.executeCommand( mkdirCmd );
+        }
+        catch ( CommandExecutionException e )
+        {
+            throw new TransferFailedException( "Error performing commands for file transfer", e );
+        }
+
+        File zipFile;
+        try
+        {
+            zipFile = File.createTempFile( "wagon", ".zip" );
+            zipFile.deleteOnExit();
+
+            List files = FileUtils.getFileNames( sourceDirectory, "**/**", "", false );
+
+            createZip( files, zipFile, sourceDirectory );
+        }
+        catch ( IOException e )
+        {
+            throw new TransferFailedException( "Unable to create ZIP archive of directory", e );
+        }
+
+        wagon.put( zipFile, getPath( destDir, zipFile.getName() ) );
+
+        try
+        {
+            executor.executeCommand( "cd " + path + "; unzip -q -o " + zipFile.getName() + "; rm -f " + zipFile.getName() );
+
+            zipFile.delete();
+
+            RepositoryPermissions permissions = repository.getPermissions();
+
+            if ( permissions != null && permissions.getGroup() != null )
+            {
+                executor.executeCommand( "chgrp -Rf " + permissions.getGroup() + " " + path );
+            }
+
+            if ( permissions != null && permissions.getFileMode() != null )
+            {
+                executor.executeCommand( "chmod -Rf " + permissions.getFileMode() + " " + path );
+            }
+        }
+        catch ( CommandExecutionException e )
+        {
+            throw new TransferFailedException( "Error performing commands for file transfer", e );
+        }
+    }
+
+    public List getFileList( String destinationDirectory, Repository repository )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        try
+        {
+            String path = getPath( repository.getBasedir(), destinationDirectory );
+            Streams streams = executor.executeCommand( "ls -la " + path, false );
+            
+            return new LSParser().parseFiles( streams.getOut() );
+        }
+        catch ( CommandExecutionException e )
+        {
+            if ( e.getMessage().trim().endsWith( "No such file or directory" ) )
+            {
+                throw new ResourceDoesNotExistException( e.getMessage().trim() );
+            }
+            else
+            {
+                throw new TransferFailedException( "Error performing file listing.", e );
+            }
+        }
+    }
+
+    public boolean resourceExists( String resourceName, Repository repository )
+        throws TransferFailedException, AuthorizationException
+    {
+        try
+        {
+            String path = getPath( repository.getBasedir(), resourceName );
+            executor.executeCommand( "ls " + path );
+
+            // Parsing of output not really needed.  As a failed ls results in a
+            // CommandExectionException on the 'ls' command.
+
+            return true;
+        }
+        catch ( CommandExecutionException e )
+        {
+            // Error?  Then the 'ls' command failed.  No such file found.
+            return false;
+        }
     }
 
-    public static void createRemoteDirectories( String path, RepositoryPermissions permissions,
-                                                CommandExecutor commandExecutor )
+    public void createRemoteDirectories( String path, RepositoryPermissions permissions )
         throws CommandExecutionException
     {
         String umaskCmd = null;
@@ -52,6 +337,6 @@
             mkdirCmd = umaskCmd + "; " + mkdirCmd;
         }
 
-        commandExecutor.executeCommand( mkdirCmd );
+        executor.executeCommand( mkdirCmd );
     }
 }

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh-external/src/main/java/org/apache/maven/wagon/providers/ssh/external/ScpExternalWagon.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh-external/src/main/java/org/apache/maven/wagon/providers/ssh/external/ScpExternalWagon.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh-external/src/main/java/org/apache/maven/wagon/providers/ssh/external/ScpExternalWagon.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh-external/src/main/java/org/apache/maven/wagon/providers/ssh/external/ScpExternalWagon.java Mon Jun  2 06:04:10 2008
@@ -21,16 +21,22 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.util.List;
 
+import org.apache.maven.wagon.AbstractWagon;
 import org.apache.maven.wagon.CommandExecutionException;
+import org.apache.maven.wagon.CommandExecutor;
 import org.apache.maven.wagon.PathUtils;
 import org.apache.maven.wagon.PermissionModeUtils;
 import org.apache.maven.wagon.ResourceDoesNotExistException;
 import org.apache.maven.wagon.Streams;
 import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.WagonConstants;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
 import org.apache.maven.wagon.authorization.AuthorizationException;
 import org.apache.maven.wagon.events.TransferEvent;
-import org.apache.maven.wagon.providers.ssh.AbstractSshWagon;
+import org.apache.maven.wagon.providers.ssh.ScpHelper;
 import org.apache.maven.wagon.repository.RepositoryPermissions;
 import org.apache.maven.wagon.resource.Resource;
 import org.codehaus.plexus.util.StringUtils;
@@ -51,7 +57,8 @@
  *   instantiation-strategy="per-lookup"
  */
 public class ScpExternalWagon
-    extends AbstractSshWagon
+    extends AbstractWagon
+    implements CommandExecutor
 {
     /**
      * The external SCP command to use - default is <code>scp</code>.
@@ -81,12 +88,28 @@
      */
     private String sshArgs;
 
+    private ScpHelper sshTool = new ScpHelper( this );
+
     private static final int SSH_FATAL_EXIT_CODE = 255;
 
     // ----------------------------------------------------------------------
     //
     // ----------------------------------------------------------------------
 
+    protected void openConnectionInternal()
+        throws AuthenticationException
+    {
+        if ( authenticationInfo == null )
+        {
+            authenticationInfo = new AuthenticationInfo();
+        }
+    }
+
+    public void closeConnection()
+    {
+        // nothing to disconnect
+    }
+
     public boolean getIfNewer( String resourceName, File destination, long timestamp )
         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
@@ -117,6 +140,14 @@
         }
     }
     
+    public void executeCommand( String command )
+        throws CommandExecutionException
+    {
+        fireTransferDebug( "Executing command: " + command );
+
+        executeCommand( command, false );
+    }
+
     public Streams executeCommand( String command, boolean ignoreFailures )
         throws CommandExecutionException
     {
@@ -125,7 +156,7 @@
         File privateKey;
         try
         {
-            privateKey = getPrivateKey();
+            privateKey = ScpHelper.getPrivateKey( authenticationInfo );
         }
         catch ( FileNotFoundException e )
         {
@@ -133,8 +164,9 @@
         }
         Commandline cl = createBaseCommandLine( putty, sshExecutable, privateKey );
 
-        int port = getPort();
-        if ( port != DEFAULT_SSH_PORT )
+        int port =
+            repository.getPort() == WagonConstants.UNKNOWN_PORT ? ScpHelper.DEFAULT_SSH_PORT : repository.getPort();
+        if ( port != ScpHelper.DEFAULT_SSH_PORT )
         {
             if ( putty )
             {
@@ -225,7 +257,7 @@
         File privateKey;
         try
         {
-            privateKey = getPrivateKey();
+            privateKey = ScpHelper.getPrivateKey( authenticationInfo );
         }
         catch ( FileNotFoundException e )
         {
@@ -237,8 +269,9 @@
 
         cl.setWorkingDirectory( localFile.getParentFile().getAbsolutePath() );
 
-        int port = getPort();
-        if ( port != DEFAULT_SSH_PORT )
+        int port =
+            repository.getPort() == WagonConstants.UNKNOWN_PORT ? ScpHelper.DEFAULT_SSH_PORT : repository.getPort();
+        if ( port != ScpHelper.DEFAULT_SSH_PORT )
         {
             cl.createArgument().setLine( "-P " + port );
         }
@@ -384,12 +417,6 @@
         firePutCompleted( resource, source );
     }
 
-    public void executeCommand( String command )
-        throws CommandExecutionException
-    {
-        executeCommand( command, false );
-    }
-
     public void get( String resourceName, File destination )
         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
@@ -417,6 +444,29 @@
     // method on a Wagon.
     //
 
+    public List getFileList( String destinationDirectory )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        return sshTool.getFileList( destinationDirectory, repository );
+    }
+
+    public void putDirectory( File sourceDirectory, String destinationDirectory )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        sshTool.putDirectory( this, sourceDirectory, destinationDirectory );
+    }
+
+    public boolean resourceExists( String resourceName )
+        throws TransferFailedException, AuthorizationException
+    {
+        return sshTool.resourceExists( resourceName, repository );
+    }
+
+    public boolean supportsDirectoryCopy()
+    {
+        return true;
+    }
+
     public String getScpExecutable()
     {
         return scpExecutable;

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/AbstractJschWagon.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/AbstractJschWagon.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/AbstractJschWagon.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/AbstractJschWagon.java Mon Jun  2 06:04:10 2008
@@ -27,16 +27,22 @@
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.List;
 import java.util.Properties;
 
 import org.apache.maven.wagon.CommandExecutionException;
+import org.apache.maven.wagon.CommandExecutor;
 import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.StreamWagon;
 import org.apache.maven.wagon.Streams;
 import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.WagonConstants;
 import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.authorization.AuthorizationException;
 import org.apache.maven.wagon.events.TransferEvent;
-import org.apache.maven.wagon.providers.ssh.AbstractSshWagon;
 import org.apache.maven.wagon.providers.ssh.CommandExecutorStreamProcessor;
+import org.apache.maven.wagon.providers.ssh.ScpHelper;
 import org.apache.maven.wagon.providers.ssh.SshWagon;
 import org.apache.maven.wagon.providers.ssh.interactive.InteractiveUserInfo;
 import org.apache.maven.wagon.providers.ssh.interactive.NullInteractiveUserInfo;
@@ -67,9 +73,11 @@
  * @version $Id$
  */
 public abstract class AbstractJschWagon
-    extends AbstractSshWagon
-    implements SshWagon
+    extends StreamWagon
+    implements SshWagon, CommandExecutor
 {
+    protected ScpHelper sshTool = new ScpHelper( this );
+    
     protected Session session;
     
     /**
@@ -94,7 +102,10 @@
     public void openConnectionInternal()
         throws AuthenticationException
     {
-        super.openConnectionInternal();
+        if ( authenticationInfo == null )
+        {
+            authenticationInfo = new AuthenticationInfo();
+        }
 
         if ( !interactive )
         {
@@ -107,7 +118,7 @@
         File privateKey;
         try
         {
-            privateKey = getPrivateKey();
+            privateKey = ScpHelper.getPrivateKey( authenticationInfo );
         }
         catch ( FileNotFoundException e )
         {
@@ -116,6 +127,7 @@
 
         if ( privateKey != null && privateKey.exists() )
         {
+            fireSessionDebug( "Using private key: " + privateKey );
             try
             {
                 sch.addIdentity( privateKey.getAbsolutePath(), authenticationInfo.getPassphrase() );
@@ -127,7 +139,8 @@
         }
 
         String host = getRepository().getHost();
-        int port = getPort();
+        int port =
+            repository.getPort() == WagonConstants.UNKNOWN_PORT ? ScpHelper.DEFAULT_SSH_PORT : repository.getPort();
         try
         {
             String userName = authenticationInfo.getUserName();
@@ -262,8 +275,6 @@
 
     public void closeConnection()
     {
-        super.closeConnection();
-        
         if ( session != null )
         {
             session.disconnect();
@@ -320,24 +331,47 @@
         }
     }
 
-    protected void handleGetException( Resource resource, Exception e, File destination )
-        throws TransferFailedException, ResourceDoesNotExistException
+    protected void handleGetException( Resource resource, Exception e )
+        throws TransferFailedException
     {
         fireTransferError( resource, e, TransferEvent.REQUEST_GET );
 
-        if ( destination.exists() )
-        {
-            boolean deleted = destination.delete();
+        String msg =
+            "Error occured while downloading '" + resource + "' from the remote repository:" + getRepository() + ": "
+                + e.getMessage();
 
-            if ( !deleted )
-            {
-                destination.deleteOnExit();
-            }
-        }
+        throw new TransferFailedException( msg, e );
+    }
 
-        String msg = "Error occured while downloading '" + resource + "' from the remote repository:" + getRepository() + ": " + e.getMessage();
+    public List getFileList( String destinationDirectory )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        return sshTool.getFileList( destinationDirectory, repository );
+    }
 
-        throw new TransferFailedException( msg, e );
+    public void putDirectory( File sourceDirectory, String destinationDirectory )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        sshTool.putDirectory( this, sourceDirectory, destinationDirectory );
+    }
+
+    public boolean resourceExists( String resourceName )
+        throws TransferFailedException, AuthorizationException
+    {
+        return sshTool.resourceExists( resourceName, repository );
+    }
+
+    public boolean supportsDirectoryCopy()
+    {
+        return true;
+    }
+
+    public void executeCommand( String command )
+        throws CommandExecutionException
+    {
+        fireTransferDebug( "Executing command: " + command );
+
+        executeCommand( command, false );
     }
 
     public InteractiveUserInfo getInteractiveUserInfo()

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java Mon Jun  2 06:04:10 2008
@@ -19,9 +19,14 @@
  * under the License.
  */
 
-import com.jcraft.jsch.ChannelExec;
-import com.jcraft.jsch.JSchException;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
 import org.apache.maven.wagon.CommandExecutionException;
+import org.apache.maven.wagon.InputData;
+import org.apache.maven.wagon.OutputData;
 import org.apache.maven.wagon.ResourceDoesNotExistException;
 import org.apache.maven.wagon.TransferFailedException;
 import org.apache.maven.wagon.authorization.AuthorizationException;
@@ -31,22 +36,14 @@
 import org.apache.maven.wagon.resource.Resource;
 import org.codehaus.plexus.util.IOUtil;
 
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSchException;
 
 /**
- * SFTP protocol wagon.
- * 
- * A base class for deployers and fetchers using protocols from SSH2 family and
- * JSch library for underlying implementation.
- * 
- * This is responsible for authentification stage of the process.
+ * SCP protocol wagon.
  * 
- * We will first try to use public keys for authentication and if that doesn't
- * work then we fall back to using the login and password.
+ * Note that this implementation is <i>not</i> thread-safe, and multiple channels can not be used on the session at
+ * the same time.
  * 
  * See <a href="http://blogs.sun.com/janp/entry/how_the_scp_protocol_works">http://blogs.sun.com/janp/entry/how_the_scp_protocol_works</a>
  * for information on how the SCP protocol works.
@@ -61,42 +58,21 @@
 public class ScpWagon
     extends AbstractJschWagon
 {
-    public boolean getIfNewer( String resourceName, File destination, long timestamp )
-        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
-    {
-        fireSessionDebug( "getIfNewer in SCP wagon is not supported - performing an unconditional get" );
-        get( resourceName, destination );
-        return true;
-    }
-
-    public void put( File source, String destination )
-        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
-    {
-        String basedir = getRepository().getBasedir();
+    private static final char COPY_START_CHAR = 'C';
 
-        Resource resource = getResource( destination );
+    private static final char ACK_SEPARATOR = ' ';
 
-        String dir = getResourceDirectory( resource.getName() );
+    private static final String END_OF_FILES_MSG = "E\n";
 
-        firePutInitiated( resource, source );
+    private static final int LINE_BUFFER_SIZE = 8192;
 
-        try
-        {
-            ScpHelper.createRemoteDirectories( getPath( basedir, dir ), getRepository().getPermissions(), this );
+    private static final byte LF = '\n';
 
-            RepositoryPermissions permissions = getRepository().getPermissions();
+    private ChannelExec channel;
 
-            put( source, basedir, resource, getOctalMode( permissions ) );
+    private InputStream channelInputStream;
 
-            setFileGroup( permissions, basedir, resource );
-        }
-        catch ( CommandExecutionException e )
-        {
-            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
-            
-            throw new TransferFailedException( e.getMessage(), e );
-        }
-    }
+    private OutputStream channelOutputStream;
 
     private void setFileGroup( RepositoryPermissions permissions, String basedir, Resource resource )
         throws CommandExecutionException
@@ -107,129 +83,48 @@
         }
     }
 
-    public void get( String resourceName, File destination )
-        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
-    {
-        String basedir = getRepository().getBasedir();
-
-        Resource resource = new Resource( resourceName );
-
-        fireGetInitiated( resource, destination );
-
-        get( basedir, resource, destination );
-    }
-
-    private static final char COPY_START_CHAR = 'C';
-
-    private static final char ACK_SEPARATOR = ' ';
-
-    private static final String END_OF_FILES_MSG = "E\n";
-
-    private static final int LINE_BUFFER_SIZE = 8192;
-
-    private static final byte LF = '\n';
-
-    public void put( File source, String basedir, Resource resource, String octalMode )
+    protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput )
         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
     {
-        String path = getPath( basedir, resource.getName() );
-
-        String resourceName = resource.getName();
-
-        ChannelExec channel = null;
-
-        OutputStream out = null;
         try
         {
-            // exec 'scp -p -t rfile' remotely
-            String command = "scp";
-            if ( octalMode != null )
-            {
-                command += " -p";
-            }
-            command += " -t \"" + path + "\"";
-
-            fireTransferDebug( "Executing command: " + command );
-
-            channel = (ChannelExec) session.openChannel( EXEC_CHANNEL );
-
-            channel.setCommand( command );
+            super.putTransfer( resource, input, output, false );
 
-            // get I/O streams for remote scp
-            out = channel.getOutputStream();
-
-            InputStream in = channel.getInputStream();
+            sendEom( output );
 
-            channel.connect();
-
-            checkAck( in );
-
-            // send "C0644 filesize filename", where filename should not include '/'
-            long filesize = source.length();
-
-            String mode = octalMode == null ? "0644" : octalMode;
-            command = "C" + mode + " " + filesize + " ";
-
-            if ( resourceName.lastIndexOf( PATH_SEPARATOR ) > 0 )
-            {
-                command += resourceName.substring( resourceName.lastIndexOf( PATH_SEPARATOR ) + 1 );
-            }
-            else
-            {
-                command += resourceName;
-            }
-
-            command += "\n";
-
-            out.write( command.getBytes() );
-
-            out.flush();
-
-            checkAck( in );
-
-            putTransfer( resource, source, out, false );
-
-            sendEom( out );
-
-            checkAck( in );
+            checkAck( channelInputStream );
 
             // This came from SCPClient in Ganymede SSH2. It is sent after all files.
-            out.write( END_OF_FILES_MSG.getBytes() );
-            out.flush();
+            output.write( END_OF_FILES_MSG.getBytes() );
+            output.flush();
         }
         catch ( IOException e )
         {
-            if ( e.getMessage().indexOf( "set mode: Operation not permitted" ) >= 0 )
+            handleIOException( resource, e );
+        }
+        finally
+        {
+            if ( closeOutput )
             {
-                fireTransferDebug( e.getMessage() );                
+                IOUtil.close( output );
             }
-            else
+            
+            if ( channel != null )
             {
-                fireTransferError( resource, e, TransferEvent.REQUEST_PUT );            
-                
-                String msg = "Error occured while deploying '" + resourceName + "' to remote repository: " +
-                    getRepository().getUrl() + ": " + e.getMessage();
-    
-                throw new TransferFailedException( msg, e );
+                channel.disconnect();
             }
-        }
-        catch ( JSchException e )
-        {
-            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );            
-            
-            String msg = "Error occured while deploying '" + resourceName + "' to remote repository: " +
-                getRepository().getUrl() + ": " + e.getMessage();
+        }        
 
-            throw new TransferFailedException( msg, e );
+        String basedir = getRepository().getBasedir();
+        try
+        {
+            setFileGroup( getRepository().getPermissions(), basedir, resource );
         }
-        finally
+        catch ( CommandExecutionException e )
         {
-            if ( channel != null )
-            {
-                IOUtil.close( out );
+            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
 
-                channel.disconnect();
-            }
+            throw new TransferFailedException( e.getMessage(), e );
         }
     }
 
@@ -255,36 +150,100 @@
         {
             throw new IOException( "SCP terminated with unknown error code" );
         }
+    }    
+    
+    protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
+                                int maxSize )
+        throws TransferFailedException
+    {
+        try
+        {
+            super.getTransfer( resource, output, input, false, (int) resource.getContentLength() );
+
+            checkAck( input );
+
+            sendEom( channelOutputStream );
+        }
+        catch ( IOException e )
+        {
+            handleGetException( resource, e );
+        }
+        finally
+        {
+            if ( closeInput )
+            {
+                IOUtil.close( input );
+            }
+            
+            if ( channel != null )
+            {
+                channel.disconnect();
+            }
+        }
     }
 
-    public void get( String basedir, Resource resource, File destination )
-        throws ResourceDoesNotExistException, TransferFailedException
+    protected String readLine( InputStream in )
+        throws IOException
     {
-        String path = getPath( basedir, resource.getName() );
+        StringBuffer sb = new StringBuffer();
 
-        //I/O streams for remote scp
-        OutputStream out = null;
+        while ( true )
+        {
+            if ( sb.length() > LINE_BUFFER_SIZE )
+            {
+                throw new IOException( "Remote server sent a too long line" );
+            }
 
-        ChannelExec channel = null;
+            int c = in.read();
 
-        try
-        {
-            String cmd = "scp -f " + path;
+            if ( c < 0 )
+            {
+                throw new IOException( "Remote connection terminated unexpectedly." );
+            }
 
-            fireTransferDebug( "Executing command: " + cmd );
+            if ( c == LF )
+            {
+                break;
+            }
 
+            sb.append( (char) c );
+        }
+        return sb.toString();
+    }
+
+    protected static void sendEom( OutputStream out )
+        throws IOException
+    {
+        out.write( 0 );
+
+        out.flush();
+    }
+
+    public void fillInputData( InputData inputData )
+        throws TransferFailedException, ResourceDoesNotExistException
+    {
+        Resource resource = inputData.getResource();
+        
+        String path = getPath( getRepository().getBasedir(), resource.getName() );
+        String cmd = "scp -f " + path;
+
+        fireTransferDebug( "Executing command: " + cmd );
+
+        try
+        {
             channel = (ChannelExec) session.openChannel( EXEC_CHANNEL );
 
             channel.setCommand( cmd );
 
             // get I/O streams for remote scp
-            out = channel.getOutputStream();
-
+            channelOutputStream = channel.getOutputStream();
+            
             InputStream in = channel.getInputStream();
+            inputData.setInputStream( in );
 
             channel.connect();
 
-            sendEom( out );
+            sendEom( channelOutputStream );
 
             int exitCode = in.read();
 
@@ -336,75 +295,148 @@
             String filename = line.substring( index + 1 );
             fireTransferDebug( "Remote filename: " + filename );
 
-            sendEom( out );
+            sendEom( channelOutputStream );
+        }
+        catch ( JSchException e )
+        {
+            handleGetException( resource, e );
+        }
+        catch ( IOException e )
+        {
+            handleGetException( resource, e );
+        }
+    }
+
+    public void fillOutputData( OutputData outputData )
+        throws TransferFailedException
+    {
+        Resource resource = outputData.getResource();
+        
+        String basedir = getRepository().getBasedir();
+
+        String path = getPath( basedir, resource.getName() );
+
+        String dir = ScpHelper.getResourceDirectory( resource.getName() );
+
+        try
+        {
+            sshTool.createRemoteDirectories( getPath( basedir, dir ), getRepository().getPermissions() );
+        }
+        catch ( CommandExecutionException e )
+        {
+            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
+
+            throw new TransferFailedException( e.getMessage(), e );
+        }
+        
+        String octalMode = getOctalMode( getRepository().getPermissions() );
+        
+        // exec 'scp -p -t rfile' remotely
+        String command = "scp";
+        if ( octalMode != null )
+        {
+            command += " -p";
+        }
+        command += " -t \"" + path + "\"";
+
+        fireTransferDebug( "Executing command: " + command );
 
-            getTransfer( resource, destination, in, false, filesize );
+        String resourceName = resource.getName();
 
-            if ( destination.length() != filesize )
+        OutputStream out = null;
+        try
+        {
+            channel = (ChannelExec) session.openChannel( EXEC_CHANNEL );
+
+            channel.setCommand( command );
+
+            // get I/O streams for remote scp
+            out = channel.getOutputStream();
+            outputData.setOutputStream( out );
+
+            channelInputStream = channel.getInputStream();
+
+            channel.connect();
+
+            checkAck( channelInputStream );
+
+            // send "C0644 filesize filename", where filename should not include '/'
+            long filesize = resource.getContentLength();
+
+            String mode = octalMode == null ? "0644" : octalMode;
+            command = "C" + mode + " " + filesize + " ";
+
+            if ( resourceName.lastIndexOf( ScpHelper.PATH_SEPARATOR ) > 0 )
             {
-                throw new IOException(
-                    "Expected file length: " + filesize + "; received = " + destination.length() );
+                command += resourceName.substring( resourceName.lastIndexOf( ScpHelper.PATH_SEPARATOR ) + 1 );
             }
+            else
+            {
+                command += resourceName;
+            }
+
+            command += "\n";
 
-            // TODO: we could possibly have received additional files here
+            out.write( command.getBytes() );
 
-            checkAck( in );
+            out.flush();
 
-            sendEom( out );
+            checkAck( channelInputStream );
         }
         catch ( JSchException e )
         {
-            handleGetException( resource, e, destination );
+            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );            
+            
+            String msg = "Error occured while deploying '" + resourceName + "' to remote repository: " +
+                getRepository().getUrl() + ": " + e.getMessage();
+
+            throw new TransferFailedException( msg, e );
         }
         catch ( IOException e )
         {
-            handleGetException( resource, e, destination );
+            handleIOException( resource, e );
         }
-        finally
-        {
-            IOUtil.close( out );
+    }
 
-            if ( channel != null )
-            {
-                channel.disconnect();
-            }
+    private void handleIOException( Resource resource, IOException e )
+        throws TransferFailedException
+    {
+        if ( e.getMessage().indexOf( "set mode: Operation not permitted" ) >= 0 )
+        {
+            fireTransferDebug( e.getMessage() );                
+        }
+        else
+        {
+            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );            
+            
+            String msg = "Error occured while deploying '" + resource.getName() + "' to remote repository: " +
+                getRepository().getUrl() + ": " + e.getMessage();
+   
+            throw new TransferFailedException( msg, e );
         }
     }
 
-    protected String readLine( InputStream in )
-        throws IOException
+    public String getOctalMode( RepositoryPermissions permissions )
     {
-        StringBuffer sb = new StringBuffer();
-
-        while ( true )
+        String mode = null;
+        if ( permissions != null && permissions.getFileMode() != null )
         {
-            if ( sb.length() > LINE_BUFFER_SIZE )
+            if ( permissions.getFileMode().matches( "[0-9]{3,4}" ) )
             {
-                throw new IOException( "Remote server sent a too long line" );
-            }
+                mode = permissions.getFileMode();
 
-            int c = in.read();
-
-            if ( c < 0 )
-            {
-                throw new IOException( "Remote connection terminated unexpectedly." );
+                if ( mode.length() == 3 )
+                {
+                    mode = "0" + mode;
+                }
             }
-
-            if ( c == LF )
+            else
             {
-                break;
+                // TODO: calculate?
+                // TODO: as warning
+                fireSessionDebug( "Not using non-octal permissions: " + permissions.getFileMode() );
             }
-
-            sb.append( (char) c );
         }
-        return sb.toString();
-    }
-
-    protected static void sendEom( OutputStream out )
-        throws IOException
-    {
-        out.write( 0 );
-
-        out.flush();
+        return mode;
     }
 }

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagon.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagon.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagon.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagon.java Mon Jun  2 06:04:10 2008
@@ -20,6 +20,8 @@
  */
 
 import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -33,6 +35,7 @@
 import org.apache.maven.wagon.authentication.AuthenticationException;
 import org.apache.maven.wagon.authorization.AuthorizationException;
 import org.apache.maven.wagon.events.TransferEvent;
+import org.apache.maven.wagon.providers.ssh.ScpHelper;
 import org.apache.maven.wagon.repository.RepositoryPermissions;
 import org.apache.maven.wagon.resource.Resource;
 
@@ -91,13 +94,19 @@
     }
 
     private void returnToParentDirectory( Resource resource )
-        throws SftpException
     {
-        String dir = getResourceDirectory( resource.getName() );
-        String[] dirs = PathUtils.dirnames( dir );
-        for ( int i = 0; i < dirs.length; i++ )
+        try
         {
-            channel.cd( ".." );
+            String dir = ScpHelper.getResourceDirectory( resource.getName() );
+            String[] dirs = PathUtils.dirnames( dir );
+            for ( int i = 0; i < dirs.length; i++ )
+            {
+                channel.cd( ".." );
+            }
+        }
+        catch ( SftpException e )
+        {
+            fireTransferDebug( "Error returning to parent directory: " + e.getMessage() );
         }
     }
 
@@ -108,7 +117,7 @@
         
         resource.setLastModified( source.lastModified() );
         
-        String filename = getResourceFilename( resource.getName() );
+        String filename = ScpHelper.getResourceFilename( resource.getName() );
 
         firePutStarted( resource, source );
 
@@ -130,7 +139,6 @@
     }
 
     private void setGroup( String filename, RepositoryPermissions permissions )
-        throws SftpException
     {
         try
         {
@@ -142,6 +150,10 @@
             // TODO: warning level
             fireTransferDebug( "Not setting group: must be a numerical GID for SFTP" );
         }
+        catch ( SftpException e )
+        {
+            fireTransferDebug( "Not setting group: " + e.getMessage() );            
+        }
     }
 
     private void setFileMode( String filename, RepositoryPermissions permissions )
@@ -234,56 +246,6 @@
         return attrs;
     }
 
-    public void put( File source, String destination )
-        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
-    {
-        Resource resource = getResource( destination );
-
-        firePutInitiated( resource, source );
-
-        try
-        {
-            RepositoryPermissions permissions = getRepository().getPermissions();
-        
-            preparePut( resource, permissions );
-        
-            putFile( source, resource, permissions );
-        
-            returnToParentDirectory( resource );
-        }
-        catch ( SftpException e )
-        {
-            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
-            
-            String msg = "Error occured while deploying '" + resource.getName() + "' " + "to remote repository: " +
-                getRepository().getUrl();
-        
-            throw new TransferFailedException( msg, e );
-        }
-    }
-
-    private void preparePut( Resource resource, RepositoryPermissions permissions )
-        throws SftpException, TransferFailedException
-    {
-        int directoryMode = getDirectoryMode( getRepository().getPermissions() );
-
-        channel.cd( "/" );
-        
-        try
-        {
-            String basedir = getRepository().getBasedir();
-            mkdirs( basedir + "/", directoryMode );
-            
-            mkdirs( resource.getName(), directoryMode );
-        }
-        catch ( TransferFailedException e )
-        {
-            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
-
-            throw e;
-        }
-    }
-
     public void putDirectory( File sourceDirectory, String destinationDirectory )
         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
@@ -302,7 +264,8 @@
                 + destinationDirectory );
             
             mkdirs( destinationDirectory, directoryMode );
-            ftpRecursivePut( sourceDirectory, null, getResourceFilename( destinationDirectory ), directoryMode );
+            ftpRecursivePut( sourceDirectory, null, ScpHelper.getResourceFilename( destinationDirectory ),
+                             directoryMode );
         }
         catch ( SftpException e )
         {
@@ -352,7 +315,7 @@
         }
         else
         {
-            Resource resource = getResource( getFileName( prefix, fileName ) );
+            Resource resource = ScpHelper.getResource( getFileName( prefix, fileName ) );
 
             firePutInitiated( resource, sourceFile );
 
@@ -376,12 +339,12 @@
     public List getFileList( String destinationDirectory )
         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
-        String filename = getResourceFilename( destinationDirectory );
+        String filename = ScpHelper.getResourceFilename( destinationDirectory );
 
-        String dir = getResourceDirectory( destinationDirectory );
+        String dir = ScpHelper.getResourceDirectory( destinationDirectory );
 
         // we already setuped the root directory. Ignore beginning /
-        if ( dir.length() > 0 && dir.charAt( 0 ) == PATH_SEPARATOR )
+        if ( dir.length() > 0 && dir.charAt( 0 ) == ScpHelper.PATH_SEPARATOR )
         {
             dir = dir.substring( 1 );
         }
@@ -417,12 +380,12 @@
     public boolean resourceExists( String resourceName )
         throws TransferFailedException, AuthorizationException
     {
-        String filename = getResourceFilename( resourceName );
+        String filename = ScpHelper.getResourceFilename( resourceName );
 
-        String dir = getResourceDirectory( resourceName );
+        String dir = ScpHelper.getResourceDirectory( resourceName );
 
         // we already setuped the root directory. Ignore beginning /
-        if ( dir.length() > 0 && dir.charAt( 0 ) == PATH_SEPARATOR )
+        if ( dir.length() > 0 && dir.charAt( 0 ) == ScpHelper.PATH_SEPARATOR )
         {
             dir = dir.substring( 1 );
         }
@@ -447,84 +410,135 @@
         }
     }
 
-    public boolean getIfNewer( String resourceName, File destination, long timestamp )
-        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
+                                int maxSize )
+        throws TransferFailedException
     {
-        createParentDirectories( destination );
+        super.getTransfer( resource, output, input, closeInput, maxSize );
 
-        Resource resource = getResource( resourceName );
+        returnToParentDirectory( resource );
+    }
+    
+    protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput )
+        throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
+    {
+        super.putTransfer( resource, input, output, closeOutput );
 
-        fireGetInitiated( resource, destination );
+        RepositoryPermissions permissions = getRepository().getPermissions();
 
-        String filename = getResourceFilename( resource.getName() );
+        String filename = ScpHelper.getResourceFilename( resource.getName() );
+        if ( permissions != null && permissions.getGroup() != null )
+        {
+            setGroup( filename, permissions );
+        }
+        
+        if ( permissions != null && permissions.getFileMode() != null )
+        {
+            setFileMode( filename, permissions );
+        }
 
-        String dir = getResourceDirectory( resource.getName() );
+        returnToParentDirectory( resource );
+    }
+
+    public void fillInputData( InputData inputData )
+        throws TransferFailedException, ResourceDoesNotExistException
+    {
+        Resource resource = inputData.getResource();
+        
+        String filename = ScpHelper.getResourceFilename( resource.getName() );
+
+        String dir = ScpHelper.getResourceDirectory( resource.getName() );
 
         // we already setuped the root directory. Ignore beginning /
-        if ( dir.length() > 0 && dir.charAt( 0 ) == PATH_SEPARATOR )
+        if ( dir.length() > 0 && dir.charAt( 0 ) == ScpHelper.PATH_SEPARATOR )
         {
             dir = dir.substring( 1 );
         }
 
-        boolean bDownloaded = true;
         try
         {
             SftpATTRS attrs = changeToRepositoryDirectory( dir, filename );
 
             long lastModified = attrs.getMTime() * MILLIS_PER_SEC;
-            if ( timestamp <= 0 || lastModified > timestamp )
-            {
-                resource.setContentLength( attrs.getSize() );
-
-                resource.setLastModified( lastModified );
+            resource.setContentLength( attrs.getSize() );
 
-                fireGetStarted( resource, destination );
+            resource.setLastModified( lastModified );
+            
+            inputData.setInputStream( channel.get( filename ) );
+        }
+        catch ( SftpException e )
+        {
+            handleGetException( resource, e );
+        }
+    }
 
-                channel.get( filename, destination.getAbsolutePath() );
+    public void fillOutputData( OutputData outputData )
+        throws TransferFailedException
+    {
+        int directoryMode = getDirectoryMode( getRepository().getPermissions() );
 
-                postProcessListeners( resource, destination, TransferEvent.REQUEST_GET );
+        Resource resource = outputData.getResource();
+        
+        try
+        {
+            channel.cd( "/" );
 
-                fireGetCompleted( resource, destination );
+            String basedir = getRepository().getBasedir();
+            mkdirs( basedir + "/", directoryMode );
 
-                String[] dirs = PathUtils.dirnames( dir );
+            mkdirs( resource.getName(), directoryMode );
 
-                for ( int i = 0; i < dirs.length; i++ )
-                {
-                    channel.cd( ".." );
-                }
+            String filename = ScpHelper.getResourceFilename( resource.getName() );
+            outputData.setOutputStream( channel.put( filename ) );
+        }
+        catch ( TransferFailedException e )
+        {
+            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
 
-                bDownloaded = true;
-            }
-            else
-            {
-                bDownloaded = false;
-            }
+            throw e;
         }
         catch ( SftpException e )
         {
-            handleGetException( resource, e, destination );
-        }
+            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
 
-        return bDownloaded;
-    }
+            String msg =
+                "Error occured while deploying '" + resource.getName() + "' " + "to remote repository: "
+                    + getRepository().getUrl();
 
-    public void get( String resourceName, File destination )
-        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
-    {
-        getIfNewer( resourceName, destination, 0 );        
+            throw new TransferFailedException( msg, e );
+        }
     }
-
-    public void fillInputData( InputData inputData )
-        throws TransferFailedException, ResourceDoesNotExistException
+    
+    /**
+     * @param permissions repository's permissions
+     * @return the directory mode for the repository or <code>-1</code> if it
+     *         wasn't set
+     */
+    public int getDirectoryMode( RepositoryPermissions permissions )
     {
-        // TODO Auto-generated method stub
-        
+        int ret = -1;
+
+        if ( permissions != null )
+        {
+            ret = getOctalMode( permissions.getDirectoryMode() );
+        }
+
+        return ret;
     }
 
-    public void fillOutputData( OutputData outputData )
-        throws TransferFailedException
+    public int getOctalMode( String mode )
     {
-        // TODO Auto-generated method stub
-        
+        int ret;
+        try
+        {
+            ret = Integer.valueOf( mode, 8 ).intValue();
+        }
+        catch ( NumberFormatException e )
+        {
+            // TODO: warning level
+            fireTransferDebug( "the file mode must be a numerical mode for SFTP" );
+            ret = -1;
+        }
+        return ret;
     }
 }

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonTest.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonTest.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonTest.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonTest.java Mon Jun  2 06:04:10 2008
@@ -21,7 +21,7 @@
 
 import java.io.File;
 
-import org.apache.maven.wagon.WagonTestCase;
+import org.apache.maven.wagon.StreamingWagonTestCase;
 import org.apache.maven.wagon.authentication.AuthenticationInfo;
 import org.apache.maven.wagon.providers.ssh.TestData;
 import org.apache.maven.wagon.repository.Repository;
@@ -32,7 +32,7 @@
  * @version $Id$
  */
 public class ScpWagonTest
-    extends WagonTestCase
+    extends StreamingWagonTestCase
 {
     protected boolean supportsGetIfNewer()
     {

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonWithSshPrivateKeySearchTest.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonWithSshPrivateKeySearchTest.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonWithSshPrivateKeySearchTest.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagonWithSshPrivateKeySearchTest.java Mon Jun  2 06:04:10 2008
@@ -19,7 +19,7 @@
  * under the License.
  */
 
-import org.apache.maven.wagon.WagonTestCase;
+import org.apache.maven.wagon.StreamingWagonTestCase;
 import org.apache.maven.wagon.authentication.AuthenticationInfo;
 import org.apache.maven.wagon.providers.ssh.TestData;
 import org.apache.maven.wagon.repository.Repository;
@@ -30,7 +30,7 @@
  * @version $Id$
  */
 public class ScpWagonWithSshPrivateKeySearchTest
-    extends WagonTestCase
+    extends StreamingWagonTestCase
 {
     protected boolean supportsGetIfNewer()
     {

Modified: maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagonTest.java
URL: http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagonTest.java?rev=662418&r1=662417&r2=662418&view=diff
==============================================================================
--- maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagonTest.java (original)
+++ maven/wagon/trunk/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/SftpWagonTest.java Mon Jun  2 06:04:10 2008
@@ -21,7 +21,7 @@
 
 import java.io.File;
 
-import org.apache.maven.wagon.WagonTestCase;
+import org.apache.maven.wagon.StreamingWagonTestCase;
 import org.apache.maven.wagon.authentication.AuthenticationInfo;
 import org.apache.maven.wagon.providers.ssh.TestData;
 import org.apache.maven.wagon.repository.Repository;
@@ -32,7 +32,7 @@
  * @version $Id$
  */
 public class SftpWagonTest
-    extends WagonTestCase
+    extends StreamingWagonTestCase
 {
     protected String getProtocol()
     {



---------------------------------------------------------------------
To unsubscribe, e-mail: wagon-commits-unsubscribe@maven.apache.org
For additional commands, e-mail: wagon-commits-help@maven.apache.org