001package org.apache.maven.wagon; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.maven.wagon.authentication.AuthenticationException; 023import org.apache.maven.wagon.authentication.AuthenticationInfo; 024import org.apache.maven.wagon.authorization.AuthorizationException; 025import org.apache.maven.wagon.events.SessionEvent; 026import org.apache.maven.wagon.events.SessionEventSupport; 027import org.apache.maven.wagon.events.SessionListener; 028import org.apache.maven.wagon.events.TransferEvent; 029import org.apache.maven.wagon.events.TransferEventSupport; 030import org.apache.maven.wagon.events.TransferListener; 031import org.apache.maven.wagon.proxy.ProxyInfo; 032import org.apache.maven.wagon.proxy.ProxyInfoProvider; 033import org.apache.maven.wagon.proxy.ProxyUtils; 034import org.apache.maven.wagon.repository.Repository; 035import org.apache.maven.wagon.repository.RepositoryPermissions; 036import org.apache.maven.wagon.resource.Resource; 037import org.codehaus.plexus.util.IOUtil; 038 039import java.io.File; 040import java.io.FileInputStream; 041import java.io.FileNotFoundException; 042import java.io.IOException; 043import java.io.InputStream; 044import java.io.OutputStream; 045import java.nio.Buffer; 046import java.nio.ByteBuffer; 047import java.nio.channels.Channels; 048import java.nio.channels.ReadableByteChannel; 049import java.util.List; 050 051import static java.lang.Math.max; 052import static java.lang.Math.min; 053 054/** 055 * Implementation of common facilities for Wagon providers. 056 * 057 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> 058 */ 059public abstract class AbstractWagon 060 implements Wagon 061{ 062 protected static final int DEFAULT_BUFFER_SIZE = 4 * 1024; 063 protected static final int MAXIMUM_BUFFER_SIZE = 512 * 1024; 064 065 /** 066 * To efficiently buffer data, use a multiple of 4 KiB as this is likely to match the hardware 067 * buffer size of certain storage devices. 068 */ 069 protected static final int BUFFER_SEGMENT_SIZE = 4 * 1024; 070 071 /** 072 * The desired minimum amount of chunks in which a {@link Resource} shall be 073 * {@link #transfer(Resource, InputStream, OutputStream, int, long) transferred}. 074 * This corresponds to the minimum times {@link #fireTransferProgress(TransferEvent, byte[], int)} 075 * is executed. 100 notifications is a conservative value that will lead to small chunks for 076 * any artifact less that {@link #BUFFER_SEGMENT_SIZE} * {@link #MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS} 077 * in size. 078 */ 079 protected static final int MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS = 100; 080 081 protected Repository repository; 082 083 protected SessionEventSupport sessionEventSupport = new SessionEventSupport(); 084 085 protected TransferEventSupport transferEventSupport = new TransferEventSupport(); 086 087 protected AuthenticationInfo authenticationInfo; 088 089 protected boolean interactive = true; 090 091 092 private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT; 093 094 /** 095 * read timeout value 096 * 097 * @since 2.2 098 */ 099 private int readTimeout = 100 Integer.parseInt( System.getProperty( "maven.wagon.rto", Integer.toString( Wagon.DEFAULT_READ_TIMEOUT ) ) ); 101 102 private ProxyInfoProvider proxyInfoProvider; 103 104 /** 105 * @deprecated 106 */ 107 protected ProxyInfo proxyInfo; 108 109 private RepositoryPermissions permissionsOverride; 110 111 // ---------------------------------------------------------------------- 112 // Accessors 113 // ---------------------------------------------------------------------- 114 115 public Repository getRepository() 116 { 117 return repository; 118 } 119 120 public ProxyInfo getProxyInfo() 121 { 122 return proxyInfoProvider != null ? proxyInfoProvider.getProxyInfo( null ) : null; 123 } 124 125 public AuthenticationInfo getAuthenticationInfo() 126 { 127 return authenticationInfo; 128 } 129 130 // ---------------------------------------------------------------------- 131 // Connection 132 // ---------------------------------------------------------------------- 133 134 public void openConnection() 135 throws ConnectionException, AuthenticationException 136 { 137 try 138 { 139 openConnectionInternal(); 140 } 141 catch ( ConnectionException e ) 142 { 143 fireSessionConnectionRefused(); 144 145 throw e; 146 } 147 catch ( AuthenticationException e ) 148 { 149 fireSessionConnectionRefused(); 150 151 throw e; 152 } 153 } 154 155 public void connect( Repository repository ) 156 throws ConnectionException, AuthenticationException 157 { 158 connect( repository, null, (ProxyInfoProvider) null ); 159 } 160 161 public void connect( Repository repository, ProxyInfo proxyInfo ) 162 throws ConnectionException, AuthenticationException 163 { 164 connect( repository, null, proxyInfo ); 165 } 166 167 public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider ) 168 throws ConnectionException, AuthenticationException 169 { 170 connect( repository, null, proxyInfoProvider ); 171 } 172 173 public void connect( Repository repository, AuthenticationInfo authenticationInfo ) 174 throws ConnectionException, AuthenticationException 175 { 176 connect( repository, authenticationInfo, (ProxyInfoProvider) null ); 177 } 178 179 public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo ) 180 throws ConnectionException, AuthenticationException 181 { 182 final ProxyInfo proxy = proxyInfo; 183 connect( repository, authenticationInfo, new ProxyInfoProvider() 184 { 185 public ProxyInfo getProxyInfo( String protocol ) 186 { 187 if ( protocol == null || proxy == null || protocol.equalsIgnoreCase( proxy.getType() ) ) 188 { 189 return proxy; 190 } 191 else 192 { 193 return null; 194 } 195 } 196 } ); 197 } 198 199 public void connect( Repository repository, AuthenticationInfo authenticationInfo, 200 ProxyInfoProvider proxyInfoProvider ) 201 throws ConnectionException, AuthenticationException 202 { 203 if ( repository == null ) 204 { 205 throw new NullPointerException( "repository cannot be null" ); 206 } 207 208 if ( permissionsOverride != null ) 209 { 210 repository.setPermissions( permissionsOverride ); 211 } 212 213 this.repository = repository; 214 215 if ( authenticationInfo == null ) 216 { 217 authenticationInfo = new AuthenticationInfo(); 218 } 219 220 if ( authenticationInfo.getUserName() == null ) 221 { 222 // Get user/pass that were encoded in the URL. 223 if ( repository.getUsername() != null ) 224 { 225 authenticationInfo.setUserName( repository.getUsername() ); 226 if ( repository.getPassword() != null && authenticationInfo.getPassword() == null ) 227 { 228 authenticationInfo.setPassword( repository.getPassword() ); 229 } 230 } 231 } 232 233 this.authenticationInfo = authenticationInfo; 234 235 this.proxyInfoProvider = proxyInfoProvider; 236 237 fireSessionOpening(); 238 239 openConnection(); 240 241 fireSessionOpened(); 242 } 243 244 protected abstract void openConnectionInternal() 245 throws ConnectionException, AuthenticationException; 246 247 public void disconnect() 248 throws ConnectionException 249 { 250 fireSessionDisconnecting(); 251 252 try 253 { 254 closeConnection(); 255 } 256 catch ( ConnectionException e ) 257 { 258 fireSessionError( e ); 259 throw e; 260 } 261 262 fireSessionDisconnected(); 263 } 264 265 protected abstract void closeConnection() 266 throws ConnectionException; 267 268 protected void createParentDirectories( File destination ) 269 throws TransferFailedException 270 { 271 File destinationDirectory = destination.getParentFile(); 272 try 273 { 274 destinationDirectory = destinationDirectory.getCanonicalFile(); 275 } 276 catch ( IOException e ) 277 { 278 // not essential to have a canonical file 279 } 280 if ( destinationDirectory != null && !destinationDirectory.exists() ) 281 { 282 destinationDirectory.mkdirs(); 283 if ( !destinationDirectory.exists() ) 284 { 285 throw new TransferFailedException( 286 "Specified destination directory cannot be created: " + destinationDirectory ); 287 } 288 } 289 } 290 291 public void setTimeout( int timeoutValue ) 292 { 293 connectionTimeout = timeoutValue; 294 } 295 296 public int getTimeout() 297 { 298 return connectionTimeout; 299 } 300 301 // ---------------------------------------------------------------------- 302 // Stream i/o 303 // ---------------------------------------------------------------------- 304 305 protected void getTransfer( Resource resource, File destination, InputStream input ) 306 throws TransferFailedException 307 { 308 getTransfer( resource, destination, input, true, Long.MAX_VALUE ); 309 } 310 311 protected void getTransfer( Resource resource, OutputStream output, InputStream input ) 312 throws TransferFailedException 313 { 314 getTransfer( resource, output, input, true, Long.MAX_VALUE ); 315 } 316 317 @Deprecated 318 protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput, 319 int maxSize ) 320 throws TransferFailedException 321 { 322 getTransfer( resource, destination, input, closeInput, (long) maxSize ); 323 } 324 325 protected void getTransfer( Resource resource, File destination, InputStream input, boolean closeInput, 326 long maxSize ) 327 throws TransferFailedException 328 { 329 // ensure that the destination is created only when we are ready to transfer 330 fireTransferDebug( "attempting to create parent directories for destination: " + destination.getName() ); 331 createParentDirectories( destination ); 332 333 fireGetStarted( resource, destination ); 334 335 OutputStream output = null; 336 try 337 { 338 output = new LazyFileOutputStream( destination ); 339 getTransfer( resource, output, input, closeInput, maxSize ); 340 output.close(); 341 output = null; 342 } 343 catch ( final IOException e ) 344 { 345 if ( destination.exists() ) 346 { 347 boolean deleted = destination.delete(); 348 349 if ( !deleted ) 350 { 351 destination.deleteOnExit(); 352 } 353 } 354 355 fireTransferError( resource, e, TransferEvent.REQUEST_GET ); 356 357 String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed"; 358 359 throw new TransferFailedException( msg, e ); 360 } 361 catch ( TransferFailedException e ) 362 { 363 if ( destination.exists() ) 364 { 365 boolean deleted = destination.delete(); 366 367 if ( !deleted ) 368 { 369 destination.deleteOnExit(); 370 } 371 } 372 throw e; 373 } 374 finally 375 { 376 IOUtil.close( output ); 377 } 378 379 fireGetCompleted( resource, destination ); 380 } 381 382 @Deprecated 383 protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput, 384 int maxSize ) 385 throws TransferFailedException 386 { 387 getTransfer( resource, output, input, closeInput, (long) maxSize ); 388 } 389 390 protected void getTransfer( Resource resource, OutputStream output, InputStream input, boolean closeInput, 391 long maxSize ) 392 throws TransferFailedException 393 { 394 try 395 { 396 transfer( resource, input, output, TransferEvent.REQUEST_GET, maxSize ); 397 398 finishGetTransfer( resource, input, output ); 399 400 if ( closeInput ) 401 { 402 input.close(); 403 input = null; 404 } 405 406 } 407 catch ( IOException e ) 408 { 409 fireTransferError( resource, e, TransferEvent.REQUEST_GET ); 410 411 String msg = "GET request of: " + resource.getName() + " from " + repository.getName() + " failed"; 412 413 throw new TransferFailedException( msg, e ); 414 } 415 finally 416 { 417 if ( closeInput ) 418 { 419 IOUtil.close( input ); 420 } 421 422 cleanupGetTransfer( resource ); 423 } 424 } 425 426 protected void finishGetTransfer( Resource resource, InputStream input, OutputStream output ) 427 throws TransferFailedException 428 { 429 } 430 431 protected void cleanupGetTransfer( Resource resource ) 432 { 433 } 434 435 protected void putTransfer( Resource resource, File source, OutputStream output, boolean closeOutput ) 436 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException 437 { 438 firePutStarted( resource, source ); 439 440 transfer( resource, source, output, closeOutput ); 441 442 firePutCompleted( resource, source ); 443 } 444 445 /** 446 * Write from {@link File} to {@link OutputStream} 447 * 448 * @param resource resource to transfer 449 * @param source file to read from 450 * @param output output stream 451 * @param closeOutput whether the output stream should be closed or not 452 * @throws TransferFailedException 453 * @throws ResourceDoesNotExistException 454 * @throws AuthorizationException 455 * @since 1.0-beta-1 456 */ 457 protected void transfer( Resource resource, File source, OutputStream output, boolean closeOutput ) 458 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException 459 { 460 InputStream input = null; 461 462 try 463 { 464 input = new FileInputStream( source ); 465 466 putTransfer( resource, input, output, closeOutput ); 467 468 input.close(); 469 input = null; 470 } 471 catch ( FileNotFoundException e ) 472 { 473 fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); 474 475 throw new TransferFailedException( "Specified source file does not exist: " + source, e ); 476 } 477 catch ( final IOException e ) 478 { 479 fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); 480 481 throw new TransferFailedException( "Failure transferring " + source, e ); 482 } 483 finally 484 { 485 IOUtil.close( input ); 486 } 487 } 488 489 protected void putTransfer( Resource resource, InputStream input, OutputStream output, boolean closeOutput ) 490 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException 491 { 492 try 493 { 494 transfer( resource, input, output, TransferEvent.REQUEST_PUT, 495 resource.getContentLength() == WagonConstants.UNKNOWN_LENGTH 496 ? Long.MAX_VALUE 497 : resource.getContentLength() ); 498 499 finishPutTransfer( resource, input, output ); 500 501 if ( closeOutput ) 502 { 503 output.close(); 504 output = null; 505 } 506 } 507 catch ( IOException e ) 508 { 509 fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); 510 511 String msg = "PUT request to: " + resource.getName() + " in " + repository.getName() + " failed"; 512 513 throw new TransferFailedException( msg, e ); 514 } 515 finally 516 { 517 if ( closeOutput ) 518 { 519 IOUtil.close( output ); 520 } 521 522 cleanupPutTransfer( resource ); 523 } 524 } 525 526 protected void cleanupPutTransfer( Resource resource ) 527 { 528 } 529 530 protected void finishPutTransfer( Resource resource, InputStream input, OutputStream output ) 531 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException 532 { 533 } 534 535 /** 536 * Write from {@link InputStream} to {@link OutputStream}. 537 * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to 538 * {@link Integer#MAX_VALUE} 539 * 540 * @param resource resource to transfer 541 * @param input input stream 542 * @param output output stream 543 * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT} 544 * @throws IOException 545 */ 546 protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType ) 547 throws IOException 548 { 549 transfer( resource, input, output, requestType, Long.MAX_VALUE ); 550 } 551 552 /** 553 * Write from {@link InputStream} to {@link OutputStream}. 554 * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, int)} with a maxSize equals to 555 * {@link Integer#MAX_VALUE} 556 * 557 * @param resource resource to transfer 558 * @param input input stream 559 * @param output output stream 560 * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT} 561 * @param maxSize size of the buffer 562 * @throws IOException 563 * @deprecated Please use the transfer using long as type of maxSize 564 */ 565 @Deprecated 566 protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, int maxSize ) 567 throws IOException 568 { 569 transfer( resource, input, output, requestType, (long) maxSize ); 570 } 571 572 /** 573 * Write from {@link InputStream} to {@link OutputStream}. 574 * Equivalent to {@link #transfer(Resource, InputStream, OutputStream, int, long)} with a maxSize equals to 575 * {@link Integer#MAX_VALUE} 576 * 577 * @param resource resource to transfer 578 * @param input input stream 579 * @param output output stream 580 * @param requestType one of {@link TransferEvent#REQUEST_GET} or {@link TransferEvent#REQUEST_PUT} 581 * @param maxSize size of the buffer 582 * @throws IOException 583 */ 584 protected void transfer( Resource resource, InputStream input, OutputStream output, int requestType, long maxSize ) 585 throws IOException 586 { 587 ByteBuffer buffer = ByteBuffer.allocate( getBufferCapacityForTransfer( resource.getContentLength() ) ); 588 int halfBufferCapacity = buffer.capacity() / 2; 589 590 TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType ); 591 transferEvent.setTimestamp( System.currentTimeMillis() ); 592 593 ReadableByteChannel in = Channels.newChannel( input ); 594 595 long remaining = maxSize; 596 while ( remaining > 0L ) 597 { 598 int read = in.read( buffer ); 599 600 if ( read == -1 ) 601 { 602 // EOF, but some data has not been written yet. 603 if ( ( (Buffer) buffer ).position() != 0 ) 604 { 605 ( (Buffer) buffer ).flip(); 606 fireTransferProgress( transferEvent, buffer.array(), ( (Buffer) buffer ).limit() ); 607 output.write( buffer.array(), 0, ( (Buffer) buffer ).limit() ); 608 ( (Buffer) buffer ).clear(); 609 } 610 611 break; 612 } 613 614 // Prevent minichunking/fragmentation: when less than half the buffer is utilized, 615 // read some more bytes before writing and firing progress. 616 if ( ( (Buffer) buffer ).position() < halfBufferCapacity ) 617 { 618 continue; 619 } 620 621 ( (Buffer) buffer ).flip(); 622 fireTransferProgress( transferEvent, buffer.array(), ( (Buffer) buffer ).limit() ); 623 output.write( buffer.array(), 0, ( (Buffer) buffer ).limit() ); 624 remaining -= ( (Buffer) buffer ).limit(); 625 ( (Buffer) buffer ).clear(); 626 } 627 output.flush(); 628 } 629 630 /** 631 * Provides a buffer size for efficiently transferring the given amount of bytes such that 632 * it is not fragmented into too many chunks. For larger files larger buffers are provided such that downstream 633 * {@link #fireTransferProgress(TransferEvent, byte[], int) listeners} are not notified too frequently. 634 * For instance, transferring gigabyte-sized resources would result in millions of notifications when using 635 * only a few kibibytes of buffer, drastically slowing down transfer since transfer progress listeners and 636 * notifications are synchronous and may block, e.g., when writing download progress status to console. 637 * 638 * @param numberOfBytes can be 0 or less, in which case a default buffer size is used. 639 * @return a byte buffer suitable for transferring the given amount of bytes without too many chunks. 640 */ 641 protected int getBufferCapacityForTransfer( long numberOfBytes ) 642 { 643 if ( numberOfBytes <= 0L ) 644 { 645 return DEFAULT_BUFFER_SIZE; 646 } 647 648 final long numberOfBufferSegments = numberOfBytes 649 / ( BUFFER_SEGMENT_SIZE * MINIMUM_AMOUNT_OF_TRANSFER_CHUNKS ); 650 final long potentialBufferSize = numberOfBufferSegments * BUFFER_SEGMENT_SIZE; 651 if ( potentialBufferSize > Integer.MAX_VALUE ) 652 { 653 return MAXIMUM_BUFFER_SIZE; 654 } 655 return min( MAXIMUM_BUFFER_SIZE, max( DEFAULT_BUFFER_SIZE, (int) potentialBufferSize ) ); 656 } 657 658 // ---------------------------------------------------------------------- 659 // 660 // ---------------------------------------------------------------------- 661 662 protected void fireTransferProgress( TransferEvent transferEvent, byte[] buffer, int n ) 663 { 664 transferEventSupport.fireTransferProgress( transferEvent, buffer, n ); 665 } 666 667 protected void fireGetCompleted( Resource resource, File localFile ) 668 { 669 long timestamp = System.currentTimeMillis(); 670 671 TransferEvent transferEvent = 672 new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_GET ); 673 674 transferEvent.setTimestamp( timestamp ); 675 676 transferEvent.setLocalFile( localFile ); 677 678 transferEventSupport.fireTransferCompleted( transferEvent ); 679 } 680 681 protected void fireGetStarted( Resource resource, File localFile ) 682 { 683 long timestamp = System.currentTimeMillis(); 684 685 TransferEvent transferEvent = 686 new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_GET ); 687 688 transferEvent.setTimestamp( timestamp ); 689 690 transferEvent.setLocalFile( localFile ); 691 692 transferEventSupport.fireTransferStarted( transferEvent ); 693 } 694 695 protected void fireGetInitiated( Resource resource, File localFile ) 696 { 697 long timestamp = System.currentTimeMillis(); 698 699 TransferEvent transferEvent = 700 new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET ); 701 702 transferEvent.setTimestamp( timestamp ); 703 704 transferEvent.setLocalFile( localFile ); 705 706 transferEventSupport.fireTransferInitiated( transferEvent ); 707 } 708 709 protected void firePutInitiated( Resource resource, File localFile ) 710 { 711 long timestamp = System.currentTimeMillis(); 712 713 TransferEvent transferEvent = 714 new TransferEvent( this, resource, TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_PUT ); 715 716 transferEvent.setTimestamp( timestamp ); 717 718 transferEvent.setLocalFile( localFile ); 719 720 transferEventSupport.fireTransferInitiated( transferEvent ); 721 } 722 723 protected void firePutCompleted( Resource resource, File localFile ) 724 { 725 long timestamp = System.currentTimeMillis(); 726 727 TransferEvent transferEvent = 728 new TransferEvent( this, resource, TransferEvent.TRANSFER_COMPLETED, TransferEvent.REQUEST_PUT ); 729 730 transferEvent.setTimestamp( timestamp ); 731 732 transferEvent.setLocalFile( localFile ); 733 734 transferEventSupport.fireTransferCompleted( transferEvent ); 735 } 736 737 protected void firePutStarted( Resource resource, File localFile ) 738 { 739 long timestamp = System.currentTimeMillis(); 740 741 TransferEvent transferEvent = 742 new TransferEvent( this, resource, TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT ); 743 744 transferEvent.setTimestamp( timestamp ); 745 746 transferEvent.setLocalFile( localFile ); 747 748 transferEventSupport.fireTransferStarted( transferEvent ); 749 } 750 751 protected void fireSessionDisconnected() 752 { 753 long timestamp = System.currentTimeMillis(); 754 755 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTED ); 756 757 sessionEvent.setTimestamp( timestamp ); 758 759 sessionEventSupport.fireSessionDisconnected( sessionEvent ); 760 } 761 762 protected void fireSessionDisconnecting() 763 { 764 long timestamp = System.currentTimeMillis(); 765 766 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_DISCONNECTING ); 767 768 sessionEvent.setTimestamp( timestamp ); 769 770 sessionEventSupport.fireSessionDisconnecting( sessionEvent ); 771 } 772 773 protected void fireSessionLoggedIn() 774 { 775 long timestamp = System.currentTimeMillis(); 776 777 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_IN ); 778 779 sessionEvent.setTimestamp( timestamp ); 780 781 sessionEventSupport.fireSessionLoggedIn( sessionEvent ); 782 } 783 784 protected void fireSessionLoggedOff() 785 { 786 long timestamp = System.currentTimeMillis(); 787 788 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_LOGGED_OFF ); 789 790 sessionEvent.setTimestamp( timestamp ); 791 792 sessionEventSupport.fireSessionLoggedOff( sessionEvent ); 793 } 794 795 protected void fireSessionOpened() 796 { 797 long timestamp = System.currentTimeMillis(); 798 799 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENED ); 800 801 sessionEvent.setTimestamp( timestamp ); 802 803 sessionEventSupport.fireSessionOpened( sessionEvent ); 804 } 805 806 protected void fireSessionOpening() 807 { 808 long timestamp = System.currentTimeMillis(); 809 810 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_OPENING ); 811 812 sessionEvent.setTimestamp( timestamp ); 813 814 sessionEventSupport.fireSessionOpening( sessionEvent ); 815 } 816 817 protected void fireSessionConnectionRefused() 818 { 819 long timestamp = System.currentTimeMillis(); 820 821 SessionEvent sessionEvent = new SessionEvent( this, SessionEvent.SESSION_CONNECTION_REFUSED ); 822 823 sessionEvent.setTimestamp( timestamp ); 824 825 sessionEventSupport.fireSessionConnectionRefused( sessionEvent ); 826 } 827 828 protected void fireSessionError( Exception exception ) 829 { 830 long timestamp = System.currentTimeMillis(); 831 832 SessionEvent sessionEvent = new SessionEvent( this, exception ); 833 834 sessionEvent.setTimestamp( timestamp ); 835 836 sessionEventSupport.fireSessionError( sessionEvent ); 837 838 } 839 840 protected void fireTransferDebug( String message ) 841 { 842 transferEventSupport.fireDebug( message ); 843 } 844 845 protected void fireSessionDebug( String message ) 846 { 847 sessionEventSupport.fireDebug( message ); 848 } 849 850 public boolean hasTransferListener( TransferListener listener ) 851 { 852 return transferEventSupport.hasTransferListener( listener ); 853 } 854 855 public void addTransferListener( TransferListener listener ) 856 { 857 transferEventSupport.addTransferListener( listener ); 858 } 859 860 public void removeTransferListener( TransferListener listener ) 861 { 862 transferEventSupport.removeTransferListener( listener ); 863 } 864 865 public void addSessionListener( SessionListener listener ) 866 { 867 sessionEventSupport.addSessionListener( listener ); 868 } 869 870 public boolean hasSessionListener( SessionListener listener ) 871 { 872 return sessionEventSupport.hasSessionListener( listener ); 873 } 874 875 public void removeSessionListener( SessionListener listener ) 876 { 877 sessionEventSupport.removeSessionListener( listener ); 878 } 879 880 protected void fireTransferError( Resource resource, Exception e, int requestType ) 881 { 882 TransferEvent transferEvent = new TransferEvent( this, resource, e, requestType ); 883 transferEventSupport.fireTransferError( transferEvent ); 884 } 885 886 887 public SessionEventSupport getSessionEventSupport() 888 { 889 return sessionEventSupport; 890 } 891 892 public void setSessionEventSupport( SessionEventSupport sessionEventSupport ) 893 { 894 this.sessionEventSupport = sessionEventSupport; 895 } 896 897 public TransferEventSupport getTransferEventSupport() 898 { 899 return transferEventSupport; 900 } 901 902 public void setTransferEventSupport( TransferEventSupport transferEventSupport ) 903 { 904 this.transferEventSupport = transferEventSupport; 905 } 906 907 /** 908 * This method is used if you are not streaming the transfer, to make sure any listeners dependent on state 909 * (eg checksum observers) succeed. 910 */ 911 protected void postProcessListeners( Resource resource, File source, int requestType ) 912 throws TransferFailedException 913 { 914 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 915 916 TransferEvent transferEvent = new TransferEvent( this, resource, TransferEvent.TRANSFER_PROGRESS, requestType ); 917 transferEvent.setTimestamp( System.currentTimeMillis() ); 918 transferEvent.setLocalFile( source ); 919 920 InputStream input = null; 921 try 922 { 923 input = new FileInputStream( source ); 924 925 while ( true ) 926 { 927 int n = input.read( buffer ); 928 929 if ( n == -1 ) 930 { 931 break; 932 } 933 934 fireTransferProgress( transferEvent, buffer, n ); 935 } 936 937 input.close(); 938 input = null; 939 } 940 catch ( IOException e ) 941 { 942 fireTransferError( resource, e, requestType ); 943 944 throw new TransferFailedException( "Failed to post-process the source file", e ); 945 } 946 finally 947 { 948 IOUtil.close( input ); 949 } 950 } 951 952 public void putDirectory( File sourceDirectory, String destinationDirectory ) 953 throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException 954 { 955 throw new UnsupportedOperationException( "The wagon you are using has not implemented putDirectory()" ); 956 } 957 958 public boolean supportsDirectoryCopy() 959 { 960 return false; 961 } 962 963 protected static String getPath( String basedir, String dir ) 964 { 965 String path; 966 path = basedir; 967 if ( !basedir.endsWith( "/" ) && !dir.startsWith( "/" ) ) 968 { 969 path += "/"; 970 } 971 path += dir; 972 return path; 973 } 974 975 public boolean isInteractive() 976 { 977 return interactive; 978 } 979 980 public void setInteractive( boolean interactive ) 981 { 982 this.interactive = interactive; 983 } 984 985 public List<String> getFileList( String destinationDirectory ) 986 throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException 987 { 988 throw new UnsupportedOperationException( "The wagon you are using has not implemented getFileList()" ); 989 } 990 991 public boolean resourceExists( String resourceName ) 992 throws TransferFailedException, AuthorizationException 993 { 994 throw new UnsupportedOperationException( "The wagon you are using has not implemented resourceExists()" ); 995 } 996 997 protected ProxyInfo getProxyInfo( String protocol, String host ) 998 { 999 if ( proxyInfoProvider != null ) 1000 { 1001 ProxyInfo proxyInfo = proxyInfoProvider.getProxyInfo( protocol ); 1002 if ( !ProxyUtils.validateNonProxyHosts( proxyInfo, host ) ) 1003 { 1004 return proxyInfo; 1005 } 1006 } 1007 return null; 1008 } 1009 1010 public RepositoryPermissions getPermissionsOverride() 1011 { 1012 return permissionsOverride; 1013 } 1014 1015 public void setPermissionsOverride( RepositoryPermissions permissionsOverride ) 1016 { 1017 this.permissionsOverride = permissionsOverride; 1018 } 1019 1020 public void setReadTimeout( int readTimeout ) 1021 { 1022 this.readTimeout = readTimeout; 1023 } 1024 1025 public int getReadTimeout() 1026 { 1027 return this.readTimeout; 1028 } 1029}