net.naonedbus.rest.controller.RestController.java Source code

Java tutorial

Introduction

Here is the source code for net.naonedbus.rest.controller.RestController.java

Source

/**
 * Copyright (C) 2013 Romain Guefveneu.
 *   
 *  This file is part of naonedbus.
 *   
 *  Naonedbus is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  Naonedbus 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 General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.naonedbus.rest.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import net.naonedbus.BuildConfig;
import net.naonedbus.rest.UrlBuilder;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.util.Log;

/**
 * @author romain.guefveneu
 * 
 */
public abstract class RestController<T> {

    private static final String LOG_TAG = "RestController";
    private static final boolean DBG = BuildConfig.DEBUG;

    /**
     * Timeout en millisecondes
     */
    private static int TIMEOUT = 15000;

    /**
     * Dbut de la plage de code d'erreur de HTTP
     */
    private static int HTTP_ERROR_CODE_START = 400;

    private final String[] mRootNodes;

    public RestController(final String... rootNode) {
        mRootNodes = rootNode;
    }

    /**
     * Parser une chane Json.
     * 
     * @param source
     *            La chane Json
     * @return L'objet correspondant
     */
    public T parseJsonObject(final String source) {
        T result = null;
        try {
            result = parseJsonObject(new JSONObject(source));
        } catch (final JSONException e) {
            Log.e(getClass().getSimpleName(), e.getMessage());
        }

        return result;
    }

    /**
     * Parser une chane Json.
     * 
     * @param source
     *            La chane Json
     * @return L'objet correspondant
     */
    public List<T> parseJsonArray(final String source) throws JSONException {
        List<T> result = null;

        final JSONTokener tokener = new JSONTokener(source);
        final Object object = tokener.nextValue();
        if (object instanceof JSONArray) {
            result = parseJsonArray(new JSONArray(source));
        } else if (object instanceof JSONObject) {
            result = parseJsonArray(new JSONObject(source));
        } else {
            throw new JSONException("L'lment n'est pas flux JSON valide.");
        }

        return result;
    }

    /**
     * Parser la rponse d'un webservice Rest json et rcuprer une instance du
     * type pass en paramtre
     * 
     * @param url
     * @return
     * @throws IOException
     */
    protected T parseJsonObject(final URL url) throws IOException {
        return parseJsonObject(readJsonFromUrl(url));
    }

    /**
     * Parser la rponse d'un webservice Rest json et rcuprer une instance du
     * type pass en paramtre
     * 
     * @param url
     * @return
     * @throws IOException
     */
    protected List<T> parseJson(final URL url) throws IOException, JSONException {
        return parseJsonArray(readJsonFromUrl(url));
    }

    /**
     * Lire un flux Json.
     * 
     * @param url
     *            L'url
     * @return Le fulx Json au format string
     * @throws IOException
     */
    protected String readJsonFromUrl(final URL url) throws IOException {
        if (DBG)
            Log.d(LOG_TAG, "readJsonFromUrl " + url.toString());

        final URLConnection conn = url.openConnection();
        conn.setConnectTimeout(TIMEOUT);
        conn.setReadTimeout(TIMEOUT);
        conn.setRequestProperty("Accept-Language", Locale.getDefault().getLanguage());

        final InputStreamReader comReader = new InputStreamReader(conn.getInputStream());
        final String source = IOUtils.toString(comReader);
        IOUtils.closeQuietly(comReader);

        return source;
    }

    protected JSONArray getRootNode(final JSONObject json) throws JSONException {
        JSONObject object = json;
        for (final String node : mRootNodes) {
            if (object.get(node) instanceof JSONObject)
                object = object.getJSONObject(node);
        }
        return object.getJSONArray(mRootNodes[mRootNodes.length - 1]);
    }

    protected List<T> parseJsonArray(final JSONObject json) throws JSONException {
        final JSONArray jsonArray = getRootNode(json);
        return parseJsonArray(jsonArray);
    }

    protected List<T> parseJsonArray(final JSONArray jsonArray) throws JSONException {
        final List<T> result = new ArrayList<T>();
        JSONObject c;

        for (int i = 0; i < jsonArray.length(); i++) {
            c = jsonArray.getJSONObject(i);
            result.add(parseJsonObject(c));
        }

        return result;
    }

    public String toJson(final List<T> items) {
        final JSONArray list = new JSONArray();
        JSONObject object;
        for (final T item : items) {
            try {
                object = toJsonObject(item);
                list.put(object);
            } catch (final JSONException e) {
                if (DBG)
                    Log.e(getClass().getSimpleName(), e.getMessage());
            }
        }
        return list.toString();
    }

    public String toJson(final T item) {
        JSONObject object = new JSONObject();
        try {
            object = toJsonObject(item);
        } catch (final JSONException e) {
            if (DBG)
                Log.e(getClass().getSimpleName(), e.getMessage());
        }
        return object.toString();
    }

    /**
     * Parser un object JsonElement.F
     * 
     * @param object
     *            L'objet  parser
     * @return L'objet reconstruit
     */
    protected abstract T parseJsonObject(JSONObject object) throws JSONException;

    /**
     * Convertir un lment en lment json.
     * 
     * @param item
     *            L'lment  convertir
     * @return L'object Json
     */
    protected abstract JSONObject toJsonObject(T item) throws JSONException;

    /**
     * @see RestController#post(URL)
     */
    protected String post(final UrlBuilder url) throws IOException, HttpException {
        return post(url.getUrl());
    }

    /**
     * Soumettre le formulaire au webservice
     * 
     * @param url
     * @return
     * @throws IOException
     * @throws HttpException
     */
    protected String post(final URL url) throws IOException, HttpException {

        final HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT);

        final HttpClient httpClient = new DefaultHttpClient(httpParams);
        final HttpPost httppost = new HttpPost(url.toString());
        final HttpResponse response = httpClient.execute(httppost);

        if (response.getStatusLine().getStatusCode() >= HTTP_ERROR_CODE_START) {
            throw new HttpException(response.getStatusLine().toString());
        }

        final HttpEntity entity = response.getEntity();

        return readResponse(entity);
    }

    /**
     * Lire la rponse du WebService
     * 
     * @param entity
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    private String readResponse(final HttpEntity entity) throws IllegalStateException, IOException {
        final StringBuilder builder = new StringBuilder();
        String line;

        if (entity != null) {
            final BufferedReader buffer = new BufferedReader(new InputStreamReader(entity.getContent()));
            while ((line = buffer.readLine()) != null) {
                builder.append(line);
            }
            buffer.close();
        }

        return builder.toString();
    }
}