org.cauldron.tasks.HttpCall.java Source code

Java tutorial

Introduction

Here is the source code for org.cauldron.tasks.HttpCall.java

Source

/*
 * Copyright (c) 2004 - 2006, Jonathan Ross <jonross@alum.mit.edu>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

package org.cauldron.tasks;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

import org.cauldron.Context;
import org.cauldron.Task;
import org.cauldron.TaskException;

/**
 * A {@link Task} that interprets its attributes and body as the parameters and
 * body of an HTTP GET or POST. Uses Commons HTTP Client.
 * <p>
 * TODO: test POST; add pooling, redirects, etc
 * </p>
 */

public class HttpCall extends AbstractTask {
    private boolean isGet = true;
    private String path;
    private String host, proxyHost;
    private int port = 80, proxyPort = 80;
    private Map params = null;
    private HostConfiguration config;

    private final static HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

    /**
     * Compiling an HttpTask validates the get/post method setting and the
     * presence of parameters appropriate for the method.
     */

    public void compile() throws TaskException {
        if (host == null)
            throw new TaskException("must specify host name");
        if (path == null)
            throw new TaskException("must specify get or post");

        config = new HostConfiguration();
        config.setHost(host, port);

        if (proxyHost != null)
            config.setProxy(proxyHost, proxyPort);
    }

    /**
     * Running an HttpTask retrieves the path contents according to the task
     * attributes. POST body comes from the input.
     */

    public Object run(Context context, Object input) throws TaskException {
        // For POST, body must be available as input.

        String body = null;
        if (!isGet) {
            body = (String) context.convert(input, String.class);
            if (body == null)
                throw new TaskException("HTTP POST input must be convertible to String");
        }

        // Prepare request parameters.

        NameValuePair[] nvp = null;
        if (params != null && params.size() > 0) {
            nvp = new NameValuePair[params.size()];
            int count = 0;

            for (Iterator entries = params.entrySet().iterator(); entries.hasNext();) {
                Map.Entry entry = (Map.Entry) entries.next();
                String key = (String) entry.getKey();
                String value = (String) entry.getValue();
                nvp[count++] = new NameValuePair(key, value);
            }
        }

        // Create the retrieval method and set parameters.
        //

        HttpMethod method;
        if (isGet) {
            GetMethod get = new GetMethod();
            if (nvp != null)
                get.setQueryString(nvp);
            method = get;
        } else {
            PostMethod post = new PostMethod();
            post.setRequestBody(body);
            if (nvp != null)
                post.addParameters(nvp);
            method = post;
        }

        // Make the call.

        method.setPath(path);
        HttpConnection connection = connectionManager.getConnection(config);

        try {
            connection.open();
            method.execute(new HttpState(), connection);
            return method.getResponseBodyAsString();
        } catch (HttpException e) {
            throw new TaskException(e);
        } catch (IOException e) {
            throw new TaskException(e);
        } finally {
            connection.close();
        }
    }

    /**
     * Set the path to be retrieved via HTTP GET.
     */

    public void setGet(String url) {
        this.path = url;
        isGet = true;
    }

    /**
     * Set the path to be retrieved via HTTP POST.
     */

    public void setPost(String url) {
        this.path = url;
        isGet = false;
    }

    /**
     * Set the request parameters.
     */

    public void setParams(Map params) {
        this.params = params;
    }

    /**
     * Set the host for the target URL. There is no default.
     */

    public void setHost(String string) {
        host = string;
    }

    /**
     * Set the port for the target URL; the default is 80.
     */

    public void setPort(int i) {
        port = i;
    }

    /**
     * Set the proxy host for accessing the target host; the default is no
     * proxy.
     */

    public void setProxyHost(String string) {
        proxyHost = string;
    }

    /**
     * Set the proxy host for accessing the target host; the default is 80.
     */

    public void setProxyPort(int i) {
        proxyPort = i;
    }

    /**
     * Cloning HttpTask clones relevant config information.
     */

    public Object clone() {
        HttpCall task = (HttpCall) super.clone();
        task.config = (HostConfiguration) config.clone();
        task.params = new HashMap(params);
        return task;
    }
}