ru.algorithmist.jquant.infr.GAEClientConnection.java Source code

Java tutorial

Introduction

Here is the source code for ru.algorithmist.jquant.infr.GAEClientConnection.java

Source

/*
 * Copyright (c) 2011, Sergey Edunov. All Rights Reserved.
 *
 * This file is part of JQuant library.
 *
 * JQuant library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * JQuant is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with JQuant. If not, see <http://www.gnu.org/licenses/>.
 */
package ru.algorithmist.jquant.infr;

import com.google.appengine.api.urlfetch.FetchOptions;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import org.apache.http.Header;
import org.apache.http.HttpConnectionMetrics;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.TimeUnit;

class GAEClientConnection implements ManagedClientConnection {

    public GAEClientConnection(ClientConnectionManager cm, HttpRoute route, Object state) {
        this.connManager = cm;
        this.route = route;
        this.state = state;
        this.closed = true;
    }

    // From interface ManagedClientConnection

    @Override
    public boolean isSecure() {
        return route.isSecure();
    }

    @Override
    public HttpRoute getRoute() {
        return route;
    }

    @Override
    public javax.net.ssl.SSLSession getSSLSession() {
        return null;
    }

    @Override
    public void open(HttpRoute route, HttpContext context, HttpParams params) throws IOException {
        close();
        this.route = route;
    }

    @Override
    public void tunnelTarget(boolean secure, HttpParams params) throws IOException {
        throw new IOException("tunnelTarget() not supported");
    }

    @Override
    public void tunnelProxy(HttpHost next, boolean secure, HttpParams params) throws IOException {
        throw new IOException("tunnelProxy() not supported");
    }

    @Override
    public void layerProtocol(HttpContext context, HttpParams params) throws IOException {
        throw new IOException("layerProtocol() not supported");
    }

    @Override
    public void markReusable() {
        reusable = true;
    }

    @Override
    public void unmarkReusable() {
        reusable = false;
    }

    @Override
    public boolean isMarkedReusable() {
        return reusable;
    }

    @Override
    public void setState(Object state) {
        this.state = state;
    }

    @Override
    public Object getState() {
        return state;
    }

    @Override
    public void setIdleDuration(long duration, TimeUnit unit) {
        // Do nothing
    }

    @Override
    public boolean isResponseAvailable(int timeout) throws IOException {
        return response != null;
    }

    @Override
    public void sendRequestHeader(HttpRequest request) throws HttpException, IOException {
        try {
            HttpHost host = route.getTargetHost();

            URI uri = new URI(host.getSchemeName() + "://" + host.getHostName()
                    + ((host.getPort() == -1) ? "" : (":" + host.getPort())) + request.getRequestLine().getUri());

            this.request = new HTTPRequest(uri.toURL(), HTTPMethod.valueOf(request.getRequestLine().getMethod()),
                    FetchOptions.Builder.disallowTruncate().doNotFollowRedirects());

        } catch (URISyntaxException ex) {
            throw new IOException("Malformed request URI: " + ex.getMessage(), ex);
        } catch (IllegalArgumentException ex) {
            throw new IOException("Unsupported HTTP method: " + ex.getMessage(), ex);
        }

        for (Header h : request.getAllHeaders()) {
            this.request.addHeader(new HTTPHeader(h.getName(), h.getValue()));
        }
    }

    @Override
    public void sendRequestEntity(HttpEntityEnclosingRequest request) throws HttpException, IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        if (request.getEntity() != null) {
            request.getEntity().writeTo(baos);
        }
        this.request.setPayload(baos.toByteArray());
    }

    @Override
    public HttpResponse receiveResponseHeader() throws HttpException, IOException {
        if (this.response == null) {
            flush();
        }

        HttpResponse response = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1),
                this.response.getResponseCode(), null);

        for (HTTPHeader h : this.response.getHeaders()) {
            response.addHeader(h.getName(), h.getValue());
        }

        return response;
    }

    @Override
    public void receiveResponseEntity(HttpResponse response) throws HttpException, IOException {
        if (this.response == null) {
            throw new IOException("receiveResponseEntity() called on closed connection");
        }

        ByteArrayEntity bae = new ByteArrayEntity(this.response.getContent());
        bae.setContentType(response.getFirstHeader("Content-Type"));
        response.setEntity(bae);

        response = null;
    }

    @Override
    public void flush() throws IOException {
        if (request != null) {
            try {
                response = urlFS.fetch(request);
                request = null;
            } catch (IOException ex) {
                ex.printStackTrace();
                throw ex;
            }
        } else {
            response = null;
        }
    }

    // From interface HttpConnection

    @Override
    public void close() throws IOException {
        request = null;
        response = null;
        closed = true;
    }

    @Override
    public boolean isOpen() {
        return request != null || response != null;
    }

    @Override
    public boolean isStale() {
        return !isOpen() && !closed;
    }

    @Override
    public void setSocketTimeout(int timeout) {
    }

    @Override
    public int getSocketTimeout() {
        return -1;
    }

    @Override
    public void shutdown() throws IOException {
        close();
    }

    @Override
    public HttpConnectionMetrics getMetrics() {
        return null;
    }

    @Override
    public InetAddress getLocalAddress() {
        return null;
    }

    @Override
    public int getLocalPort() {
        return 0;
    }

    @Override
    public InetAddress getRemoteAddress() {
        return null;
    }

    @Override
    public int getRemotePort() {
        HttpHost host = route.getTargetHost();
        return connManager.getSchemeRegistry().getScheme(host).resolvePort(host.getPort());
    }

    @Override
    public void releaseConnection() throws IOException {
        connManager.releaseConnection(this, Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    }

    @Override
    public void abortConnection() throws IOException {
        unmarkReusable();
        shutdown();
    }

    private ClientConnectionManager connManager;
    private HttpRoute route;
    private Object state;
    private boolean reusable;

    private HTTPRequest request;
    private HTTPResponse response;
    private boolean closed;

    private static URLFetchService urlFS = URLFetchServiceFactory.getURLFetchService();
}