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