org.quizpoll.net.AppEngineHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.quizpoll.net.AppEngineHelper.java

Source

/*
 Copyright 2011 Google Inc. All Rights Reserved.
    
 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 org.quizpoll.net;

import com.google.gson.reflect.TypeToken;

import android.net.Uri;
import android.net.Uri.Builder;
import android.text.TextUtils;
import android.widget.Toast;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.quizpoll.data.Preferences;
import org.quizpoll.data.Preferences.PrefType;
import org.quizpoll.data.model.Answer;
import org.quizpoll.data.model.DocsEntry;
import org.quizpoll.data.model.LeaderboardEntry;
import org.quizpoll.data.model.Poll;
import org.quizpoll.data.model.PollResponse;
import org.quizpoll.data.model.Question;
import org.quizpoll.data.model.Quiz;
import org.quizpoll.ui.GoogleAuthActivity;
import org.quizpoll.R;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Creating and parsing of requests for the AppEngine backend.
 */
public class AppEngineHelper extends HttpHelper {

    // URL to broker JSON API
    public static final String BROKER_URL = "http://quiz-n-poll.appspot.com";

    // Message types
    public static final int LOGIN = -1;
    public static final int COLLECTION_DOCUMENTS = 0;
    public static final int QUIZ = 1;
    public static final int QUIZ_LEADERBOARD = 2;
    public static final int QUIZ_SUBMIT = 3;
    public static final int POLL = 4;
    public static final int POLL_STATUS = 5;
    public static final int POLL_SUBMIT = 6;

    protected GoogleAuthActivity authActivity;

    public AppEngineHelper(int messageType, Object data, boolean showDialog, GoogleAuthActivity authActivity,
            HttpListener listener) {
        super(messageType, data, showDialog, authActivity, listener);
        this.authActivity = authActivity;
        if (messageType == LOGIN) {
            start();
        } else {
            authActivity.authenticatedRequest(GoogleAuthActivity.AUTHSERVER_APPENGINE, this);
        }
    }

    @Override
    public int getDialogMessage() {
        switch (messageType) {
        case LOGIN:
            return R.string.verifying_google_account;
        case COLLECTION_DOCUMENTS:
            return R.string.fetching_quiz_games;
        case QUIZ:
            return R.string.loading_quiz;
        case QUIZ_LEADERBOARD:
            return R.string.fetching_leaderboard;
        case QUIZ_SUBMIT:
            return R.string.submitting_score;
        case POLL:
            return R.string.loading_polling;
        case POLL_SUBMIT:
            return R.string.submitting_answer;
        }
        return UNKNOWN_DIALOG_MESSAGE;
    }

    @Override
    public HttpUriRequest createRequest() {
        Builder url = Uri.parse(BROKER_URL).buildUpon().appendPath("qp_api");
        String postData = null;
        switch (messageType) {
        case LOGIN:
            return createLoginRequest(BROKER_URL);
        case COLLECTION_DOCUMENTS:
            url.appendPath("documents").appendPath((String) requestData);
            break;
        case QUIZ:
            url.appendPath("quiz").appendPath((String) requestData);
            break;
        case QUIZ_LEADERBOARD:
            @SuppressWarnings("unchecked")
            List<String> args = (List<String>) requestData;
            url.appendPath("quiz").appendPath("leaderboard").appendPath(args.get(0)).appendPath(args.get(1));
            break;
        case QUIZ_SUBMIT:
            url.appendPath("quiz").appendPath("submit");
            postData = getGson().toJson(requestData);
            break;
        case POLL:
            url.appendPath("poll").appendPath((String) requestData);
            break;
        case POLL_STATUS:
            @SuppressWarnings("unchecked")
            List<String> pargs = (List<String>) requestData;
            url.appendPath("poll").appendPath("status").appendPath(pargs.get(0)).appendPath(pargs.get(1));
            break;
        case POLL_SUBMIT:
            Poll poll = (Poll) requestData;
            url.appendPath("poll").appendPath("submit");
            postData = createPollSubmitRequest(poll);
            break;
        }
        if (postData == null) {
            return addCookie(new HttpGet(url.build().toString()));
        } else {
            HttpPost post = new HttpPost(url.build().toString());
            try {
                post.setEntity(new StringEntity(postData, "utf8"));
            } catch (UnsupportedEncodingException e) {
                return null;
            }
            return addCookie(post);
        }
    }

