com.vincestyling.netroid.stack.HttpClientStack.java Source code

Java tutorial

Introduction

Here is the source code for com.vincestyling.netroid.stack.HttpClientStack.java

Source

/*
 * Copyright (C) 2015 Vince Styling
 *
 * 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 com.vincestyling.netroid.stack;

import android.net.http.AndroidHttpClient;
import com.vincestyling.netroid.AuthFailureError;
import com.vincestyling.netroid.Request;
import com.vincestyling.netroid.Request.Method;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;

import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.Map.Entry;

/**
 * An HttpStack that performs request over an {@link HttpClient}.
 */
public class HttpClientStack implements HttpStack {
    protected final HttpClient mClient;

    public HttpClientStack(String userAgent) {
        mClient = AndroidHttpClient.newInstance(userAgent);
    }

    public HttpClientStack(HttpClient client) {
        mClient = client;
    }

    private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {
        for (Entry<String, String> header : headers.entrySet()) {
            httpRequest.setHeader(header.getKey(), header.getValue());
        }
    }

    //    private static List<NameValuePair> getPostParameterPairs(Map<String, String> postParams) {
    //        List<NameValuePair> result = new ArrayList<>(postParams.size());
    //        for (Entry<String, String> param : postParams.entrySet()) {
    //            result.add(new BasicNameValuePair(param.getKey(), param.getValue()));
    //        }
    //        return result;
    //    }

    @Override
    public HttpResponse performRequest(Request<?> request) throws IOException, AuthFailureError {
        HttpUriRequest httpRequest = createHttpRequest(request);
        onPrepareRequest(httpRequest);
        addHeaders(httpRequest, request.getHeaders());
        HttpParams httpParams = httpRequest.getParams();
        int timeoutMs = request.getTimeoutMs();
        // TODO: Reevaluate this connection timeout based on more wide-scale
        // data collection and possibly different for wifi vs. 3G.
        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
        HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);
        return mClient.execute(httpRequest);
    }

    /**
     * Creates the appropriate subclass of HttpUriRequest for passed in request.
     */
    private static HttpUriRequest createHttpRequest(Request<?> request) throws AuthFailureError {
        switch (request.getMethod()) {
        case Method.GET:
            return new HttpGet(request.getUrl());
        case Method.DELETE:
            return new HttpDelete(request.getUrl());
        case Method.POST: {
            HttpPost postRequest = new HttpPost(request.getUrl());
            postRequest.addHeader(HTTP.CONTENT_TYPE, request.getBodyContentType());
            setEntityIfNonEmptyBody(postRequest, request);
            return postRequest;
        }
        case Method.PUT: {
            HttpPut putRequest = new HttpPut(request.getUrl());
            putRequest.addHeader(HTTP.CONTENT_TYPE, request.getBodyContentType());
            setEntityIfNonEmptyBody(putRequest, request);
            return putRequest;
        }
        case Method.HEAD:
            return new HttpHead(request.getUrl());
        case Method.OPTIONS:
            return new HttpOptions(request.getUrl());
        case Method.TRACE:
            return new HttpTrace(request.getUrl());
        case Method.PATCH: {
            HttpPatch patchRequest = new HttpPatch(request.getUrl());
            patchRequest.addHeader(HTTP.CONTENT_TYPE, request.getBodyContentType());
            setEntityIfNonEmptyBody(patchRequest, request);
            return patchRequest;
        }
        default:
            throw new IllegalStateException("Unknown request method.");
        }
    }

    private static void setEntityIfNonEmptyBody(HttpEntityEnclosingRequestBase httpRequest, Request<?> request)
            throws AuthFailureError {
        byte[] body = request.getBody();
        if (body != null) {
            HttpEntity entity = new ByteArrayEntity(body);
            httpRequest.setEntity(entity);
        }
    }

    /**
     * Called before the request is executed using the underlying HttpClient.
     * <p/>
     * <p>Overwrite in subclasses to augment the request.</p>
     */
    protected void onPrepareRequest(HttpUriRequest request) throws IOException {
        request.addHeader("Accept-Encoding", "gzip");
    }

    /**
     * The HttpPatch class does not exist in the Android framework, so this has been defined here.
     */
    public static final class HttpPatch extends HttpEntityEnclosingRequestBase {
        public final static String METHOD_NAME = "PATCH";

        public HttpPatch() {
            super();
        }

        public HttpPatch(final URI uri) {
            super();
            setURI(uri);
        }

        /**
         * @throws IllegalArgumentException if the uri is invalid.
         */
        public HttpPatch(final String uri) {
            super();
            setURI(URI.create(uri));
        }

        @Override
        public String getMethod() {
            return METHOD_NAME;
        }
    }
}