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
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
73
74
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
83
84 protected ProxyInfo proxyInfo;
85
86 private RepositoryPermissions permissionsOverride;
87
88
89
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
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
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
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
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
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
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
383
384
385
386
387
388
389
390
391
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
455
456
457
458
459
460
461
462
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
472
473
474
475
476
477
478
479
480
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
760
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 }