org.geotools.data.wfs.protocol.http.DefaultHTTPProtocol.java Source code

Java tutorial

Introduction

Here is the source code for org.geotools.data.wfs.protocol.http.DefaultHTTPProtocol.java

Source

/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
 *
 *    This 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;
 *    version 2.1 of the License.
 *
 *    This library 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.
 */
package org.geotools.data.wfs.protocol.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Map;
import java.util.logging.Level;
import java.util.zip.GZIPInputStream;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.geotools.factory.GeoTools;

/**
 * Default implementation of {@link HTTPProtocol} based on apache's common-http-client
 * 
 * @author Gabriel Roldan (OpenGeo)
 * @version $Id$
 * @since 2.6
 *
 *
 *
 * @source $URL$
 *         http://gtsvn.refractions.net/trunk/modules/plugin/wfs/src/main/java/org/geotools/data
 *         /wfs/protocol/http/DefaultHTTPProtocol.java $
 */
@SuppressWarnings("nls")
public class DefaultHTTPProtocol extends AbstractHttpProtocol implements HTTPProtocol {

    /**
     * An {@link HTTPResponse} wrapping an executed {@link GetMethod} or {@link PostMethod} from the
     * apache commons-httpclient package
     * 
     * @author Gabriel Roldan (OpenGeo)
     */
    public class HTTPClientResponse implements HTTPResponse {

        private HttpMethodBase method;

        public HTTPClientResponse(HttpMethodBase method) {
            this.method = method;
        }

        /**
         * @see HTTPResponse#getResponseStream()
         */
        public InputStream getResponseStream() throws IOException {
            final InputStream in;
            {
                InputStream responseStream = method.getResponseBodyAsStream();

                String encoding = getResponseHeader("Content-Encoding");
                if (encoding != null) {
                    if (encoding.toLowerCase().indexOf("gzip") > -1) {
                        LOGGER.finest("Response is GZIP encoded, wrapping with gzip input stream");
                        responseStream = new GZIPInputStream(responseStream);
                    }
                } else {
                    LOGGER.finest("HTTP response is not gzip encoded");
                }
                in = responseStream;
            }

            InputStream releaseConnectionInputStream = new InputStream() {

                @Override
                public int read() throws IOException {
                    return in.read();
                }

                @Override
                public void close() throws IOException {
                    method.releaseConnection();
                }
            };
            return releaseConnectionInputStream;
        }

        public String getContentType() {
            return getResponseHeader("Content-Type");
        }

        public String getResponseCharset() {
            String responseCharSet = method.getResponseCharSet();
            return responseCharSet;
        }

        /**
         * @see HTTPResponse#getResponseHeader()
         */
        public String getResponseHeader(String headerName) {
            Header header = method.getResponseHeader(headerName);
            String headerValue = null;
            if (header != null) {
                headerValue = header.getValue();
            }
            return headerValue;
        }

        /**
         * @see HTTPResponse#getTargetUrl()
         */
        public String getTargetUrl() {
            try {
                URI uri = method.getURI();
                return uri.toString();
            } catch (URIException e) {
                LOGGER.log(Level.FINE, "can't get HTTP request URI", e);
            }
            return null;
        }

        public String toString() {
            StringBuilder sb = new StringBuilder(getClass().getSimpleName());
            sb.append("[Method=").append(method.getName());
            sb.append("\n\tHTTP version=").append(method.getEffectiveVersion());
            sb.append("\n\tstatus code=").append(method.getStatusCode());
            sb.append("\n\tpath=").append(method.getPath());
            sb.append("\n\tquery string=").append(method.getQueryString());
            sb.append("\n\tresponse charset=").append(getResponseCharset());
            Header[] responseHeaders = method.getResponseHeaders();
            sb.append("\n\tresponse headers=");
            for (Header header : responseHeaders) {
                sb.append(header.toExternalForm());
            }
            sb.append("]");
            return sb.toString();
        }
    }

    public HTTPResponse issuePost(final URL targetUrl, final POSTCallBack callback) throws IOException {
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("About to issue POST request to " + targetUrl.toExternalForm());
        }

        final String uri = targetUrl.toExternalForm();

        final PostMethod postRequest = new PostMethod(uri);

        final RequestEntity requestEntity = new RequestEntity() {
            public long getContentLength() {
                return callback.getContentLength();
            }

            public String getContentType() {
                return callback.getContentType();
            }

            public boolean isRepeatable() {
                return false;
            }

            public void writeRequest(OutputStream out) throws IOException {
                callback.writeBody(out);
            }
        };

        postRequest.setRequestEntity(requestEntity);

        HTTPResponse httpResponse = issueRequest(postRequest);

        return httpResponse;
    }

    public HTTPResponse issueGet(final URL baseUrl, final Map<String, String> kvp) throws IOException {
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest(
                    "About to issue GET request to " + baseUrl.toExternalForm() + " with query parameters: " + kvp);
        }

        final String uri = createUri(baseUrl, kvp);
        GetMethod getRequest = new GetMethod(uri);

        HTTPResponse httpResponse = issueRequest(getRequest);

        return httpResponse;
    }

    private HttpClient client;

    /**
     * 
     * @param httpRequest
     *            either a {@link HttpMethod} or {@link PostMethod} set up with the request to be
     *            sent
     * @return
     * @throws IOException
     */
    private HTTPResponse issueRequest(final HttpMethodBase httpRequest) throws IOException {
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine("Executing HTTP request: " + httpRequest.getURI());
        }
        if (client == null) {
            client = new HttpClient();
            client.getParams().setParameter("http.useragent",
                    "GeoTools " + GeoTools.getVersion() + " WFS DataStore");
        }
        if (timeoutMillis > 0) {
            client.getParams().setSoTimeout(timeoutMillis);
        }

        // TODO: remove this
        System.err.println("Executing HTTP request: " + httpRequest);

        if (isTryGzip()) {
            LOGGER.finest("Adding 'Accept-Encoding=gzip' header to request");
            httpRequest.addRequestHeader("Accept-Encoding", "gzip");
        }

        int statusCode;
        try {
            statusCode = client.executeMethod(httpRequest);
        } catch (IOException e) {
            httpRequest.releaseConnection();
            throw e;
        }

        if (statusCode != HttpStatus.SC_OK) {
            httpRequest.releaseConnection();
            String statusText = HttpStatus.getStatusText(statusCode);
            throw new IOException("Request failed with status code " + statusCode + "(" + statusText + "): "
                    + httpRequest.getURI());
        }

        HTTPResponse httpResponse = new HTTPClientResponse(httpRequest);
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine("Got " + httpResponse);
        }
        return httpResponse;
    }
}