package org.apache.maven.wagon;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.events.SessionEvent;
import org.apache.maven.wagon.events.SessionEventSupport;
import org.apache.maven.wagon.events.SessionListener;
import org.apache.maven.wagon.events.TransferEvent;
import org.apache.maven.wagon.events.TransferEventSupport;
import org.apache.maven.wagon.events.TransferListener;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.proxy.ProxyInfoProvider;
import org.apache.maven.wagon.proxy.ProxyUtils;
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.IOUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

Implementation of common facilities for Wagon providers.
Author:Michal Maczka
/** * Implementation of common facilities for Wagon providers. * * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> */
public abstract class AbstractWagon implements Wagon { protected static final int DEFAULT_BUFFER_SIZE = 4 * 1024; protected static final int MAXIMUM_BUFFER_SIZE = 512 * 1024;
To efficiently buffer data, use a multiple of 4 KiB as this is likely to match the hardware buffer size of certain storage devices.
/** * To efficiently buffer data, use a multiple of 4 KiB as this is likely to match the hardware * buffer size of certain storage devices. */
protected static final int BUFFER_SEGMENT_SIZE = 4 * 1024;
The desired minimum amount of chunks in which a Resource shall be transferred. This corresponds to the minimum times fireTransferProgress(TransferEvent, byte[], int) is executed. 100 notifications is a conservative value that will lead to small chunks for any artifact less that BUFFER_SEGMENT_SIZE * MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS in size.
/** * The desired minimum amount of chunks in which a {@link Resource} shall be * {@link #transfer(Resource, InputStream, OutputStream, int, long) transferred}. * This corresponds to the minimum times {@link #fireTransferProgress(TransferEvent, byte[], int)} * is executed. 100 notifications is a conservative value that will lead to small chunks for * any artifact less that {@link #BUFFER_SEGMENT_SIZE} * {@link #MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS} * in size. */
protected static final int MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS = 100; protected Repository repository; protected SessionEventSupport sessionEventSupport = new SessionEventSupport(); protected TransferEventSupport transferEventSupport = new TransferEventSupport(); protected AuthenticationInfo authenticationInfo; protected boolean interactive = true; private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
read timeout value
Since:2.2
/** * read timeout value * * @since 2.2 */
private int readTimeout = Integer.parseInt( System.getProperty( "maven.wagon.rto", Integer.toString( Wagon.DEFAULT_READ_TIMEOUT ) ) ); private ProxyInfoProvider proxyInfoProvider;
Deprecated:
/** * @deprecated */
protected ProxyInfo proxyInfo; private RepositoryPermissions permissionsOverride; // ---------------------------------------------------------------------- // Accessors // ---------------------------------------------------------------------- public Repository getRepository() { return repository; } public ProxyInfo getProxyInfo() { return proxyInfoProvider != null ? proxyInfoProvider.getProxyInfo( null ) : null; } public AuthenticationInfo getAuthenticationInfo() { return authenticationInfo; } // ---------------------------------------------------------------------- // Connection // ---------------------------------------------------------------------- public void openConnection() throws ConnectionException, AuthenticationException { try { openConnectionInternal(); } catch ( ConnectionException e ) { fireSessionConnectionRefused(); throw e; } catch ( AuthenticationException e ) { fireSessionConnectionRefused(); throw e; } } public void connect( Repository repository ) throws ConnectionException, AuthenticationException { connect( repository, null, (ProxyInfoProvider) null ); } public void connect( Repository repository, ProxyInfo proxyInfo ) throws ConnectionException, AuthenticationException { connect( repository, null, proxyInfo ); } public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider ) throws ConnectionException, AuthenticationException { connect( repository, null, proxyInfoProvider ); } public void connect( Repository repository, AuthenticationInfo authenticationInfo ) throws ConnectionException, AuthenticationException { connect( repository, authenticationInfo, (ProxyInfoProvider) null ); } public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo ) throws ConnectionException, AuthenticationException { final ProxyInfo proxy = proxyInfo; connect( repository, authenticationInfo, new ProxyInfoProvider() { public ProxyInfo getProxyInfo( String protocol ) { if ( protocol == null || proxy == null || protocol.equalsIgnoreCase( proxy.getType() ) ) { return proxy; } else { return null; } } } ); } public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfoProvider proxyInfoProvider ) throws ConnectionException, AuthenticationException { if ( repository == null ) { throw new NullPointerException( "repository cannot be null" ); } if ( permissionsOverride != null ) { repository.setPermissions( permissionsOverride ); } this.repository = repository; if ( authenticationInfo == null ) { authenticationInfo = new AuthenticationInfo(); } if ( authenticationInfo.getUserName() == null ) { // Get user/pass that were encoded in the URL. if ( repository.getUsername() != null ) { authenticationInfo.setUserName( repository.getUsername() ); if ( repository.getPassword() != null && authenticationInfo.getPassword() == null ) { authenticationInfo.setPassword( repository.getPassword() ); } } } this.authenticationInfo = authenticationInfo; this.proxyInfoProvider = proxyInfoProvider; fireSessionOpening(); openConnection(); fireSessionOpened(); } protected abstract void openConnectionInternal() throws ConnectionException, AuthenticationException; public void disconnect() throws ConnectionException { fireSessionDisconnecting(); try { closeConnection(); } catch ( ConnectionException e ) { fireSessionError( e ); throw e; } fireSessionDisconnected(); } protected abstract void closeConnection() throws ConnectionException; protected void createParentDirectories( File destination ) throws TransferFailedException { File destinationDirectory = destination.getParentFile(); try { destinationDirectory = destinationDirectory.getCanonicalFile(); } catch ( IOException e ) { // not essential to have a canonical file } if ( destinationDirectory != null && !destinationDirectory.exists() ) { destinationDirectory.mkdirs(); if ( !destinationDirectory.exists() ) { throw new TransferFailedException( "Specified destination directory cannot be created: " + destinationDirectory ); } } } public void setTimeout( int timeoutValue ) { connectionTimeout = timeoutValue; } public int getTimeout() { return connectionTimeout; } // ---------------------------------------------------------------------- // Stream i/o // ---------------------------------------------------------------------- protected void getTransfer( Resource resource, File destination, InputStream input ) throws TransferFailedException { getTransfer( resource, destination, input, true, Long.MAX_VALUE ); } protected void getTransfer( Resource resource, OutputStream output, InputStream input ) throws TransferFailedException { getTransfer( resource, output, input, true, Long.MAX_VALUE ); } @Deprecated protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput, int maxSize ) throws TransferFailedException { getTransfer( resource, destination, input, closeInput, (long) maxSize ); } protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput, long maxSize ) throws TransferFailedException { // ensure that the destination is created only when we are ready to transfer fireTransferDebug( "attempting to create parent directories for destination: " + destination.getName() ); createParentDirectories( destination ); fireGetStarted( resource, destination ); OutputStream output = null; try { output = new LazyFileOutputStream( destination ); getTransfer( resource, output, input, closeInput, maxSize ); output.close(); output = null; } catch ( final IOException e ) { if ( destination.exists() ) { boolean deleted = destination.delete(); if ( !deleted ) { destination.deleteOnExit(); } } fireTransferError( resource, e, TransferEvent.REQUEST_GET ); String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed"; throw new TransferFailedException( msg, e ); } catch ( TransferFailedException e ) { if ( destination.exists() ) { boolean deleted = destination.delete(); if ( !deleted ) { destination.deleteOnExit(); } } throw e; } finally { IOUtil.close( output ); } fireGetCompleted( resource, destination ); } @Deprecated protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput, int maxSize ) throws TransferFailedException { getTransfer( resource, output, input, closeInput, (long) maxSize ); } protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput, long maxSize ) throws TransferFailedException { try { transfer( resource, input, output, TransferEvent.REQUEST_GET, maxSize ); finishGetTransfer( resource, input, output ); if ( closeInput ) { input.close(); input = null; } } catch ( IOException e ) { fireTransferError( resource, e, TransferEvent.REQUEST_GET ); String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed"; throw new TransferFailedException( msg, e ); } finally { if ( closeInput ) { IOUtil.close( input ); } cleanupGetTransfer( resource ); } } protected void finishGetTransfer( Resource resource, InputStream input, OutputStream output ) throws TransferFailedException { } protected void cleanupGetTransfer( Resource resource ) { } protected void putTransfer( Resource resource, File source, OutputStream output, boolean closeOutput ) throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException { firePutStarted( resource, source ); transfer( resource, source, output, closeOutput ); firePutCompleted( resource, source ); }
Write from File to OutputStream
Params:
  • resource – resource to transfer
  • source – file to read from
  • output – output stream
  • closeOutput – whether the output stream should be closed or not
Throws:
Since:1.0-beta-1
/** * Write from {@link File} to {@link OutputStream} * * @param resource resource to transfer * @param source file to read from * @param output output stream * @param closeOutput whether the output stream should be closed or not * @throws TransferFailedException * @throws ResourceDoesNotExistException * @throws AuthorizationException * @since 1.0-beta-1 */
protected void transfer( Resource resource, File source, OutputStream output, boolean closeOutput ) throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException { InputStream input = null; try { input = new FileInputStream( source ); putTransfer( resource, input, output, closeOutput ); input.close(); input = null; } catch ( FileNotFoundException e ) { fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); throw new TransferFailedException( "Specified source file does not exist: " + source, e ); } catch ( final IOException e ) { fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); throw new TransferFailedException( "Failure transferring " + source, e ); } finally { IOUtil.close( input ); } } protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput ) throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException { try { transfer( resource, input, output, TransferEvent.REQUEST_PUT, resource.getContentLength() == WagonConstants.UNKNOWN_LENGTH ? Long.MAX_VALUE : resource.getContentLength() ); finishPutTransfer( resource, input, output ); if ( closeOutput ) { output.close(); output = null; } } catch ( IOException e ) { fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); String msg = "PUT request to: " + resource.getName() + " in " + repository.getName() + " failed"; throw new TransferFailedException( msg, e ); } finally { if ( closeOutput ) { IOUtil.close( output ); } cleanupPutTransfer( resource ); } } protected void cleanupPutTransfer( Resource resource ) { } protected void finishPutTransfer( Resource resource, InputStream input, OutputStream output ) throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException { }
Params:
Throws:
/** * Write from {@link InputStream} to {@link OutputStream}. * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to * {@link Integer#MAX_VALUE} * * @param resource resource to transfer * @param input input stream * @param output output stream * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT} * @throws IOException */
protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType ) throws IOException { transfer( resource, input, output, requestType, Long.MAX_VALUE ); }
Params:
Throws:
Deprecated:Please use the transfer using long as type of maxSize
/** * Write from {@link InputStream} to {@link OutputStream}. * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to * {@link Integer#MAX_VALUE} * * @param resource resource to transfer * @param input input stream * @param output output stream * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT} * @param maxSize size of the buffer * @throws IOException * @deprecated Please use the transfer using long as type of maxSize */
@Deprecated protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, int maxSize ) throws IOException { transfer( resource, input, output, requestType, (long) maxSize ); }
Params:
Throws:
/** * Write from {@link InputStream} to {@link OutputStream}. * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, long)} with a maxSize equals to * {@link Integer#MAX_VALUE} * * @param resource resource to transfer * @param input input stream * @param output output stream * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT} * @param maxSize size of the buffer * @throws IOException */
protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, long maxSize ) throws IOException { ByteBuffer buffer = ByteBuffer.allocate( getBufferCapacityForTransfer( resource.getContentLength() ) ); int halfBufferCapacity = buffer.capacity() / 2; TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType ); transferEvent.setTimestamp( System.currentTimeMillis() ); ReadableByteChannel in = Channels.newChannel( input ); long remaining = maxSize; while ( remaining > 0L ) { int read = in.read( buffer ); if ( read == -1 ) { // EOF, but some data has not been written yet. if ( buffer.position() != 0 ) { buffer.flip(); fireTransferProgress( transferEvent, buffer.array(), buffer.limit() ); output.write( buffer.array(), 0, buffer.limit() ); } break; } // Prevent minichunking / fragmentation: when less than half the buffer is utilized, // read some more bytes before writing and firing progress. if ( buffer.position() < halfBufferCapacity ) { continue; } buffer.flip(); fireTransferProgress( transferEvent, buffer.array(), buffer.limit() ); output.write( buffer.array(), 0, buffer.limit() ); remaining -= buffer.limit(); buffer.clear(); } output.flush(); }
Provides a buffer size for efficiently transferring the given amount of bytes such that it is not fragmented into too many chunks. For larger files larger buffers are provided such that downstream listeners are not notified too frequently. For instance, transferring gigabyte-sized resources would result in millions of notifications when using only a few kibibytes of buffer, drastically slowing down transfer since transfer progress listeners and notifications are synchronous and may block, e.g., when writing download progress status to console.
Params:
  • numberOfBytes – can be 0 or less, in which case a default buffer size is used.
Returns:a byte buffer suitable for transferring the given amount of bytes without too many chunks.
/** * Provides a buffer size for efficiently transferring the given amount of bytes such that * it is not fragmented into too many chunks. For larger files larger buffers are provided such that downstream * {@link #fireTransferProgress(TransferEvent, byte[], int) listeners} are not notified too frequently. * For instance, transferring gigabyte-sized resources would result in millions of notifications when using * only a few kibibytes of buffer, drastically slowing down transfer since transfer progress listeners and * notifications are synchronous and may block, e.g., when writing download progress status to console. * * @param numberOfBytes can be 0 or less, in which case a default buffer size is used. * @return a byte buffer suitable for transferring the given amount of bytes without too many chunks. */
protected int getBufferCapacityForTransfer( long numberOfBytes ) { if ( numberOfBytes <= 0L ) { return DEFAULT_BUFFER_SIZE; } final long numberOfBufferSegments = numberOfBytes / ( BUFFER_SEGMENT_SIZE * MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS ); final long potentialBufferSize = numberOfBufferSegments * BUFFER_SEGMENT_SIZE; if ( potentialBufferSize > Integer.MAX_VALUE ) { return MAXIMUM_BUFFER_SIZE; } return min( MAXIMUM_BUFFER_SIZE, max( DEFAULT_BUFFER_SIZE, (int) potentialBufferSize ) ); } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- protected void fireTransferProgress( TransferEvent transferEvent, byte[] buffer, int n ) { transferEventSupport.fireTransferProgress( transferEvent, buffer, n ); } protected void fireGetCompleted( Resource resource, File localFile ) { long timestamp = System.currentTimeMillis(); TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_GET ); transferEvent.setTimestamp( timestamp ); transferEvent.setLocalFile( localFile ); transferEventSupport.fireTransferCompleted( transferEvent ); } protected void fireGetStarted( Resource resource, File localFile ) { long timestamp = System.currentTimeMillis(); TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_GET ); transferEvent.setTimestamp( timestamp ); transferEvent.setLocalFile( localFile ); transferEventSupport.fireTransferStarted( transferEvent ); } protected void fireGetInitiated( Resource resource, File localFile ) { long timestamp = System.currentTimeMillis(); TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET ); transferEvent.setTimestamp( timestamp ); transferEvent.setLocalFile( localFile ); transferEventSupport.fireTransferInitiated( transferEvent ); } protected void firePutInitiated( Resource resource, File localFile ) { long timestamp = System.currentTimeMillis(); TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_PUT ); transferEvent.setTimestamp( timestamp ); transferEvent.setLocalFile( localFile ); transferEventSupport.fireTransferInitiated( transferEvent ); } protected void firePutCompleted( Resource resource, File localFile ) { long timestamp = System.currentTimeMillis(); TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_PUT ); transferEvent.setTimestamp( timestamp ); transferEvent.setLocalFile( localFile ); transferEventSupport.fireTransferCompleted( transferEvent ); } protected void firePutStarted( Resource resource, File localFile ) { long timestamp = System.currentTimeMillis(); TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT ); transferEvent.setTimestamp( timestamp ); transferEvent.setLocalFile( localFile ); transferEventSupport.fireTransferStarted( transferEvent ); } protected void fireSessionDisconnected() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTED ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionDisconnected( sessionEvent ); } protected void fireSessionDisconnecting() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTING ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionDisconnecting( sessionEvent ); } protected void fireSessionLoggedIn() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_IN ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionLoggedIn( sessionEvent ); } protected void fireSessionLoggedOff() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_OFF ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionLoggedOff( sessionEvent ); } protected void fireSessionOpened() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENED ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionOpened( sessionEvent ); } protected void fireSessionOpening() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENING ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionOpening( sessionEvent ); } protected void fireSessionConnectionRefused() { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_CONNECTION_REFUSED ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionConnectionRefused( sessionEvent ); } protected void fireSessionError( Exception exception ) { long timestamp = System.currentTimeMillis(); SessionEvent sessionEvent = new SessionEvent( this, exception ); sessionEvent.setTimestamp( timestamp ); sessionEventSupport.fireSessionError( sessionEvent ); } protected void fireTransferDebug( String message ) { transferEventSupport.fireDebug( message ); } protected void fireSessionDebug( String message ) { sessionEventSupport.fireDebug( message ); } public boolean hasTransferListener( TransferListener listener ) { return transferEventSupport.hasTransferListener( listener ); } public void addTransferListener( TransferListener listener ) { transferEventSupport.addTransferListener( listener ); } public void removeTransferListener( TransferListener listener ) { transferEventSupport.removeTransferListener( listener ); } public void addSessionListener( SessionListener listener ) { sessionEventSupport.addSessionListener( listener ); } public boolean hasSessionListener( SessionListener listener ) { return sessionEventSupport.hasSessionListener( listener ); } public void removeSessionListener( SessionListener listener ) { sessionEventSupport.removeSessionListener( listener ); } protected void fireTransferError( Resource resource, Exception e, int requestType ) { TransferEvent transferEvent = new TransferEvent( this, resource, e, requestType ); transferEventSupport.fireTransferError( transferEvent ); } public SessionEventSupport getSessionEventSupport() { return sessionEventSupport; } public void setSessionEventSupport( SessionEventSupport sessionEventSupport ) { this.sessionEventSupport = sessionEventSupport; } public TransferEventSupport getTransferEventSupport() { return transferEventSupport; } public void setTransferEventSupport( TransferEventSupport transferEventSupport ) { this.transferEventSupport = transferEventSupport; }
This method is used if you are not streaming the transfer, to make sure any listeners dependent on state (eg checksum observers) succeed.
/** * This method is used if you are not streaming the transfer, to make sure any listeners dependent on state * (eg checksum observers) succeed. */
protected void postProcessListeners( Resource resource, File source, int requestType ) throws TransferFailedException { byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType ); transferEvent.setTimestamp( System.currentTimeMillis() ); transferEvent.setLocalFile( source ); InputStream input = null; try { input = new FileInputStream( source ); while ( true ) { int n = input.read( buffer ); if ( n == -1 ) { break; } fireTransferProgress( transferEvent, buffer, n ); } input.close(); input = null; } catch ( IOException e ) { fireTransferError( resource, e, requestType ); throw new TransferFailedException( "Failed to post-process the source file", e ); } finally { IOUtil.close( input ); } } public void putDirectory( File sourceDirectory, String destinationDirectory ) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException { throw new UnsupportedOperationException( "The wagon you are using has not implemented putDirectory()" ); } public boolean supportsDirectoryCopy() { return false; } protected static String getPath( String basedir, String dir ) { String path; path = basedir; if ( !basedir.endsWith( "/" ) && !dir.startsWith( "/" ) ) { path += "/"; } path += dir; return path; } public boolean isInteractive() { return interactive; } public void setInteractive( boolean interactive ) { this.interactive = interactive; } public List<String> getFileList( String destinationDirectory ) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException { throw new UnsupportedOperationException( "The wagon you are using has not implemented getFileList()" ); } public boolean resourceExists( String resourceName ) throws TransferFailedException, AuthorizationException { throw new UnsupportedOperationException( "The wagon you are using has not implemented resourceExists()" ); } protected ProxyInfo getProxyInfo( String protocol, String host ) { if ( proxyInfoProvider != null ) { ProxyInfo proxyInfo = proxyInfoProvider.getProxyInfo( protocol ); if ( !ProxyUtils.validateNonProxyHosts( proxyInfo, host ) ) { return proxyInfo; } } return null; } public RepositoryPermissions getPermissionsOverride() { return permissionsOverride; } public void setPermissionsOverride( RepositoryPermissions permissionsOverride ) { this.permissionsOverride = permissionsOverride; } public void setReadTimeout( int readTimeout ) { this.readTimeout = readTimeout; } public int getReadTimeout() { return this.readTimeout; } }