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   */
53  public abstract class AbstractWagon
54      implements Wagon
55  {
56      protected static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
57  
58      protected Repository repository;
59  
60      protected SessionEventSupport sessionEventSupport = new SessionEventSupport();
61  
62      protected TransferEventSupport transferEventSupport = new TransferEventSupport();
63  
64      protected AuthenticationInfo authenticationInfo;
65  
66      protected boolean interactive = true;
67  
68  
69      private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
70  
71      /**
72       * read timeout value
73       *
74       * @since 2.2
75       */
76      private int readTimeout =
77          Integer.parseInt( System.getProperty( "maven.wagon.rto", Integer.toString( Wagon.DEFAULT_READ_TIMEOUT ) ) );
78  
79      private ProxyInfoProvider proxyInfoProvider;
80  
81      /**
82       * @deprecated
83       */
84      protected ProxyInfo proxyInfo;
85  
86      private RepositoryPermissions permissionsOverride;
87  
88      // ----------------------------------------------------------------------
89      // Accessors
90      // ----------------------------------------------------------------------
91  
92      public Repository getRepository()
93      {
94          return repository;
95      }
96  
97      public ProxyInfo getProxyInfo()
98      {
99          return proxyInfoProvider != null ? proxyInfoProvider.getProxyInfo( null ) : null;
100     }
101 
102     public AuthenticationInfo getAuthenticationInfo()
103     {
104         return authenticationInfo;
105     }
106 
107     // ----------------------------------------------------------------------
108     // Connection
109     // ----------------------------------------------------------------------
110 
111     public void openConnection()
112         throws ConnectionException, AuthenticationException
113     {
114         try
115         {
116             openConnectionInternal();
117         }
118         catch ( ConnectionException e )
119         {
120             fireSessionConnectionRefused();
121 
122             throw e;
123         }
124         catch ( AuthenticationException e )
125         {
126             fireSessionConnectionRefused();
127 
128             throw e;
129         }
130     }
131 
132     public void connect( Repository repository )
133         throws ConnectionException, AuthenticationException
134     {
135         connect( repository, null, (ProxyInfoProvider) null );
136     }
137 
138     public void connect( Repository repository, ProxyInfo proxyInfo )
139         throws ConnectionException, AuthenticationException
140     {
141         connect( repository, null, proxyInfo );
142     }
143 
144     public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider )
145         throws ConnectionException, AuthenticationException
146     {
147         connect( repository, null, proxyInfoProvider );
148     }
149 
150     public void connect( Repository repository, AuthenticationInfo authenticationInfo )
151         throws ConnectionException, AuthenticationException
152     {
153         connect( repository, authenticationInfo, (ProxyInfoProvider) null );
154     }
155 
156     public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo )
157         throws ConnectionException, AuthenticationException
158     {
159         final ProxyInfo proxy = proxyInfo;
160         connect( repository, authenticationInfo, new ProxyInfoProvider()
161         {
162             public ProxyInfo getProxyInfo( String protocol )
163             {
164                 if ( protocol == null || proxy == null || protocol.equalsIgnoreCase( proxy.getType() ) )
165                 {
166                     return proxy;
167                 }
168                 else
169                 {
170                     return null;
171                 }
172             }
173         } );
174         this.proxyInfo = proxyInfo;
175     }
176 
177     public void connect( Repository repository, AuthenticationInfo authenticationInfo,
178                          ProxyInfoProvider proxyInfoProvider )
179         throws ConnectionException, AuthenticationException
180     {
181         if ( repository == null )
182         {
183             throw new IllegalStateException( "The repository specified cannot be null." );
184         }
185 
186         if ( permissionsOverride != null )
187         {
188             repository.setPermissions( permissionsOverride );
189         }
190 
191         this.repository = repository;
192 
193         if ( authenticationInfo == null )
194         {
195             authenticationInfo = new AuthenticationInfo();
196         }
197 
198         if ( authenticationInfo.getUserName() == null )
199         {
200             // Get user/pass that were encoded in the URL.
201             if ( repository.getUsername() != null )
202             {
203                 authenticationInfo.setUserName( repository.getUsername() );
204                 if ( repository.getPassword() != null && authenticationInfo.getPassword() == null )
205                 {
206                     authenticationInfo.setPassword( repository.getPassword() );
207                 }
208             }
209         }
210 
211         // TODO: Do these needs to be fields, or are they only used in openConnection()?
212         this.authenticationInfo = authenticationInfo;
213 
214         this.proxyInfoProvider = proxyInfoProvider;
215 
216         fireSessionOpening();
217 
218         openConnection();
219 
220         fireSessionOpened();
221     }
222 
223     protected abstract void openConnectionInternal()
224         throws ConnectionException, AuthenticationException;
225 
226     public void disconnect()
227         throws ConnectionException
228     {
229         fireSessionDisconnecting();
230 
231         try
232         {
233             closeConnection();
234         }
235         catch ( ConnectionException e )
236         {
237             fireSessionError( e );
238             throw e;
239         }
240 
241         fireSessionDisconnected();
242     }
243 
244     protected abstract void closeConnection()
245         throws ConnectionException;
246 
247     protected void createParentDirectories( File destination )
248         throws TransferFailedException
249     {
250         File destinationDirectory = destination.getParentFile();
251         try
252         {
253             destinationDirectory = destinationDirectory.getCanonicalFile();
254         }
255         catch ( IOException e )
256         {
257             // not essential to have a canonical file
258         }
259         if ( destinationDirectory != null && !destinationDirectory.exists() )
260         {
261             destinationDirectory.mkdirs();
262             if ( !destinationDirectory.exists() )
263             {
264                 throw new TransferFailedException(
265                     "Specified destination directory cannot be created: " + destinationDirectory );
266             }
267         }
268     }
269 
270     public void setTimeout( int timeoutValue )
271     {
272         connectionTimeout = timeoutValue;
273     }
274 
275     public int getTimeout()
276     {
277         return connectionTimeout;
278     }
279 
280     // ----------------------------------------------------------------------
281     // Stream i/o
282     // ----------------------------------------------------------------------
283 
284     protected void getTransfer( Resource resource, File destination, InputStream input )
285         throws TransferFailedException
286     {
287         getTransfer( resource, destination, input, true, Integer.MAX_VALUE );
288     }
289 
290     protected void getTransfer( Resource resource, OutputStream output, InputStream input )
291         throws TransferFailedException
292     {
293         getTransfer( resource, output, input, true, Integer.MAX_VALUE );
294     }
295 
296     protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput,
297                                 int maxSize )
298         throws TransferFailedException
299     {
300         // ensure that the destination is created only when we are ready to transfer
301         fireTransferDebug( "attempting to create parent directories for destination: " + destination.getName() );
302         createParentDirectories( destination );
303 
304         OutputStream output = new LazyFileOutputStream( destination );
305 
306         fireGetStarted( resource, destination );
307 
308         try
309         {
310             getTransfer( resource, output, input, closeInput, maxSize );
311         }
312         catch ( TransferFailedException e )
313         {
314             if ( destination.exists() )
315             {
316                 boolean deleted = destination.delete();
317 
318                 if ( !deleted )
319                 {
320                     destination.deleteOnExit();
321                 }
322             }
323             throw e;
324         }
325         finally
326         {
327             IOUtil.close( output );
328         }
329 
330         fireGetCompleted( resource, destination );
331     }
332 
333     protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput,
334                                 int maxSize )
335         throws TransferFailedException
336     {
337         try
338         {
339             transfer( resource, input, output, TransferEvent.REQUEST_GET, maxSize );
340 
341             finishGetTransfer( resource, input, output );
342         }
343         catch ( IOException e )
344         {
345             fireTransferError( resource, e, TransferEvent.REQUEST_GET );
346 
347             String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed";
348 
349             throw new TransferFailedException( msg, e );
350         }
351         finally
352         {
353             if ( closeInput )
354             {
355                 IOUtil.close( input );
356             }
357 
358             cleanupGetTransfer( resource );
359         }
360     }
361 
362     protected void finishGetTransfer( Resource resource, InputStream input, OutputStream output )
363         throws TransferFailedException
364     {
365     }
366 
367     protected void cleanupGetTransfer( Resource resource )
368     {
369     }
370 
371     protected void putTransfer( Resource resource, File source, OutputStream output, boolean closeOutput )
372         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
373     {
374         firePutStarted( resource, source );
375 
376         transfer( resource, source, output, closeOutput );
377 
378         firePutCompleted( resource, source );
379     }
380 
381     /**
382      * Write from {@link File} to {@link OutputStream}
383      *
384      * @param resource    resource to transfer
385      * @param source      file to read from
386      * @param output      output stream
387      * @param closeOutput whether the output stream should be closed or not
388      * @throws TransferFailedException
389      * @throws ResourceDoesNotExistException
390      * @throws AuthorizationException
391      * @since 1.0-beta-1
392      */
393     protected void transfer( Resource resource, File source, OutputStream output, boolean closeOutput )
394         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
395     {
396         InputStream input = null;
397 
398         try
399         {
400             input = new FileInputStream( source );
401 
402             putTransfer( resource, input, output, closeOutput );
403         }
404         catch ( FileNotFoundException e )
405         {
406             fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
407 
408             throw new TransferFailedException( "Specified source file does not exist: " + source, e );
409         }
410         finally
411         {
412             IOUtil.close( input );
413         }
414     }
415 
416     protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput )
417         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
418     {
419         try
420         {
421             transfer( resource, input, output, TransferEvent.REQUEST_PUT );
422 
423             finishPutTransfer( resource, input, output );
424         }
425         catch ( IOException e )
426         {
427             fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
428 
429             String msg = "PUT request to: " + resource.getName() + " in " + repository.getName() + " failed";
430 
431             throw new TransferFailedException( msg, e );
432         }
433         finally
434         {
435             if ( closeOutput )
436             {
437                 IOUtil.close( output );
438             }
439 
440             cleanupPutTransfer( resource );
441         }
442     }
443 
444     protected void cleanupPutTransfer( Resource resource )
445     {
446     }
447 
448     protected void finishPutTransfer( Resource resource, InputStream input, OutputStream output )
449         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
450     {
451     }
452 
453     /**
454      * Write from {@link InputStream} to {@link OutputStream}.
455      * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to
456      * {@link Integer#MAX_VALUE}
457      *
458      * @param resource    resource to transfer
459      * @param input       input stream
460      * @param output      output stream
461      * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT}
462      * @throws IOException
463      */
464     protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType )
465         throws IOException
466     {
467         transfer( resource, input, output, requestType, Integer.MAX_VALUE );
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      * @param maxSize     size of the buffer
480      * @throws IOException
481      */
482     protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, int maxSize )
483         throws IOException
484     {
485         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
486 
487         TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType );
488         transferEvent.setTimestamp( System.currentTimeMillis() );
489 
490         int remaining = maxSize;
491         while ( remaining > 0 )
492         {
493             int n = input.read( buffer, 0, Math.min( buffer.length, remaining ) );
494 
495             if ( n == -1 )
496             {
497                 break;
498             }
499 
500             fireTransferProgress( transferEvent, buffer, n );
501 
502             output.write( buffer, 0, n );
503 
504             remaining -= n;
505         }
506         output.flush();
507     }
508 
509     // ----------------------------------------------------------------------
510     //
511     // ----------------------------------------------------------------------
512 
513     protected void fireTransferProgress( TransferEvent transferEvent, byte[] buffer, int n )
514     {
515         transferEventSupport.fireTransferProgress( transferEvent, buffer, n );
516     }
517 
518     protected void fireGetCompleted( Resource resource, File localFile )
519     {
520         long timestamp = System.currentTimeMillis();
521 
522         TransferEvent transferEvent =
523             new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_GET );
524 
525         transferEvent.setTimestamp( timestamp );
526 
527         transferEvent.setLocalFile( localFile );
528 
529         transferEventSupport.fireTransferCompleted( transferEvent );
530     }
531 
532     protected void fireGetStarted( Resource resource, File localFile )
533     {
534         long timestamp = System.currentTimeMillis();
535 
536         TransferEvent transferEvent =
537             new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_GET );
538 
539         transferEvent.setTimestamp( timestamp );
540 
541         transferEvent.setLocalFile( localFile );
542 
543         transferEventSupport.fireTransferStarted( transferEvent );
544     }
545 
546     protected void fireGetInitiated( Resource resource, File localFile )
547     {
548         long timestamp = System.currentTimeMillis();
549 
550         TransferEvent transferEvent =
551             new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET );
552 
553         transferEvent.setTimestamp( timestamp );
554 
555         transferEvent.setLocalFile( localFile );
556 
557         transferEventSupport.fireTransferInitiated( transferEvent );
558     }
559 
560     protected void firePutInitiated( Resource resource, File localFile )
561     {
562         long timestamp = System.currentTimeMillis();
563 
564         TransferEvent transferEvent =
565             new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_PUT );
566 
567         transferEvent.setTimestamp( timestamp );
568 
569         transferEvent.setLocalFile( localFile );
570 
571         transferEventSupport.fireTransferInitiated( transferEvent );
572     }
573 
574     protected void firePutCompleted( Resource resource, File localFile )
575     {
576         long timestamp = System.currentTimeMillis();
577 
578         TransferEvent transferEvent =
579             new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_PUT );
580 
581         transferEvent.setTimestamp( timestamp );
582 
583         transferEvent.setLocalFile( localFile );
584 
585         transferEventSupport.fireTransferCompleted( transferEvent );
586     }
587 
588     protected void firePutStarted( Resource resource, File localFile )
589     {
590         long timestamp = System.currentTimeMillis();
591 
592         TransferEvent transferEvent =
593             new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT );
594 
595         transferEvent.setTimestamp( timestamp );
596 
597         transferEvent.setLocalFile( localFile );
598 
599         transferEventSupport.fireTransferStarted( transferEvent );
600     }
601 
602     protected void fireSessionDisconnected()
603     {
604         long timestamp = System.currentTimeMillis();
605 
606         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTED );
607 
608         sessionEvent.setTimestamp( timestamp );
609 
610         sessionEventSupport.fireSessionDisconnected( sessionEvent );
611     }
612 
613     protected void fireSessionDisconnecting()
614     {
615         long timestamp = System.currentTimeMillis();
616 
617         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTING );
618 
619         sessionEvent.setTimestamp( timestamp );
620 
621         sessionEventSupport.fireSessionDisconnecting( sessionEvent );
622     }
623 
624     protected void fireSessionLoggedIn()
625     {
626         long timestamp = System.currentTimeMillis();
627 
628         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_IN );
629 
630         sessionEvent.setTimestamp( timestamp );
631 
632         sessionEventSupport.fireSessionLoggedIn( sessionEvent );
633     }
634 
635     protected void fireSessionLoggedOff()
636     {
637         long timestamp = System.currentTimeMillis();
638 
639         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_OFF );
640 
641         sessionEvent.setTimestamp( timestamp );
642 
643         sessionEventSupport.fireSessionLoggedOff( sessionEvent );
644     }
645 
646     protected void fireSessionOpened()
647     {
648         long timestamp = System.currentTimeMillis();
649 
650         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENED );
651 
652         sessionEvent.setTimestamp( timestamp );
653 
654         sessionEventSupport.fireSessionOpened( sessionEvent );
655     }
656 
657     protected void fireSessionOpening()
658     {
659         long timestamp = System.currentTimeMillis();
660 
661         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENING );
662 
663         sessionEvent.setTimestamp( timestamp );
664 
665         sessionEventSupport.fireSessionOpening( sessionEvent );
666     }
667 
668     protected void fireSessionConnectionRefused()
669     {
670         long timestamp = System.currentTimeMillis();
671 
672         SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_CONNECTION_REFUSED );
673 
674         sessionEvent.setTimestamp( timestamp );
675 
676         sessionEventSupport.fireSessionConnectionRefused( sessionEvent );
677     }
678 
679     protected void fireSessionError( Exception exception )
680     {
681         long timestamp = System.currentTimeMillis();
682 
683         SessionEvent sessionEvent = new SessionEvent( this, exception );
684 
685         sessionEvent.setTimestamp( timestamp );
686 
687         sessionEventSupport.fireSessionError( sessionEvent );
688 
689     }
690 
691     protected void fireTransferDebug( String message )
692     {
693         transferEventSupport.fireDebug( message );
694     }
695 
696     protected void fireSessionDebug( String message )
697     {
698         sessionEventSupport.fireDebug( message );
699     }
700 
701     public boolean hasTransferListener( TransferListener listener )
702     {
703         return transferEventSupport.hasTransferListener( listener );
704     }
705 
706     public void addTransferListener( TransferListener listener )
707     {
708         transferEventSupport.addTransferListener( listener );
709     }
710 
711     public void removeTransferListener( TransferListener listener )
712     {
713         transferEventSupport.removeTransferListener( listener );
714     }
715 
716     public void addSessionListener( SessionListener listener )
717     {
718         sessionEventSupport.addSessionListener( listener );
719     }
720 
721     public boolean hasSessionListener( SessionListener listener )
722     {
723         return sessionEventSupport.hasSessionListener( listener );
724     }
725 
726     public void removeSessionListener( SessionListener listener )
727     {
728         sessionEventSupport.removeSessionListener( listener );
729     }
730 
731     protected void fireTransferError( Resource resource, Exception e, int requestType )
732     {
733         TransferEvent transferEvent = new TransferEvent( this, resource, e, requestType );
734         transferEventSupport.fireTransferError( transferEvent );
735     }
736 
737 
738     public SessionEventSupport getSessionEventSupport()
739     {
740         return sessionEventSupport;
741     }
742 
743     public void setSessionEventSupport( SessionEventSupport sessionEventSupport )
744     {
745         this.sessionEventSupport = sessionEventSupport;
746     }
747 
748     public TransferEventSupport getTransferEventSupport()
749     {
750         return transferEventSupport;
751     }
752 
753     public void setTransferEventSupport( TransferEventSupport transferEventSupport )
754     {
755         this.transferEventSupport = transferEventSupport;
756     }
757 
758     /**
759      * This method is used if you are not streaming the transfer, to make sure any listeners dependent on state
760      * (eg checksum observers) succeed.
761      */
762     protected void postProcessListeners( Resource resource, File source, int requestType )
763         throws TransferFailedException
764     {
765         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
766 
767         TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType );
768         transferEvent.setTimestamp( System.currentTimeMillis() );
769         transferEvent.setLocalFile( source );
770 
771         InputStream input = null;
772         try
773         {
774             input = new FileInputStream( source );
775 
776             while ( true )
777             {
778                 int n = input.read( buffer );
779 
780                 if ( n == -1 )
781                 {
782                     break;
783                 }
784 
785                 fireTransferProgress( transferEvent, buffer, n );
786             }
787         }
788         catch ( IOException e )
789         {
790             fireTransferError( resource, e, requestType );
791 
792             throw new TransferFailedException( "Failed to post-process the source file", e );
793         }
794         finally
795         {
796             IOUtil.close( input );
797         }
798     }
799 
800     public void putDirectory( File sourceDirectory, String destinationDirectory )
801         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
802     {
803         throw new UnsupportedOperationException( "The wagon you are using has not implemented putDirectory()" );
804     }
805 
806     public boolean supportsDirectoryCopy()
807     {
808         return false;
809     }
810 
811     protected static String getPath( String basedir, String dir )
812     {
813         String path;
814         path = basedir;
815         if ( !basedir.endsWith( "/" ) && !dir.startsWith( "/" ) )
816         {
817             path += "/";
818         }
819         path += dir;
820         return path;
821     }
822 
823     public boolean isInteractive()
824     {
825         return interactive;
826     }
827 
828     public void setInteractive( boolean interactive )
829     {
830         this.interactive = interactive;
831     }
832 
833     public List getFileList( String destinationDirectory )
834         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
835     {
836         throw new UnsupportedOperationException( "The wagon you are using has not implemented getFileList()" );
837     }
838 
839     public boolean resourceExists( String resourceName )
840         throws TransferFailedException, AuthorizationException
841     {
842         throw new UnsupportedOperationException( "The wagon you are using has not implemented resourceExists()" );
843     }
844 
845     protected ProxyInfo getProxyInfo( String protocol, String host )
846     {
847         if ( proxyInfoProvider != null )
848         {
849             ProxyInfo proxyInfo = proxyInfoProvider.getProxyInfo( protocol );
850             if ( !ProxyUtils.validateNonProxyHosts( proxyInfo, host ) )
851             {
852                 return proxyInfo;
853             }
854         }
855         return null;
856     }
857 
858     public RepositoryPermissions getPermissionsOverride()
859     {
860         return permissionsOverride;
861     }
862 
863     public void setPermissionsOverride( RepositoryPermissions permissionsOverride )
864     {
865         this.permissionsOverride = permissionsOverride;
866     }
867 
868     public void setReadTimeout( int readTimeout )
869     {
870         this.readTimeout = readTimeout;
871     }
872 
873     public int getReadTimeout()
874     {
875         return this.readTimeout;
876     }
877 }