org.springframework.social.facebook.api.impl.FeedTemplate.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.social.facebook.api.impl.FeedTemplate.java

Source

/*
 * Copyright 2014 the original author or authors.
 *
 * 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 org.springframework.social.facebook.api.impl;

import static org.springframework.social.facebook.api.impl.PagedListUtils.*;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.social.UncategorizedApiException;
import org.springframework.social.facebook.api.FacebookLink;
import org.springframework.social.facebook.api.FeedOperations;
import org.springframework.social.facebook.api.GraphApi;
import org.springframework.social.facebook.api.PagedList;
import org.springframework.social.facebook.api.PagingParameters;
import org.springframework.social.facebook.api.Post;
import org.springframework.social.facebook.api.Post.PostType;
import org.springframework.social.facebook.api.PostData;
import org.springframework.social.support.URIBuilder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

class FeedTemplate extends AbstractFacebookOperations implements FeedOperations {

    private static final PagingParameters FIRST_PAGE = new PagingParameters(25, null, null, null);

    private final GraphApi graphApi;

    private ObjectMapper objectMapper;

    private final RestTemplate restTemplate;

    public FeedTemplate(GraphApi graphApi, RestTemplate restTemplate, ObjectMapper objectMapper,
            boolean isAuthorizedForUser) {
        super(isAuthorizedForUser);
        this.graphApi = graphApi;
        this.restTemplate = restTemplate;
        this.objectMapper = objectMapper;
    }

    public PagedList<Post> getFeed() {
        return getFeed("me", FIRST_PAGE);
    }

    public PagedList<Post> getFeed(PagingParameters pagedListParameters) {
        return getFeed("me", pagedListParameters);
    }

    public PagedList<Post> getFeed(String ownerId) {
        return getFeed(ownerId, FIRST_PAGE);
    }

    public PagedList<Post> getFeed(String ownerId, PagingParameters pagedListParameters) {
        requireAuthorization();
        JsonNode responseNode = fetchConnectionList(GraphApi.GRAPH_API_URL + ownerId + "/feed",
                pagedListParameters);
        return deserializeList(responseNode, null, Post.class);
    }

    public PagedList<Post> getHomeFeed() {
        return getHomeFeed(FIRST_PAGE);
    }

    public PagedList<Post> getHomeFeed(PagingParameters pagedListParameters) {
        requireAuthorization();
        JsonNode responseNode = fetchConnectionList(GraphApi.GRAPH_API_URL + "me/home", pagedListParameters);
        return deserializeList(responseNode, null, Post.class);
    }

    public PagedList<Post> getStatuses() {
        return getStatuses("me", FIRST_PAGE);
    }

    public PagedList<Post> getStatuses(PagingParameters pagedListParameters) {
        return getStatuses("me", pagedListParameters);
    }

    public PagedList<Post> getStatuses(String userId) {
        return getStatuses(userId, FIRST_PAGE);
    }

    public PagedList<Post> getStatuses(String userId, PagingParameters pagedListParameters) {
        requireAuthorization();
        JsonNode responseNode = fetchConnectionList(GraphApi.GRAPH_API_URL + userId + "/statuses",
                pagedListParameters);
        return deserializeList(responseNode, "status", Post.class);
    }

    public PagedList<Post> getLinks() {
        return getLinks("me", FIRST_PAGE);
    }

    public PagedList<Post> getLinks(PagingParameters pagedListParameters) {
        return getLinks("me", pagedListParameters);
    }

    public PagedList<Post> getLinks(String ownerId) {
        return getLinks(ownerId, FIRST_PAGE);
    }

    public PagedList<Post> getLinks(String ownerId, PagingParameters pagedListParameters) {
        requireAuthorization();
        JsonNode responseNode = fetchConnectionList(GraphApi.GRAPH_API_URL + ownerId + "/links",
                pagedListParameters);
        return deserializeList(responseNode, "link", Post.class);
    }

    public PagedList<Post> getPosts() {
        return getPosts("me", FIRST_PAGE);
    }

    public PagedList<Post> getPosts(PagingParameters pagedListParameters) {
        return getPosts("me", pagedListParameters);
    }

    public PagedList<Post> getPosts(String ownerId) {
        return getPosts(ownerId, FIRST_PAGE);
    }

    public PagedList<Post> getPosts(String ownerId, PagingParameters pagedListParameters) {
        requireAuthorization();
        JsonNode responseNode = fetchConnectionList(GraphApi.GRAPH_API_URL + ownerId + "/posts",
                pagedListParameters);
        return deserializeList(responseNode, null, Post.class);
    }

    public Post getPost(String entryId) {
        requireAuthorization();
        ObjectNode responseNode = (ObjectNode) restTemplate.getForObject(GraphApi.GRAPH_API_URL + entryId,
                JsonNode.class);
        return deserializePost(null, Post.class, responseNode);
    }

    public String updateStatus(String message) {
        return post("me", message);
    }

    public String postLink(String message, FacebookLink link) {
        return postLink("me", message, link);
    }

    public String postLink(String ownerId, String message, FacebookLink link) {
        requireAuthorization();
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
        map.set("link", link.getLink());
        map.set("name", link.getName());
        map.set("caption", link.getCaption());
        map.set("description", link.getDescription());
        map.set("message", message);
        return graphApi.publish(ownerId, "feed", map);
    }

    public String post(PostData post) {
        requireAuthorization();
        return graphApi.publish(post.getTargetFeedId(), "feed", post.toRequestParameters());
    }

    public String post(String ownerId, String message) {
        requireAuthorization();
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
        map.set("message", message);
        return graphApi.publish(ownerId, "feed", map);
    }

    public void deletePost(String id) {
        requireAuthorization();
        graphApi.delete(id);
    }

    public PagedList<Post> searchPublicFeed(String query) {
        return searchPublicFeed(query, FIRST_PAGE);
    }

    public PagedList<Post> searchPublicFeed(String query, PagingParameters pagedListParameters) {
        String url = GraphApi.GRAPH_API_URL + "search?q={query}&type=post";
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("query", query);
        if (pagedListParameters.getLimit() != null) {
            url += "&limit={limit}";
            params.put("limit", pagedListParameters.getLimit());
        }
        if (pagedListParameters.getSince() != null) {
            url += "&since={since}";
            params.put("since", pagedListParameters.getSince());
        }
        if (pagedListParameters.getUntil() != null) {
            url += "&until={until}";
            params.put("until", pagedListParameters.getUntil());
        }
        JsonNode responseNode = restTemplate.getForObject(url, JsonNode.class, params);
        return deserializeList(responseNode, null, Post.class);
    }

    public PagedList<Post> searchHomeFeed(String query) {
        return searchHomeFeed(query, FIRST_PAGE);
    }

    public PagedList<Post> searchHomeFeed(String query, PagingParameters pagedListParameters) {
        requireAuthorization();
        URIBuilder uriBuilder = URIBuilder.fromUri(GraphApi.GRAPH_API_URL + "me/home").queryParam("q", query);
        uriBuilder = appendPagedListParameters(pagedListParameters, uriBuilder);
        URI uri = uriBuilder.build();
        JsonNode responseNode = restTemplate.getForObject(uri, JsonNode.class);
        return deserializeList(responseNode, null, Post.class);
    }

    public PagedList<Post> searchUserFeed(String query) {
        return searchUserFeed("me", query, FIRST_PAGE);
    }

    public PagedList<Post> searchUserFeed(String query, PagingParameters pagedListParameters) {
        return searchUserFeed("me", query, pagedListParameters);
    }

    public PagedList<Post> searchUserFeed(String userId, String query) {
        return searchUserFeed(userId, query, FIRST_PAGE);
    }

    public PagedList<Post> searchUserFeed(String userId, String query, PagingParameters pagedListParameters) {
        requireAuthorization();
        URIBuilder uriBuilder = URIBuilder.fromUri(GraphApi.GRAPH_API_URL + userId + "/feed").queryParam("q",
                query);
        uriBuilder = appendPagedListParameters(pagedListParameters, uriBuilder);
        URI uri = uriBuilder.build();
        JsonNode responseNode = restTemplate.getForObject(uri, JsonNode.class);
        return deserializeList(responseNode, null, Post.class);
    }

    public PagedList<Post> getCheckins() {
        return getCheckins(new PagingParameters(25, 0, null, null));
    }

    public PagedList<Post> getCheckins(PagingParameters pagedListParameters) {
        requireAuthorization();
        MultiValueMap<String, String> params = getPagingParameters(pagedListParameters);
        params.set("with", "location");
        return graphApi.fetchConnections("me", "posts", Post.class, params);
    }

    public Post getCheckin(String checkinId) {
        requireAuthorization();
        return graphApi.fetchObject(checkinId, Post.class);
    }

    // private helpers

    private JsonNode fetchConnectionList(String baseUri, PagingParameters pagedListParameters) {
        URIBuilder uriBuilder = URIBuilder.fromUri(baseUri);
        uriBuilder = appendPagedListParameters(pagedListParameters, uriBuilder);
        URI uri = uriBuilder.build();
        JsonNode responseNode = restTemplate.getForObject(uri, JsonNode.class);
        return responseNode;
    }

    private <T> PagedList<T> deserializeList(JsonNode jsonNode, String postType, Class<T> type) {
        JsonNode dataNode = jsonNode.get("data");
        List<T> posts = new ArrayList<T>();
        for (Iterator<JsonNode> iterator = dataNode.iterator(); iterator.hasNext();) {
            posts.add(deserializePost(postType, type, (ObjectNode) iterator.next()));
        }
        if (jsonNode.has("paging")) {
            JsonNode pagingNode = jsonNode.get("paging");
            PagingParameters previousPage = getPagedListParameters(pagingNode, "previous");
            PagingParameters nextPage = getPagedListParameters(pagingNode, "next");
            return new PagedList<T>(posts, previousPage, nextPage);
        }

        return new PagedList<T>(posts, null, null);
    }

    private <T> T deserializePost(String postType, Class<T> type, ObjectNode node) {
        try {
            if (postType == null) {
                postType = determinePostType(node);
            }

            // Must have separate postType field for polymorphic deserialization. If we key off of the "type" field, then it will
            // be null when trying to deserialize the type property.
            node.put("postType", postType); // used for polymorphic deserialization
            node.put("type", postType); // used to set Post's type property
            return objectMapper.reader(type).readValue(node.toString()); // TODO: EXTREMELY HACKY--TEMPORARY UNTIL I FIGURE OUT HOW JACKSON 2 DOES THIS
        } catch (IOException shouldntHappen) {
            throw new UncategorizedApiException("facebook", "Error deserializing " + postType + " post",
                    shouldntHappen);
        }
    }

    private String determinePostType(ObjectNode node) {
        if (node.has("type")) {
            try {
                String type = node.get("type").textValue();
                PostType.valueOf(type.toUpperCase());
                return type;
            } catch (IllegalArgumentException e) {
                return "post";
            }
        }
        return "post";
    }

    private URIBuilder appendPagedListParameters(PagingParameters pagedListParameters, URIBuilder uriBuilder) {
        if (pagedListParameters.getLimit() != null) {
            uriBuilder = uriBuilder.queryParam("limit", String.valueOf(pagedListParameters.getLimit()));
        }
        if (pagedListParameters.getSince() != null) {
            uriBuilder = uriBuilder.queryParam("since", String.valueOf(pagedListParameters.getSince()));
        }
        if (pagedListParameters.getUntil() != null) {
            uriBuilder = uriBuilder.queryParam("until", String.valueOf(pagedListParameters.getUntil()));
        }
        return uriBuilder;
    }

}