/* Copyright (C) 2014 Prasanna Thirumalai This file is part of StackX. StackX 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. StackX 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 StackX. If not, see <http://www.gnu.org/licenses/>. */ package com.prasanna.android.stacknetwork.service; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; import com.prasanna.android.http.SecureHttpHelper; import com.prasanna.android.http.SecureHttpHelper.HttpResponseBodyParser; import com.prasanna.android.http.SecureHttpHelper.HttpResponseParseException; import com.prasanna.android.stacknetwork.model.Answer; import com.prasanna.android.stacknetwork.model.IdentifiableItem; import com.prasanna.android.stacknetwork.model.Question; import com.prasanna.android.stacknetwork.model.StackXPage; import com.prasanna.android.stacknetwork.model.User; import com.prasanna.android.stacknetwork.model.User.UserType; import com.prasanna.android.stacknetwork.utils.AppUtils; import com.prasanna.android.stacknetwork.utils.JSONObjectWrapper; import com.prasanna.android.stacknetwork.utils.JsonFields; import com.prasanna.android.stacknetwork.utils.OperatingSite; import com.prasanna.android.stacknetwork.utils.StackUri; import com.prasanna.android.stacknetwork.utils.StackUri.QueryParamDefaultValues; import com.prasanna.android.utils.LogWrapper; public abstract class AbstractBaseServiceHelper { protected abstract String getLogTag(); public static final JSONParser JSON_PARSER = new JSONParser(); public static class JSONParser implements HttpResponseBodyParser<JSONObjectWrapper> { @Override public JSONObjectWrapper parse(String responseBody) throws HttpResponseParseException { try { return new JSONObjectWrapper(new JSONObject(responseBody)); } catch (JSONException e) { throw new HttpResponseParseException(e); } } } protected SecureHttpHelper getHttpHelper() { return SecureHttpHelper.getInstance(); } protected void getPageInfo(JSONObjectWrapper jsonObjectWrapper, StackXPage<? extends IdentifiableItem> page) { if (jsonObjectWrapper != null && page != null) { page.quota_remaining = jsonObjectWrapper.getInt(JsonFields.QUOTA_REMAINING); page.quota_max = jsonObjectWrapper.getInt(JsonFields.QUOTA_MAX); page.hasMore = jsonObjectWrapper.getBoolean(JsonFields.HAS_MORE); } } protected StackXPage<User> getSerializedUserObject(JSONObjectWrapper jsonObject) { StackXPage<User> page = new StackXPage<User>(); User user = null; if (jsonObject != null) { JSONArray jsonArray = jsonObject.getJSONArray(JsonFields.ITEMS); JSONObjectWrapper userJsonObject = JSONObjectWrapper.wrap(getIndexFromArray(jsonArray, 0, JSONObject.class)); page.items = new ArrayList<User>(); getPageInfo(jsonObject, page); if (userJsonObject != null) { user = new User(); user.id = userJsonObject.getLong(JsonFields.User.USER_ID); user.type = UserType.toEnum(userJsonObject.getString(JsonFields.User.USER_TYPE)); user.accountId = userJsonObject.getLong(JsonFields.User.ACCOUNT_ID); user.displayName = userJsonObject.getString(JsonFields.User.DISPLAY_NAME); user.reputation = userJsonObject.getInt(JsonFields.User.REPUTATION); user.profileImageLink = userJsonObject.getString(JsonFields.User.PROFILE_IMAGE); user.questionCount = userJsonObject.getInt(JsonFields.User.QUESTION_COUNT); user.answerCount = userJsonObject.getInt(JsonFields.User.ANSWER_COUNT); user.upvoteCount = userJsonObject.getInt(JsonFields.User.UP_VOTE_COUNT); user.downvoteCount = userJsonObject.getInt(JsonFields.User.DOWN_VOTE_COUNT); user.profileViews = userJsonObject.getInt(JsonFields.User.VIEW_COUNT); user.badgeCounts = getBadgeCounts(userJsonObject.getJSONObject(JsonFields.User.BADGE_COUNTS)); user.lastAccessTime = userJsonObject.getLong(JsonFields.User.LAST_ACCESS_DATE); user.acceptRate = userJsonObject.getInt(JsonFields.User.ACCEPT_RATE); user.creationDate = userJsonObject.getLong(JsonFields.User.CREATION_DATE); page.items.add(user); } } return page; } protected int[] getBadgeCounts(JSONObjectWrapper badgeCountJsonObject) { int[] badgeCounts = { 0, 0, 0 }; if (badgeCountJsonObject != null) { badgeCounts[0] = badgeCountJsonObject.getInt(JsonFields.BadgeCounts.GOLD); badgeCounts[1] = badgeCountJsonObject.getInt(JsonFields.BadgeCounts.SILVER); badgeCounts[2] = badgeCountJsonObject.getInt(JsonFields.BadgeCounts.BRONZE); } return badgeCounts; } protected StackXPage<Question> getQuestionModel(JSONObjectWrapper questionsJsonResponse) { StackXPage<Question> page = new StackXPage<Question>(); if (questionsJsonResponse != null) { page.items = new ArrayList<Question>(); getPageInfo(questionsJsonResponse, page); JSONArray jsonArray = questionsJsonResponse.getJSONArray(JsonFields.ITEMS); if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { try { JSONObjectWrapper jsonObject = JSONObjectWrapper.wrap(jsonArray.getJSONObject(i)); page.items.add(getSerializedQuestionObject(jsonObject)); } catch (JSONException e) { LogWrapper.d(getLogTag(), e.getMessage()); } } } } return page; } protected Question getSerializedQuestionObject(JSONObjectWrapper jsonObject) throws JSONException { Question question = new Question(); question.title = jsonObject.getString(JsonFields.Question.TITLE); question.id = jsonObject.getLong(JsonFields.Question.QUESTION_ID); question.answered = jsonObject.getBoolean(JsonFields.Question.IS_ANSWERED); question.score = jsonObject.getInt(JsonFields.Question.SCORE); question.answerCount = jsonObject.getInt(JsonFields.Question.ANSWER_COUNT); question.viewCount = jsonObject.getInt(JsonFields.Question.VIEW_COUNT); question.tags = getTags(jsonObject); question.upvoted = jsonObject.getBoolean(JsonFields.Question.UPVOTED); question.downvoted = jsonObject.getBoolean(JsonFields.Question.DOWNVOTED); question.favorited = jsonObject.getBoolean(JsonFields.Question.FAVORITED); question.bountyAmount = jsonObject.getInt(JsonFields.Question.BOUNTY_AMOUNT); question.creationDate = jsonObject.getLong(JsonFields.Question.CREATION_DATE); question.link = jsonObject.getString(JsonFields.Question.LINK); if (jsonObject.has(JsonFields.Question.ACCEPTED_ANSWER_ID)) question.hasAcceptedAnswer = true; question.owner = getSerializableUserSnippetObject(jsonObject.getJSONObject(JsonFields.Question.OWNER)); return question; } protected User getSerializableUserSnippetObject(JSONObjectWrapper userJsonObject) { User user = null; if (userJsonObject != null) { user = new User(); user.id = userJsonObject.getLong(JsonFields.User.USER_ID); user.type = UserType.toEnum(userJsonObject.getString(JsonFields.User.USER_TYPE)); user.displayName = userJsonObject.getString(JsonFields.User.DISPLAY_NAME); user.reputation = userJsonObject.getInt(JsonFields.User.REPUTATION); user.profileImageLink = userJsonObject.getString(JsonFields.User.PROFILE_IMAGE); user.acceptRate = userJsonObject.getInt(JsonFields.User.ACCEPT_RATE); } return user; } protected Answer getSerializedAnswerObject(JSONObjectWrapper jsonObject) throws JSONException { Answer answer = new Answer(); answer.id = jsonObject.getLong(JsonFields.Answer.ANSWER_ID); answer.questionId = jsonObject.getLong(JsonFields.Answer.QUESTION_ID); answer.link = jsonObject.getString(JsonFields.Answer.LINK); answer.body = jsonObject.getString(JsonFields.Answer.BODY); answer.title = jsonObject.getString(JsonFields.Answer.TITLE); answer.score = jsonObject.getInt(JsonFields.Answer.SCORE); answer.creationDate = jsonObject.getLong(JsonFields.Answer.CREATION_DATE); answer.accepted = jsonObject.getBoolean(JsonFields.Answer.IS_ACCEPTED); answer.upvoted = jsonObject.getBoolean(JsonFields.Answer.UPVOTED); answer.downvoted = jsonObject.getBoolean(JsonFields.Answer.DOWNVOTED); answer.owner = getSerializableUserSnippetObject(jsonObject.getJSONObject(JsonFields.Answer.OWNER)); return answer; } protected String[] getTags(JSONObjectWrapper jsonObject) throws JSONException { String[] tags = null; JSONArray tagsJsonArray = jsonObject.getJSONArray(JsonFields.Question.TAGS); if (tagsJsonArray != null) { tags = new String[tagsJsonArray.length()]; for (int i = 0; i < tags.length; i++) { tags[i] = tagsJsonArray.getString(i); } } return tags; } @SuppressWarnings("unchecked") protected <T> T getIndexFromArray(JSONArray jsonArray, int index, Class<T> type) { T wrapperObject = null; if (jsonArray != null && jsonArray.length() > index) { try { wrapperObject = (T) jsonArray.get(index); } catch (JSONException e) { Log.w(getLogTag(), e.getMessage()); } } return wrapperObject; } protected List<BasicNameValuePair> getBasicNameValuePartListForPost() { List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>(); parameters.add(new BasicNameValuePair(StackUri.QueryParams.ACCESS_TOKEN, AppUtils.loadAccessToken(null))); parameters.add(new BasicNameValuePair(StackUri.QueryParams.KEY, StackUri.QueryParamDefaultValues.KEY)); parameters.add(new BasicNameValuePair(StackUri.QueryParams.CLIENT_ID, QueryParamDefaultValues.CLIENT_ID)); parameters.add(new BasicNameValuePair(StackUri.QueryParams.SITE, OperatingSite.getSite().apiSiteParameter)); return parameters; } protected JSONObjectWrapper executeHttpGetRequest(String restEndPoint, Map<String, String> queryParams) { return getHttpHelper().executeHttpGet(StackUri.STACKX_API_HOST, restEndPoint, queryParams, SecureHttpHelper.HTTP_GZIP_RESPONSE_INTERCEPTOR, JSON_PARSER); } protected JSONObjectWrapper executeHttpPostRequest(String restEndPoint, Map<String, String> requestHeaders, Map<String, String> queryParams, HttpEntity httpEntity) { return getHttpHelper().executeHttpPost(StackUri.STACKX_API_HOST, restEndPoint, requestHeaders, queryParams, httpEntity, SecureHttpHelper.HTTP_GZIP_RESPONSE_INTERCEPTOR, JSON_PARSER); } protected Map<String, String> getDefaultQueryParams(String apiSiteParameter) { Map<String, String> queryParams = AppUtils.getDefaultQueryParams(); if (apiSiteParameter != null) { queryParams.put(StackUri.QueryParams.SITE, apiSiteParameter); } queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.ITEM_DETAIL_FILTER); return queryParams; } protected void sleep(long ms) { try { Thread.sleep(ms); } catch (InterruptedException e) { LogWrapper.e(getLogTag(), e.getMessage()); } } }