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 IllegalStateException( "The repository specified 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         // TODO: Do these needs to be fields, or are they only used in openConnection()?
210         this.authenticationInfo = authenticationInfo;
211 
212         this.proxyInfoProvider = proxyInfoProvider;
213 
214         fireSessionOpening();
215 
216         openConnection();
217 
218         fireSessionOpened();
219     }
220 
221     protected abstract void openConnectionInternal()
222         throws ConnectionException, AuthenticationException;
223 
224     public void disconnect()
225         throws ConnectionException
226     {
227         fireSessionDisconnecting();
228 
229         try
230         {
231             closeConnection();
232         }
233         catch ( ConnectionException e )
234         {
235             fireSessionError( e );
236             throw e;
237         }
238 
239         fireSessionDisconnected();
240     }
241 
242     protected abstract void closeConnection()
243         throws ConnectionException;
244 
245     protected void createParentDirectories( File destination )
246         throws TransferFailedException
247     {
248         File destinationDirectory = destination.getParentFile();
249         try
250         {
251             destinationDirectory = destinationDirectory.getCanonicalFile();
252         }
253         catch ( IOException e )
254         {
255             // not essential to have a canonical file
256         }
257         if ( destinationDirectory != null && !destinationDirectory.exists() )
258         {
259             destinationDirectory.mkdirs();
260             if ( !destinationDirectory.exists() )
261             {
262                 throw new TransferFailedException(
263                     "Specified destination directory cannot be created: " + destinationDirectory );
264             }
265         }
266     }
267 
268     public void setTimeout( int timeoutValue )
269     {
270         connectionTimeout = timeoutValue;
271     }
272 
273     public int getTimeout()
274     {
275         return connectionTimeout;
276     }
277 
278     // ----------------------------------------------------------------------
279     // Stream i/o
280     // ----------------------------------------------------------------------
281 
282     protected void getTransfer( Resource resource, File destination, InputStream input )
283         throws TransferFailedException
284     {
285         getTransfer( resource, destination, input, true, Long.MAX_VALUE );
286     }
287 
288     protected void getTransfer( Resource resource, OutputStream output, InputStream input )
289         throws TransferFailedException
290     {
291         getTransfer( resource, output, input, true, Long.MAX_VALUE );
292     }
293 
294     @Deprecated
295     protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput,
296                                 int maxSize )
297         throws TransferFailedException
298     {
299         getTransfer( resource, destination, input, closeInput, (long) maxSize );
300     }
301 
302     protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput,
303                                 long maxSize )
304         throws TransferFailedException
305     {
306         // ensure that the destination is created only when we are ready to transfer
307         fireTransferDebug( "attempting to create parent directories for destination: " + destination.getName() );
308         createParentDirectories( destination );
309 
310         OutputStream output = new LazyFileOutputStream( destination );
311 
312         fireGetStarted( resource, destination );
313 
314         try
315         {
316             getTransfer( resource, output, input, closeInput, maxSize );
317         }
318         catch ( TransferFailedException e )
319         {
320             if ( destination.exists() )
321             {
322                 boolean deleted = destination.delete();
323 
324                 if ( !deleted )
325                 {
326                     destination.deleteOnExit();
327                 }
328             }
329             throw e;
330         }
331         finally
332         {
333             IOUtil.close( output );
334         }
335 
336         fireGetCompleted( resource, destination );
337     }
338 
339     @Deprecated
340     protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
341                                 int maxSize )
342         throws TransferFailedException
343     {
344         getTransfer( resource, output, input, closeInput, (long) maxSize );
345     }
346 
347     protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
348                                 long maxSize )
349         throws TransferFailedException
350     {
351         try
352         {
353             transfer( resource, input, output, TransferEvent.REQUEST_GET, maxSize );
354 
355             finishGetTransfer( resource, input, output );
356         }
357         catch ( IOException e )
358         {
359             fireTransferError( resource, e, TransferEvent.REQUEST_GET );
360 
361             String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed";
362 
363             throw new TransferFailedException( msg, e );
364         }
365         finally
366         {
367             if ( closeInput )
368             {
369                 IOUtil.close( input );
370             }
371 
372             cleanupGetTransfer( resource );
373         }
374     }
375 
376     protected void finishGetTransfer( Resource resource, InputStream input, OutputStream output )
377         throws TransferFailedException
378     {
379     }
380 
381     protected void cleanupGetTransfer( Resource resource )
382     {
383     }
384 
385     protected void putTransfer( Resource resource, File source, OutputStream output, boolean closeOutput )
386         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
387     {
388         firePutStarted( resource, source );
389 
390         transfer( resource, source, output, closeOutput );
391 
392         firePutCompleted( resource, source );
393     }
394 
395     /**
396      * Write from {@link File} to {@link OutputStream}
397      *
398      * @param resource    resource to transfer
399      * @param source      file to read from
400      * @param output      output stream
401      * @param closeOutput whether the output stream should be closed or not
402      * @throws TransferFailedException
403      * @throws ResourceDoesNotExistException
404      * @throws AuthorizationException
405      * @since 1.0-beta-1
406      */
407     protected void transfer( Resource resource, File source, OutputStream output, boolean closeOutput )
408         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
409     {
410         InputStream input = null;
411 
412         try
413         {
414             input = new FileInputStream( source );
415 
416             putTransfer( resource, input, output, closeOutput );
417         }
418         catch ( FileNotFoundException e )
419         {
420             fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
421 
422             throw new TransferFailedException( "Specified source file does not exist: " + source, e );
423         }
424         finally
425         {
426             IOUtil.close( input );
427         }
428     }
429 
430     protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput )
431         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
432     {
433         try
434         {
435             transfer( resource, input, output, TransferEvent.REQUEST_PUT,
436                       resource.getContentLength() == WagonConstants.UNKNOWN_LENGTH
437                           ? Long.MAX_VALUE
438                           : resource.getContentLength() );
439 
440             finishPutTransfer( resource, input, output );
441         }
442         catch ( IOException e )
443         {
444             fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
445 
446             String msg = "PUT request to: " + resource.getName() + " in " + repository.getName() + " failed";
447 
448             throw new TransferFailedException( msg, e );
449         }
450         finally
451         {
452             if ( closeOutput )
453             {
454                 IOUtil.close( output );
455             }
456 
457             cleanupPutTransfer( resource );
458         }
459     }
460 
461     protected void cleanupPutTransfer( Resource resource )
462     {
463     }
464 
465     protected void finishPutTransfer( Resource resource, InputStream input, OutputStream output )
466         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
467     {
468     }
469 
470     /**
471      * Write from {@link InputStream} to {@link OutputStream}.
472      * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to
473      * {@link Integer#MAX_VALUE}
474      *
475      * @param resource    resource to transfer
476      * @param input       input stream
477      * @param output      output stream
478      * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
479      * @throws IOException
480      */
481     protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType )
482         throws IOException
483     {
484         transfer( resource, input, output, requestType, Long.MAX_VALUE );
485     }
486 
487     /**
488      * Write from {@link InputStream} to {@link OutputStream}.
489      * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to
490      * {@link Integer#MAX_VALUE}
491      *
492      * @param resource    resource to transfer
493      * @param input       input stream
494      * @param output      output stream
495      * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
496      * @param maxSize     size of the buffer
497      * @throws IOException
498      * @deprecated Please use the transfer using long as type of maxSize
499      */
500     @Deprecated
501     protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, int maxSize )
502         throws IOException
503     {
504         transfer( resource, input, output, requestType, (long) maxSize );
505     }
506 
507     /**
508      * Write from {@link InputStream} to {@link OutputStream}.
509      * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, long)} with a maxSize equals to
510      * {@link Integer#MAX_VALUE}
511      *
512      * @param resource    resource to transfer
513      * @param input       input stream
514      * @param output      output stream
515      * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
516      * @param maxSize     size of the buffer
517      * @throws IOException
518      */
519     protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, long maxSize )
520         throws IOException
521     {
522         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
523 
524         TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType );
525         transferEvent.setTimestamp( System.currentTimeMillis() );
526 
527         long remaining = maxSize;
528         while ( remaining > 0 )
529         {
530             // let's safely cast to int because the min value will be lower than the buffer size.
531             int n = input.read( buffer, 0, (int) Math.min( buffer.length, remaining ) );
532 
533             if ( n == -1 )
534             {
535                 break;
536             }
537 
538             fireTransferProgress( transferEvent, buffer, n );
539 
540             output.write( buffer, 0, n );
541 
542             remaining -= n;
543         }
544         output.flush();
545     }
546 
547     // ----------------------------------------------------------------------
548     //
549     // ----------------------------------------------------------------------
550 
551     protected void fireTransferProgress( TransferEvent transferEvent, byte[] buffer, int n )
552     {
553         transferEventSupport.fireTransferProgress( transferEvent, buffer, n );
554     }
555 
556     protected void fireGetCompleted( Resource resource, File localFile )
557     {
558         long timestamp = System.currentTimeMillis();
559 
560         TransferEvent transferEvent =
561             new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_GET );
562 
563         transferEvent.setTimestamp( timestamp );
564 
565         transferEvent.setLocalFile( localFile );
566 
567         transferEventSupport.fireTransferCompleted( transferEvent );
568     }
569 
570     protected void fireGetStarted( Resource resource, File localFile )
571     {
572         long timestamp = System.currentTimeMillis();
573 
574         TransferEvent transferEvent =
575             new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_GET );
576 
577         transferEvent.setTimestamp( timestamp );
578 
579         transferEvent.setLocalFile( localFile );
580 
581         transferEventSupport.fireTransferStarted( transferEvent );
582     }
583 
584     protected void fireGetInitiated( Resource resource, File localFile )
585     {
586         long timestamp = System.currentTimeMillis();
587 
588         TransferEvent transferEvent =
589             new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET );
590 
591         transferEvent.setTimestamp( timestamp );
592 
593         transferEvent.setLocalFile( localFile );
594 
595         transferEventSupport.fireTransferInitiated( transferEvent );
596     }
597 
598     protected void firePutInitiated( Resource resource, File localFile )
599     {
600         long timestamp = System.currentTimeMillis();
601 
602         TransferEvent transferEvent =
603             new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_PUT );
604 
605         transferEvent.setTimestamp( timestamp );
606 
607         transferEvent.setLocalFile( localFile );
608 
609         transferEventSupport.fireTransferInitiated( transferEvent );
610     }
611 
612     protected void firePutCompleted( Resource resource, File localFile )
613     {
614         long timestamp = System.currentTimeMillis();
615 
616         TransferEvent transferEvent =
617             new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_PUT );
618 
619         transferEvent.setTimestamp( timestamp );
620 
621         transferEvent.setLocalFile( localFile );
622 
623         transferEventSupport.fireTransferCompleted( transferEvent );
624     }
625 
626     protected void firePutStarted( Resource resource, File localFile )
627     {
628         long timestamp = System.currentTimeMillis();
629 
630         TransferEvent transferEvent =
631             new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT );
632 
633         transferEvent.setTimestamp( timestamp );
634 
635         transferEvent.setLocalFile( localFile );
636 
637         transferEventSupport.fireTransferStarted( transferEvent );
638     }
639 
640     protected void fireSessionDisconnected()
641     {
642         long timestamp = System.currentTimeMillis();
643 
644         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTED );
645 
646         sessionEvent.setTimestamp( timestamp );
647 
648         sessionEventSupport.fireSessionDisconnected( sessionEvent );
649     }
650 
651     protected void fireSessionDisconnecting()
652     {
653         long timestamp = System.currentTimeMillis();
654 
655         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTING );
656 
657         sessionEvent.setTimestamp( timestamp );
658 
659         sessionEventSupport.fireSessionDisconnecting( sessionEvent );
660     }
661 
662     protected void fireSessionLoggedIn()
663     {
664         long timestamp = System.currentTimeMillis();
665 
666         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_IN );
667 
668         sessionEvent.setTimestamp( timestamp );
669 
670         sessionEventSupport.fireSessionLoggedIn( sessionEvent );
671     }
672 
673     protected void fireSessionLoggedOff()
674     {
675         long timestamp = System.currentTimeMillis();
676 
677         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_OFF );
678 
679         sessionEvent.setTimestamp( timestamp );
680 
681         sessionEventSupport.fireSessionLoggedOff( sessionEvent );
682     }
683 
684     protected void fireSessionOpened()
685     {
686         long timestamp = System.currentTimeMillis();
687 
688         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENED );
689 
690         sessionEvent.setTimestamp( timestamp );
691 
692         sessionEventSupport.fireSessionOpened( sessionEvent );
693     }
694 
695     protected void fireSessionOpening()
696     {
697         long timestamp = System.currentTimeMillis();
698 
699         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENING );
700 
701         sessionEvent.setTimestamp( timestamp );
702 
703         sessionEventSupport.fireSessionOpening( sessionEvent );
704     }
705 
706     protected void fireSessionConnectionRefused()
707     {
708         long timestamp = System.currentTimeMillis();
709 
710         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_CONNECTION_REFUSED );
711 
712         sessionEvent.setTimestamp( timestamp );
713 
714         sessionEventSupport.fireSessionConnectionRefused( sessionEvent );
715     }
716 
717     protected void fireSessionError( Exception exception )
718     {
719         long timestamp = System.currentTimeMillis();
720 
721         SessionEvent sessionEvent = new SessionEvent( this, exception );
722 
723         sessionEvent.setTimestamp( timestamp );
724 
725         sessionEventSupport.fireSessionError( sessionEvent );
726 
727     }
728 
729     protected void fireTransferDebug( String message )
730     {
731         transferEventSupport.fireDebug( message );
732     }
733 
734     protected void fireSessionDebug( String message )
735     {
736         sessionEventSupport.fireDebug( message );
737     }
738 
739     public boolean hasTransferListener( TransferListener listener )
740     {
741         return transferEventSupport.hasTransferListener( listener );
742     }
743 
744     public void addTransferListener( TransferListener listener )
745     {
746         transferEventSupport.addTransferListener( listener );
747     }
748 
749     public void removeTransferListener( TransferListener listener )
750     {
751         transferEventSupport.removeTransferListener( listener );
752     }
753 
754     public void addSessionListener( SessionListener listener )
755     {
756         sessionEventSupport.addSessionListener( listener );
757     }
758 
759     public boolean hasSessionListener( SessionListener listener )
760     {
761         return sessionEventSupport.hasSessionListener( listener );
762     }
763 
764     public void removeSessionListener( SessionListener listener )
765     {
766         sessionEventSupport.removeSessionListener( listener );
767     }
768 
769     protected void fireTransferError( Resource resource, Exception e, int requestType )
770     {
771         TransferEvent transferEvent = new TransferEvent( this, resource, e, requestType );
772         transferEventSupport.fireTransferError( transferEvent );
773     }
774 
775 
776     public SessionEventSupport getSessionEventSupport()
777     {
778         return sessionEventSupport;
779     }
780 
781     public void setSessionEventSupport( SessionEventSupport sessionEventSupport )
782     {
783         this.sessionEventSupport = sessionEventSupport;
784     }
785 
786     public TransferEventSupport getTransferEventSupport()
787     {
788         return transferEventSupport;
789     }
790 
791     public void setTransferEventSupport( TransferEventSupport transferEventSupport )
792     {
793         this.transferEventSupport = transferEventSupport;
794     }
795 
796     /**
797      * This method is used if you are not streaming the transfer, to make sure any listeners dependent on state
798      * (eg checksum observers) succeed.
799      */
800     protected void postProcessListeners( Resource resource, File source, int requestType )
801         throws TransferFailedException
802     {
803         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
804 
805         TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType );
806         transferEvent.setTimestamp( System.currentTimeMillis() );
807         transferEvent.setLocalFile( source );
808 
809         InputStream input = null;
810         try
811         {
812             input = new FileInputStream( source );
813 
814             while ( true )
815             {
816                 int n = input.read( buffer );
817 
818                 if ( n == -1 )
819                 {
820                     break;
821                 }
822 
823                 fireTransferProgress( transferEvent, buffer, n );
824             }
825         }
826         catch ( IOException e )
827         {
828             fireTransferError( resource, e, requestType );
829 
830             throw new TransferFailedException( "Failed to post-process the source file", e );
831         }
832         finally
833         {
834             IOUtil.close( input );
835         }
836     }
837 
838     public void putDirectory( File sourceDirectory, String destinationDirectory )
839         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
840     {
841         throw new UnsupportedOperationException( "The wagon you are using has not implemented putDirectory()" );
842     }
843 
844     public boolean supportsDirectoryCopy()
845     {
846         return false;
847     }
848 
849     protected static String getPath( String basedir, String dir )
850     {
851         String path;
852         path = basedir;
853         if ( !basedir.endsWith( "/" ) && !dir.startsWith( "/" ) )
854         {
855             path += "/";
856         }
857         path += dir;
858         return path;
859     }
860 
861     public boolean isInteractive()
862     {
863         return interactive;
864     }
865 
866     public void setInteractive( boolean interactive )
867     {
868         this.interactive = interactive;
869     }
870 
871     public List<String> getFileList( String destinationDirectory )
872         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
873     {
874         throw new UnsupportedOperationException( "The wagon you are using has not implemented getFileList()" );
875     }
876 
877     public boolean resourceExists( String resourceName )
878         throws TransferFailedException, AuthorizationException
879     {
880         throw new UnsupportedOperationException( "The wagon you are using has not implemented resourceExists()" );
881     }
882 
883     protected ProxyInfo getProxyInfo( String protocol, String host )
884     {
885         if ( proxyInfoProvider != null )
886         {
887             ProxyInfo proxyInfo = proxyInfoProvider.getProxyInfo( protocol );
888             if ( !ProxyUtils.validateNonProxyHosts( proxyInfo, host ) )
889             {
890                 return proxyInfo;
891             }
892         }
893         return null;
894     }
895 
896     public RepositoryPermissions getPermissionsOverride()
897     {
898         return permissionsOverride;
899     }
900 
901     public void setPermissionsOverride( RepositoryPermissions permissionsOverride )
902     {
903         this.permissionsOverride = permissionsOverride;
904     }
905 
906     public void setReadTimeout( int readTimeout )
907     {
908         this.readTimeout = readTimeout;
909     }
910 
911     public int getReadTimeout()
912     {
913         return this.readTimeout;
914     }
915 }