com.voidsearch.data.provider.facebook.SimpleGraphAPIClient.java Source code

Java tutorial

Introduction

Here is the source code for com.voidsearch.data.provider.facebook.SimpleGraphAPIClient.java

Source

/*
 * Copyright 2010 VoidSearch.com
 *
 * 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.voidsearch.data.provider.facebook;

import com.voidsearch.data.provider.facebook.objects.*;
import com.voidsearch.voidbase.client.VoidBaseHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.StringReader;
import java.net.URLEncoder;
import java.util.LinkedList;

public class SimpleGraphAPIClient extends VoidBaseHttpClient {

    private static String GRAPH_API_HOST = "https://graph.facebook.com/";
    private static String ACCESS_TOKEN_PARAM = "access_token";
    private static long DEFAULT_QUERY_DELAY = 5000;

    private String accessToken;
    private long queryDelay;

    private long queryTimer = System.currentTimeMillis();

    public SimpleGraphAPIClient(String accessToken, long queryDelay) {
        this.accessToken = accessToken;
        this.queryDelay = queryDelay;
    }

    public SimpleGraphAPIClient(String accessToken) {
        this.accessToken = accessToken;
        this.queryDelay = DEFAULT_QUERY_DELAY;
    }

    /**
     * set millisecond delay between queries 
     *
     * @param delayTime
     */
    public void setQueryDelay(long delayTime) {
        this.queryDelay = delayTime;
    }

    /**
     * get list of friends for current authenticated user
     *
     * @return
     * @throws Exception
     */
    public LinkedList<FacebookUser> getFriends() throws Exception {
        return getFriends("me");
    }

    /**
     * get list of friends corresponding to specific user
     *
     * @param user
     * @return
     * @throws Exception
     */
    public LinkedList<FacebookUser> getFriends(String user) throws Exception {
        return this.<FacebookUser>getResultList(user, "friends");
    }

    /**
     * get all likes for particular user
     * 
     * @param user
     * @return
     * @throws Exception
     */
    public LinkedList<LikedEntry> getLikes(String user) throws Exception {
        return this.<LikedEntry>getResultList(user, "likes");
    }

    /**
     * get all photos for single user
     *
     * @param user
     * @return
     * @throws Exception
     */
    public LinkedList<PhotoEntry> getPhotos(String user) throws Exception {
        return this.<PhotoEntry>getResultList(user, "photos");
    }

    /**
     * get all groups for single user
     *
     * @param user
     * @return
     * @throws Exception
     */
    public LinkedList<GroupEntry> getGroups(String user) throws Exception {
        return this.<GroupEntry>getResultList(user, "groups");
    }

    /**
     * get all news events for single user
     *
     * @param user
     * @return
     * @throws Exception
     */
    public LinkedList<NewsEntry> getNews(String user) throws Exception {
        return this.<NewsEntry>getResultList(user, "home");
    }

    /**
     * get paginated list of results
     *
     * @param user
     * @param feedName
     * @param <T>
     * @return
     * @throws Exception
     */
    private <T> LinkedList<T> getResultList(String user, String feedName) throws Exception {

        LinkedList<T> results = new LinkedList<T>();
        String query = GRAPH_API_HOST + user + "/" + feedName;

        boolean hasMore = true;

        while (hasMore == true) {

            JSONObject response = getResponse(query);
            JSONArray resultArray = response.getJSONArray("data");

            loadResults(results, resultArray, feedName);

            if (hasMore(response)) {
                String nextQuery = getNextPageURL(response);
                if (!nextQuery.equals(query)) {
                    query = nextQuery;
                } else {
                    hasMore = false;
                }
            } else {
                hasMore = false;
            }

        }

        return results;
    }

    /**
     * load result list from json response for given feed
     *
     * @param results
     * @param resultArray
     * @param feedName
     * @param <T>
     * @throws Exception
     */
    private <T> void loadResults(LinkedList<T> results, JSONArray resultArray, String feedName) throws Exception {
        for (int i = 0; i < resultArray.length(); i++) {
            results.add((T) GraphObjectFactory.getObject(feedName, (JSONObject) resultArray.get(i)));
        }

    }

    /**
     * get "data" entry fron JSON response
     *
     * @param query
     * @return
     * @throws Exception
     */
    private JSONArray getDataArray(String query) throws Exception {
        JSONObject response = getResponse(query);
        return response.getJSONArray("data");
    }

    /**
     * get response from Graph API
     *
     * @param query
     * @return
     * @throws Exception
     */
    private JSONObject getResponse(String query) throws Exception {
        if (!(query.contains("?") && query.contains(ACCESS_TOKEN_PARAM))) {
            query += "?" + ACCESS_TOKEN_PARAM + "=" + URLEncoder.encode(accessToken);
        }

        // force query delay interval
        long lastQueryElapsed = getQueryDelay();
        if (lastQueryElapsed < queryDelay) {
            Thread.sleep(queryDelay - lastQueryElapsed);
        }
        resetQueryTimer();

        byte[] response = get(query);
        return new JSONObject(new JSONTokener(new StringReader(new String(new String(response)))));
    }

    /**
     * get elapsed time since last query
     *
     * @return
     */
    private long getQueryDelay() {
        return System.currentTimeMillis() - queryTimer;
    }

    /**
     * reset internal query delay counter
     *
     */
    private void resetQueryTimer() {
        queryTimer = System.currentTimeMillis();
    }

    /**
     * check whether return object has pagination
     *
     * @param object
     * @return
     */
    private boolean hasMore(JSONObject object) throws Exception {
        return object.has("paging");
    }

    /**
     * get next page url
     *
     * @param object
     * @return
     * @throws Exception
     */
    private String getNextPageURL(JSONObject object) throws Exception {
        JSONObject paging = (JSONObject) object.get("paging");
        return (String) paging.get("next");
    }

}