Android Open Source - CCSocialNetwork Response






From Project

Back to project page CCSocialNetwork.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project CCSocialNetwork listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2010-present Facebook.//  ww w.j av  a2  s .c  o  m
 *
 * 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 com.facebook;

import android.content.Context;
import com.facebook.internal.*;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphObjectList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * Encapsulates the response, successful or otherwise, of a call to the Facebook platform.
 */
public class Response {
    private final HttpURLConnection connection;
    private final GraphObject graphObject;
    private final GraphObjectList<GraphObject> graphObjectList;
    private final boolean isFromCache;
    private final FacebookRequestError error;
    private final Request request;

    /**
     * Property name of non-JSON results in the GraphObject. Certain calls to Facebook result in a non-JSON response
     * (e.g., the string literal "true" or "false"). To present a consistent way of accessing results, these are
     * represented as a GraphObject with a single string property with this name.
     */
    public static final String NON_JSON_RESPONSE_PROPERTY = "FACEBOOK_NON_JSON_RESULT";

    private static final int INVALID_SESSION_FACEBOOK_ERROR_CODE = 190;

    private static final String CODE_KEY = "code";
    private static final String BODY_KEY = "body";

    private static final String RESPONSE_LOG_TAG = "Response";

    private static final String RESPONSE_CACHE_TAG = "ResponseCache";
    private static FileLruCache responseCache;

    Response(Request request, HttpURLConnection connection, GraphObject graphObject, boolean isFromCache) {
        this.request = request;
        this.connection = connection;
        this.graphObject = graphObject;
        this.graphObjectList = null;
        this.isFromCache = isFromCache;
        this.error = null;
    }

    Response(Request request, HttpURLConnection connection, GraphObjectList<GraphObject> graphObjects,
            boolean isFromCache) {
        this.request = request;
        this.connection = connection;
        this.graphObject = null;
        this.graphObjectList = graphObjects;
        this.isFromCache = isFromCache;
        this.error = null;
    }

    Response(Request request, HttpURLConnection connection, FacebookRequestError error) {
        this.request = request;
        this.connection = connection;
        this.graphObject = null;
        this.graphObjectList = null;
        this.isFromCache = false;
        this.error = error;
    }

    /**
     * Returns information about any errors that may have occurred during the request.
     *
     * @return the error from the server, or null if there was no server error
     */
    public final FacebookRequestError getError() {
        return error;
    }

    /**
     * The single graph object returned for this request, if any.
     *
     * @return the graph object returned, or null if none was returned (or if the result was a list)
     */
    public final GraphObject getGraphObject() {
        return graphObject;
    }

    /**
     * The single graph object returned for this request, if any, cast into a particular type of GraphObject.
     *
     * @param graphObjectClass the GraphObject-derived interface to cast the graph object into
     * @return the graph object returned, or null if none was returned (or if the result was a list)
     * @throws FacebookException If the passed in Class is not a valid GraphObject interface
     */
    public final <T extends GraphObject> T getGraphObjectAs(Class<T> graphObjectClass) {
        if (graphObject == null) {
            return null;
        }
        if (graphObjectClass == null) {
            throw new NullPointerException("Must pass in a valid interface that extends GraphObject");
        }
        return graphObject.cast(graphObjectClass);
    }

    /**
     * The list of graph objects returned for this request, if any.
     *
     * @return the list of graph objects returned, or null if none was returned (or if the result was not a list)
     */
    public final GraphObjectList<GraphObject> getGraphObjectList() {
        return graphObjectList;
    }

    /**
     * The list of graph objects returned for this request, if any, cast into a particular type of GraphObject.
     *
     * @param graphObjectClass the GraphObject-derived interface to cast the graph objects into
     * @return the list of graph objects returned, or null if none was returned (or if the result was not a list)
     * @throws FacebookException If the passed in Class is not a valid GraphObject interface
     */
    public final <T extends GraphObject> GraphObjectList<T> getGraphObjectListAs(Class<T> graphObjectClass) {
        if (graphObjectList == null) {
            return null;
        }
        return graphObjectList.castToListOf(graphObjectClass);
    }

    /**
     * Returns the HttpURLConnection that this response was generated from. If the response was retrieved
     * from the cache, this will be null.
     *
     * @return the connection, or null
     */
    public final HttpURLConnection getConnection() {
        return connection;
    }

    /**
     * Returns the request that this response is for.
     *
     * @return the request that this response is for
     */
    public Request getRequest() {
        return request;
    }

    /**
     * Indicates whether paging is being done forward or backward.
     */
    public enum PagingDirection {
        /**
         * Indicates that paging is being performed in the forward direction.
         */
        NEXT,
        /**
         * Indicates that paging is being performed in the backward direction.
         */
        PREVIOUS
    }

