001package org.apache.maven.wagon;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.wagon.authentication.AuthenticationException;
023import org.apache.maven.wagon.authentication.AuthenticationInfo;
024import org.apache.maven.wagon.authorization.AuthorizationException;
025import org.apache.maven.wagon.events.SessionEvent;
026import org.apache.maven.wagon.events.SessionEventSupport;
027import org.apache.maven.wagon.events.SessionListener;
028import org.apache.maven.wagon.events.TransferEvent;
029import org.apache.maven.wagon.events.TransferEventSupport;
030import org.apache.maven.wagon.events.TransferListener;
031import org.apache.maven.wagon.proxy.ProxyInfo;
032import org.apache.maven.wagon.proxy.ProxyInfoProvider;
033import org.apache.maven.wagon.proxy.ProxyUtils;
034import org.apache.maven.wagon.repository.Repository;
035import org.apache.maven.wagon.repository.RepositoryPermissions;
036import org.apache.maven.wagon.resource.Resource;
037import org.codehaus.plexus.util.IOUtil;
038
039import java.io.File;
040import java.io.FileInputStream;
041import java.io.FileNotFoundException;
042import java.io.IOException;
043import java.io.InputStream;
044import java.io.OutputStream;
045import java.util.List;
046
047/**
048 * Implementation of common facilities for Wagon providers.
049 *
050 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
051 */
052public abstract class AbstractWagon
053    implements Wagon
054{
055    protected static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
056
057    protected Repository repository;
058
059    protected SessionEventSupport sessionEventSupport = new SessionEventSupport();
060
061    protected TransferEventSupport transferEventSupport = new TransferEventSupport();
062
063    protected AuthenticationInfo authenticationInfo;
064
065    protected boolean interactive = true;
066
067
068    private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
069
070    /**
071     * read timeout value
072     *
073     * @since 2.2
074     */
075    private int readTimeout =
076        Integer.parseInt( System.getProperty( "maven.wagon.rto", Integer.toString( Wagon.DEFAULT_READ_TIMEOUT ) ) );
077
078    private ProxyInfoProvider proxyInfoProvider;
079
080    /**
081     * @deprecated
082     */
083    protected ProxyInfo proxyInfo;
084
085    private RepositoryPermissions permissionsOverride;
086
087    // ----------------------------------------------------------------------
088    // Accessors
089    // ----------------------------------------------------------------------
090
091    public Repository getRepository()
092    {
093        return repository;
094    }
095
096    public ProxyInfo getProxyInfo()
097    {
098        return proxyInfoProvider != null ? proxyInfoProvider.getProxyInfo( null ) : null;
099    }
100
101    public AuthenticationInfo getAuthenticationInfo()
102    {
103        return authenticationInfo;
104    }
105
106    // ----------------------------------------------------------------------
107    // Connection
108    // ----------------------------------------------------------------------
109
110    public void openConnection()
111        throws ConnectionException, AuthenticationException
112    {
113        try
114        {
115            openConnectionInternal();
116        }
117        catch ( ConnectionException e )
118        {
119            fireSessionConnectionRefused();
120
121            throw e;
122        }
123        catch ( AuthenticationException e )
124        {
125            fireSessionConnectionRefused();
126
127            throw e;
128        }
129    }
130
131    public void connect( Repository repository )
132        throws ConnectionException, AuthenticationException
133    {
134        connect( repository, null, (ProxyInfoProvider) null );
135    }
136
137    public void connect( Repository repository, ProxyInfo proxyInfo )
138        throws ConnectionException, AuthenticationException
139    {
140        connect( repository, null, proxyInfo );
141    }
142
143    public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider )
144        throws ConnectionException, AuthenticationException
145    {
146        connect( repository, null, proxyInfoProvider );
147    }
148
149    public void connect( Repository repository, AuthenticationInfo authenticationInfo )
150        throws ConnectionException, AuthenticationException
151    {
152        connect( repository, authenticationInfo, (ProxyInfoProvider) null );
153    }
154
155    public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo )
156        throws ConnectionException, AuthenticationException
157    {
158        final ProxyInfo proxy = proxyInfo;
159        connect( repository, authenticationInfo, new ProxyInfoProvider()
160        {
161            public ProxyInfo getProxyInfo( String protocol )
162            {
163                if ( protocol == null || proxy == null || protocol.equalsIgnoreCase( proxy.getType() ) )
164                {
165                    return proxy;
166                }
167                else
168                {
169                    return null;
170                }
171            }
172        } );
173    }
174
175    public void connect( Repository repository, AuthenticationInfo authenticationInfo,
176                         ProxyInfoProvider proxyInfoProvider )
177        throws ConnectionException, AuthenticationException
178    {
179        if ( repository == null )
180        {
181            throw new NullPointerException( "repository cannot be null" );
182        }
183
184        if ( permissionsOverride != null )
185        {
186            repository.setPermissions( permissionsOverride );
187        }
188
189        this.repository = repository;
190
191        if ( authenticationInfo == null )
192        {
193            authenticationInfo = new AuthenticationInfo();
194        }
195
196        if ( authenticationInfo.getUserName() == null )
197        {
198            // Get user/pass that were encoded in the URL.
199            if ( repository.getUsername() != null )
200            {
201                authenticationInfo.setUserName( repository.getUsername() );
202                if ( repository.getPassword() != null && authenticationInfo.getPassword() == null )
203                {
204                    authenticationInfo.setPassword( repository.getPassword() );
205                }
206            }
207        }
208
209        this.authenticationInfo = authenticationInfo;
210
211        this.proxyInfoProvider = proxyInfoProvider;
212
213        fireSessionOpening();
214
215        openConnection();
216
217        fireSessionOpened();
218    }
219
220    protected abstract void openConnectionInternal()
221        throws ConnectionException, AuthenticationException;
222
223    public void disconnect()
224        throws ConnectionException
225    {
226        fireSessionDisconnecting();
227
228        try
229        {
230            closeConnection();
231        }
232        catch ( ConnectionException e )
233        {
234            fireSessionError( e );
235            throw e;
236        }
237
238        fireSessionDisconnected();
239    }
240
241    protected abstract void closeConnection()
242        throws ConnectionException;
243
244    protected void createParentDirectories( File destination )
245        throws TransferFailedException
246    {
247        File destinationDirectory = destination.getParentFile();
248        try
249        {
250            destinationDirectory = destinationDirectory.getCanonicalFile();
251        }
252        catch ( IOException e )
253        {
254            // not essential to have a canonical file
255        }
256        if ( destinationDirectory != null && !destinationDirectory.exists() )
257        {
258            destinationDirectory.mkdirs();
259            if ( !destinationDirectory.exists() )
260            {
261                throw new TransferFailedException(
262                    "Specified destination directory cannot be created: " + destinationDirectory );
263            }
264        }
265    }
266
267    public void setTimeout( int timeoutValue )
268    {
269        connectionTimeout = timeoutValue;
270    }
271
272    public int getTimeout()
273    {
274        return connectionTimeout;
275    }
276
277    // ----------------------------------------------------------------------
278    // Stream i/o
279    // ----------------------------------------------------------------------
280
281    protected void getTransfer( Resource resource, File destination, InputStream input )
282        throws TransferFailedException
283    {
284        getTransfer( resource, destination, input, true, Long.MAX_VALUE );
285    }
286
287    protected void getTransfer( Resource resource, OutputStream output, InputStream input )
288        throws TransferFailedException
289    {
290        getTransfer( resource, output, input, true, Long.MAX_VALUE );
291    }
292
293    @Deprecated
294    protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput,
295                                int maxSize )
296        throws TransferFailedException
297    {
298        getTransfer( resource, destination, input, closeInput, (long) maxSize );
299    }
300
301    protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput,
302                                long maxSize )
303        throws TransferFailedException
304    {
305        // ensure that the destination is created only when we are ready to transfer
306        fireTransferDebug( "attempting to create parent directories for destination: " + destination.getName() );
307        createParentDirectories( destination );
308
309        fireGetStarted( resource, destination );
310
311        OutputStream output = null;
312        try
313        {
314            output = new LazyFileOutputStream( destination );
315            getTransfer( resource, output, input, closeInput, maxSize );
316            output.close();
317            output = null;
318        }
319        catch ( final IOException e )
320        {
321            if ( destination.exists() )
322            {
323                boolean deleted = destination.delete();
324
325                if ( !deleted )
326                {
327                    destination.deleteOnExit();
328                }
329            }
330
331            fireTransferError( resource, e, TransferEvent.REQUEST_GET );
332
333            String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed";
334
335            throw new TransferFailedException( msg, e );
336        }
337        catch ( TransferFailedException e )
338        {
339            if ( destination.exists() )
340            {
341                boolean deleted = destination.delete();
342
343                if ( !deleted )
344                {
345                    destination.deleteOnExit();
346                }
347            }
348            throw e;
349        }
350        finally
351        {
352            IOUtil.close( output );
353        }
354
355        fireGetCompleted( resource, destination );
356    }
357
358    @Deprecated
359    protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
360                                int maxSize )
361        throws TransferFailedException
362    {
363        getTransfer( resource, output, input, closeInput, (long) maxSize );
364    }
365
366    protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
367                                long maxSize )
368        throws TransferFailedException
369    {
370        try
371        {
372            transfer( resource, input, output, TransferEvent.REQUEST_GET, maxSize );
373
374            finishGetTransfer( resource, input, output );
375
376            if ( closeInput )
377            {
378                input.close();
379                input = null;
380            }
381
382        }
383        catch ( IOException e )
384        {
385            fireTransferError( resource, e, TransferEvent.REQUEST_GET );
386
387            String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed";
388
389            throw new TransferFailedException( msg, e );
390        }
391        finally
392        {
393            if ( closeInput )
394            {
395                IOUtil.close( input );
396            }
397
398            cleanupGetTransfer( resource );
399        }
400    }
401
402    protected void finishGetTransfer( Resource resource, InputStream input, OutputStream output )
403        throws TransferFailedException
404    {
405    }
406
407    protected void cleanupGetTransfer( Resource resource )
408    {
409    }
410
411    protected void putTransfer( Resource resource, File source, OutputStream output, boolean closeOutput )
412        throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
413    {
414        firePutStarted( resource, source );
415
416        transfer( resource, source, output, closeOutput );
417
418        firePutCompleted( resource, source );
419    }
420
421    /**
422     * Write from {@link File} to {@link OutputStream}
423     *
424     * @param resource    resource to transfer
425     * @param source      file to read from
426     * @param output      output stream
427     * @param closeOutput whether the output stream should be closed or not
428     * @throws TransferFailedException
429     * @throws ResourceDoesNotExistException
430     * @throws AuthorizationException
431     * @since 1.0-beta-1
432     */
433    protected void transfer( Resource resource, File source, OutputStream output, boolean closeOutput )
434        throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
435    {
436        InputStream input = null;
437
438        try
439        {
440            input = new FileInputStream( source );
441
442            putTransfer( resource, input, output, closeOutput );
443
444            input.close();
445            input = null;
446        }
447        catch ( FileNotFoundException e )
448        {
449            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
450
451            throw new TransferFailedException( "Specified source file does not exist: " + source, e );
452        }
453        catch ( final IOException e )
454        {
455            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
456
457            throw new TransferFailedException( "Failure transferring " + source, e );
458        }
459        finally
460        {
461            IOUtil.close( input );
462        }
463    }
464
465    protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput )
466        throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
467    {
468        try
469        {
470            transfer( resource, input, output, TransferEvent.REQUEST_PUT,
471                      resource.getContentLength() == WagonConstants.UNKNOWN_LENGTH
472                          ? Long.MAX_VALUE
473                          : resource.getContentLength() );
474
475            finishPutTransfer( resource, input, output );
476
477            if ( closeOutput )
478            {
479                output.close();
480                output = null;
481            }
482        }
483        catch ( IOException e )
484        {
485            fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
486
487            String msg = "PUT request to: " + resource.getName() + " in " + repository.getName() + " failed";
488
489            throw new TransferFailedException( msg, e );
490        }
491        finally
492        {
493            if ( closeOutput )
494            {
495                IOUtil.close( output );
496            }
497
498            cleanupPutTransfer( resource );
499        }
500    }
501
502    protected void cleanupPutTransfer( Resource resource )
503    {
504    }
505
506    protected void finishPutTransfer( Resource resource, InputStream input, OutputStream output )
507        throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
508    {
509    }
510
511    /**
512     * Write from {@link InputStream} to {@link OutputStream}.
513     * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to
514     * {@link Integer#MAX_VALUE}
515     *
516     * @param resource    resource to transfer
517     * @param input       input stream
518     * @param output      output stream
519     * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
520     * @throws IOException
521     */
522    protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType )
523        throws IOException
524    {
525        transfer( resource, input, output, requestType, Long.MAX_VALUE );
526    }
527
528    /**
529     * Write from {@link InputStream} to {@link OutputStream}.
530     * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to
531     * {@link Integer#MAX_VALUE}
532     *
533     * @param resource    resource to transfer
534     * @param input       input stream
535     * @param output      output stream
536     * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
537     * @param maxSize     size of the buffer
538     * @throws IOException
539     * @deprecated Please use the transfer using long as type of maxSize
540     */
541    @Deprecated
542    protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, int maxSize )
543        throws IOException
544    {
545        transfer( resource, input, output, requestType, (long) maxSize );
546    }
547
548    /**
549     * Write from {@link InputStream} to {@link OutputStream}.
550     * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, long)} with a maxSize equals to
551     * {@link Integer#MAX_VALUE}
552     *
553     * @param resource    resource to transfer
554     * @param input       input stream
555     * @param output      output stream
556     * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
557     * @param maxSize     size of the buffer
558     * @throws IOException
559     */
560    protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, long maxSize )
561        throws IOException
562    {
563        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
564
565        TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType );
566        transferEvent.setTimestamp( System.currentTimeMillis() );
567
568        long remaining = maxSize;
569        while ( remaining > 0 )
570        {
571            // let's safely cast to int because the min value will be lower than the buffer size.
572            int n = input.read( buffer, 0, (int) Math.min( buffer.length, remaining ) );
573
574            if ( n == -1 )
575            {
576                break;
577            }
578
579            fireTransferProgress( transferEvent, buffer, n );
580
581            output.write( buffer, 0, n );
582
583            remaining -= n;
584        }
585        output.flush();
586    }
587
588    // ----------------------------------------------------------------------
589    //
590    // ----------------------------------------------------------------------
591
592    protected void fireTransferProgress( TransferEvent transferEvent, byte[] buffer, int n )
593    {
594        transferEventSupport.fireTransferProgress( transferEvent, buffer, n );
595    }
596
597    protected void fireGetCompleted( Resource resource, File localFile )
598    {
599        long timestamp = System.currentTimeMillis();
600
601        TransferEvent transferEvent =
602            new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_GET );
603
604        transferEvent.setTimestamp( timestamp );
605
606        transferEvent.setLocalFile( localFile );
607
608        transferEventSupport.fireTransferCompleted( transferEvent );
609    }
610
611    protected void fireGetStarted( Resource resource, File localFile )
612    {
613        long timestamp = System.currentTimeMillis();
614
615        TransferEvent transferEvent =
616            new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_GET );
617
618        transferEvent.setTimestamp( timestamp );
619
620        transferEvent.setLocalFile( localFile );
621
622        transferEventSupport.fireTransferStarted( transferEvent );
623    }
624
625    protected void fireGetInitiated( Resource resource, File localFile )
626    {
627        long timestamp = System.currentTimeMillis();
628
629        TransferEvent transferEvent =
630            new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET );
631
632        transferEvent.setTimestamp( timestamp );
633
634        transferEvent.setLocalFile( localFile );
635
636        transferEventSupport.fireTransferInitiated( transferEvent );
637    }
638
639    protected void firePutInitiated( Resource resource, File localFile )
640    {
641        long timestamp = System.currentTimeMillis();
642
643        TransferEvent transferEvent =
644            new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_PUT );
645
646        transferEvent.setTimestamp( timestamp );
647
648        transferEvent.setLocalFile( localFile );
649
650        transferEventSupport.fireTransferInitiated( transferEvent );
651    }
652
653    protected void firePutCompleted( Resource resource, File localFile )
654    {
655        long timestamp = System.currentTimeMillis();
656
657        TransferEvent transferEvent =
658            new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_PUT );
659
660        transferEvent.setTimestamp( timestamp );
661
662        transferEvent.setLocalFile( localFile );
663
664        transferEventSupport.fireTransferCompleted( transferEvent );
665    }
666
667    protected void firePutStarted( Resource resource, File localFile )
668    {
669        long timestamp = System.currentTimeMillis();
670
671        TransferEvent transferEvent =
672            new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT );
673
674        transferEvent.setTimestamp( timestamp );
675
676        transferEvent.setLocalFile( localFile );
677
678        transferEventSupport.fireTransferStarted( transferEvent );
679    }
680
681    protected void fireSessionDisconnected()
682    {
683        long timestamp = System.currentTimeMillis();
684
685        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTED );
686
687        sessionEvent.setTimestamp( timestamp );
688
689        sessionEventSupport.fireSessionDisconnected( sessionEvent );
690    }
691
692    protected void fireSessionDisconnecting()
693    {
694        long timestamp = System.currentTimeMillis();
695
696        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTING );
697
698        sessionEvent.setTimestamp( timestamp );
699
700        sessionEventSupport.fireSessionDisconnecting( sessionEvent );
701    }
702
703    protected void fireSessionLoggedIn()
704    {
705        long timestamp = System.currentTimeMillis();
706
707        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_IN );
708
709        sessionEvent.setTimestamp( timestamp );
710
711        sessionEventSupport.fireSessionLoggedIn( sessionEvent );
712    }
713
714    protected void fireSessionLoggedOff()
715    {
716        long timestamp = System.currentTimeMillis();
717
718        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_OFF );
719
720        sessionEvent.setTimestamp( timestamp );
721
722        sessionEventSupport.fireSessionLoggedOff( sessionEvent );
723    }
724
725    protected void fireSessionOpened()
726    {
727        long timestamp = System.currentTimeMillis();
728
729        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENED );
730
731        sessionEvent.setTimestamp( timestamp );
732
733        sessionEventSupport.fireSessionOpened( sessionEvent );
734    }
735
736    protected void fireSessionOpening()
737    {
738        long timestamp = System.currentTimeMillis();
739
740        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENING );
741
742        sessionEvent.setTimestamp( timestamp );
743
744        sessionEventSupport.fireSessionOpening( sessionEvent );
745    }
746
747    protected void fireSessionConnectionRefused()
748    {
749        long timestamp = System.currentTimeMillis();
750
751        SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_CONNECTION_REFUSED );
752
753        sessionEvent.setTimestamp( timestamp );
754
755        sessionEventSupport.fireSessionConnectionRefused( sessionEvent );
756    }
757
758    protected void fireSessionError( Exception exception )
759    {
760        long timestamp = System.currentTimeMillis();
761
762        SessionEvent sessionEvent = new SessionEvent( this, exception );
763
764        sessionEvent.setTimestamp( timestamp );
765
766        sessionEventSupport.fireSessionError( sessionEvent );
767
768    }
769
770    protected void fireTransferDebug( String message )
771    {
772        transferEventSupport.fireDebug( message );
773    }
774
775    protected void fireSessionDebug( String message )
776    {
777        sessionEventSupport.fireDebug( message );
778    }
779
780    public boolean hasTransferListener( TransferListener listener )
781    {
782        return transferEventSupport.hasTransferListener( listener );
783    }
784
785    public void addTransferListener( TransferListener listener )
786    {
787        transferEventSupport.addTransferListener( listener );
788    }
789
790    public void removeTransferListener( TransferListener listener )
791    {
792        transferEventSupport.removeTransferListener( listener );
793    }
794
795    public void addSessionListener( SessionListener listener )
796    {
797        sessionEventSupport.addSessionListener( listener );
798    }
799
800    public boolean hasSessionListener( SessionListener listener )
801    {
802        return sessionEventSupport.hasSessionListener( listener );
803    }
804
805    public void removeSessionListener( SessionListener listener )
806    {
807        sessionEventSupport.removeSessionListener( listener );
808    }
809
810    protected void fireTransferError( Resource resource, Exception e, int requestType )
811    {
812        TransferEvent transferEvent = new TransferEvent( this, resource, e, requestType );
813        transferEventSupport.fireTransferError( transferEvent );
814    }
815
816
817    public SessionEventSupport getSessionEventSupport()
818    {
819        return sessionEventSupport;
820    }
821
822    public void setSessionEventSupport( SessionEventSupport sessionEventSupport )
823    {
824        this.sessionEventSupport = sessionEventSupport;
825    }
826
827    public TransferEventSupport getTransferEventSupport()
828    {
829        return transferEventSupport;
830    }
831
832    public void setTransferEventSupport( TransferEventSupport transferEventSupport )
833    {
834        this.transferEventSupport = transferEventSupport;
835    }
836
837    /**
838     * This method is used if you are not streaming the transfer, to make sure any listeners dependent on state
839     * (eg checksum observers) succeed.
840     */
841    protected void postProcessListeners( Resource resource, File source, int requestType )
842        throws TransferFailedException
843    {
844        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
845
846        TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType );
847        transferEvent.setTimestamp( System.currentTimeMillis() );
848        transferEvent.setLocalFile( source );
849
850        InputStream input = null;
851        try
852        {
853            input = new FileInputStream( source );
854
855            while ( true )
856            {
857                int n = input.read( buffer );
858
859                if ( n == -1 )
860                {
861                    break;
862                }
863
864                fireTransferProgress( transferEvent, buffer, n );
865            }
866
867            input.close();
868            input = null;
869        }
870        catch ( IOException e )
871        {
872            fireTransferError( resource, e, requestType );
873
874            throw new TransferFailedException( "Failed to post-process the source file", e );
875        }
876        finally
877        {
878            IOUtil.close( input );
879        }
880    }
881
882    public void putDirectory( File sourceDirectory, String destinationDirectory )
883        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
884    {
885        throw new UnsupportedOperationException( "The wagon you are using has not implemented putDirectory()" );
886    }
887
888    public boolean supportsDirectoryCopy()
889    {
890        return false;
891    }
892
893    protected static String getPath( String basedir, String dir )
894    {
895        String path;
896        path = basedir;
897        if ( !basedir.endsWith( "/" ) && !dir.startsWith( "/" ) )
898        {
899            path += "/";
900        }
901        path += dir;
902        return path;
903    }
904
905    public boolean isInteractive()
906    {
907        return interactive;
908    }
909
910    public void setInteractive( boolean interactive )
911    {
912        this.interactive = interactive;
913    }
914
915    public List<String> getFileList( String destinationDirectory )
916        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
917    {
918        throw new UnsupportedOperationException( "The wagon you are using has not implemented getFileList()" );
919    }
920
921    public boolean resourceExists( String resourceName )
922        throws TransferFailedException, AuthorizationException
923    {
924        throw new UnsupportedOperationException( "The wagon you are using has not implemented resourceExists()" );
925    }
926
927    protected ProxyInfo getProxyInfo( String protocol, String host )
928    {
929        if ( proxyInfoProvider != null )
930        {
931            ProxyInfo proxyInfo = proxyInfoProvider.getProxyInfo( protocol );
932            if ( !ProxyUtils.validateNonProxyHosts( proxyInfo, host ) )
933            {
934                return proxyInfo;
935            }
936        }
937        return null;
938    }
939
940    public RepositoryPermissions getPermissionsOverride()
941    {
942        return permissionsOverride;
943    }
944
945    public void setPermissionsOverride( RepositoryPermissions permissionsOverride )
946    {
947        this.permissionsOverride = permissionsOverride;
948    }
949
950    public void setReadTimeout( int readTimeout )
951    {
952        this.readTimeout = readTimeout;
953    }
954
955    public int getReadTimeout()
956    {
957        return this.readTimeout;
958    }
959}