ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.connectors.RemoteConnector.java Source code

Java tutorial

Introduction

Here is the source code for ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.connectors.RemoteConnector.java

Source

/*
 * Copyright 2012-2013 Sebastien Zurfluh
 * 
 * This file is part of "Parcours".
 * 
 * "Parcours" 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.
 * 
 * "Parcours" 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 "Parcours".  If not, see <http://www.gnu.org/licenses/>.
 */

package ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.connectors;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.json.JSONException;

import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.interfaces.BasicInputConnector;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.DALContract.AffiliationsContract;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.DALContract.GroupsContract;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.DALContract.MenusContract;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.DALContract.PagesContract;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.DALContract.ResourcesContract;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.impl.Affiliations;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.impl.Groups;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.impl.Menus;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.impl.Pages;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.model.io.structure.impl.Resources;
import ch.sebastienzurfluh.swissmuseumguides.contentprovider.patterns.AsyncCallback;

/**
 * Connects to the Cake back-end in order to get the remote DB content.
 *
 * @author Sebastien Zurfluh
 *
 */
public class RemoteConnector extends AsyncTask<URI, Integer, String> implements BasicInputConnector {
    private String cakePath;
    private final static String CAKE_SUFFIX = ".json";
    private final static String CAKE_ARGS_SEPARATOR = "/";

    private AndroidHttpClient client;

    /**
     * This callback will be called when the asynchronous task is finished.
     * See {@code onPostExecute()}
     */
    private AsyncCallback<String> asyncCallback;

    /**
     * Retrieves data from a default remote location using a defined JSON format.
     */
    public RemoteConnector() {
        this("http://www.sebastienzurfluh.ch/swissmuseumbooklets/cakePHPv2/index.php");
    }

    /**
     * Retrieves data from the given remote location using a defined JSON format.
     * (This constructor is for testing purpose as we need only one source, and one connector
     * object.)
     * @param cakePath the location of the remote content
     */
    public RemoteConnector(String cakePath) {
        this.cakePath = cakePath;
    }

    /**
     * Setup the requests for the remote cake PHP back-end.
     * Those requests will be handled in background by {@link #doInBackground}.
     * 
     * @param requestString for cake php's API.
     * @param asyncCallback the resulting JSON string
     */
    public void remoteRequest(String requestString, final AsyncCallback<String> asyncCallback) {

        this.asyncCallback = asyncCallback;

        URI requestURI;
        try {
            requestURI = new URI(cakePath + CAKE_ARGS_SEPARATOR + requestString + CAKE_SUFFIX);
            execute(requestURI);
        } catch (URISyntaxException e) {
            System.out.println("RemoteConnector: sendRequest: request URI is wrong.");

            asyncCallback.onFailure(e);
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        client = AndroidHttpClient.newInstance("Android");
    }

    @Override
    protected String doInBackground(URI... params) {
        URI url = params[0];
        StringBuilder builder = new StringBuilder();

        HttpGet request = new HttpGet(url);
        try {
            HttpResponse response = client.execute(request);
            HttpEntity entity = response.getEntity();
            if (response.getStatusLine().getStatusCode() == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line).append("\n");
                }
            } else {
                // handle "error loading data"
            }
            entity.consumeContent();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            // handle "error connecting to the server"
        }
        return builder.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        if (result != null)
            asyncCallback.onSuccess(result);
        asyncCallback.onFailure(new Throwable("Data result is empty"));
        client.close();
        client = null;
    }

    @Override
    public void getAffiliations(final AsyncCallback<Affiliations> asyncCallback) {
        remoteRequest(AffiliationsContract.TABLE_NAME + CAKE_ARGS_SEPARATOR + "listAll",

                new AsyncCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        try {
                            asyncCallback.onSuccess(new Affiliations(result));
                        } catch (JSONException e) {
                            onFailure(e);
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        asyncCallback.onFailure(caught);
                    }
                });
    }

    @Override
    public void getGroups(final AsyncCallback<Groups> asyncCallback) {
        remoteRequest(GroupsContract.TABLE_NAME + CAKE_ARGS_SEPARATOR + "listAll",

                new AsyncCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        try {
                            asyncCallback.onSuccess(new Groups(result));
                        } catch (JSONException e) {
                            onFailure(e);
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        asyncCallback.onFailure(caught);
                    }
                });
    }

    @Override
    public void getMenus(final AsyncCallback<Menus> asyncCallback) {
        remoteRequest(MenusContract.TABLE_NAME + CAKE_ARGS_SEPARATOR + "listAll",

                new AsyncCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        try {
                            asyncCallback.onSuccess(new Menus(result));
                        } catch (JSONException e) {
                            onFailure(e);
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        asyncCallback.onFailure(caught);
                    }
                });
    }

    @Override
    public void getPages(final AsyncCallback<Pages> asyncCallback) {
        remoteRequest(PagesContract.TABLE_NAME + CAKE_ARGS_SEPARATOR + "listAll",

                new AsyncCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        try {
                            asyncCallback.onSuccess(new Pages(result));
                        } catch (JSONException e) {
                            onFailure(e);
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        asyncCallback.onFailure(caught);
                    }
                });
    }

    @Override
    public void getResources(final AsyncCallback<Resources> asyncCallback) {
        remoteRequest(ResourcesContract.TABLE_NAME + CAKE_ARGS_SEPARATOR + "listAll",

                new AsyncCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        try {
                            asyncCallback.onSuccess(new Resources(result));
                        } catch (JSONException e) {
                            onFailure(e);
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        asyncCallback.onFailure(caught);
                    }
                });
    }
}