    /**
     * If a Response contains results that contain paging information, returns a new
     * Request that will retrieve the next page of results, in whichever direction
     * is desired. If no paging information is available, returns null.
     *
     * @param direction enum indicating whether to page forward or backward
     * @return a Request that will retrieve the next page of results in the desired
     *         direction, or null if no paging information is available
     */
    public Request getRequestForPagedResults(PagingDirection direction) {
        String link = null;
        if (graphObject != null) {
            PagedResults pagedResults = graphObject.cast(PagedResults.class);
            PagingInfo pagingInfo = pagedResults.getPaging();
            if (pagingInfo != null) {
                if (direction == PagingDirection.NEXT) {
                    link = pagingInfo.getNext();
                } else {
                    link = pagingInfo.getPrevious();
                }
            }
        }
        if (Utility.isNullOrEmpty(link)) {
            return null;
        }

        if (link != null && link.equals(request.getUrlForSingleRequest())) {
            // We got the same "next" link as we just tried to retrieve. This could happen if cached
            // data is invalid. All we can do in this case is pretend we have finished.
            return null;
        }

        Request pagingRequest;
        try {
            pagingRequest = new Request(request.getSession(), new URL(link));
        } catch (MalformedURLException e) {
            return null;
        }

        return pagingRequest;
    }

    /**
     * Provides a debugging string for this response.
     */
    @Override
    public String toString() {
        String responseCode;
        try {
            responseCode = String.format("%d", (connection != null) ? connection.getResponseCode() : 200);
        } catch (IOException e) {
            responseCode = "unknown";
        }

        return new StringBuilder().append("{Response: ").append(" responseCode: ").append(responseCode)
                .append(", graphObject: ").append(graphObject).append(", error: ").append(error)
                .append(", isFromCache:").append(isFromCache).append("}")
                .toString();
    }

    /**
     * Indicates whether the response was retrieved from a local cache or from the server.
     *
     * @return true if the response was cached locally, false if it was retrieved from the server
     */
    public final boolean getIsFromCache() {
        return isFromCache;
    }

    static FileLruCache getResponseCache() {
        if (responseCache == null) {
            Context applicationContext = Session.getStaticContext();
            if (applicationContext != null) {
                responseCache = new FileLruCache(applicationContext, RESPONSE_CACHE_TAG, new FileLruCache.Limits());
            }
        }

        return responseCache;
    }

    @SuppressWarnings("resource")
    static List<Response> fromHttpConnection(HttpURLConnection connection, RequestBatch requests) {
        InputStream stream = null;

        FileLruCache cache = null;
        String cacheKey = null;
        if (requests instanceof CacheableRequestBatch) {
            CacheableRequestBatch cacheableRequestBatch = (CacheableRequestBatch) requests;
            cache = getResponseCache();
            cacheKey = cacheableRequestBatch.getCacheKeyOverride();
            if (Utility.isNullOrEmpty(cacheKey)) {
                if (requests.size() == 1) {
                    // Default for single requests is to use the URL.
                    cacheKey = requests.get(0).getUrlForSingleRequest();
                } else {
                    Logger.log(LoggingBehavior.REQUESTS, RESPONSE_CACHE_TAG,
                            "Not using cache for cacheable request because no key was specified");
                }
            }

            // Try loading from cache.  If that fails, load from the network.
            if (!cacheableRequestBatch.getForceRoundTrip() && cache != null && !Utility.isNullOrEmpty(cacheKey)) {
                try {
                    stream = cache.get(cacheKey);
                    if (stream != null) {
                        return createResponsesFromStream(stream, null, requests, true);
                    }
                } catch (FacebookException exception) { // retry via roundtrip below
                } catch (JSONException exception) {
                } catch (IOException exception) {
                } finally {
                    Utility.closeQuietly(stream);
                }
            }
        }

        // Load from the network, and cache the result if not an error.
        try {
            if (connection.getResponseCode() >= 400) {
                stream = connection.getErrorStream();
            } else {
                stream = connection.getInputStream();
                if ((cache != null) && (cacheKey != null) && (stream != null)) {
                    InputStream interceptStream = cache.interceptAndPut(cacheKey, stream);
                    if (interceptStream != null) {
                        stream = interceptStream;
                    }
                }
            }

            return createResponsesFromStream(stream, connection, requests, false);
        } catch (FacebookException facebookException) {
            Logger.log(LoggingBehavior.REQUESTS, RESPONSE_LOG_TAG, "Response <Error>: %s", facebookException);
            return constructErrorResponses(requests, connection, facebookException);
        } catch (JSONException exception) {
            Logger.log(LoggingBehavior.REQUESTS, RESPONSE_LOG_TAG, "Response <Error>: %s", exception);
            return constructErrorResponses(requests, connection, new FacebookException(exception));
        } catch (IOException exception) {
            Logger.log(LoggingBehavior.REQUESTS, RESPONSE_LOG_TAG, "Response <Error>: %s", exception);
            return constructErrorResponses(requests, connection, new FacebookException(exception));
        } finally {
            Utility.closeQuietly(stream);
        }
    }

