tr.com.turkcellteknoloji.turkcellupdater.RestRequest.java Source code

Java tutorial

Introduction

Here is the source code for tr.com.turkcellteknoloji.turkcellupdater.RestRequest.java

Source

/*******************************************************************************
 *
 *  Copyright (C) 2013 Turkcell
 *  
 *  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 tr.com.turkcellteknoloji.turkcellupdater;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;

class RestRequest {

    enum HttpMethod {
        GET, PUT, POST, DELETE
    }

    private HttpMethod httpMethod = HttpMethod.GET;
    private URI uri;

    protected URI getUri() {
        return uri;
    }

    protected void setUri(URI uri) {
        this.uri = uri;
    }

    private JSONObject inputJsonObject;

    private RestNoValueResultHandler noValueResultHandler;
    private RestJsonObjectResultHandler jsonObjectResultHandler;

    private int[] expectedHttpStatusCodes = { 200, 201, 202, 204 };

    private void setResultHandlerNone() {
        this.noValueResultHandler = null;
        this.jsonObjectResultHandler = null;
    }

    protected final void setResultHandler(RestNoValueResultHandler noValueResultHandler) {
        Utilities.checkArgumentNotNull("noValueResultHandler", noValueResultHandler);

        setResultHandlerNone();

        this.noValueResultHandler = noValueResultHandler;
    }

    protected final void setResultHandler(RestJsonObjectResultHandler jsonObjectResultHandler) {
        Utilities.checkArgumentNotNull("jsonObjectResultHandler", jsonObjectResultHandler);

        setResultHandlerNone();

        this.jsonObjectResultHandler = jsonObjectResultHandler;
    }

    private RestFailureHandler getFailureHandler() {
        if (noValueResultHandler != null) {
            return noValueResultHandler;
        }

        return jsonObjectResultHandler;
    }

    protected final void setInputNone() {
        this.inputJsonObject = null;
    }

    protected final void setInput(JSONObject inputJsonObject) {
        Utilities.checkArgumentNotNull("inputJsonObject", inputJsonObject);

        setInputNone();

        this.inputJsonObject = inputJsonObject;
    }

    protected final RestNoValueResultHandler getNoValueResultHandler() {
        return noValueResultHandler;
    }

    protected final RestJsonObjectResultHandler getJsonObjectResultHandler() {
        return jsonObjectResultHandler;
    }

    protected final JSONObject getInputJsonObject() {
        return inputJsonObject;
    }

    protected final int[] getExpectedHttpStatusCodes() {
        return expectedHttpStatusCodes;
    }

    protected final void setExpectedHttpStatusCodes(int expectedHttpStatusCode) {
        this.expectedHttpStatusCodes = new int[] { expectedHttpStatusCode };
    }

    protected final void setExpectedHttpStatusCodes(int... expectedHttpStatusCodes) {
        this.expectedHttpStatusCodes = expectedHttpStatusCodes;
    }

    protected final HttpMethod getHttpMethod() {
        return httpMethod;
    }

    protected final void setHttpMethod(HttpMethod httpMethod) {
        this.httpMethod = httpMethod;
    }

    protected HttpUriRequest createHttpRequest() throws Exception {
        final HttpMethod method = getHttpMethod();
        if (method == null) {
            throw new Exception("HTTP method should not be null");
        }

        final HttpUriRequest result;

        switch (method) {
        case GET:
            result = createHttpGetRequest();
            break;
        case POST:
            result = createHttpPostRequest();
            break;
        case PUT:
            result = createHttpPutRequest();
            break;
        case DELETE:
            result = createHttpDeleteRequest();
            break;
        default:
            throw new Exception("Unknown HTTP method:" + httpMethod.toString());
        }

        return result;
    }

    protected void appendHeaders(HttpUriRequest request) {
    }

    private HttpGet createHttpGetRequest() {
        final HttpGet result = new HttpGet();
        result.setURI(getUri());
        appendHeaders(result);
        return result;
    }

    private HttpPost createHttpPostRequest() throws Exception {
        final HttpPost result = new HttpPost();
        result.setURI(getUri());
        appendHeaders(result);
        result.setEntity(getRequestContents());
        return result;
    }

    private HttpPut createHttpPutRequest() throws Exception {
        final HttpPut result = new HttpPut();
        result.setURI(getUri());
        appendHeaders(result);
        result.setEntity(getRequestContents());
        return result;
    }

    private HttpDelete createHttpDeleteRequest() {
        final HttpDelete result = new HttpDelete();
        result.setURI(getUri());
        appendHeaders(result);
        return result;
    }

    /**
     * Subclasses may override this method to place different object types to request body
     * @return contents of request.
     * @throws JsonConversionException
     * @throws JSONException
     */
    protected HttpEntity getRequestContents() throws Exception {
        try {
            final JSONObject jsonObject;
            if (inputJsonObject == null) {
                jsonObject = new JSONObject();
            } else {
                jsonObject = inputJsonObject;
            }

            final String string = jsonObject.toString();

            final byte[] bytes;
            bytes = string.getBytes("UTF-8");

            final ByteArrayEntity result = new ByteArrayEntity(bytes);
            result.setContentType("application/json; charset=UTF-8");

            return result;

        } catch (Exception e) {
            throw new Exception("Couldn't create request contents", e);
        }
    }

    protected String getExpectedResponseContentType() {
        return "application/json";
    }

    protected byte[] getByteArrayFromResponse(HttpResponse response) throws IOException {
        final HttpEntity entity = response.getEntity();
        if (entity == null) {
            return null;
        }

        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            entity.writeTo(byteArrayOutputStream);
            return byteArrayOutputStream.toByteArray();
        } finally {
            try {
                entity.consumeContent();
            } catch (Exception e) {
                // Omit
            }
            try {
                byteArrayOutputStream.close();
            } catch (Exception e) {
            }
        }
    }

    protected String getStringFromResponse(HttpResponse response) throws IOException, UnsupportedEncodingException {
        final byte[] byteArray = getByteArrayFromResponse(response);
        if (byteArray == null) {
            return null;
        }
        return new String(byteArray, "UTF-8");
    }

    protected JSONObject getJsonObjectFromResponse(HttpResponse response)
            throws IOException, UnsupportedEncodingException, Exception {

        String json = getStringFromResponse(response);

        // see http://code.google.com/p/android/issues/detail?id=18508
        json = Utilities.removeUTF8BOM(json);

        JSONObject jsonObject = null;
        if (json != null) {
            try {
                jsonObject = new JSONObject(json);
            } catch (JSONException e) {
                throw new Exception("Json result couldn't be parsed", e);
            }
        }
        return jsonObject;
    }

    protected void proccessJsonResponseContents(JSONObject jsonObject) throws Exception {
        if (jsonObjectResultHandler != null) {
            if (jsonObject == null) {
                throw new Exception("Json object is null");
            }
            jsonObjectResultHandler.onSuccess(jsonObject);

        } else if (noValueResultHandler != null) {
            noValueResultHandler.onSuccess();

        } else {
            throw new Exception("No result handlers found");

        }
    }

    void execute(final HttpClient client) throws Exception {
        try {
            final HttpResponse response;
            try {
                response = client.execute(createHttpRequest());
            } catch (ClientProtocolException e) {
                throw new Exception(e);
            }
            checkResponse(response);
            final JSONObject jsonObject = getJsonObjectFromResponse(response);
            proccessJsonResponseContents(jsonObject);

        } catch (Exception e) {
            final RestFailureHandler failureHandler = getFailureHandler();
            if (failureHandler == null) {
                e.printStackTrace();
            } else {
                try {
                    failureHandler.onFail(e);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    AsyncTask<?, ?, ?> executeAsync(final HttpClient client) throws Exception {
        final Worker worker = new Worker(client);
        worker.execute();
        return worker;
    }

    protected void checkResponse(HttpResponse response) throws Exception {
        if (response == null) {
            throw new Exception("Response is null.");
        }
        checkResponseStatus(response);
        checkResponseContentType(response);
    }

    private void checkResponseStatus(HttpResponse response) throws Exception {
        final StatusLine statusLine = response.getStatusLine();

        if (statusLine == null) {
            throw new Exception("Status line is null.");
        }

        final int statusCode = statusLine.getStatusCode();
        final int[] expectedHttpStatusCodes = getExpectedHttpStatusCodes();
        if (expectedHttpStatusCodes != null) {
            if (!Utilities.isElementFound(expectedHttpStatusCodes, statusCode)) {
                throw new Exception("Unexpected status code: " + statusCode);
            }
        }
    }

    private void checkResponseContentType(HttpResponse response) throws Exception {
        final String expectedResponseContentType = getExpectedResponseContentType();
        if (expectedResponseContentType != null) {
            final Header contentTypeHeader = response.getFirstHeader("Content-Type");
            if (contentTypeHeader == null) {
                throw new Exception(
                        "Missing content-type header. '" + expectedResponseContentType + "' is expected");
            }

            final String contentType = contentTypeHeader.getValue();
            if (Utilities.isNullOrEmpty(contentType)) {
                throw new Exception(
                        "Missing content-type header value. '" + expectedResponseContentType + "' is expected");
            }

            if (!contentType.startsWith(expectedResponseContentType)) {
                throw new Exception("Unexpected content-type header value: '" + contentType + "'. '"
                        + expectedResponseContentType + "' is expected");
            }

        }
    }

    class Worker extends AsyncTask<Void, Void, JSONObject> {
        final HttpClient client;
        private HttpUriRequest request;

        private Worker(HttpClient client) {
            super();
            this.client = client;
        }

        private volatile Exception exception;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            try {
                request = createHttpRequest();
            } catch (Exception e) {
                exception = e;
            }
        }

        @Override
        protected JSONObject doInBackground(Void... params) {
            if (exception != null) {
                return null;
            }

            HttpResponse response = null;
            try {
                try {
                    response = client.execute(request);
                } catch (ClientProtocolException e) {
                    throw new Exception(e);
                }

                checkResponse(response);

                return getJsonObjectFromResponse(response);
            } catch (Exception e) {

                // ensure that connection is released
                if (response != null) {
                    final HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        try {
                            entity.consumeContent();
                        } catch (IOException e1) {
                            // omitted
                        }
                    }
                }

                exception = e;
                return null;
            }
        }

        @Override
        protected void onCancelled() {
            try {
                if (request != null) {
                    request.abort();
                }
            } catch (Exception e) {
                // omitted
            }
            super.onCancelled();
        }

        @Override
        protected void onPostExecute(JSONObject result) {
            if (exception == null) {
                try {
                    proccessJsonResponseContents(result);
                    return;
                } catch (Exception e) {
                    exception = e;
                }
            }

            final RestFailureHandler failureHandler = getFailureHandler();
            if (failureHandler == null) {
                exception.printStackTrace();
            } else {
                try {
                    failureHandler.onFail(exception);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }

        }

    }

}