View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v 1.17 2003/06/27 03:20:32 mbecke Exp $ 3 * $Revision: 1.17 $ 4 * $Date: 2003/06/27 03:20:32 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 2002-2003 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>;. 59 * 60 * [Additional notices, if required by prior licensing conditions] 61 * 62 */ 63 64 package org.apache.commons.httpclient; 65 66 import java.io.IOException; 67 import java.io.InputStream; 68 import java.io.OutputStream; 69 import java.lang.ref.Reference; 70 import java.lang.ref.ReferenceQueue; 71 import java.lang.ref.WeakReference; 72 import java.net.SocketException; 73 import java.util.Collections; 74 import java.util.HashMap; 75 import java.util.Iterator; 76 import java.util.LinkedList; 77 import java.util.Map; 78 79 import org.apache.commons.httpclient.protocol.Protocol; 80 import org.apache.commons.logging.Log; 81 import org.apache.commons.logging.LogFactory; 82 83 /*** 84 * Manages a set of HttpConnections for various HostConfigurations. 85 * 86 * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a> 87 * @author Eric Johnson 88 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 89 * @author Carl A. Dunham 90 * 91 * @since 2.0 92 */ 93 public class MultiThreadedHttpConnectionManager implements HttpConnectionManager { 94 95 // -------------------------------------------------------- Class Variables 96 /*** Log object for this class. */ 97 private static final Log LOG = LogFactory.getLog(MultiThreadedHttpConnectionManager.class); 98 99 /*** The default maximum number of connections allowed per host */ 100 public static final int DEFAULT_MAX_HOST_CONNECTIONS = 2; // Per RFC 2616 sec 8.1.4 101 102 /*** The default maximum number of connections allowed overall */ 103 public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; 104 105 // ----------------------------------------------------- Instance Variables 106 /*** Maximum number of connections allowed per host */ 107 private int maxHostConnections = DEFAULT_MAX_HOST_CONNECTIONS; 108 109 /*** Maximum number of connections allowed overall */ 110 private int maxTotalConnections = DEFAULT_MAX_TOTAL_CONNECTIONS; 111 112 /*** Connection Pool */ 113 private ConnectionPool connectionPool; 114 115 /*** mapping from reference to hostConfiguration */ 116 private Map referenceToHostConfig; 117 118 /*** 119 * the reference queue used to track when HttpConnections are lost to the 120 * garbage collector 121 */ 122 private ReferenceQueue referenceQueue; 123 124 /*** 125 * No-args constructor 126 */ 127 public MultiThreadedHttpConnectionManager() { 128 129 this.referenceToHostConfig = Collections.synchronizedMap(new HashMap()); 130 this.connectionPool = new ConnectionPool(); 131 132 this.referenceQueue = new ReferenceQueue(); 133 134 new ReferenceQueueThread().start(); 135 136 } 137 138 /*** 139 * Sets the maximum number of connections allowed for a given 140 * HostConfiguration. Per RFC 2616 section 8.1.4, this value defaults to 2. 141 * 142 * @param maxHostConnections the number of connections allowed for each 143 * hostConfiguration 144 */ 145 public void setMaxConnectionsPerHost(int maxHostConnections) { 146 this.maxHostConnections = maxHostConnections; 147 } 148 149 /*** 150 * Gets the maximum number of connections allowed for a given 151 * hostConfiguration. 152 * 153 * @return The maximum number of connections allowed for a given 154 * hostConfiguration. 155 */ 156 public int getMaxConnectionsPerHost() { 157 return maxHostConnections; 158 } 159 160 /*** 161 * Sets the maximum number of connections allowed in the system. 162 * 163 * @param maxTotalConnections the maximum number of connections allowed 164 */ 165 public void setMaxTotalConnections(int maxTotalConnections) { 166 this.maxTotalConnections = maxTotalConnections; 167 } 168 169 /*** 170 * Gets the maximum number of connections allowed in the system. 171 * 172 * @return The maximum number of connections allowed 173 */ 174 public int getMaxTotalConnections() { 175 return maxTotalConnections; 176 } 177 178 /*** 179 * @see HttpConnectionManager#getConnection(HostConfiguration) 180 */ 181 public HttpConnection getConnection(HostConfiguration hostConfiguration) { 182 183 while (true) { 184 try { 185 return getConnection(hostConfiguration, 0); 186 } catch (HttpException e) { 187 // we'll go ahead and log this, but it should never happen. HttpExceptions 188 // are only thrown when the timeout occurs and since we have no timeout 189 // it should never happen. 190 LOG.debug( 191 "Unexpected exception while waiting for connection", 192 e 193 ); 194 }; 195 } 196 } 197 198 /*** 199 * @see HttpConnectionManager#getConnection(HostConfiguration, long) 200 */ 201 public HttpConnection getConnection(HostConfiguration hostConfiguration, 202 long timeout) throws HttpException { 203 204 LOG.trace("enter HttpConnectionManager.getConnection(HostConfiguration, long)"); 205 206 if (hostConfiguration == null) { 207 throw new IllegalArgumentException("hostConfiguration is null"); 208 } 209 210 if (LOG.isDebugEnabled()) { 211 LOG.debug("HttpConnectionManager.getConnection: config = " 212 + hostConfiguration + ", timeout = " + timeout); 213 } 214 215 final HttpConnection conn = doGetConnection(hostConfiguration, timeout); 216 217 // wrap the connection in an adapter so we can ensure it is used 218 // only once 219 return new HttpConnectionAdapter(conn); 220 } 221 222 /*** 223 * Gets a connection or waits if one is not available. A connection is 224 * available if one exists that is not being used or if fewer than 225 * maxHostConnections have been created in the connectionPool, and fewer 226 * than maxTotalConnections have been created in all connectionPools. 227 * 228 * @param hostConfiguration The host configuration. 229 * @param timeout the number of milliseconds to wait for a connection, 0 to 230 * wait indefinitely 231 * 232 * @return HttpConnection an available connection 233 * 234 * @throws HttpException if a connection does not become available in 235 * 'timeout' milliseconds 236 */ 237 private HttpConnection doGetConnection(HostConfiguration hostConfiguration, 238 long timeout) throws HttpException { 239 240 HttpConnection connection = null; 241 242 synchronized (connectionPool) { 243 244 // we clone the hostConfiguration 245 // so that it cannot be changed once the connection has been retrieved 246 hostConfiguration = new HostConfiguration(hostConfiguration); 247 HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration); 248 WaitingThread waitingThread = null; 249 250 boolean useTimeout = (timeout > 0); 251 long timeToWait = timeout; 252 long startWait = 0; 253 long endWait = 0; 254 255 while (connection == null) { 256 257 // happen to have a free connection with the right specs 258 // 259 if (hostPool.freeConnections.size() > 0) { 260 connection = connectionPool.getFreeConnection(hostConfiguration); 261 262 // have room to make more 263 // 264 } else if ((hostPool.numConnections < maxHostConnections) 265 && (connectionPool.numConnections < maxTotalConnections)) { 266 267 connection = connectionPool.createConnection(hostConfiguration); 268 269 // have room to add host connection, and there is at least one free 270 // connection that can be liberated to make overall room 271 // 272 } else if ((hostPool.numConnections < maxHostConnections) 273 && (connectionPool.freeConnections.size() > 0)) { 274 275 connectionPool.deleteLeastUsedConnection(); 276 connection = connectionPool.createConnection(hostConfiguration); 277 278 // otherwise, we have to wait for one of the above conditions to 279 // become true 280 // 281 } else { 282 // todo: keep track of which hostConfigurations have waiting 283 // threads, so they avoid being sacrificed before necessary 284 285 try { 286 287 if (useTimeout && timeToWait <= 0) { 288 throw new HttpException("Timeout waiting for connection"); 289 } 290 291 if (LOG.isDebugEnabled()) { 292 LOG.debug("Waiting for a connection "); 293 } 294 295 if (waitingThread == null) { 296 waitingThread = new WaitingThread(); 297 waitingThread.hostConnectionPool = hostPool; 298 waitingThread.thread = Thread.currentThread(); 299 } 300 301 if (useTimeout) { 302 startWait = System.currentTimeMillis(); 303 } 304 305 hostPool.waitingThreads.addLast(waitingThread); 306 connectionPool.waitingThreads.addLast(waitingThread); 307 connectionPool.wait(timeToWait); 308 309 // we have not been interrupted so we need to remove ourselves from the 310 // wait queue 311 hostPool.waitingThreads.remove(waitingThread); 312 connectionPool.waitingThreads.remove(waitingThread); 313 } catch (InterruptedException e) { 314 // do nothing 315 } finally { 316 if (useTimeout) { 317 endWait = System.currentTimeMillis(); 318 timeToWait -= (endWait - startWait); 319 } 320 } 321 } 322 } 323 } 324 return connection; 325 } 326 327 /*** 328 * Gets the number of connections in use for this configuration. 329 * 330 * @param hostConfiguration the key that connections are tracked on 331 * @return the number of connections in use 332 */ 333 public int getConnectionsInUse(HostConfiguration hostConfiguration) { 334 synchronized (connectionPool) { 335 HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration); 336 return hostPool.numConnections; 337 } 338 } 339 340 /*** 341 * Gets the total number of connections in use. 342 * 343 * @return the total number of connections in use 344 */ 345 public int getConnectionsInUse() { 346 synchronized (connectionPool) { 347 return connectionPool.numConnections; 348 } 349 } 350 351 /*** 352 * Make the given HttpConnection available for use by other requests. 353 * If another thread is blocked in getConnection() that could use this 354 * connection, it will be woken up. 355 * 356 * @param conn the HttpConnection to make available. 357 */ 358 public void releaseConnection(HttpConnection conn) { 359 LOG.trace("enter HttpConnectionManager.releaseConnection(HttpConnection)"); 360 361 if (conn instanceof HttpConnectionAdapter) { 362 // connections given out are wrapped in an HttpConnectionAdapter 363 conn = ((HttpConnectionAdapter) conn).getWrappedConnection(); 364 } else { 365 // this is okay, when an HttpConnectionAdapter is released 366 // is releases the real connection 367 } 368 369 // make sure that the response has been read. 370 SimpleHttpConnectionManager.finishLastResponse(conn); 371 372 connectionPool.freeConnection(conn); 373 } 374 375 /*** 376 * Gets the host configuration for a connection. 377 * @param conn the connection to get the configuration of 378 * @return a new HostConfiguration 379 */ 380 private HostConfiguration configurationForConnection(HttpConnection conn) { 381 382 HostConfiguration connectionConfiguration = new HostConfiguration(); 383 connectionConfiguration.setHost( 384 conn.getHost(), 385 conn.getVirtualHost(), 386 conn.getPort(), 387 conn.getProtocol()); 388 if (conn.getProxyHost() != null) { 389 connectionConfiguration.setProxy(conn.getProxyHost(), conn.getProxyPort()); 390 } 391 392 return connectionConfiguration; 393 } 394 395 396 /*** 397 * Global Connection Pool, including per-host pools 398 */ 399 private class ConnectionPool { 400 401 /*** The list of free connections */ 402 private LinkedList freeConnections = new LinkedList(); 403 404 /*** The list of WaitingThreads waiting for a connection */ 405 private LinkedList waitingThreads = new LinkedList(); 406 407 /*** 408 * Map where keys are {@link HostConfiguration}s and values are {@link 409 * HostConnectionPool}s 410 */ 411 private final Map mapHosts = new HashMap(); 412 413 /*** The number of created connections */ 414 private int numConnections = 0; 415 416 /*** 417 * Creates a new connection and returns is for use of the calling method. 418 * 419 * @param hostConfiguration the configuration for the connection 420 * @return a new connection or <code>null</code> if none are available 421 */ 422 public synchronized HttpConnection createConnection(HostConfiguration hostConfiguration) { 423 HttpConnection connection = null; 424 425 HostConnectionPool hostPool = getHostPool(hostConfiguration); 426 427 if ((hostPool.numConnections < getMaxConnectionsPerHost()) 428 && (numConnections < getMaxTotalConnections())) { 429 430 connection = new HttpConnection(hostConfiguration); 431 connection.setHttpConnectionManager(MultiThreadedHttpConnectionManager.this); 432 numConnections++; 433 hostPool.numConnections++; 434 435 // add a weak reference to this connection 436 referenceToHostConfig.put(new WeakReference(connection, referenceQueue), 437 hostConfiguration); 438 } 439 return connection; 440 } 441 442 /*** 443 * Get the pool (list) of connections available for the given hostConfig. 444 * 445 * @param hostConfiguration the configuraton for the connection pool 446 * @return a pool (list) of connections available for the given config 447 */ 448 public synchronized HostConnectionPool getHostPool(HostConfiguration hostConfiguration) { 449 LOG.trace("enter HttpConnectionManager.ConnectionPool.getHostPool(HostConfiguration)"); 450 451 // Look for a list of connections for the given config 452 HostConnectionPool listConnections = (HostConnectionPool) 453 mapHosts.get(hostConfiguration); 454 if (listConnections == null) { 455 // First time for this config 456 listConnections = new HostConnectionPool(); 457 mapHosts.put(hostConfiguration, listConnections); 458 } 459 460 return listConnections; 461 } 462 463 /*** 464 * If available, get a free connection for this host 465 * 466 * @param hostConfiguration the configuraton for the connection pool 467 * @return an available connection for the given config 468 */ 469 public synchronized HttpConnection getFreeConnection(HostConfiguration hostConfiguration) { 470 471 HttpConnection connection = null; 472 473 HostConnectionPool hostPool = getHostPool(hostConfiguration); 474 475 if (hostPool.freeConnections.size() > 0) { 476 connection = (HttpConnection) hostPool.freeConnections.removeFirst(); 477 freeConnections.remove(connection); 478 } 479 return connection; 480 } 481 482 /*** 483 * Close and delete an old, unused connection to make room for a new one. 484 */ 485 public synchronized void deleteLeastUsedConnection() { 486 487 HttpConnection connection = (HttpConnection) freeConnections.removeFirst(); 488 489 if (connection != null) { 490 HostConfiguration connectionConfiguration = configurationForConnection(connection); 491 492 if (LOG.isDebugEnabled()) { 493 LOG.debug("Reclaiming unused connection for hostConfig: " 494 + connectionConfiguration); 495 } 496 497 connection.close(); 498 499 // make sure this connection will not be cleaned up again when garbage 500 // collected 501 for (Iterator iter = referenceToHostConfig.keySet().iterator(); iter.hasNext();) { 502 WeakReference connectionRef = (WeakReference) iter.next(); 503 if (connectionRef.get() == connection) { 504 iter.remove(); 505 connectionRef.enqueue(); 506 break; 507 } 508 } 509 510 HostConnectionPool hostPool = getHostPool(connectionConfiguration); 511 512 hostPool.freeConnections.remove(connection); 513 hostPool.numConnections--; 514 numConnections--; 515 } 516 } 517 518 /*** 519 * Notifies a waiting thread that a connection for the given configuration is 520 * available. 521 * @param configuration the host config to use for notifying 522 * @see #notifyWaitingThread(HostConnectionPool) 523 */ 524 public synchronized void notifyWaitingThread(HostConfiguration configuration) { 525 notifyWaitingThread(getHostPool(configuration)); 526 } 527 528 /*** 529 * Notifies a waiting thread that a connection for the given configuration is 530 * available. This will wake a thread witing in tis hostPool or if there is not 531 * one a thread in the ConnectionPool will be notified. 532 * 533 * @param hostPool the host pool to use for notifying 534 */ 535 public synchronized void notifyWaitingThread(HostConnectionPool hostPool) { 536 537 // find the thread we are going to notify, we want to ensure that each 538 // waiting thread is only interrupted once so we will remove it from 539 // all wait queues before interrupting it 540 WaitingThread waitingThread = null; 541 542 if (hostPool.waitingThreads.size() > 0) { 543 if (LOG.isDebugEnabled()) { 544 LOG.debug("Notifying thread waiting on hostPool"); 545 } 546 waitingThread = (WaitingThread) hostPool.waitingThreads.removeFirst(); 547 waitingThreads.remove(waitingThread); 548 } else if (waitingThreads.size() > 0) { 549 if (LOG.isDebugEnabled()) { 550 LOG.debug("Notifying next waiting thread"); 551 } 552 waitingThread = (WaitingThread) waitingThreads.removeFirst(); 553 waitingThread.hostConnectionPool.waitingThreads.remove(waitingThread); 554 } else if (LOG.isDebugEnabled()) { 555 LOG.debug("Notifying no-one, there are no waiting threads"); 556 } 557 558 if (waitingThread != null) { 559 waitingThread.thread.interrupt(); 560 } 561 } 562 563 /*** 564 * Marks the given connection as free. 565 * @param conn a connection that is no longer being used 566 */ 567 public void freeConnection(HttpConnection conn) { 568 569 HostConfiguration connectionConfiguration = configurationForConnection(conn); 570 571 if (LOG.isDebugEnabled()) { 572 LOG.debug("Freeing connection: " + conn); 573 } 574 575 synchronized (this) { 576 HostConnectionPool hostPool = getHostPool(connectionConfiguration); 577 578 // Put the connect back in the available list and notify a waiter 579 hostPool.freeConnections.add(conn); 580 if (hostPool.numConnections == 0) { 581 // for some reason this connection pool didn't already exist 582 LOG.error("host connection pool not found for: " 583 + connectionConfiguration); 584 hostPool.numConnections = 1; 585 } 586 587 freeConnections.add(conn); 588 if (numConnections == 0) { 589 // for some reason this connection pool didn't already exist 590 LOG.error("connection pool not found for: " 591 + connectionConfiguration); 592 numConnections = 1; 593 } 594 595 notifyWaitingThread(hostPool); 596 } 597 598 } 599 } 600 601 /*** 602 * A simple struct-like class to combine the connection list and the count 603 * of created connections. 604 */ 605 private class HostConnectionPool { 606 /*** The list of free connections */ 607 public LinkedList freeConnections = new LinkedList(); 608 609 /*** The list of WaitingThreads for this host */ 610 public LinkedList waitingThreads = new LinkedList(); 611 612 /*** The number of created connections */ 613 public int numConnections = 0; 614 } 615 616 /*** 617 * A simple struct-like class to combine the waiting thread and the connection 618 * pool it is waiting on. 619 */ 620 private class WaitingThread { 621 /*** The thread that is waiting for a connection */ 622 public Thread thread; 623 624 /*** The connection pool the thread is waiting for */ 625 public HostConnectionPool hostConnectionPool; 626 } 627 628 /*** 629 * A thread for listening for HttpConnections reclaimed by the garbage 630 * collector. 631 */ 632 private class ReferenceQueueThread extends Thread { 633 634 /*** 635 * Create an instance and make this a daemon thread. 636 */ 637 public ReferenceQueueThread() { 638 setDaemon(true); 639 } 640 641 /*** 642 * Handles cleaning up for the given reference. Decrements any connection counts 643 * and notifies waiting threads, if appropriate. 644 * 645 * @param ref the reference to clean up 646 */ 647 private void handleReference(Reference ref) { 648 synchronized (connectionPool) { 649 // only clean up for this reference if it is still associated with 650 // a HostConfiguration 651 if (referenceToHostConfig.containsKey(ref)) { 652 HostConfiguration config = (HostConfiguration) referenceToHostConfig.get(ref); 653 referenceToHostConfig.remove(ref); 654 655 HostConnectionPool hostPool = connectionPool.getHostPool(config); 656 hostPool.numConnections--; 657 658 connectionPool.numConnections--; 659 connectionPool.notifyWaitingThread(config); 660 } 661 } 662 } 663 664 /*** 665 * Start execution. 666 */ 667 public void run() { 668 while (true) { 669 try { 670 Reference ref = referenceQueue.remove(); 671 if (ref != null) { 672 handleReference(ref); 673 } 674 } catch (InterruptedException e) { 675 LOG.debug("ReferenceQueueThread interrupted", e); 676 } 677 } 678 } 679 680 } 681 682 /*** 683 * An HttpConnection wrapper that ensures a connection cannot be used 684 * once released. 685 */ 686 private static class HttpConnectionAdapter extends HttpConnection { 687 688 // the wrapped connection 689 private HttpConnection wrappedConnection; 690 691 /*** 692 * Creates a new HttpConnectionAdapter. 693 * @param connection the connection to be wrapped 694 */ 695 public HttpConnectionAdapter(HttpConnection connection) { 696 super(connection.getHost(), connection.getPort(), connection.getProtocol()); 697 this.wrappedConnection = connection; 698 } 699 700 /*** 701 * Tests if the wrapped connection is still available. 702 * @return boolean 703 */ 704 protected boolean hasConnection() { 705 return wrappedConnection != null; 706 } 707 708 /*** 709 * @return HttpConnection 710 */ 711 HttpConnection getWrappedConnection() { 712 return wrappedConnection; 713 } 714 715 public void close() { 716 if (hasConnection()) { 717 wrappedConnection.close(); 718 } else { 719 // do nothing 720 } 721 } 722 723 public String getHost() { 724 if (hasConnection()) { 725 return wrappedConnection.getHost(); 726 } else { 727 return null; 728 } 729 } 730 731 public HttpConnectionManager getHttpConnectionManager() { 732 if (hasConnection()) { 733 return wrappedConnection.getHttpConnectionManager(); 734 } else { 735 return null; 736 } 737 } 738 739 public InputStream getLastResponseInputStream() { 740 if (hasConnection()) { 741 return wrappedConnection.getLastResponseInputStream(); 742 } else { 743 return null; 744 } 745 } 746 747 public int getPort() { 748 if (hasConnection()) { 749 return wrappedConnection.getPort(); 750 } else { 751 return -1; 752 } 753 } 754 755 public Protocol getProtocol() { 756 if (hasConnection()) { 757 return wrappedConnection.getProtocol(); 758 } else { 759 return null; 760 } 761 } 762 763 public String getProxyHost() { 764 if (hasConnection()) { 765 return wrappedConnection.getProxyHost(); 766 } else { 767 return null; 768 } 769 } 770 771 public int getProxyPort() { 772 if (hasConnection()) { 773 return wrappedConnection.getProxyPort(); 774 } else { 775 return -1; 776 } 777 } 778 779 public OutputStream getRequestOutputStream() 780 throws IOException, IllegalStateException { 781 if (hasConnection()) { 782 return wrappedConnection.getRequestOutputStream(); 783 } else { 784 return null; 785 } 786 } 787 788 public OutputStream getRequestOutputStream(boolean useChunking) 789 throws IOException, IllegalStateException { 790 if (hasConnection()) { 791 return wrappedConnection.getRequestOutputStream(useChunking); 792 } else { 793 return null; 794 } 795 } 796 797 public InputStream getResponseInputStream() 798 throws IOException, IllegalStateException { 799 if (hasConnection()) { 800 return wrappedConnection.getResponseInputStream(); 801 } else { 802 return null; 803 } 804 } 805 806 public InputStream getResponseInputStream(HttpMethod method) 807 throws IOException, IllegalStateException { 808 if (hasConnection()) { 809 return wrappedConnection.getResponseInputStream(method); 810 } else { 811 return null; 812 } 813 } 814 815 public boolean isOpen() { 816 if (hasConnection()) { 817 return wrappedConnection.isOpen(); 818 } else { 819 return false; 820 } 821 } 822 823 public boolean isProxied() { 824 if (hasConnection()) { 825 return wrappedConnection.isProxied(); 826 } else { 827 return false; 828 } 829 } 830 831 public boolean isResponseAvailable() throws IOException { 832 if (hasConnection()) { 833 return wrappedConnection.isResponseAvailable(); 834 } else { 835 return false; 836 } 837 } 838 839 public boolean isResponseAvailable(int timeout) throws IOException { 840 if (hasConnection()) { 841 return wrappedConnection.isResponseAvailable(timeout); 842 } else { 843 return false; 844 } 845 } 846 847 public boolean isSecure() { 848 if (hasConnection()) { 849 return wrappedConnection.isSecure(); 850 } else { 851 return false; 852 } 853 } 854 855 public boolean isTransparent() { 856 if (hasConnection()) { 857 return wrappedConnection.isTransparent(); 858 } else { 859 return false; 860 } 861 } 862 863 public void open() throws IOException { 864 if (hasConnection()) { 865 wrappedConnection.open(); 866 } else { 867 throw new IllegalStateException("Connection has been released"); 868 } 869 } 870 871 public void print(String data) 872 throws IOException, IllegalStateException, HttpRecoverableException { 873 if (hasConnection()) { 874 wrappedConnection.print(data); 875 } else { 876 throw new IllegalStateException("Connection has been released"); 877 } 878 } 879 880 public void printLine() 881 throws IOException, IllegalStateException, HttpRecoverableException { 882 if (hasConnection()) { 883 wrappedConnection.printLine(); 884 } else { 885 throw new IllegalStateException("Connection has been released"); 886 } 887 } 888 889 public void printLine(String data) 890 throws IOException, IllegalStateException, HttpRecoverableException { 891 if (hasConnection()) { 892 wrappedConnection.printLine(data); 893 } else { 894 throw new IllegalStateException("Connection has been released"); 895 } 896 } 897 898 public String readLine() throws IOException, IllegalStateException { 899 if (hasConnection()) { 900 return wrappedConnection.readLine(); 901 } else { 902 throw new IllegalStateException("Connection has been released"); 903 } 904 } 905 906 public void releaseConnection() { 907 if (hasConnection()) { 908 HttpConnection wrappedConnection = this.wrappedConnection; 909 this.wrappedConnection = null; 910 wrappedConnection.releaseConnection(); 911 } else { 912 // do nothing 913 } 914 } 915 916 public void setConnectionTimeout(int timeout) { 917 if (hasConnection()) { 918 wrappedConnection.setConnectionTimeout(timeout); 919 } else { 920 // do nothing 921 } 922 } 923 924 public void setHost(String host) throws IllegalStateException { 925 if (hasConnection()) { 926 wrappedConnection.setHost(host); 927 } else { 928 // do nothing 929 } 930 } 931 932 public void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) { 933 if (hasConnection()) { 934 wrappedConnection.setHttpConnectionManager(httpConnectionManager); 935 } else { 936 // do nothing 937 } 938 } 939 940 public void setLastResponseInputStream(InputStream inStream) { 941 if (hasConnection()) { 942 wrappedConnection.setLastResponseInputStream(inStream); 943 } else { 944 // do nothing 945 } 946 } 947 948 public void setPort(int port) throws IllegalStateException { 949 if (hasConnection()) { 950 wrappedConnection.setPort(port); 951 } else { 952 // do nothing 953 } 954 } 955 956 public void setProtocol(Protocol protocol) { 957 if (hasConnection()) { 958 wrappedConnection.setProtocol(protocol); 959 } else { 960 // do nothing 961 } 962 } 963 964 public void setProxyHost(String host) throws IllegalStateException { 965 if (hasConnection()) { 966 wrappedConnection.setProxyHost(host); 967 } else { 968 // do nothing 969 } 970 } 971 972 public void setProxyPort(int port) throws IllegalStateException { 973 if (hasConnection()) { 974 wrappedConnection.setProxyPort(port); 975 } else { 976 // do nothing 977 } 978 } 979 980 public void setSecure(boolean secure) throws IllegalStateException { 981 if (hasConnection()) { 982 wrappedConnection.setSecure(secure); 983 } else { 984 // do nothing 985 } 986 } 987 988 public void setSoTimeout(int timeout) 989 throws SocketException, IllegalStateException { 990 if (hasConnection()) { 991 wrappedConnection.setSoTimeout(timeout); 992 } else { 993 // do nothing 994 } 995 } 996 997 public void shutdownOutput() { 998 if (hasConnection()) { 999 wrappedConnection.shutdownOutput(); 1000 } else { 1001 // do nothing 1002 } 1003 } 1004 1005 public void tunnelCreated() throws IllegalStateException, IOException { 1006 if (hasConnection()) { 1007 wrappedConnection.tunnelCreated(); 1008 } else { 1009 // do nothing 1010 } 1011 } 1012 1013 public void write(byte[] data, int offset, int length) 1014 throws IOException, IllegalStateException, HttpRecoverableException { 1015 if (hasConnection()) { 1016 wrappedConnection.write(data, offset, length); 1017 } else { 1018 throw new IllegalStateException("Connection has been released"); 1019 } 1020 } 1021 1022 public void write(byte[] data) 1023 throws IOException, IllegalStateException, HttpRecoverableException { 1024 if (hasConnection()) { 1025 wrappedConnection.write(data); 1026 } else { 1027 throw new IllegalStateException("Connection has been released"); 1028 } 1029 } 1030 1031 public void writeLine() 1032 throws IOException, IllegalStateException, HttpRecoverableException { 1033 if (hasConnection()) { 1034 wrappedConnection.writeLine(); 1035 } else { 1036 throw new IllegalStateException("Connection has been released"); 1037 } 1038 } 1039 1040 public void writeLine(byte[] data) 1041 throws IOException, IllegalStateException, HttpRecoverableException { 1042 if (hasConnection()) { 1043 wrappedConnection.writeLine(data); 1044 } else { 1045 throw new IllegalStateException("Connection has been released"); 1046 } 1047 } 1048 1049 public void flushRequestOutputStream() throws IOException { 1050 if (hasConnection()) { 1051 wrappedConnection.flushRequestOutputStream(); 1052 } else { 1053 throw new IllegalStateException("Connection has been released"); 1054 } 1055 } 1056 1057 public int getSoTimeout() throws SocketException { 1058 if (hasConnection()) { 1059 return wrappedConnection.getSoTimeout(); 1060 } else { 1061 throw new IllegalStateException("Connection has been released"); 1062 } 1063 } 1064 1065 public String getVirtualHost() { 1066 if (hasConnection()) { 1067 return wrappedConnection.getVirtualHost(); 1068 } else { 1069 throw new IllegalStateException("Connection has been released"); 1070 } 1071 } 1072 1073 public void setVirtualHost(String host) throws IllegalStateException { 1074 if (hasConnection()) { 1075 wrappedConnection.setVirtualHost(host); 1076 } else { 1077 throw new IllegalStateException("Connection has been released"); 1078 } 1079 } 1080 1081 public int getSendBufferSize() throws SocketException { 1082 if (hasConnection()) { 1083 return wrappedConnection.getSendBufferSize(); 1084 } else { 1085 throw new IllegalStateException("Connection has been released"); 1086 } 1087 } 1088 1089 public void setSendBufferSize(int sendBufferSize) throws SocketException { 1090 if (hasConnection()) { 1091 wrappedConnection.setSendBufferSize(sendBufferSize); 1092 } else { 1093 throw new IllegalStateException("Connection has been released"); 1094 } 1095 } 1096 1097 } 1098 1099 } 1100

This page was automatically generated by Maven