    static List<Response> createResponsesFromStream(InputStream stream, HttpURLConnection connection,
            RequestBatch requests, boolean isFromCache) throws FacebookException, JSONException, IOException {

        String responseString = Utility.readStreamToString(stream);
        Logger.log(LoggingBehavior.INCLUDE_RAW_RESPONSES, RESPONSE_LOG_TAG,
                "Response (raw)\n  Size: %d\n  Response:\n%s\n", responseString.length(),
                responseString);

        return createResponsesFromString(responseString, connection, requests, isFromCache);
    }

    static List<Response> createResponsesFromString(String responseString, HttpURLConnection connection,
            RequestBatch requests, boolean isFromCache) throws FacebookException, JSONException, IOException {
        JSONTokener tokener = new JSONTokener(responseString);
        Object resultObject = tokener.nextValue();

        List<Response> responses = createResponsesFromObject(connection, requests, resultObject, isFromCache);
        Logger.log(LoggingBehavior.REQUESTS, RESPONSE_LOG_TAG, "Response\n  Id: %s\n  Size: %d\n  Responses:\n%s\n",
                requests.getId(), responseString.length(), responses);

        return responses;
    }

    private static List<Response> createResponsesFromObject(HttpURLConnection connection, List<Request> requests,
            Object object, boolean isFromCache) throws FacebookException, JSONException {
        assert (connection != null) || isFromCache;

        int numRequests = requests.size();
        List<Response> responses = new ArrayList<Response>(numRequests);
        Object originalResult = object;

        if (numRequests == 1) {
            Request request = requests.get(0);
            try {
                // Single request case -- the entire response is the result, wrap it as "body" so we can handle it
                // the same as we do in the batched case. We get the response code from the actual HTTP response,
                // as opposed to the batched case where it is returned as a "code" element.
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(BODY_KEY, object);
                int responseCode = (connection != null) ? connection.getResponseCode() : 200;
                jsonObject.put(CODE_KEY, responseCode);

                JSONArray jsonArray = new JSONArray();
                jsonArray.put(jsonObject);

                // Pretend we got an array of 1 back.
                object = jsonArray;
            } catch (JSONException e) {
                responses.add(new Response(request, connection, new FacebookRequestError(connection, e)));
            } catch (IOException e) {
                responses.add(new Response(request, connection, new FacebookRequestError(connection, e)));
            }
        }

        if (!(object instanceof JSONArray) || ((JSONArray) object).length() != numRequests) {
            FacebookException exception = new FacebookException("Unexpected number of results");
            throw exception;
        }

        JSONArray jsonArray = (JSONArray) object;

        for (int i = 0; i < jsonArray.length(); ++i) {
            Request request = requests.get(i);
            try {
                Object obj = jsonArray.get(i);
                responses.add(createResponseFromObject(request, connection, obj, isFromCache, originalResult));
            } catch (JSONException e) {
                responses.add(new Response(request, connection, new FacebookRequestError(connection, e)));
            } catch (FacebookException e) {
                responses.add(new Response(request, connection, new FacebookRequestError(connection, e)));
            }
        }

        return responses;
    }

    private static Response createResponseFromObject(Request request, HttpURLConnection connection, Object object,
            boolean isFromCache, Object originalResult) throws JSONException {
        if (object instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) object;

            FacebookRequestError error =
                    FacebookRequestError.checkResponseAndCreateError(jsonObject, originalResult, connection);
            if (error != null) {
                if (error.getErrorCode() == INVALID_SESSION_FACEBOOK_ERROR_CODE) {
                    Session session = request.getSession();
                    if (session != null) {
                        session.closeAndClearTokenInformation();
                    }
                }
                return new Response(request, connection, error);
            }

            Object body = Utility.getStringPropertyAsJSON(jsonObject, BODY_KEY, NON_JSON_RESPONSE_PROPERTY);

            if (body instanceof JSONObject) {
                GraphObject graphObject = GraphObject.Factory.create((JSONObject) body);
                return new Response(request, connection, graphObject, isFromCache);
            } else if (body instanceof JSONArray) {
                GraphObjectList<GraphObject> graphObjectList = GraphObject.Factory.createList(
                        (JSONArray) body, GraphObject.class);
                return new Response(request, connection, graphObjectList, isFromCache);
            }
            // We didn't get a body we understand how to handle, so pretend we got nothing.
            object = JSONObject.NULL;
        }