    @Override
    public void parseResponse(HttpResponse response) {
        if (messageType == LOGIN) {
            parseLoginResponse(response);
        } else {
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) {
                // Cookie expired
                error(HttpStatus.SC_UNAUTHORIZED);
                authActivity.authenticatedRequest(GoogleAuthActivity.AUTHSERVER_APPENGINE, this, true);
            } else {
                switch (messageType) {
                case COLLECTION_DOCUMENTS:
                    handleDocuments(response);
                    break;
                case QUIZ:
                    handleQuiz(response);
                    break;
                case QUIZ_LEADERBOARD:
                    handleLeaderboard(response);
                    break;
                case QUIZ_SUBMIT:
                    success(null); // Ignore response
                    break;
                case POLL:
                    handlePoll(response);
                    break;
                case POLL_STATUS:
                    handlePollStatus(response);
                    break;
                case POLL_SUBMIT:
                    success(null); // Ignore response
                    break;
                }
            }
        }
    }

    @Override
    protected void error(int statusCode) {
        if (statusCode == HttpStatus.SC_FORBIDDEN) {
            Toast.makeText(activity, R.string.wrong_permissions_error, Toast.LENGTH_SHORT).show();
        } else if (statusCode == HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE) {
            Toast.makeText(activity, R.string.format_error, Toast.LENGTH_SHORT).show();
        }
        super.error(statusCode);
    }

    /**
     * Makes login request to AppEngine server
     */
    protected HttpUriRequest createLoginRequest(String baseUrl) {
        Uri url = Uri.parse(baseUrl).buildUpon().appendEncodedPath("_ah/login")
                .appendQueryParameter("auth", (String) requestData).build();
        return new HttpGet(url.toString());
    }

    /**
     * Saves cookies from AppEngine login
     */
    protected void parseLoginResponse(HttpResponse response) {
        Header[] cookies = response.getHeaders("Set-Cookie");
        String acsid = null;
        if (cookies.length > 0) {
            acsid = cookies[0].getValue().split("; ")[0];
            success(acsid);
        } else {
            error(HttpStatus.SC_UNAUTHORIZED);
        }
    }

    /**
     * Adds AppEngine cookies to the request
     */
    private HttpUriRequest addCookie(HttpUriRequest request) {
        String cookie = Preferences.getString(PrefType.COOKIE_APPENGINE, activity);
        if (cookie != null) {
            request.setHeader("Cookie", cookie);
        }
        return request;
    }

    /**
     * Create polling submit request
     */
    private String createPollSubmitRequest(Poll poll) {
        Question question = poll.getQuestions().get(poll.getCurrentQuestion());
        List<String> answeredAnswers = new ArrayList<String>();
        for (Answer answer : question.getAnswers()) {
            if (answer.isAnswered()) {
                answeredAnswers.add(String.valueOf(answer.getNumber() + 1));
            }
        }
        String answers = TextUtils.join(",", answeredAnswers);
        PollResponse response = new PollResponse(poll.getDocumentId(), poll.getResponsesSheet(),
                question.isAnonymous(), poll.getCurrentQuestion() + 1, answers, question.isSuccess());
        return getGson().toJson(response);
    }

    /**
     * Parses document list inside collection from broker
     */
    private void handleDocuments(HttpResponse response) {
        String content = readContent(response);
        Type collectionType = new TypeToken<List<DocsEntry>>() {
        }.getType();
        List<DocsEntry> entries = getGson().fromJson(content, collectionType);
        success(entries);
    }

    /**
     * Parses the quiz from broker
     */
    private void handleQuiz(HttpResponse response) {
        String content = readContent(response);
        Quiz quiz = getGson().fromJson(content, Quiz.class);
        success(quiz);
    }

    /**
     * Parses statistics from broker
     */
    private void handleLeaderboard(HttpResponse response) {
        String content = readContent(response);
        Type collectionType = new TypeToken<List<LeaderboardEntry>>() {
        }.getType();
        List<LeaderboardEntry> entries = getGson().fromJson(content, collectionType);
        success(entries);
    }

    /**
     * Parses the polling from broker
     */
    private void handlePoll(HttpResponse response) {
        String content = readContent(response);
        Poll polling = getGson().fromJson(content, Poll.class);
        success(polling);
    }

    /**
     * Parses the polling status from broker
     */
    private void handlePollStatus(HttpResponse response) {
        String content = readContent(response);
        Integer questionNumber = getGson().fromJson(content, Integer.class);
        if (questionNumber != Poll.CLOSED && questionNumber != Poll.WAITING_FOR_INSTRUCTOR) {
            questionNumber--;
        }
        success(questionNumber);
    }

}