Package net.oauth.http

Source Code of net.oauth.http.TimeLimitedHttpClient

/*
* Copyright 2009 John Kristian
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.oauth.http;

import java.util.concurrent.Future;

import java.io.InterruptedIOException;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
* A decorator for an HttpClient, to limit the amount of time to send a request
* and receive the response. Typical usage: <code>
* OAuthClient client = new OAuthClient(new TimeLimitedHttpClient(new HttpClient3()));
* client.getHttpParameters().put(TimeLimitedHttpClient.EXECUTE_TIMEOUT, 3000);
* client.access(...
* </code>
*
* @author John Kristian
*/
public class TimeLimitedHttpClient implements HttpClient {

    /**
     * The name of the HTTP parameter that is the maximum time to wait for the
     * execute method. (Long msec)
     */
    public static final String EXECUTE_TIMEOUT = "executeTimeout";

    public TimeLimitedHttpClient(HttpClient client) {
        this(client, Executors.newCachedThreadPool(DAEMON_THREAD_FACTORY));
    }

    public TimeLimitedHttpClient(HttpClient client, Executor executor) {
        this.client = client;
        this.executor = executor;
    }

    protected final HttpClient client;
    protected final Executor executor;

    protected static final ThreadFactory DAEMON_THREAD_FACTORY = new ThreadFactory() {
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    };

    /**
     * Send an HTTP request and return the response. If httpParameters contains
     * an integer value for EXECUTE_TIMEOUT, either return or propagate an
     * exception within that many milliseconds (approximately). If there is no
     * such value in httpParameters, simply call the underlying
     * HttpClient.execute.
     *
     * @throws SocketTimeoutException
     *             the EXECUTE_TIMEOUT was exceeded
     * @throws InterruptedIOException
     *             this thread was interrupted
     * @throws IOException
     *             from the underlying HttpClient
     */
    public HttpResponseMessage execute(HttpMessage request, Map<String, Object> httpParameters) throws IOException {
        Object et = httpParameters.get(EXECUTE_TIMEOUT);
        if (et == null) {
            return client.execute(request, httpParameters);
        }
        long timeout = Long.parseLong(et.toString());
        Future<HttpResponseMessage> response = start(request, httpParameters);
        try {
            return response.get(timeout, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            IOException e2 = new SocketTimeoutException("no response after " + timeout + " msec");
            e2.initCause(e);
            throw e2;
        } catch (InterruptedException e) {
            IOException e2 = new InterruptedIOException(e.getMessage());
            e2.initCause(e);
            throw e2;
        } catch (ExecutionException e) {
            throw wrap(e.getCause());
        } catch (Exception e) {
            throw wrap(e);
        }
    }

    /**
     * At some future time, send the given HTTP request and return the response.
     *
     * @return the future response
     */
    protected Future<HttpResponseMessage> start(HttpMessage request, Map<String, Object> httpParameters) {
        FutureTask<HttpResponseMessage> task = new FutureTask<HttpResponseMessage>(new Execute(client, request,
                httpParameters));
        executor.execute(task);
        return task;
    }

    protected static class Execute implements Callable<HttpResponseMessage> {

        protected Execute(HttpClient client, HttpMessage request, Map<String, Object> httpParameters) {
            this.client = client;
            this.request = request;
            this.httpParameters = httpParameters;
        }

        protected final HttpClient client;
        protected final HttpMessage request;
        protected final Map<String, Object> httpParameters;

        /** Send the given HTTP request and return the response. */
        public HttpResponseMessage call() throws IOException {
            return client.execute(request, httpParameters);
        }
    }

    /**
     * Return an IOException that either is the given exception, or contains the
     * given exception as its cause.
     */
    protected IOException wrap(Throwable e) {
        if (e instanceof IOException) {
            return (IOException) e;
        }
        IOException e2 = new IOException(e.getMessage());
        e2.initCause(e);
        return e2;
    }

}
TOP

Related Classes of net.oauth.http.TimeLimitedHttpClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.