        if (object == JSONObject.NULL) {
            return new Response(request, connection, (GraphObject)null, isFromCache);
        } else {
            throw new FacebookException("Got unexpected object type in response, class: "
                    + object.getClass().getSimpleName());
        }
    }

    static List<Response> constructErrorResponses(List<Request> requests, HttpURLConnection connection,
            FacebookException error) {
        int count = requests.size();
        List<Response> responses = new ArrayList<Response>(count);
        for (int i = 0; i < count; ++i) {
            Response response = new Response(requests.get(i), connection, new FacebookRequestError(connection, error));
            responses.add(response);
        }
        return responses;
    }

    interface PagingInfo extends GraphObject {
        String getNext();

        String getPrevious();
    }

    interface PagedResults extends GraphObject {
        GraphObjectList<GraphObject> getData();

        PagingInfo getPaging();
    }

}




Java Source Code List

com.facebook.AccessTokenSource.java
com.facebook.AccessToken.java
com.facebook.AuthorizationClient.java
com.facebook.FacebookAuthorizationException.java
com.facebook.FacebookDialogException.java
com.facebook.FacebookException.java
com.facebook.FacebookGraphObjectException.java
com.facebook.FacebookOperationCanceledException.java
com.facebook.FacebookRequestError.java
com.facebook.FacebookSdkVersion.java
com.facebook.FacebookServiceException.java
com.facebook.GetTokenClient.java
com.facebook.HttpMethod.java
com.facebook.InsightsLogger.java
com.facebook.LegacyHelper.java
com.facebook.LoggingBehavior.java
com.facebook.LoginActivity.java
com.facebook.NativeProtocol.java
com.facebook.NonCachingTokenCachingStrategy.java
com.facebook.RequestAsyncTask.java
com.facebook.RequestBatch.java
com.facebook.Request.java
com.facebook.Response.java
com.facebook.SessionDefaultAudience.java
com.facebook.SessionLoginBehavior.java
com.facebook.SessionState.java
com.facebook.Session.java
com.facebook.Settings.java
com.facebook.SharedPreferencesTokenCachingStrategy.java
com.facebook.TestSession.java
com.facebook.TokenCachingStrategy.java
com.facebook.UiLifecycleHelper.java
com.facebook.android.AsyncFacebookRunner.java
com.facebook.android.DialogError.java
com.facebook.android.FacebookError.java
com.facebook.android.Facebook.java
com.facebook.android.FbDialog.java
com.facebook.android.Util.java
com.facebook.internal.CacheableRequestBatch.java
com.facebook.internal.FileLruCache.java
com.facebook.internal.Logger.java
com.facebook.internal.ServerProtocol.java
com.facebook.internal.SessionAuthorizationType.java
com.facebook.internal.SessionTracker.java
com.facebook.internal.Utility.java
com.facebook.internal.Validate.java
com.facebook.internal.package-info.java
com.facebook.model.GraphLocation.java
com.facebook.model.GraphMultiResult.java
com.facebook.model.GraphObjectList.java
com.facebook.model.GraphObject.java
com.facebook.model.GraphPlace.java
com.facebook.model.GraphUser.java
com.facebook.model.JsonUtil.java
com.facebook.model.OpenGraphAction.java
com.facebook.model.PropertyName.java
com.facebook.widget.FacebookFragment.java
com.facebook.widget.FriendPickerFragment.java
com.facebook.widget.GraphObjectAdapter.java
com.facebook.widget.GraphObjectCursor.java
com.facebook.widget.GraphObjectPagingLoader.java
com.facebook.widget.ImageDownloader.java
com.facebook.widget.ImageRequest.java
com.facebook.widget.ImageResponseCache.java
com.facebook.widget.ImageResponse.java
com.facebook.widget.LoginButton.java
com.facebook.widget.PickerFragment.java
com.facebook.widget.PlacePickerFragment.java
com.facebook.widget.ProfilePictureView.java
com.facebook.widget.SimpleGraphObjectCursor.java
com.facebook.widget.UrlRedirectCache.java
com.facebook.widget.UserSettingsFragment.java
com.facebook.widget.WebDialog.java
com.facebook.widget.WorkQueue.java
org.example.SocialNetwork.CCSocialNetwork.java
org.example.SocialNetwork.EmailSender.java
org.example.SocialNetwork.InternetConnection.java