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