com.facebook.internal.FacebookRequestErrorClassification.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.internal.FacebookRequestErrorClassification.java

Source

/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
 * copy, modify, and distribute this software in source code or binary form for use
 * in connection with the web services and APIs provided by Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use of
 * this software is subject to the Facebook Developer Principles and Policies
 * [http://developers.facebook.com/policy/]. This copyright notice shall be
 * included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.facebook.internal;

import com.facebook.FacebookRequestError;

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

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * com.facebook.internal is solely for the use of other packages within the Facebook SDK for
 * Android. Use of any of the classes in this package is unsupported, and they may be modified or
 * removed without warning at any time.
 */
public final class FacebookRequestErrorClassification {
    public static final int EC_SERVICE_UNAVAILABLE = 2;
    public static final int EC_APP_TOO_MANY_CALLS = 4;
    public static final int EC_RATE = 9;
    public static final int EC_USER_TOO_MANY_CALLS = 17;
    public static final int EC_INVALID_SESSION = 102;
    public static final int EC_INVALID_TOKEN = 190;
    public static final int EC_TOO_MANY_USER_ACTION_CALLS = 341;

    public static final String KEY_RECOVERY_MESSAGE = "recovery_message";
    public static final String KEY_NAME = "name";
    public static final String KEY_OTHER = "other";
    public static final String KEY_TRANSIENT = "transient";
    public static final String KEY_LOGIN_RECOVERABLE = "login_recoverable";

    // Key is error code, value is the subcodes. Null subcodes means all subcodes are accepted.
    private final Map<Integer, Set<Integer>> otherErrors;
    private final Map<Integer, Set<Integer>> transientErrors;
    private final Map<Integer, Set<Integer>> loginRecoverableErrors;
    private final String otherRecoveryMessage;
    private final String transientRecoveryMessage;
    private final String loginRecoverableRecoveryMessage;

    private static FacebookRequestErrorClassification defaultInstance;

    FacebookRequestErrorClassification(Map<Integer, Set<Integer>> otherErrors,
            Map<Integer, Set<Integer>> transientErrors, Map<Integer, Set<Integer>> loginRecoverableErrors,
            String otherRecoveryMessage, String transientRecoveryMessage, String loginRecoverableRecoveryMessage) {
        this.otherErrors = otherErrors;
        this.transientErrors = transientErrors;
        this.loginRecoverableErrors = loginRecoverableErrors;
        this.otherRecoveryMessage = otherRecoveryMessage;
        this.transientRecoveryMessage = transientRecoveryMessage;
        this.loginRecoverableRecoveryMessage = loginRecoverableRecoveryMessage;
    }

    public Map<Integer, Set<Integer>> getOtherErrors() {
        return otherErrors;
    }

    public Map<Integer, Set<Integer>> getTransientErrors() {
        return transientErrors;
    }

    public Map<Integer, Set<Integer>> getLoginRecoverableErrors() {
        return loginRecoverableErrors;
    }

    public String getRecoveryMessage(FacebookRequestError.Category category) {
        switch (category) {
        case OTHER:
            return otherRecoveryMessage;
        case LOGIN_RECOVERABLE:
            return loginRecoverableRecoveryMessage;
        case TRANSIENT:
            return transientRecoveryMessage;
        default:
            return null;
        }
    }

    public FacebookRequestError.Category classify(int errorCode, int errorSubCode, boolean isTransient) {
        if (isTransient) {
            return FacebookRequestError.Category.TRANSIENT;
        }

        if (otherErrors != null && otherErrors.containsKey(errorCode)) {
            Set<Integer> subCodes = otherErrors.get(errorCode);
            if (subCodes == null || subCodes.contains(errorSubCode)) {
                return FacebookRequestError.Category.OTHER;
            }
        }

        if (loginRecoverableErrors != null && loginRecoverableErrors.containsKey(errorCode)) {
            Set<Integer> subCodes = loginRecoverableErrors.get(errorCode);
            if (subCodes == null || subCodes.contains(errorSubCode)) {
                return FacebookRequestError.Category.LOGIN_RECOVERABLE;
            }
        }

        if (transientErrors != null && transientErrors.containsKey(errorCode)) {
            Set<Integer> subCodes = transientErrors.get(errorCode);
            if (subCodes == null || subCodes.contains(errorSubCode)) {
                return FacebookRequestError.Category.TRANSIENT;
            }
        }
        return FacebookRequestError.Category.OTHER;
    }

    public static synchronized FacebookRequestErrorClassification getDefaultErrorClassification() {
        if (defaultInstance == null) {
            defaultInstance = getDefaultErrorClassificationImpl();
        }
        return defaultInstance;
    }

    private static FacebookRequestErrorClassification getDefaultErrorClassificationImpl() {
        Map<Integer, Set<Integer>> transientErrors = new HashMap<Integer, Set<Integer>>() {
            {
                put(EC_SERVICE_UNAVAILABLE, null);
                put(EC_APP_TOO_MANY_CALLS, null);
                put(EC_RATE, null);
                put(EC_USER_TOO_MANY_CALLS, null);
                put(EC_TOO_MANY_USER_ACTION_CALLS, null);
            }
        };

        Map<Integer, Set<Integer>> loginRecoverableErrors = new HashMap<Integer, Set<Integer>>() {
            {
                put(EC_INVALID_SESSION, null);
                put(EC_INVALID_TOKEN, null);
            }
        };

        return new FacebookRequestErrorClassification(null, transientErrors, loginRecoverableErrors, null, null,
                null);
    }

    private static Map<Integer, Set<Integer>> parseJSONDefinition(JSONObject definition) {
        JSONArray itemsArray = definition.optJSONArray("items");
        if (itemsArray.length() == 0) {
            return null;
        }

        Map<Integer, Set<Integer>> items = new HashMap<>();
        for (int i = 0; i < itemsArray.length(); i++) {
            JSONObject item = itemsArray.optJSONObject(i);
            if (item == null) {
                continue;
            }
            int code = item.optInt("code");
            if (code == 0) {
                continue;
            }
            Set<Integer> subcodes = null;
            JSONArray subcodesArray = item.optJSONArray("subcodes");
            if (subcodesArray != null && subcodesArray.length() > 0) {
                subcodes = new HashSet<>();
                for (int j = 0; j < subcodesArray.length(); j++) {
                    int subCode = subcodesArray.optInt(j);
                    if (subCode != 0) {
                        subcodes.add(subCode);
                    }
                }
            }
            items.put(code, subcodes);
        }
        return items;
    }

    public static FacebookRequestErrorClassification createFromJSON(JSONArray jsonArray) {
        if (jsonArray == null) {
            return null;
        }
        Map<Integer, Set<Integer>> otherErrors = null;
        Map<Integer, Set<Integer>> transientErrors = null;
        Map<Integer, Set<Integer>> loginRecoverableErrors = null;
        String otherRecoveryMessage = null;
        String transientRecoveryMessage = null;
        String loginRecoverableRecoveryMessage = null;

        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject definition = jsonArray.optJSONObject(i);
            if (definition == null) {
                continue;
            }
            String name = definition.optString(KEY_NAME);
            if (name == null) {
                continue;
            }
            if (name.equalsIgnoreCase(KEY_OTHER)) {
                otherRecoveryMessage = definition.optString(KEY_RECOVERY_MESSAGE, null);
                otherErrors = parseJSONDefinition(definition);
            } else if (name.equalsIgnoreCase(KEY_TRANSIENT)) {
                transientRecoveryMessage = definition.optString(KEY_RECOVERY_MESSAGE, null);
                transientErrors = parseJSONDefinition(definition);
            } else if (name.equalsIgnoreCase(KEY_LOGIN_RECOVERABLE)) {
                loginRecoverableRecoveryMessage = definition.optString(KEY_RECOVERY_MESSAGE, null);
                loginRecoverableErrors = parseJSONDefinition(definition);
            }
        }
        return new FacebookRequestErrorClassification(otherErrors, transientErrors, loginRecoverableErrors,
                otherRecoveryMessage, transientRecoveryMessage, loginRecoverableRecoveryMessage);
    }
}