View Javadoc
1   package org.apache.maven.wagon;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.wagon.authentication.AuthenticationException;
23  import org.apache.maven.wagon.authentication.AuthenticationInfo;
24  import org.apache.maven.wagon.authorization.AuthorizationException;
25  import org.apache.maven.wagon.events.SessionEvent;
26  import org.apache.maven.wagon.events.SessionEventSupport;
27  import org.apache.maven.wagon.events.SessionListener;
28  import org.apache.maven.wagon.events.TransferEvent;
29  import org.apache.maven.wagon.events.TransferEventSupport;
30  import org.apache.maven.wagon.events.TransferListener;
31  import org.apache.maven.wagon.proxy.ProxyInfo;
32  import org.apache.maven.wagon.proxy.ProxyInfoProvider;
33  import org.apache.maven.wagon.proxy.ProxyUtils;
34  import org.apache.maven.wagon.repository.Repository;
35  import org.apache.maven.wagon.repository.RepositoryPermissions;
36  import org.apache.maven.wagon.resource.Resource;
37  import org.codehaus.plexus.util.IOUtil;
38  
39  import java.io.File;
40  import java.io.FileInputStream;
41  import java.io.FileNotFoundException;
42  import java.io.IOException;
43  import java.io.InputStream;
44  import java.io.OutputStream;
45  import java.util.List;
46  
47  /**
48   * Implementation of common facilities for Wagon providers.
49   *
50   * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
51   */
52  public abstract class AbstractWagon
53      implements Wagon
54  {
55      protected static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
56  
57      protected Repository repository;
58  
59      protected SessionEventSupport sessionEventSupport = new SessionEventSupport();
60  
61      protected TransferEventSupport transferEventSupport = new TransferEventSupport();
62  
63      protected AuthenticationInfo authenticationInfo;
64  
65      protected boolean interactive = true;
66  
67  
68      private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
69  
70      /**
71       * read timeout value
72       *
73       * @since 2.2
74       */
75      private int readTimeout =
76          Integer.parseInt( System.getProperty( "maven.wagon.rto", Integer.toString( Wagon.DEFAULT_READ_TIMEOUT ) ) );
77  
78      private ProxyInfoProvider proxyInfoProvider;
79  
80      /**
81       * @deprecated
82       */
83      protected ProxyInfo proxyInfo;
84  
85      private RepositoryPermissions permissionsOverride;
86  
87      // ----------------------------------------------------------------------
88      // Accessors
89      // ----------------------------------------------------------------------
90  
91      public Repository getRepository()
92      {
93          return repository;
94      }
95  
96      public ProxyInfo getProxyInfo()
97      {
98          return proxyInfoProvider != null ? proxyInfoProvider.getProxyInfo( null ) : null;
99      }
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 }