mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractClientConnAdapter.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractClientConnAdapter.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,355 @@
     1.4 +/*
     1.5 + * ====================================================================
     1.6 + *
     1.7 + *  Licensed to the Apache Software Foundation (ASF) under one or more
     1.8 + *  contributor license agreements.  See the NOTICE file distributed with
     1.9 + *  this work for additional information regarding copyright ownership.
    1.10 + *  The ASF licenses this file to You under the Apache License, Version 2.0
    1.11 + *  (the "License"); you may not use this file except in compliance with
    1.12 + *  the License.  You may obtain a copy of the License at
    1.13 + *
    1.14 + *      http://www.apache.org/licenses/LICENSE-2.0
    1.15 + *
    1.16 + *  Unless required by applicable law or agreed to in writing, software
    1.17 + *  distributed under the License is distributed on an "AS IS" BASIS,
    1.18 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.19 + *  See the License for the specific language governing permissions and
    1.20 + *  limitations under the License.
    1.21 + * ====================================================================
    1.22 + *
    1.23 + * This software consists of voluntary contributions made by many
    1.24 + * individuals on behalf of the Apache Software Foundation.  For more
    1.25 + * information on the Apache Software Foundation, please see
    1.26 + * <http://www.apache.org/>.
    1.27 + *
    1.28 + */
    1.29 +
    1.30 +package ch.boye.httpclientandroidlib.impl.conn;
    1.31 +
    1.32 +import java.io.IOException;
    1.33 +import java.io.InterruptedIOException;
    1.34 +import java.net.InetAddress;
    1.35 +import java.net.Socket;
    1.36 +import java.util.concurrent.TimeUnit;
    1.37 +
    1.38 +import javax.net.ssl.SSLSocket;
    1.39 +import javax.net.ssl.SSLSession;
    1.40 +
    1.41 +import ch.boye.httpclientandroidlib.HttpException;
    1.42 +import ch.boye.httpclientandroidlib.HttpRequest;
    1.43 +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest;
    1.44 +import ch.boye.httpclientandroidlib.HttpResponse;
    1.45 +import ch.boye.httpclientandroidlib.HttpConnectionMetrics;
    1.46 +import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
    1.47 +import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
    1.48 +import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
    1.49 +import ch.boye.httpclientandroidlib.protocol.HttpContext;
    1.50 +
    1.51 +/**
    1.52 + * Abstract adapter from {@link OperatedClientConnection operated} to
    1.53 + * {@link ManagedClientConnection managed} client connections.
    1.54 + * Read and write methods are delegated to the wrapped connection.
    1.55 + * Operations affecting the connection state have to be implemented
    1.56 + * by derived classes. Operations for querying the connection state
    1.57 + * are delegated to the wrapped connection if there is one, or
    1.58 + * return a default value if there is none.
    1.59 + * <p>
    1.60 + * This adapter tracks the checkpoints for reusable communication states,
    1.61 + * as indicated by {@link #markReusable markReusable} and queried by
    1.62 + * {@link #isMarkedReusable isMarkedReusable}.
    1.63 + * All send and receive operations will automatically clear the mark.
    1.64 + * <p>
    1.65 + * Connection release calls are delegated to the connection manager,
    1.66 + * if there is one. {@link #abortConnection abortConnection} will
    1.67 + * clear the reusability mark first. The connection manager is
    1.68 + * expected to tolerate multiple calls to the release method.
    1.69 + *
    1.70 + * @since 4.0
    1.71 + */
    1.72 +public abstract class AbstractClientConnAdapter
    1.73 +                            implements ManagedClientConnection, HttpContext {
    1.74 +
    1.75 +    /**
    1.76 +     * The connection manager, if any.
    1.77 +     * This attribute MUST NOT be final, so the adapter can be detached
    1.78 +     * from the connection manager without keeping a hard reference there.
    1.79 +     */
    1.80 +    private volatile ClientConnectionManager connManager;
    1.81 +
    1.82 +    /** The wrapped connection. */
    1.83 +    private volatile OperatedClientConnection wrappedConnection;
    1.84 +
    1.85 +    /** The reusability marker. */
    1.86 +    private volatile boolean markedReusable;
    1.87 +
    1.88 +    /** True if the connection has been shut down or released. */
    1.89 +    private volatile boolean released;
    1.90 +
    1.91 +    /** The duration this is valid for while idle (in ms). */
    1.92 +    private volatile long duration;
    1.93 +
    1.94 +    /**
    1.95 +     * Creates a new connection adapter.
    1.96 +     * The adapter is initially <i>not</i>
    1.97 +     * {@link #isMarkedReusable marked} as reusable.
    1.98 +     *
    1.99 +     * @param mgr       the connection manager, or <code>null</code>
   1.100 +     * @param conn      the connection to wrap, or <code>null</code>
   1.101 +     */
   1.102 +    protected AbstractClientConnAdapter(ClientConnectionManager mgr,
   1.103 +                                        OperatedClientConnection conn) {
   1.104 +        super();
   1.105 +        connManager = mgr;
   1.106 +        wrappedConnection = conn;
   1.107 +        markedReusable = false;
   1.108 +        released = false;
   1.109 +        duration = Long.MAX_VALUE;
   1.110 +    }
   1.111 +
   1.112 +    /**
   1.113 +     * Detaches this adapter from the wrapped connection.
   1.114 +     * This adapter becomes useless.
   1.115 +     */
   1.116 +    protected synchronized void detach() {
   1.117 +        wrappedConnection = null;
   1.118 +        connManager = null; // base class attribute
   1.119 +        duration = Long.MAX_VALUE;
   1.120 +    }
   1.121 +
   1.122 +    protected OperatedClientConnection getWrappedConnection() {
   1.123 +        return wrappedConnection;
   1.124 +    }
   1.125 +
   1.126 +    protected ClientConnectionManager getManager() {
   1.127 +        return connManager;
   1.128 +    }
   1.129 +
   1.130 +    /**
   1.131 +     * @deprecated use {@link #assertValid(OperatedClientConnection)}
   1.132 +     */
   1.133 +    @Deprecated
   1.134 +    protected final void assertNotAborted() throws InterruptedIOException {
   1.135 +        if (isReleased()) {
   1.136 +            throw new InterruptedIOException("Connection has been shut down");
   1.137 +        }
   1.138 +    }
   1.139 +
   1.140 +    /**
   1.141 +     * @since 4.1
   1.142 +     * @return value of released flag
   1.143 +     */
   1.144 +    protected boolean isReleased() {
   1.145 +        return released;
   1.146 +    }
   1.147 +
   1.148 +    /**
   1.149 +     * Asserts that there is a valid wrapped connection to delegate to.
   1.150 +     *
   1.151 +     * @throws ConnectionShutdownException if there is no wrapped connection
   1.152 +     *                                  or connection has been aborted
   1.153 +     */
   1.154 +    protected final void assertValid(
   1.155 +            final OperatedClientConnection wrappedConn) throws ConnectionShutdownException {
   1.156 +        if (isReleased() || wrappedConn == null) {
   1.157 +            throw new ConnectionShutdownException();
   1.158 +        }
   1.159 +    }
   1.160 +
   1.161 +    public boolean isOpen() {
   1.162 +        OperatedClientConnection conn = getWrappedConnection();
   1.163 +        if (conn == null)
   1.164 +            return false;
   1.165 +
   1.166 +        return conn.isOpen();
   1.167 +    }
   1.168 +
   1.169 +    public boolean isStale() {
   1.170 +        if (isReleased())
   1.171 +            return true;
   1.172 +        OperatedClientConnection conn = getWrappedConnection();
   1.173 +        if (conn == null)
   1.174 +            return true;
   1.175 +
   1.176 +        return conn.isStale();
   1.177 +    }
   1.178 +
   1.179 +    public void setSocketTimeout(int timeout) {
   1.180 +        OperatedClientConnection conn = getWrappedConnection();
   1.181 +        assertValid(conn);
   1.182 +        conn.setSocketTimeout(timeout);
   1.183 +    }
   1.184 +
   1.185 +    public int getSocketTimeout() {
   1.186 +        OperatedClientConnection conn = getWrappedConnection();
   1.187 +        assertValid(conn);
   1.188 +        return conn.getSocketTimeout();
   1.189 +    }
   1.190 +
   1.191 +    public HttpConnectionMetrics getMetrics() {
   1.192 +        OperatedClientConnection conn = getWrappedConnection();
   1.193 +        assertValid(conn);
   1.194 +        return conn.getMetrics();
   1.195 +    }
   1.196 +
   1.197 +    public void flush() throws IOException {
   1.198 +        OperatedClientConnection conn = getWrappedConnection();
   1.199 +        assertValid(conn);
   1.200 +        conn.flush();
   1.201 +    }
   1.202 +
   1.203 +    public boolean isResponseAvailable(int timeout) throws IOException {
   1.204 +        OperatedClientConnection conn = getWrappedConnection();
   1.205 +        assertValid(conn);
   1.206 +        return conn.isResponseAvailable(timeout);
   1.207 +    }
   1.208 +
   1.209 +    public void receiveResponseEntity(HttpResponse response)
   1.210 +        throws HttpException, IOException {
   1.211 +        OperatedClientConnection conn = getWrappedConnection();
   1.212 +        assertValid(conn);
   1.213 +        unmarkReusable();
   1.214 +        conn.receiveResponseEntity(response);
   1.215 +    }
   1.216 +
   1.217 +    public HttpResponse receiveResponseHeader()
   1.218 +        throws HttpException, IOException {
   1.219 +        OperatedClientConnection conn = getWrappedConnection();
   1.220 +        assertValid(conn);
   1.221 +        unmarkReusable();
   1.222 +        return conn.receiveResponseHeader();
   1.223 +    }
   1.224 +
   1.225 +    public void sendRequestEntity(HttpEntityEnclosingRequest request)
   1.226 +        throws HttpException, IOException {
   1.227 +        OperatedClientConnection conn = getWrappedConnection();
   1.228 +        assertValid(conn);
   1.229 +        unmarkReusable();
   1.230 +        conn.sendRequestEntity(request);
   1.231 +    }
   1.232 +
   1.233 +    public void sendRequestHeader(HttpRequest request)
   1.234 +        throws HttpException, IOException {
   1.235 +        OperatedClientConnection conn = getWrappedConnection();
   1.236 +        assertValid(conn);
   1.237 +        unmarkReusable();
   1.238 +        conn.sendRequestHeader(request);
   1.239 +    }
   1.240 +
   1.241 +    public InetAddress getLocalAddress() {
   1.242 +        OperatedClientConnection conn = getWrappedConnection();
   1.243 +        assertValid(conn);
   1.244 +        return conn.getLocalAddress();
   1.245 +    }
   1.246 +
   1.247 +    public int getLocalPort() {
   1.248 +        OperatedClientConnection conn = getWrappedConnection();
   1.249 +        assertValid(conn);
   1.250 +        return conn.getLocalPort();
   1.251 +    }
   1.252 +
   1.253 +    public InetAddress getRemoteAddress() {
   1.254 +        OperatedClientConnection conn = getWrappedConnection();
   1.255 +        assertValid(conn);
   1.256 +        return conn.getRemoteAddress();
   1.257 +    }
   1.258 +
   1.259 +    public int getRemotePort() {
   1.260 +        OperatedClientConnection conn = getWrappedConnection();
   1.261 +        assertValid(conn);
   1.262 +        return conn.getRemotePort();
   1.263 +    }
   1.264 +
   1.265 +    public boolean isSecure() {
   1.266 +        OperatedClientConnection conn = getWrappedConnection();
   1.267 +        assertValid(conn);
   1.268 +        return conn.isSecure();
   1.269 +    }
   1.270 +
   1.271 +    public SSLSession getSSLSession() {
   1.272 +        OperatedClientConnection conn = getWrappedConnection();
   1.273 +        assertValid(conn);
   1.274 +        if (!isOpen())
   1.275 +            return null;
   1.276 +
   1.277 +        SSLSession result = null;
   1.278 +        Socket    sock    = conn.getSocket();
   1.279 +        if (sock instanceof SSLSocket) {
   1.280 +            result = ((SSLSocket)sock).getSession();
   1.281 +        }
   1.282 +        return result;
   1.283 +    }
   1.284 +
   1.285 +    public void markReusable() {
   1.286 +        markedReusable = true;
   1.287 +    }
   1.288 +
   1.289 +    public void unmarkReusable() {
   1.290 +        markedReusable = false;
   1.291 +    }
   1.292 +
   1.293 +    public boolean isMarkedReusable() {
   1.294 +        return markedReusable;
   1.295 +    }
   1.296 +
   1.297 +    public void setIdleDuration(long duration, TimeUnit unit) {
   1.298 +        if(duration > 0) {
   1.299 +            this.duration = unit.toMillis(duration);
   1.300 +        } else {
   1.301 +            this.duration = -1;
   1.302 +        }
   1.303 +    }
   1.304 +
   1.305 +    public synchronized void releaseConnection() {
   1.306 +        if (released) {
   1.307 +            return;
   1.308 +        }
   1.309 +        released = true;
   1.310 +        if (connManager != null) {
   1.311 +            connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
   1.312 +        }
   1.313 +    }
   1.314 +
   1.315 +    public synchronized void abortConnection() {
   1.316 +        if (released) {
   1.317 +            return;
   1.318 +        }
   1.319 +        released = true;
   1.320 +        unmarkReusable();
   1.321 +        try {
   1.322 +            shutdown();
   1.323 +        } catch (IOException ignore) {
   1.324 +        }
   1.325 +        if (connManager != null) {
   1.326 +            connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
   1.327 +        }
   1.328 +    }
   1.329 +
   1.330 +    public synchronized Object getAttribute(final String id) {
   1.331 +        OperatedClientConnection conn = getWrappedConnection();
   1.332 +        assertValid(conn);
   1.333 +        if (conn instanceof HttpContext) {
   1.334 +            return ((HttpContext) conn).getAttribute(id);
   1.335 +        } else {
   1.336 +            return null;
   1.337 +        }
   1.338 +    }
   1.339 +
   1.340 +    public synchronized Object removeAttribute(final String id) {
   1.341 +        OperatedClientConnection conn = getWrappedConnection();
   1.342 +        assertValid(conn);
   1.343 +        if (conn instanceof HttpContext) {
   1.344 +            return ((HttpContext) conn).removeAttribute(id);
   1.345 +        } else {
   1.346 +            return null;
   1.347 +        }
   1.348 +    }
   1.349 +
   1.350 +    public synchronized void setAttribute(final String id, final Object obj) {
   1.351 +        OperatedClientConnection conn = getWrappedConnection();
   1.352 +        assertValid(conn);
   1.353 +        if (conn instanceof HttpContext) {
   1.354 +            ((HttpContext) conn).setAttribute(id, obj);
   1.355 +        }
   1.356 +    }
   1.357 +
   1.358 +}

mercurial