com.prasanna.android.stacknetwork.service.UserServiceHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.prasanna.android.stacknetwork.service.UserServiceHelper.java

Source

/*
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.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.prasanna.android.stacknetwork.model.Account;
import com.prasanna.android.stacknetwork.model.Answer;
import com.prasanna.android.stacknetwork.model.InboxItem;
import com.prasanna.android.stacknetwork.model.InboxItem.ItemType;
import com.prasanna.android.stacknetwork.model.Post;
import com.prasanna.android.stacknetwork.model.Question;
import com.prasanna.android.stacknetwork.model.Reputation;
import com.prasanna.android.stacknetwork.model.Site;
import com.prasanna.android.stacknetwork.model.StackExchangeHttpError;
import com.prasanna.android.stacknetwork.model.StackXPage;
import com.prasanna.android.stacknetwork.model.Tag;
import com.prasanna.android.stacknetwork.model.User;
import com.prasanna.android.stacknetwork.model.User.UserType;
import com.prasanna.android.stacknetwork.model.WritePermission;
import com.prasanna.android.stacknetwork.model.WritePermission.ObjectType;
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.Order;
import com.prasanna.android.stacknetwork.utils.StackUri.Sort;
import com.prasanna.android.stacknetwork.utils.StringConstants;
import com.prasanna.android.utils.LogWrapper;

public class UserServiceHelper extends AbstractBaseServiceHelper {
    private final String TAG = UserServiceHelper.class.getSimpleName();

    private static final UserServiceHelper userService = new UserServiceHelper();

    public static UserServiceHelper getInstance() {
        return userService;
    }

    @Override
    protected String getLogTag() {
        return TAG;
    }

    public LinkedHashMap<String, Site> getAllSitesInNetwork() {
        String restEndPoint = StringConstants.SITES;
        LinkedHashMap<String, Site> sites = new LinkedHashMap<String, Site>();
        boolean hasMore = true;
        int page = 1;
        final int PAGE_SIZE = 100;
        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf(PAGE_SIZE));

        while (hasMore) {
            queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(page++));
            JSONObjectWrapper jsonObject = executeHttpGetRequest(restEndPoint, queryParams);

            try {
                hasMore = addSites(sites, jsonObject);
            } catch (JSONException e) {
                LogWrapper.d(getLogTag(), e.getMessage());
                hasMore = false;
            }
        }
        return sites;
    }

    private boolean addSites(LinkedHashMap<String, Site> sites, JSONObjectWrapper jsonObject) throws JSONException {
        if (jsonObject != null) {
            JSONArray jsonArray = jsonObject.getJSONArray(JsonFields.ITEMS);

            if (jsonArray != null) {
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject siteJsonObject = jsonArray.getJSONObject(i);
                    Site site = getSerializedSiteObject(new JSONObjectWrapper(siteJsonObject));
                    if (site != null)
                        sites.put(site.link, site);
                }
            }

            return jsonObject.getBoolean(JsonFields.HAS_MORE);
        }

        return false;
    }

    private Site getSerializedSiteObject(JSONObjectWrapper siteJsonObject) {
        if (siteJsonObject == null)
            return null;

        Site site = new Site();
        site.apiSiteParameter = siteJsonObject.getString(JsonFields.Site.API_SITE_PARAMETER);
        site.logoUrl = siteJsonObject.getString(JsonFields.Site.LOGO_URL);
        site.name = siteJsonObject.getString(JsonFields.Site.NAME);
        site.audience = siteJsonObject.getString(JsonFields.Site.AUDIENCE);
        site.link = siteJsonObject.getString(JsonFields.Site.SITE_URL);
        site.faviconUrl = siteJsonObject.getString(JsonFields.Site.FAVICON_URL);
        site.iconUrl = siteJsonObject.getString(JsonFields.Site.ICON_URL);
        return site;
    }

    private StackXPage<Question> getQuestions(String restEndPoint, Map<String, String> queryParams) {
        JSONObjectWrapper questionsJsonResponse = executeHttpGetRequest(restEndPoint, queryParams);

        if (questionsJsonResponse != null) {
            return getQuestionModel(questionsJsonResponse);
        }

        return null;
    }

    public StackXPage<Question> getMyQuestions(int page) {
        return getQuestions("/me/questions", getQueryParams(page));
    }

    public StackXPage<Question> getQuestionsByUser(long userId, int page) {
        return getQuestions("/users/" + userId + "/questions", getQueryParams(page));
    }

    public StackXPage<Question> getMyFavorites(int page) {
        return getQuestions("/me/favorites", getQueryParams(page));
    }

    public StackXPage<Question> getFavoritesByUser(long userId, int page) {
        return getQuestions("/users/" + userId + "/favorites", getQueryParams(page));
    }

    private Map<String, String> getQueryParams(int page) {
        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.ORDER, StackUri.QueryParamDefaultValues.ORDER);
        queryParams.put(StackUri.QueryParams.SORT, StackUri.Sort.ACTIVITY);
        queryParams.put(StackUri.QueryParams.SITE, OperatingSite.getSite().apiSiteParameter);
        queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(page));
        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf(StackUri.QueryParamDefaultValues.PAGE_SIZE));
        return queryParams;
    }

    public StackXPage<User> getMe(String site) {
        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.SITE, site);
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.USER_DETAIL_FILTER);
        return getSerializedUserObject(executeHttpGetRequest("/me", queryParams));
    }

    public StackXPage<User> getUserById(long userId, String site) {
        StackXPage<User> page = null;
        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.SITE, site);
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.USER_DETAIL_FILTER);

        if (userId != -1)
            page = getSerializedUserObject(executeHttpGetRequest("/users/" + userId, queryParams));

        return page;
    }

    private StackXPage<Answer> getAnswers(String restEndPoint, Map<String, String> queryParams) {
        StackXPage<Answer> page = new StackXPage<Answer>();

        JSONObjectWrapper answersJsonObject = executeHttpGetRequest(restEndPoint, queryParams);

        if (answersJsonObject != null) {
            getPageInfo(answersJsonObject, page);
            page.items = new ArrayList<Answer>();
            JSONArray jsonArray = answersJsonObject.getJSONArray(JsonFields.ITEMS);
            if (jsonArray != null) {

                try {
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObjectWrapper jsonObject = JSONObjectWrapper.wrap(jsonArray.getJSONObject(i));
                        page.items.add(getSerializedAnswerObject(jsonObject));
                    }
                } catch (JSONException e) {
                    LogWrapper.d(getLogTag(), e.getMessage());
                }
            }
        }

        return page;
    }

    public StackXPage<Answer> getMyAnswers(int page) {
        return answers("/me/answers", page);
    }

    public StackXPage<Answer> getAnswersByUser(long userId, int page) {
        return answers("/users/" + userId + "/answers", page);
    }

    private StackXPage<Answer> answers(String restEndPoint, int page) {
        Map<String, String> queryParams = getQueryParams(page);
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.ITEM_DETAIL_FILTER);
        return getAnswers(restEndPoint, queryParams);
    }

    public ArrayList<WritePermission> getWritePermissions(String site) {
        ArrayList<WritePermission> permissions = new ArrayList<WritePermission>();

        String restEndPoint = "me/write-permissions";

        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.SITE, site);
        JSONObjectWrapper jsonObjectWrapper = executeHttpGetRequest(restEndPoint, queryParams);

        if (jsonObjectWrapper != null) {
            JSONArray jsonArray = jsonObjectWrapper.getJSONArray(JsonFields.ITEMS);
            if (jsonArray != null && jsonArray.length() > 0) {
                try {
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObjectWrapper permissionJsonObject = JSONObjectWrapper.wrap(jsonArray.getJSONObject(i));

                        WritePermission permission = new WritePermission();
                        permission.canAdd = permissionJsonObject.getBoolean(JsonFields.Permission.CAN_ADD);
                        permission.canDelete = permissionJsonObject.getBoolean(JsonFields.Permission.CAN_DELETE);
                        permission.canEdit = permissionJsonObject.getBoolean(JsonFields.Permission.CAN_EDIT);
                        permission.maxDailyActions = permissionJsonObject
                                .getInt(JsonFields.Permission.MAX_DAILY_ACTIONS);
                        permission.minSecondsBetweenActions = permissionJsonObject
                                .getInt(JsonFields.Permission.MIN_SECONDS_BETWEEN_ACTIONS);
                        permission.objectType = ObjectType
                                .getEnum(permissionJsonObject.getString(JsonFields.Permission.OBJECT_TYPE));
                        permission.userId = permissionJsonObject.getLong(JsonFields.Permission.USER_ID);
                        permissions.add(permission);
                    }
                } catch (JSONException e) {
                    LogWrapper.d(getLogTag(), e.getMessage());
                }
            }
        }

        return permissions;
    }

    public StackXPage<InboxItem> getInbox(int page, int pageSize) {
        String restEndPoint = "inbox";

        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.ORDER, StackUri.QueryParamDefaultValues.ORDER);
        queryParams.put(StackUri.QueryParams.SORT, StackUri.Sort.ACTIVITY);
        queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(page));
        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf(pageSize));
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.USER_INBOX_FILTER);

        return getInboxItems(restEndPoint, queryParams);
    }

    public StackXPage<InboxItem> getUnreadItemsInInbox(int page) {
        String restEndPoint = "/inbox/unread";

        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(page));
        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf(StackUri.QueryParamDefaultValues.PAGE_SIZE));
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.USER_INBOX_FILTER);

        return getInboxItems(restEndPoint, queryParams);
    }

    private StackXPage<InboxItem> getInboxItems(String restEndPoint, Map<String, String> queryParams) {
        StackXPage<InboxItem> page = null;

        JSONObjectWrapper jsonOfInboxItems = executeHttpGetRequest(restEndPoint, queryParams);
        if (jsonOfInboxItems != null) {
            JSONArray itemsArray = jsonOfInboxItems.getJSONArray(JsonFields.ITEMS);

            if (itemsArray != null) {
                page = new StackXPage<InboxItem>();
                getPageInfo(jsonOfInboxItems, page);

                page.items = new ArrayList<InboxItem>();

                for (int i = 0; i < itemsArray.length(); i++) {
                    try {
                        JSONObjectWrapper itemJsonObject = JSONObjectWrapper.wrap(itemsArray.getJSONObject(i));
                        if (itemJsonObject != null)
                            page.items.add(getSerializedInboxItem(itemJsonObject));
                    } catch (JSONException e) {
                        LogWrapper.d(getLogTag(), e.getMessage());
                    }

                }
            }
        }
        return page;
    }

    private InboxItem getSerializedInboxItem(JSONObjectWrapper itemJsonObject) {
        InboxItem inboxItem = new InboxItem();
        inboxItem.questionId = itemJsonObject.getLong(JsonFields.InboxItem.QUESTION_ID);
        inboxItem.answerId = itemJsonObject.getLong(JsonFields.InboxItem.ANSWER_ID);
        inboxItem.commentId = itemJsonObject.getLong(JsonFields.InboxItem.COMMENT_ID);
        inboxItem.itemType = ItemType.getValue(itemJsonObject.getString(JsonFields.InboxItem.ITEM_TYPE));
        inboxItem.title = itemJsonObject.getString(JsonFields.InboxItem.TITLE);
        inboxItem.creationDate = itemJsonObject.getLong(JsonFields.InboxItem.CREATION_DATE);
        inboxItem.body = itemJsonObject.getString(JsonFields.InboxItem.BODY);
        inboxItem.unread = itemJsonObject.getBoolean(JsonFields.InboxItem.IS_UNREAD);
        inboxItem.site = getSerializedSiteObject(itemJsonObject.getJSONObject(JsonFields.InboxItem.SITE));
        return inboxItem;
    }

    public HashMap<String, Account> getMyAccount() {
        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.NETWORK_USER_TYPE_FILTER);
        return getAccounts("/me/associated", 1, queryParams);
    }

    public HashMap<String, Account> getAccount(long accountId) {
        return getAccounts("/users/" + accountId + "/associated", 1, AppUtils.getDefaultQueryParams());
    }

    private HashMap<String, Account> getAccounts(String restEndPoint, int page, Map<String, String> queryParams) {
        final int PAGE_SIZE = 100;
        boolean hasMore = true;
        HashMap<String, Account> accounts = new HashMap<String, Account>();

        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf(PAGE_SIZE));

        while (hasMore) {
            queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(page++));
            hasMore = addAccountsToMap(accounts, executeHttpGetRequest(restEndPoint, queryParams));
        }
        return accounts;
    }

    private boolean addAccountsToMap(HashMap<String, Account> accounts, JSONObjectWrapper accountsJsonObject) {
        if (accountsJsonObject != null) {
            JSONArray jsonArray = accountsJsonObject.getJSONArray(JsonFields.ITEMS);
            if (jsonArray != null) {
                for (int i = 0; i < jsonArray.length(); i++) {
                    try {
                        JSONObjectWrapper accountJsonObject = JSONObjectWrapper.wrap(jsonArray.getJSONObject(i));
                        Account account = new Account();
                        account.id = accountJsonObject.getLong(JsonFields.Account.ACCOUNT_ID);
                        account.userId = accountJsonObject.getLong(JsonFields.Account.USER_ID);
                        account.siteName = accountJsonObject.getString(JsonFields.Account.SITE_NAME);
                        account.siteUrl = accountJsonObject.getString(JsonFields.Account.SITE_URL);
                        account.userType = UserType
                                .toEnum(accountJsonObject.getString(JsonFields.Account.USER_TYPE));
                        accounts.put(account.siteUrl, account);
                    } catch (JSONException e) {
                        LogWrapper.d(getLogTag(), e.getMessage());
                    }
                }
            }

            return accountsJsonObject.getBoolean(JsonFields.HAS_MORE);
        }

        return false;
    }

    public StackExchangeHttpError logout(String accessToken) {
        StackExchangeHttpError error = new StackExchangeHttpError();
        error.id = -1;

        String restEndPoint = "/apps/" + accessToken + "/de-authenticate";
        JSONObjectWrapper jsonObject = executeHttpGetRequest(restEndPoint, null);
        if (jsonObject != null) {
            String deauthenticatedAccessToken = jsonObject.getString(JsonFields.AccessToken.ACCESS_TOKEN);
            if (deauthenticatedAccessToken == null || !accessToken.equals(deauthenticatedAccessToken)) {
                error.id = jsonObject.getInt(JsonFields.Error.ERROR_ID);
                error.name = jsonObject.getString(JsonFields.Error.ERROR_NAME);
                error.message = jsonObject.getString(JsonFields.Error.ERROR_MESSAGE);
            }
        }

        return error;
    }

    public LinkedHashSet<Tag> getTags(String site, int pageSize, boolean meTags) {
        int page = 1;
        LinkedHashSet<Tag> tags = null;
        String restEndPoint = meTags ? "/me/tags" : "/tags";
        boolean hasMore = true;

        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.SORT, StackUri.Sort.ACTIVITY);
        queryParams.put(StackUri.QueryParams.SITE, OperatingSite.getSite().apiSiteParameter);
        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf(pageSize));
        queryParams.put(StackUri.QueryParams.SORT, meTags ? Sort.NAME : Sort.POPULAR);
        queryParams.put(StackUri.QueryParams.ORDER, meTags ? Order.ASC : Order.DESC);

        while (hasMore) {
            queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(page++));
            JSONObjectWrapper jsonObjectWrapper = executeHttpGetRequest(restEndPoint, queryParams);

            if (jsonObjectWrapper != null) {
                JSONArray jsonArray = jsonObjectWrapper.getJSONArray(JsonFields.ITEMS);
                if (jsonArray != null && jsonArray.length() > 0) {
                    if (tags == null)
                        tags = new LinkedHashSet<Tag>();

                    for (int i = 0; i < jsonArray.length(); i++) {
                        try {
                            JSONObjectWrapper tagJson = JSONObjectWrapper.wrap(jsonArray.getJSONObject(i));
                            tags.add(new Tag(tagJson.getString(JsonFields.Tag.NAME)));
                        } catch (JSONException e) {
                            LogWrapper.d(getLogTag(), e.getMessage());
                        }
                    }
                }

                /* Get all the tags only for a registered user */
                hasMore = meTags ? jsonObjectWrapper.getBoolean(JsonFields.HAS_MORE) : false;

                /*
                 * Dont bombard the server if the user has like 10-15 pages of tags,
                 * delay each request by 100ms
                 */
                sleep(100);
            }
        }

        return tags;
    }

    public StackXPage<Reputation> reputationHistoryFull(int pageNum) {
        final StackXPage<Reputation> page = new StackXPage<Reputation>();
        final String restEndPoint = "me/reputation-history/full";

        Map<String, String> queryParams = AppUtils.getDefaultQueryParams();
        queryParams.put(StackUri.QueryParams.FILTER, StackUri.QueryParamDefaultValues.POST_TITLE_FILTER);
        queryParams.put(StackUri.QueryParams.SITE, OperatingSite.getSite().apiSiteParameter);
        queryParams.put(StackUri.QueryParams.PAGE, String.valueOf(pageNum));
        queryParams.put(StackUri.QueryParams.PAGE_SIZE, String.valueOf("50"));

        JSONObjectWrapper repHistory = executeHttpGetRequest(restEndPoint, queryParams);
        getPageInfo(repHistory, page);
        page.items = Reputation.parseCollection(repHistory);

        final Map<Long, List<Reputation>> postIdToRepMap = new HashMap<Long, List<Reputation>>();

        for (Reputation reputation : page.items) {
            if (!postIdToRepMap.containsKey(reputation.postId)) {
                postIdToRepMap.put(reputation.postId, new ArrayList<Reputation>());
            }
            postIdToRepMap.get(reputation.postId).add(reputation);
        }

        for (Post post : PostServiceHelper.getInstance().getPosts(postIdToRepMap.keySet(),
                OperatingSite.getSite().apiSiteParameter)) {
            for (Reputation reputation : postIdToRepMap.get(post.id)) {
                reputation.postTitle = new String(post.title);
            }
        }
        return page;
    }
}