All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.facebook.api.ExtensibleClient Maven / Gradle / Ivy

The newest version!
/*
  +---------------------------------------------------------------------------+
  | Facebook Development Platform Java Client                                 |
  +---------------------------------------------------------------------------+
  | Copyright (c) 2007 Facebook, Inc.                                         |
  | All rights reserved.                                                      |
  |                                                                           |
  | Redistribution and use in source and binary forms, with or without        |
  | modification, are permitted provided that the following conditions        |
  | are met:                                                                  |
  |                                                                           |
  | 1. Redistributions of source code must retain the above copyright         |
  |    notice, this list of conditions and the following disclaimer.          |
  | 2. Redistributions in binary form must reproduce the above copyright      |
  |    notice, this list of conditions and the following disclaimer in the    |
  |    documentation and/or other materials provided with the distribution.   |
  |                                                                           |
  | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      |
  | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
  | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   |
  | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  |
  | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
  | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
  | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  |
  | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         |
  +---------------------------------------------------------------------------+
  | For help with this library, contact [email protected]          |
  +---------------------------------------------------------------------------+
*/

package com.facebook.api;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

/**
 * Base class for interacting with the Facebook Application Programming Interface (API).
 * Most Facebook API methods map directly to function calls of this class.
 * 
* Instances of FacebookRestClient should be initialized via calls to * {@link #auth_createToken}, followed by {@link #auth_getSession}. *
* For continually updated documentation, please refer to the * * Developer Wiki. */ public abstract class ExtensibleClient implements IFacebookRestClient { public static URL SERVER_URL = null; public static URL HTTPS_SERVER_URL = null; static { try { SERVER_URL = new URL(SERVER_ADDR); HTTPS_SERVER_URL = new URL(HTTPS_SERVER_ADDR); } catch (MalformedURLException e) { System.err.println("MalformedURLException: " + e.getMessage()); System.exit(1); } } protected final String _secret; protected final String _apiKey; protected final URL _serverUrl; protected String rawResponse; protected String _sessionKey; protected boolean _isDesktop = false; protected long _userId = -1; /** * filled in when session is established * only used for desktop apps */ protected String _sessionSecret; /** * The number of parameters required for every request. * @see #callMethod(IFacebookMethod,Collection) */ public static int NUM_AUTOAPPENDED_PARAMS = 6; private static boolean DEBUG = false; protected Boolean _debug = null; protected File _uploadFile = null; protected static final String CRLF = "\r\n"; protected static final String PREF = "--"; protected static final int UPLOAD_BUFFER_SIZE = 512; public static final String MARKETPLACE_STATUS_DEFAULT = "DEFAULT"; public static final String MARKETPLACE_STATUS_NOT_SUCCESS = "NOT_SUCCESS"; public static final String MARKETPLACE_STATUS_SUCCESS = "SUCCESS"; protected ExtensibleClient(URL serverUrl, String apiKey, String secret, String sessionKey) { _sessionKey = sessionKey; _apiKey = apiKey; _secret = secret; _serverUrl = (null != serverUrl) ? serverUrl : SERVER_URL; } /** * The response format in which results to FacebookMethod calls are returned * @return the format: either XML, JSON, or null (API default) */ public String getResponseFormat() { return null; } /** * Retrieves whether two users are friends. * @param userId1 * @param userId2 * @return T * @see * Developers Wiki: Friends.areFriends */ public T friends_areFriends(long userId1, long userId2) throws FacebookException, IOException { return this.callMethod(FacebookMethod.FRIENDS_ARE_FRIENDS, new Pair("uids1", Long.toString(userId1)), new Pair("uids2", Long.toString(userId2))); } /** * Retrieves whether pairs of users are friends. * Returns whether the first user in userIds1 is friends with the first user in * userIds2, the second user in userIds1 is friends with the second user in * userIds2, etc. * @param userIds1 * @param userIds2 * @return T * @throws IllegalArgumentException if one of the collections is null, or empty, or if the * collection sizes differ. * @see * Developers Wiki: Friends.areFriends */ public T friends_areFriends(Collection userIds1, Collection userIds2) throws FacebookException, IOException { if (userIds1 == null || userIds2 == null || userIds1.isEmpty() || userIds2.isEmpty()) { throw new IllegalArgumentException("Collections passed to friends_areFriends should not be null or empty"); } if (userIds1.size() != userIds2.size()) { throw new IllegalArgumentException(String.format("Collections should be same size: got userIds1: %d elts; userIds2: %d elts", userIds1.size(), userIds2.size())); } return this.callMethod(FacebookMethod.FRIENDS_ARE_FRIENDS, new Pair("uids1", delimit(userIds1)), new Pair("uids2", delimit(userIds2))); } /** * Gets the FBML for a user's profile, including the content for both the profile box * and the profile actions. * @param userId - the user whose profile FBML to set * @return a T containing FBML markup */ public T profile_getFBML(Long userId) throws FacebookException, IOException { return this.callMethod(FacebookMethod.PROFILE_GET_FBML, new Pair("uid", Long.toString(userId))); } /** * Recaches the referenced url. * @param url string representing the URL to refresh * @return boolean indicating whether the refresh succeeded */ public boolean fbml_refreshRefUrl(String url) throws FacebookException, IOException { return fbml_refreshRefUrl(new URL(url)); } /** * Helper function: assembles the parameters used by feed_publishActionOfUser and * feed_publishStoryToUser * @param feedMethod feed_publishStoryToUser / feed_publishActionOfUser * @param title title of the story * @param body body of the story * @param images optional images to be included in he story * @param priority * @return whether the call to feedMethod was successful */ protected boolean feedHandler(IFacebookMethod feedMethod, CharSequence title, CharSequence body, Collection> images, Integer priority) throws FacebookException, IOException { ArrayList> params = new ArrayList>(feedMethod.numParams()); params.add(new Pair("title", title)); if (null != body) params.add(new Pair("body", body)); if (null != priority) params.add(new Pair("priority", priority.toString())); handleFeedImages(params, images); return extractBoolean(this.callMethod(feedMethod, params)); } /** * Adds image parameters * @param params * @param images */ protected void handleFeedImages(List> params, Collection> images) { if (images != null && images.size() > 4) { throw new IllegalArgumentException("At most four images are allowed, got " + Integer.toString(images.size())); } if (null != images && !images.isEmpty()) { int image_count = 0; for (Pair image : images) { ++image_count; assert null != image.first : "Image URL must be provided"; params.add(new Pair(String.format("image_%d", image_count), image.first.toString())); if (null != image.second) params.add(new Pair(String.format("image_%d_link", image_count), image.second.toString())); } } } /** * Publish the notification of an action taken by a user to newsfeed. * @param title the title of the feed story (up to 60 characters, excluding tags) * @param body (optional) the body of the feed story (up to 200 characters, excluding tags) * @param images (optional) up to four pairs of image URLs and (possibly null) link URLs * @return whether the story was successfully published; false in case of permission error * @see * Developers Wiki: Feed.publishActionOfUser */ public boolean feed_publishActionOfUser(CharSequence title, CharSequence body, Collection> images) throws FacebookException, IOException { return feedHandler(FacebookMethod.FEED_PUBLISH_ACTION_OF_USER, title, body, images, null); } /** * Publish the notification of an action taken by a user to newsfeed. * @param title the title of the feed story (up to 60 characters, excluding tags) * @param body (optional) the body of the feed story (up to 200 characters, excluding tags) * @return whether the story was successfully published; false in case of permission error * @see * Developers Wiki: Feed.publishActionOfUser */ public boolean feed_publishActionOfUser(CharSequence title, CharSequence body) throws FacebookException, IOException { return feed_publishActionOfUser(title, body, null); } /** * Call this function to retrieve the session information after your user has * logged in. * @param authToken the token returned by auth_createToken or passed back to your callback_url. */ public abstract String auth_getSession(String authToken) throws FacebookException, IOException; /** * Publish a story to the logged-in user's newsfeed. * @param title the title of the feed story * @param body the body of the feed story * @return whether the story was successfully published; false in case of permission error * @see * Developers Wiki: Feed.publishStoryToUser */ public boolean feed_publishStoryToUser(CharSequence title, CharSequence body) throws FacebookException, IOException { return feed_publishStoryToUser(title, body, null, null); } /** * Publish a story to the logged-in user's newsfeed. * @param title the title of the feed story * @param body the body of the feed story * @param images (optional) up to four pairs of image URLs and (possibly null) link URLs * @return whether the story was successfully published; false in case of permission error * @see * Developers Wiki: Feed.publishStoryToUser */ public boolean feed_publishStoryToUser(CharSequence title, CharSequence body, Collection> images) throws FacebookException, IOException { return feed_publishStoryToUser(title, body, images, null); } /** * Publish a story to the logged-in user's newsfeed. * @param title the title of the feed story * @param body the body of the feed story * @param priority * @return whether the story was successfully published; false in case of permission error * @see * Developers Wiki: Feed.publishStoryToUser */ public boolean feed_publishStoryToUser(CharSequence title, CharSequence body, Integer priority) throws FacebookException, IOException { return feed_publishStoryToUser(title, body, null, priority); } /** * Publish a story to the logged-in user's newsfeed. * @param title the title of the feed story * @param body the body of the feed story * @param images (optional) up to four pairs of image URLs and (possibly null) link URLs * @param priority * @return whether the story was successfully published; false in case of permission error * @see * Developers Wiki: Feed.publishStoryToUser */ public boolean feed_publishStoryToUser(CharSequence title, CharSequence body, Collection> images, Integer priority) throws FacebookException, IOException { return feedHandler(FacebookMethod.FEED_PUBLISH_STORY_TO_USER, title, body, images, priority); } /** * Publishes a Mini-Feed story describing an action taken by a user, and * publishes aggregating News Feed stories to the friends of that user. * Stories are identified as being combinable if they have matching templates and substituted values. * @param actorId the user into whose mini-feed the story is being published. * @param titleTemplate markup (up to 60 chars, tags excluded) for the feed story's title * section. Must include the token {actor}. * @return whether the action story was successfully published; false in case * of a permission error * @see * Developers Wiki: Feed.publishTemplatizedAction */ public boolean feed_publishTemplatizedAction(Long actorId, CharSequence titleTemplate) throws FacebookException, IOException { return feed_publishTemplatizedAction(actorId, titleTemplate, null, null, null, null, null, null ); } /** * Publishes a Mini-Feed story describing an action taken by a user, and * publishes aggregating News Feed stories to the friends of that user. * Stories are identified as being combinable if they have matching templates and substituted values. * @param actorId the user into whose mini-feed the story is being published. * @param titleTemplate markup (up to 60 chars, tags excluded) for the feed story's title * section. Must include the token {actor}. * @param titleData (optional) contains token-substitution mappings for tokens that appear in * titleTemplate. Should not contain mappings for the {actor} or * {target} tokens. Required if tokens other than {actor} * or {target} appear in the titleTemplate. * @param bodyTemplate (optional) markup to be displayed in the feed story's body section. * can include tokens, of the form {token}, to be substituted using * bodyData. * @param bodyData (optional) contains token-substitution mappings for tokens that appear in * bodyTemplate. Required if the bodyTemplate contains tokens other than {actor} * and {target}. * @param bodyGeneral (optional) additional body markup that is not aggregated. If multiple instances * of this templated story are combined together, the markup in the bodyGeneral of * one of their stories may be displayed. * @param targetIds The user ids of friends of the actor, used for stories about a direct action between * the actor and these targets of his/her action. Required if either the titleTemplate or bodyTemplate * includes the token {target}. * @param images (optional) additional body markup that is not aggregated. If multiple instances * of this templated story are combined together, the markup in the bodyGeneral of * one of their stories may be displayed. * @return whether the action story was successfully published; false in case * of a permission error * @see * Developers Wiki: Feed.publishTemplatizedAction */ public boolean feed_publishTemplatizedAction(Long actorId, CharSequence titleTemplate, Map titleData, CharSequence bodyTemplate, Map bodyData, CharSequence bodyGeneral, Collection targetIds, Collection> images ) throws FacebookException, IOException { assert null != actorId && actorId > 0 : "Invalid actorId: " + Long.toString(actorId); assert null != titleTemplate && !"".equals(titleTemplate); FacebookMethod method = FacebookMethod.FEED_PUBLISH_TEMPLATIZED_ACTION; ArrayList> params = new ArrayList>(method.numParams()); params.add(new Pair("actorId", actorId.toString())); params.add(new Pair("title_template", titleTemplate)); if (null != titleData && !titleData.isEmpty()) { JSONObject titleDataJson = new JSONObject(); for (String key : titleData.keySet()) { try { titleDataJson.put(key, titleData.get(key)); } catch (Exception ignored) {} } params.add(new Pair("title_data", titleDataJson.toString())); } if (null != bodyTemplate && !"".equals(bodyTemplate)) { params.add(new Pair("body_template", bodyTemplate)); if (null != bodyData && !bodyData.isEmpty()) { JSONObject bodyDataJson = new JSONObject(); for (String key : bodyData.keySet()) { try { bodyDataJson.put(key, bodyData.get(key)); } catch (Exception ignored) {} } params.add(new Pair("body_data", bodyDataJson.toString())); } } if (null != bodyTemplate && !"".equals(bodyTemplate)) { params.add(new Pair("body_template", bodyTemplate)); } if (null != targetIds && !targetIds.isEmpty()) { params.add(new Pair("targetIds", delimit(targetIds))); } handleFeedImages(params, images); return extractBoolean(this.callMethod(method, params)); } /** * Retrieves the membership list of a group * @param groupId the group id * @return a T containing four membership lists of * 'members', 'admins', 'officers', and 'not_replied' */ public T groups_getMembers(Number groupId) throws FacebookException, IOException { assert (null != groupId); return this.callMethod(FacebookMethod.GROUPS_GET_MEMBERS, new Pair("gid", groupId.toString())); } private static String encode(CharSequence target) { String result = target.toString(); try { result = URLEncoder.encode(result, "UTF8"); } catch (UnsupportedEncodingException e) { System.err.printf("Unsuccessful attempt to encode '%s' into UTF8", result); } return result; } /** * Retrieves the membership list of an event * @param eventId event id * @return T consisting of four membership lists corresponding to RSVP status, with keys * 'attending', 'unsure', 'declined', and 'not_replied' */ public T events_getMembers(Number eventId) throws FacebookException, IOException { assert (null != eventId); return this.callMethod(FacebookMethod.EVENTS_GET_MEMBERS, new Pair("eid", eventId.toString())); } /** * Retrieves the friends of the currently logged in user, who are also users * of the calling application. * @return array of friends */ public T friends_getAppUsers() throws FacebookException, IOException { return this.callMethod(FacebookMethod.FRIENDS_GET_APP_USERS); } /** * Retrieves the results of a Facebook Query Language query * @param query : the FQL query statement * @return varies depending on the FQL query */ public T fql_query(CharSequence query) throws FacebookException, IOException { assert (null != query); return this.callMethod(FacebookMethod.FQL_QUERY, new Pair("query", query)); } private String generateSignature(List params, boolean requiresSession) { String secret = (isDesktop() && requiresSession) ? this._sessionSecret : this._secret; return FacebookSignatureUtil.generateSignature(params, secret); } public static void setDebugAll(boolean isDebug) { ExtensibleClient.DEBUG = isDebug; } private static CharSequence delimit(Collection iterable) { // could add a thread-safe version that uses StringBuffer as well if (iterable == null || iterable.isEmpty()) return null; StringBuilder buffer = new StringBuilder(); boolean notFirst = false; for (Object item : iterable) { if (notFirst) buffer.append(","); else notFirst = true; buffer.append(item.toString()); } return buffer; } /** * Call the specified method, with the given parameters, and return a DOM tree with the results. * * @param method the fieldName of the method * @param paramPairs a list of arguments to the method * @throws Exception with a description of any errors given to us by the server. */ protected T callMethod(IFacebookMethod method, Pair... paramPairs) throws FacebookException, IOException { return callMethod(method, Arrays.asList(paramPairs)); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param photoIds retrieve from this list of photos (optional) * @return an T of photo objects. * @see #photos_get(Long, Long, Collection) * @see * Developers Wiki: Photos.get */ public T photos_get(Collection photoIds) throws FacebookException, IOException { return photos_get(null /*subjId*/, null /*albumId*/, photoIds); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param subjId retrieve from photos associated with this user (optional). * @param albumId retrieve from photos from this album (optional) * @return an T of photo objects. * @see #photos_get(Long, Long, Collection) * @see * Developers Wiki: Photos.get */ public T photos_get(Long subjId, Long albumId) throws FacebookException, IOException { return photos_get(subjId, albumId, null /*photoIds*/); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param subjId retrieve from photos associated with this user (optional). * @param photoIds retrieve from this list of photos (optional) * @return an T of photo objects. * @see #photos_get(Long, Long, Collection) * @see * Developers Wiki: Photos.get */ public T photos_get(Long subjId, Collection photoIds) throws FacebookException, IOException { return photos_get(subjId, null /*albumId*/, photoIds); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param subjId retrieve from photos associated with this user (optional). * @return an T of photo objects. * @see #photos_get(Long, Long, Collection) * @see * Developers Wiki: Photos.get */ public T photos_get(Long subjId) throws FacebookException, IOException { return photos_get(subjId, null /*albumId*/, null /*photoIds*/); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param subjId retrieve from photos associated with this user (optional). * @param albumId retrieve from photos from this album (optional) * @param photoIds retrieve from this list of photos (optional) * @return an T of photo objects. * @see * Developers Wiki: Photos.get */ public T photos_get(Long subjId, Long albumId, Collection photoIds) throws FacebookException, IOException { ArrayList> params = new ArrayList>(FacebookMethod.PHOTOS_GET.numParams()); boolean hasUserId = null != subjId && 0 != subjId; boolean hasAlbumId = null != albumId && 0 != albumId; boolean hasPhotoIds = null != photoIds && !photoIds.isEmpty(); if (!hasUserId && !hasAlbumId && !hasPhotoIds) { throw new IllegalArgumentException("At least one of photoIds, albumId, or subjId must be provided"); } if (hasUserId) params.add(new Pair("subj_id", Long.toString(subjId))); if (hasAlbumId) params.add(new Pair("aid", Long.toString(albumId))); if (hasPhotoIds) params.add(new Pair("pids", delimit(photoIds))); return this.callMethod(FacebookMethod.PHOTOS_GET, params); } /** * Retrieves the requested info fields for the requested set of users. * @param userIds a collection of user IDs for which to fetch info * @param fields a set of strings describing the info fields desired, such as "last_name", "sex" * @return a T consisting of a list of users, with each user element * containing the requested fields. */ public T users_getInfo(Collection userIds, Set fields) throws FacebookException, IOException { // assertions test for invalid params if (null == userIds) { throw new IllegalArgumentException("userIds cannot be null"); } if (fields == null || fields.isEmpty()) { throw new IllegalArgumentException("fields should not be empty"); } return this.callMethod(FacebookMethod.USERS_GET_INFO, new Pair("uids", delimit(userIds)), new Pair("fields", delimit(fields))); } /** * Retrieves the tags for the given set of photos. * @param photoIds The list of photos from which to extract photo tags. * @return the created album */ public T photos_getTags(Collection photoIds) throws FacebookException, IOException { return this.callMethod(FacebookMethod.PHOTOS_GET_TAGS, new Pair("pids", delimit(photoIds))); } /** * Retrieves the groups associated with a user * @param userId Optional: User associated with groups. * A null parameter will default to the session user. * @param groupIds Optional: group ids to query. * A null parameter will get all groups for the user. * @return array of groups */ public T groups_get(Long userId, Collection groupIds) throws FacebookException, IOException { boolean hasGroups = (null != groupIds && !groupIds.isEmpty()); if (null != userId) return hasGroups ? this.callMethod(FacebookMethod.GROUPS_GET, new Pair("uid", userId.toString()), new Pair("gids", delimit(groupIds))) : this.callMethod(FacebookMethod.GROUPS_GET, new Pair("uid", userId.toString())); else return hasGroups ? this.callMethod(FacebookMethod.GROUPS_GET, new Pair("gids", delimit(groupIds))) : this.callMethod(FacebookMethod.GROUPS_GET); } /** * Call the specified method, with the given parameters, and return a DOM tree with the results. * * @param method the fieldName of the method * @param paramPairs a list of arguments to the method * @throws Exception with a description of any errors given to us by the server. */ protected T callMethod(IFacebookMethod method, Collection> paramPairs) throws FacebookException, IOException { this.rawResponse = null; HashMap params = new HashMap(2 * method.numTotalParams()); params.put("method", method.methodName()); params.put("api_key", _apiKey); params.put("v", TARGET_API_VERSION); String format = getResponseFormat(); if (null != format) { params.put("format", format); } if (method.requiresSession()) { params.put("call_id", Long.toString(System.currentTimeMillis())); params.put("session_key", _sessionKey); } CharSequence oldVal; for (Pair p : paramPairs) { oldVal = params.put(p.first, p.second); if (oldVal != null) System.err.printf("For parameter %s, overwrote old value %s with new value %s.", p.first, oldVal, p.second); } assert (!params.containsKey("sig")); String signature = generateSignature(FacebookSignatureUtil.convert(params.entrySet()), method.requiresSession()); params.put("sig", signature); boolean doHttps = this.isDesktop() && FacebookMethod.AUTH_GET_SESSION.equals(method); InputStream data = method.takesFile() ? postFileRequest(method.methodName(), params) : postRequest(method.methodName(), params, doHttps, true); BufferedReader in = new BufferedReader(new InputStreamReader(data, "UTF-8")); StringBuffer buffer = new StringBuffer(); String line; while ((line = in.readLine()) != null) { buffer.append(line); } String xmlResp = new String(buffer); this.rawResponse = xmlResp; return parseCallResult(new ByteArrayInputStream(xmlResp.getBytes("UTF-8")), method); } /** * Parses the result of an API call into a T. * @param data an InputStream with the results of a request to the Facebook servers * @param method the method called * @throws FacebookException if data represents an error * @throws IOException if data is not readable * @return a T */ protected abstract T parseCallResult(InputStream data, IFacebookMethod method) throws FacebookException, IOException; /** * Recaches the referenced url. * @param url the URL to refresh * @return boolean indicating whether the refresh succeeded */ public boolean fbml_refreshRefUrl(URL url) throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.FBML_REFRESH_REF_URL, new Pair("url", url.toString()))); } /** * Retrieves the outstanding notifications for the session user. * @return a T containing * notification count pairs for 'messages', 'pokes' and 'shares', * a uid list of 'friend_requests', a gid list of 'group_invites', * and an eid list of 'event_invites' */ public T notifications_get() throws FacebookException, IOException { return this.callMethod(FacebookMethod.NOTIFICATIONS_GET); } /** * Retrieves the requested info fields for the requested set of users. * @param userIds a collection of user IDs for which to fetch info * @param fields a set of ProfileFields * @return a T consisting of a list of users, with each user element * containing the requested fields. */ public T users_getInfo(Collection userIds, EnumSet fields) throws FacebookException, IOException { // assertions test for invalid params assert (userIds != null); assert (fields != null); assert (!fields.isEmpty()); return this.callMethod(FacebookMethod.USERS_GET_INFO, new Pair("uids", delimit(userIds)), new Pair("fields", delimit(fields))); } /** * Retrieves the user ID of the user logged in to this API session * @return the Facebook user ID of the logged-in user */ public long users_getLoggedInUser() throws FacebookException, IOException { T result = this.callMethod(FacebookMethod.USERS_GET_LOGGED_IN_USER); return extractInt(result); } /** * Call this function to get the user ID. * * @return The ID of the current session's user, or -1 if none. */ public long auth_getUserId(String authToken) throws FacebookException, IOException { /* * Get the session information if we don't have it; this will populate * the user ID as well. */ if (null == this._sessionKey) auth_getSession(authToken); return this._userId; } public boolean isDesktop() { return this._isDesktop; } private boolean photos_addTag(Long photoId, Double xPct, Double yPct, Long taggedUserId, CharSequence tagText) throws FacebookException, IOException { assert (null != photoId && !photoId.equals(0)); assert (null != taggedUserId || null != tagText); assert (null != xPct && xPct >= 0 && xPct <= 100); assert (null != yPct && yPct >= 0 && yPct <= 100); T d = this.callMethod(FacebookMethod.PHOTOS_ADD_TAG, new Pair("pid", photoId.toString()), new Pair("tag_uid", taggedUserId.toString()), new Pair("x", xPct.toString()), new Pair("y", yPct.toString())); return extractBoolean(d); } /** * Retrieves an indicator of whether the logged-in user has installed the * application associated with the _apiKey. * @return boolean indicating whether the user has installed the app */ public boolean users_isAppAdded() throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.USERS_IS_APP_ADDED)); } /** * Retrieves whether the logged-in user has granted the specified permission * to this application. * @param permission an extended permission (e.g. FacebookExtendedPerm.MARKETPLACE, * "photo_upload") * @return boolean indicating whether the user has the permission * @see FacebookExtendedPerm * @see * Developers Wiki: Users.hasAppPermission */ public boolean users_hasAppPermission(CharSequence permission) throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.USERS_HAS_APP_PERMISSION, new Pair("ext_perm", permission))); } /** * Sets the logged-in user's Facebook status. * Requires the status_update extended permission. * @return whether the status was successfully set * @see #users_hasAppPermission * @see FacebookExtendedPerm#STATUS_UPDATE * @see * Developers Wiki: Users.setStatus */ public boolean users_setStatus(String status) throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.USERS_SET_STATUS, new Pair("status", status))); } /** * Clears the logged-in user's Facebook status. * Requires the status_update extended permission. * @return whether the status was successfully cleared * @see #users_hasAppPermission * @see FacebookExtendedPerm#STATUS_UPDATE * @see * Developers Wiki: Users.setStatus */ public boolean users_clearStatus() throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.USERS_SET_STATUS, new Pair("clear", "1"))); } /** * Adds a tag to a photo. * @param photoId The photo id of the photo to be tagged. * @param xPct The horizontal position of the tag, as a percentage from 0 to 100, from the left of the photo. * @param yPct The list of photos from which to extract photo tags. * @param tagText The text of the tag. * @return whether the tag was successfully added. */ public boolean photos_addTag(Long photoId, CharSequence tagText, Double xPct, Double yPct) throws FacebookException, IOException { return photos_addTag(photoId, xPct, yPct, null, tagText); } /** * Helper function for posting a request that includes raw file data, eg {@link #photos_upload}. * @param methodName the name of the method * @param params request parameters (not including the file) * @return an InputStream with the request response * @see #photos_upload */ protected InputStream postFileRequest(String methodName, Map params) throws IOException { assert (null != _uploadFile); try { BufferedInputStream bufin = new BufferedInputStream(new FileInputStream(_uploadFile)); String boundary = Long.toString(System.currentTimeMillis(), 16); URLConnection con = SERVER_URL.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); con.setRequestProperty("MIME-version", "1.0"); DataOutputStream out = new DataOutputStream(con.getOutputStream()); for (Map.Entry entry : params.entrySet()) { out.writeBytes(PREF + boundary + CRLF); out.writeBytes("Content-disposition: form-data; name=\"" + entry.getKey() + "\""); out.writeBytes(CRLF + CRLF); out.writeBytes(entry.getValue().toString()); out.writeBytes(CRLF); } out.writeBytes(PREF + boundary + CRLF); out.writeBytes("Content-disposition: form-data; filename=\"" + _uploadFile.getName() + "\"" + CRLF); out.writeBytes("Content-Type: image/jpeg" + CRLF); // out.writeBytes("Content-Transfer-Encoding: binary" + CRLF); // not necessary // Write the file out.writeBytes(CRLF); byte b[] = new byte[UPLOAD_BUFFER_SIZE]; int byteCounter = 0; int i; while (-1 != (i = bufin.read(b))) { byteCounter += i; out.write(b, 0, i); } out.writeBytes(CRLF + PREF + boundary + PREF + CRLF); out.flush(); out.close(); InputStream is = con.getInputStream(); return is; } catch (Exception e) { logException(e); return null; } } /** * Logs an exception with default message * @param e the exception */ protected final void logException(Exception e) { logException("exception", e); } /** * Logs an exception with an introductory message in addition to the * exception's getMessage(). * @param msg message * @param e exception * @see Exception#getMessage */ protected void logException(CharSequence msg, Exception e) { System.err.println(msg + ":" + e.getMessage()); e.printStackTrace(); } /** * Logs a message. Override this for more detailed logging. * @param message */ protected void log(CharSequence message) { System.out.println(message); } /** * @return whether debugging is activated */ public boolean isDebug() { return (null == _debug) ? DEBUG : _debug.booleanValue(); } /** * Send a notification message to the specified users. * @param recipientIds the user ids to which the message is to be sent * @param notification the FBML to display on the notifications page * @param email the FBML to send to the specified users via email, or null * if no email should be sent * @return a URL, possibly null, to which the user should be redirected to finalize * the sending of the email */ public URL notifications_send(Collection recipientIds, CharSequence notification, CharSequence email) throws FacebookException, IOException { assert (null != recipientIds && !recipientIds.isEmpty()); assert (null != notification); ArrayList> args = new ArrayList>(3); args.add(new Pair("to_ids", delimit(recipientIds))); args.add(new Pair("notification", notification)); if (null != email) { args.add(new Pair("email", email)); } T result = this.callMethod(FacebookMethod.NOTIFICATIONS_SEND, args); return extractURL(result); } /** * Extracts a URL from a result that consists of a URL only. * @param result * @return the URL */ protected abstract URL extractURL(T result) throws IOException; /** * Recaches the image with the specified imageUrl. * @param imageUrl String representing the image URL to refresh * @return boolean indicating whether the refresh succeeded */ public boolean fbml_refreshImgSrc(String imageUrl) throws FacebookException, IOException { return fbml_refreshImgSrc(new URL(imageUrl)); } /** * Uploads a photo to Facebook. * @param photo an image file * @return a T with the standard Facebook photo information * @see * Developers wiki: Photos.upload */ public T photos_upload(File photo) throws FacebookException, IOException { return photos_upload(photo, null /* caption */ , null /* albumId */); } /** * Uploads a photo to Facebook. * @param photo an image file * @param caption a description of the image contents * @return a T with the standard Facebook photo information * @see * Developers wiki: Photos.upload */ public T photos_upload(File photo, String caption) throws FacebookException, IOException { return photos_upload(photo, caption, null /* albumId */); } /** * Uploads a photo to Facebook. * @param photo an image file * @param albumId the album into which the photo should be uploaded * @return a T with the standard Facebook photo information * @see * Developers wiki: Photos.upload */ public T photos_upload(File photo, Long albumId) throws FacebookException, IOException { return photos_upload(photo, null /* caption */, albumId); } /** * Uploads a photo to Facebook. * @param photo an image file * @param caption a description of the image contents * @param albumId the album into which the photo should be uploaded * @return a T with the standard Facebook photo information * @see * Developers wiki: Photos.upload */ public T photos_upload(File photo, String caption, Long albumId) throws FacebookException, IOException { ArrayList> params = new ArrayList>(FacebookMethod.PHOTOS_UPLOAD.numParams()); assert (photo.exists() && photo.canRead()); this._uploadFile = photo; if (null != albumId) params.add(new Pair("aid", Long.toString(albumId))); if (null != caption) params.add(new Pair("caption", caption)); return callMethod(FacebookMethod.PHOTOS_UPLOAD, params); } /** * Creates an album. * @param albumName The list of photos from which to extract photo tags. * @return the created album */ public T photos_createAlbum(String albumName) throws FacebookException, IOException { return this.photos_createAlbum(albumName, null /*description*/, null /*location*/); } /** * Adds a tag to a photo. * @param photoId The photo id of the photo to be tagged. * @param xPct The horizontal position of the tag, as a percentage from 0 to 100, from the left of the photo. * @param yPct The vertical position of the tag, as a percentage from 0 to 100, from the top of the photo. * @param taggedUserId The list of photos from which to extract photo tags. * @return whether the tag was successfully added. */ public boolean photos_addTag(Long photoId, Long taggedUserId, Double xPct, Double yPct) throws FacebookException, IOException { return photos_addTag(photoId, xPct, yPct, taggedUserId, null); } /** * Adds several tags to a photo. * @param photoId The photo id of the photo to be tagged. * @param tags A list of PhotoTags. * @return a list of booleans indicating whether the tag was successfully added. */ public T photos_addTags(Long photoId, Collection tags) throws FacebookException, IOException { assert (photoId > 0); assert (null != tags && !tags.isEmpty()); JSONArray jsonTags=new JSONArray(); for (PhotoTag tag : tags) { jsonTags.put(tag.jsonify()); } return this.callMethod(FacebookMethod.PHOTOS_ADD_TAG, new Pair("pid", photoId.toString()), new Pair("tags", jsonTags.toString())); } public void setIsDesktop(boolean isDesktop) { this._isDesktop = isDesktop; } /** * Returns all visible events according to the filters specified. This may be used to find all events of a user, or to query specific eids. * @param eventIds filter by these event ID's (optional) * @param userId filter by this user only (optional) * @param startTime UTC lower bound (optional) * @param endTime UTC upper bound (optional) * @return T of events */ public T events_get(Long userId, Collection eventIds, Long startTime, Long endTime) throws FacebookException, IOException { ArrayList> params = new ArrayList>(FacebookMethod.EVENTS_GET.numParams()); boolean hasUserId = null != userId && 0 != userId; boolean hasEventIds = null != eventIds && !eventIds.isEmpty(); boolean hasStart = null != startTime && 0 != startTime; boolean hasEnd = null != endTime && 0 != endTime; if (hasUserId) params.add(new Pair("uid", Long.toString(userId))); if (hasEventIds) params.add(new Pair("eids", delimit(eventIds))); if (hasStart) params.add(new Pair("start_time", startTime.toString())); if (hasEnd) params.add(new Pair("end_time", endTime.toString())); return this.callMethod(FacebookMethod.EVENTS_GET, params); } /** * Sets the FBML for a user's profile, including the content for both the profile box * and the profile actions. * @param userId - the user whose profile FBML to set * @param fbmlMarkup - refer to the FBML documentation for a description of the markup and its role in various contexts * @return a boolean indicating whether the FBML was successfully set */ public boolean profile_setFBML(CharSequence fbmlMarkup, Long userId) throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.PROFILE_SET_FBML, new Pair("uid", Long.toString(userId)), new Pair("markup", fbmlMarkup))); } protected static CharSequence delimit(Collection> entries, CharSequence delimiter, CharSequence equals, boolean doEncode) { if (entries == null || entries.isEmpty()) return null; StringBuilder buffer = new StringBuilder(); boolean notFirst = false; for (Map.Entry entry : entries) { if (notFirst) buffer.append(delimiter); else notFirst = true; CharSequence value = entry.getValue(); buffer.append(entry.getKey()).append(equals).append(doEncode ? encode(value) : value); } return buffer; } /** * Creates an album. * @param name The album name. * @param location The album location (optional). * @param description The album description (optional). * @return an array of photo objects. */ public T photos_createAlbum(String name, String description, String location) throws FacebookException, IOException { assert (null != name && !"".equals(name)); ArrayList> params = new ArrayList>(FacebookMethod.PHOTOS_CREATE_ALBUM.numParams()); params.add(new Pair("name", name)); if (null != description) params.add(new Pair("description", description)); if (null != location) params.add(new Pair("location", location)); return this.callMethod(FacebookMethod.PHOTOS_CREATE_ALBUM, params); } public void setDebug(boolean isDebug) { _debug = isDebug; } /** * Extracts a Boolean from a result that consists of a Boolean only. * @param result * @return the Boolean */ protected boolean extractBoolean(T result) { return 1 == extractInt(result); } /** * Extracts an Long from a result that consists of an Long only. * @param result * @return the Long */ protected abstract int extractInt(T result); /** * Extracts an Long from a result that consists of a Long only. * @param result * @return the Long */ protected abstract Long extractLong(T result); /** * Retrieves album metadata for a list of album IDs. * @param albumIds the ids of albums whose metadata is to be retrieved * @return album objects * @see * Developers Wiki: Photos.getAlbums */ public T photos_getAlbums(Collection albumIds) throws FacebookException, IOException { return photos_getAlbums(null /*userId*/, albumIds); } /** * Retrieves album metadata for albums owned by a user. * @param userId (optional) the id of the albums' owner (optional) * @return album objects * @see * Developers Wiki: Photos.getAlbums */ public T photos_getAlbums(Long userId) throws FacebookException, IOException { return photos_getAlbums(userId, null /*albumIds*/); } /** * Retrieves album metadata. Pass a user id and/or a list of album ids to specify the albums * to be retrieved (at least one must be provided) * * @param userId (optional) the id of the albums' owner (optional) * @param albumIds (optional) the ids of albums whose metadata is to be retrieved * @return album objects * @see * Developers Wiki: Photos.getAlbums */ public T photos_getAlbums(Long userId, Collection albumIds) throws FacebookException, IOException { boolean hasUserId = null != userId && userId != 0; boolean hasAlbumIds = null != albumIds && !albumIds.isEmpty(); assert (hasUserId || hasAlbumIds); // one of the two must be provided if (hasUserId) return (hasAlbumIds) ? this.callMethod(FacebookMethod.PHOTOS_GET_ALBUMS, new Pair("uid", Long.toString(userId)), new Pair("aids", delimit(albumIds))) : this.callMethod(FacebookMethod.PHOTOS_GET_ALBUMS, new Pair("uid", Long.toString(userId))); else return this.callMethod(FacebookMethod.PHOTOS_GET_ALBUMS, new Pair("aids", delimit(albumIds))); } /** * Recaches the image with the specified imageUrl. * @param imageUrl the image URL to refresh * @return boolean indicating whether the refresh succeeded */ public boolean fbml_refreshImgSrc(URL imageUrl) throws FacebookException, IOException { return extractBoolean(this.callMethod(FacebookMethod.FBML_REFRESH_IMG_SRC, new Pair("url", imageUrl.toString()))); } /** * Retrieves the friends of the currently logged in user. * @return array of friends */ public T friends_get() throws FacebookException, IOException { return this.callMethod(FacebookMethod.FRIENDS_GET); } private InputStream postRequest(CharSequence method, Map params, boolean doHttps, boolean doEncode) throws IOException { CharSequence buffer = (null == params) ? "" : delimit(params.entrySet(), "&", "=", doEncode); URL serverUrl = (doHttps) ? HTTPS_SERVER_URL : _serverUrl; if (isDebug()) { StringBuilder debugMsg = new StringBuilder() .append(method) .append(" POST: ") .append(serverUrl.toString()) .append("?"); debugMsg.append(buffer); log(debugMsg); } HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection(); try { conn.setRequestMethod("POST"); } catch (ProtocolException ex) { logException(ex); } conn.setDoOutput(true); conn.connect(); conn.getOutputStream().write(buffer.toString().getBytes()); return conn.getInputStream(); } /** * Call this function and store the result, using it to generate the * appropriate login url and then to retrieve the session information. * @return an authentication token */ public String auth_createToken() throws FacebookException, IOException { T d = this.callMethod(FacebookMethod.AUTH_CREATE_TOKEN); return extractString(d); } /** * Extracts a String from a T consisting entirely of a String. * @param result * @return the String */ protected abstract String extractString(T result); /** * Create a marketplace listing * @param showOnProfile whether the listing can be shown on the user's profile * @param attrs the properties of the listing * @return the id of the created listing * @see MarketplaceListing * @see * Developers Wiki: marketplace.createListing */ public Long marketplace_createListing(Boolean showOnProfile, MarketplaceListing attrs) throws FacebookException, IOException { T result = this.callMethod(FacebookMethod.MARKETPLACE_CREATE_LISTING, new Pair("show_on_profile", showOnProfile ? "1" : "0"), new Pair("listing_id", "0"), new Pair("listing_attrs", attrs.jsonify().toString())); return this.extractLong(result); } /** * Modify a marketplace listing * @param listingId identifies the listing to be modified * @param showOnProfile whether the listing can be shown on the user's profile * @param attrs the properties of the listing * @return the id of the edited listing * @see MarketplaceListing * @see * Developers Wiki: marketplace.createListing */ public Long marketplace_editListing(Long listingId, Boolean showOnProfile, MarketplaceListing attrs) throws FacebookException, IOException { T result = this.callMethod(FacebookMethod.MARKETPLACE_CREATE_LISTING, new Pair("show_on_profile", showOnProfile ? "1" : "0"), new Pair("listing_id", listingId.toString()), new Pair("listing_attrs", attrs.jsonify().toString())); return this.extractLong(result); } /** * Remove a marketplace listing * @param listingId the listing to be removed * @return boolean indicating whether the listing was removed * @see * Developers Wiki: marketplace.removeListing */ public boolean marketplace_removeListing(Long listingId) throws FacebookException, IOException { return marketplace_removeListing(listingId, MARKETPLACE_STATUS_DEFAULT); } /** * Remove a marketplace listing * @param listingId the listing to be removed * @param status MARKETPLACE_STATUS_DEFAULT, MARKETPLACE_STATUS_SUCCESS, or MARKETPLACE_STATUS_NOT_SUCCESS * @return boolean indicating whether the listing was removed * @see * Developers Wiki: marketplace.removeListing */ public boolean marketplace_removeListing(Long listingId, CharSequence status) throws FacebookException, IOException { assert MARKETPLACE_STATUS_DEFAULT.equals(status) || MARKETPLACE_STATUS_SUCCESS.equals(status) || MARKETPLACE_STATUS_NOT_SUCCESS.equals(status) : "Invalid status: " + status; T result = this.callMethod(FacebookMethod.MARKETPLACE_REMOVE_LISTING, new Pair("listing_id", listingId.toString()), new Pair("status", status)); return this.extractBoolean(result); } /** * Get the categories available in marketplace. * @return a T listing the marketplace categories * @see * Developers Wiki: marketplace.getCategories */ public List marketplace_getCategories() throws FacebookException, IOException { T temp = this.callMethod(FacebookMethod.MARKETPLACE_GET_CATEGORIES); List results = new ArrayList(); if (temp instanceof Document) { Document d = (Document)temp; NodeList cats = d.getElementsByTagName("marketplace_category"); for (int count = 0; count < cats.getLength(); count++) { results.add(cats.item(count).getFirstChild().getTextContent()); } } else { JSONObject j = (JSONObject)temp; Iterator it = j.keys(); while (it.hasNext()) { try { results.add(j.get((String)it.next()).toString()); } catch (Exception ignored) { } } } return results; } /** * Get the subcategories available for a category. * @param category a category, e.g. "HOUSING" * @return a T listing the marketplace sub-categories * @see * Developers Wiki: marketplace.getSubCategories */ public T marketplace_getSubCategories(CharSequence category) throws FacebookException, IOException { return this.callMethod(FacebookMethod.MARKETPLACE_GET_SUBCATEGORIES, new Pair("category", category)); } /** * Fetch marketplace listings, filtered by listing IDs and/or the posting users' IDs. * @param listingIds listing identifiers (required if uids is null/empty) * @param userIds posting user identifiers (required if listingIds is null/empty) * @return a T of marketplace listings * @see * Developers Wiki: marketplace.getListings */ public T marketplace_getListings(Collection listingIds, Collection userIds) throws FacebookException, IOException { ArrayList> params = new ArrayList>(FacebookMethod.MARKETPLACE_GET_LISTINGS.numParams()); if (null != listingIds && !listingIds.isEmpty()) { params.add(new Pair("listing_ids", delimit(listingIds))); } if (null != userIds && !userIds.isEmpty()) { params.add(new Pair("uids", delimit(userIds))); } assert !params.isEmpty() : "Either listingIds or userIds should be provided"; return this.callMethod(FacebookMethod.MARKETPLACE_GET_LISTINGS, params); } /** * Search for marketplace listings, optionally by category, subcategory, and/or query string. * @param category the category of listings desired (optional except if subcategory is provided) * @param subCategory the subcategory of listings desired (optional) * @param query a query string (optional) * @return a T of marketplace listings * @see * Developers Wiki: marketplace.search */ public T marketplace_search(CharSequence category, CharSequence subCategory, CharSequence query) throws FacebookException, IOException { ArrayList> params = new ArrayList>(FacebookMethod.MARKETPLACE_SEARCH.numParams()); if (null != category && !"".equals(category)) { params.add(new Pair("category", category)); if (null != subCategory && !"".equals(subCategory)) { params.add(new Pair("subcategory", subCategory)); } } if (null != query && !"".equals(query)) { params.add(new Pair("query", category)); } return this.callMethod(FacebookMethod.MARKETPLACE_SEARCH, params); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param albumId retrieve from photos from this album (optional) * @param photoIds retrieve from this list of photos (optional) * @return an T of photo objects. * @see #photos_get(Integer, Long, Collection) * @see * Developers Wiki: Photos.get */ public T photos_getByAlbum(Long albumId, Collection photoIds) throws FacebookException, IOException { return photos_get(null /*subjId*/, albumId, photoIds); } /** * Used to retrieve photo objects using the search parameters (one or more of the * parameters must be provided). * * @param albumId retrieve from photos from this album (optional) * @return an T of photo objects. * @see #photos_get(Integer, Long, Collection) * @see * Developers Wiki: Photos.get */ public T photos_getByAlbum(Long albumId) throws FacebookException, IOException { return photos_get(null /*subjId*/, albumId, null /*photoIds*/); } /** * Get the categories available in marketplace. * @return a T listing the marketplace categories * @see * Developers Wiki: marketplace.getCategories */ public T marketplace_getCategoriesObject() throws FacebookException, IOException { T temp = this.callMethod(FacebookMethod.MARKETPLACE_GET_CATEGORIES); return temp; } public String getRawResponse() { return this.rawResponse; } public Object getResponsePOJO() { if (this.rawResponse == null) { return null; } if ((this.getResponseFormat() != null) && (! "xml".equals(this.getResponseFormat().toLowerCase()))) { //JAXB will not work with JSON throw new RuntimeException("You can only generate a response POJO when using XML formatted API responses! JSON users go elsewhere!"); } JAXBContext jc; Object pojo = null; try { jc = JAXBContext.newInstance("com.facebook.api.schema"); Unmarshaller unmarshaller = jc.createUnmarshaller(); pojo = unmarshaller.unmarshal(new ByteArrayInputStream(this.rawResponse.getBytes("UTF-8"))); } catch (JAXBException e) { System.err.println("getResponsePOJO() - Could not unmarshall XML stream into POJO"); e.printStackTrace(); } catch (NullPointerException e) { System.err.println("getResponsePOJO() - Could not unmarshall XML stream into POJO."); e.printStackTrace(); } catch (UnsupportedEncodingException e) { System.err.println("getResponsePOJO() - Could not unmarshall XML stream into POJO."); e.printStackTrace(); } return pojo; } public boolean feed_PublishTemplatizedAction(TemplatizedAction action) throws FacebookException, IOException{ return this.templatizedFeedHandler(FacebookMethod.FEED_PUBLISH_TEMPLATIZED_ACTION, action.getTitleTemplate(), action.getTitleParams(), action.getBodyTemplate(), action.getBodyParams(), action.getBodyGeneral(), action.getPictures(), action.getTargetIds()); } public boolean feed_publishTemplatizedAction(String titleTemplate, String titleData, String bodyTemplate, String bodyData, String bodyGeneral, Collection> pictures, String targetIds) throws FacebookException, IOException { return this.templatizedFeedHandler(FacebookMethod.FEED_PUBLISH_TEMPLATIZED_ACTION, titleTemplate, titleData, bodyTemplate, bodyData, bodyGeneral, pictures, targetIds); } protected boolean templatizedFeedHandler(FacebookMethod method, String titleTemplate, String titleData, String bodyTemplate, String bodyData, String bodyGeneral, Collection> pictures, String targetIds) throws FacebookException, IOException { assert (pictures == null || pictures.size() <= 4); long actorId = this.users_getLoggedInUser(); ArrayList> params = new ArrayList>(method.numParams()); //these are always required parameters params.add(new Pair("actor_id", Long.toString(actorId))); params.add(new Pair("title_template", titleTemplate)); //these are optional parameters if (titleData != null) { params.add(new Pair("title_data", titleData)); } if (bodyTemplate != null) { params.add(new Pair("body_template", bodyTemplate)); if (bodyData != null) { params.add(new Pair("body_data", bodyData)); } } if (bodyGeneral != null) { params.add(new Pair("body_general", bodyGeneral)); } if (pictures != null) { int count = 1; for (Pair picture : pictures) { params.add(new Pair("image_" + count, picture.first.toString())); if (picture.second != null) { params.add(new Pair("image_" + count + "_link", picture.second.toString())); } count++; } } if (targetIds != null) { params.add(new Pair("target_ids", targetIds)); } this.callMethod(method, params); return this.rawResponse.contains(">1<"); //a code of '1' indicates success } public boolean users_hasAppPermission(Permission perm) throws FacebookException, IOException { return this.users_hasAppPermission(perm.getName()); } public Long marketplace_createListing(Long listingId, boolean showOnProfile, String attributes) throws FacebookException, IOException { T result = this.callMethod(FacebookMethod.MARKETPLACE_CREATE_LISTING, new Pair("show_on_profile", showOnProfile ? "1" : "0"), new Pair("listing_id", "0"), new Pair("listing_attrs", attributes)); return this.extractLong(result); } public Long marketplace_createListing(Long listingId, boolean showOnProfile, MarketListing listing) throws FacebookException, IOException { return this.marketplace_createListing(listingId, showOnProfile, listing.getAttribs()); } public Long marketplace_createListing(boolean showOnProfile, MarketListing listing) throws FacebookException, IOException { return this.marketplace_createListing(null, showOnProfile, listing.getAttribs()); } public boolean marketplace_removeListing(Long listingId, MarketListingStatus status) throws FacebookException, IOException { return this.marketplace_removeListing(listingId, status.getName()); } public Long marketplace_editListing(Long listingId, Boolean showOnProfile, MarketListing attrs) throws FacebookException, IOException { T result = this.callMethod(FacebookMethod.MARKETPLACE_CREATE_LISTING, new Pair("show_on_profile", showOnProfile ? "1" : "0"), new Pair("listing_id", listingId.toString()), new Pair("listing_attrs", attrs.getAttribs())); return this.extractLong(result); } public boolean users_setStatus(String newStatus, boolean clear) throws FacebookException, IOException { if (clear) { this.users_clearStatus(); } return this.users_setStatus(newStatus); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy