com.google.code.facebookapi.ExtensibleClient Maven / Gradle / Ivy
package com.google.code.facebookapi;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
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.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
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 {
protected static Log log = LogFactory.getLog( ExtensibleClient.class );
public static final int BATCH_LIMIT = 20;
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 ex ) {
log.error( "MalformedURLException: " + ex.getMessage(), ex );
}
}
protected static JAXBContext JAXB_CONTEXT;
public static void initJaxbSupport() {
if ( JAXB_CONTEXT == null ) {
try {
JAXB_CONTEXT = JAXBContext.newInstance( "com.google.code.facebookapi.schema" );
}
catch ( JAXBException ex ) {
log.error( "MalformedURLException: " + ex.getMessage(), ex );
}
}
}
protected URL _serverUrl;
protected int _timeout;
protected int _readTimeout;
protected final String _apiKey;
protected final String _secret;
protected boolean _isDesktop;
protected String cacheSessionKey;
protected Long cacheUserId;
protected Long cacheSessionExpires;
/** filled in when session is established only used for desktop apps */
protected String cacheSessionSecret;
protected String rawResponse;
protected boolean batchMode;
protected List queries;
protected String permissionsApiKey = null;
protected static final String CRLF = "\r\n";
protected static final String PREF = "--";
protected static final int UPLOAD_BUFFER_SIZE = 1024;
protected ExtensibleClient( String apiKey, String secret ) {
this( SERVER_URL, apiKey, secret, null );
}
protected ExtensibleClient( String apiKey, String secret, int timeout ) {
this( SERVER_URL, apiKey, secret, null, timeout );
}
protected ExtensibleClient( String apiKey, String secret, String sessionKey ) {
this( SERVER_URL, apiKey, secret, sessionKey );
}
protected ExtensibleClient( String apiKey, String secret, String sessionKey, int connectionTimeout ) {
this( SERVER_URL, apiKey, secret, sessionKey, connectionTimeout );
}
protected ExtensibleClient( String serverAddr, String apiKey, String secret, String sessionKey ) throws MalformedURLException {
this( new URL( serverAddr ), apiKey, secret, sessionKey );
}
protected ExtensibleClient( String serverAddr, String apiKey, String secret, String sessionKey, int connectionTimeout ) throws MalformedURLException {
this( new URL( serverAddr ), apiKey, secret, sessionKey, connectionTimeout );
}
protected ExtensibleClient( URL serverUrl, String apiKey, String secret, String sessionKey, int timeout ) {
this( serverUrl, apiKey, secret, sessionKey );
_timeout = timeout;
}
protected ExtensibleClient( URL serverUrl, String apiKey, String secret, String sessionKey, int timeout, int readTimeout ) {
this( serverUrl, apiKey, secret, sessionKey );
_timeout = timeout;
_readTimeout = readTimeout;
}
protected ExtensibleClient( URL serverUrl, String apiKey, String secret, String sessionKey ) {
this.cacheSessionKey = sessionKey;
this._apiKey = apiKey;
this._secret = secret;
this._serverUrl = ( null != serverUrl ) ? serverUrl : SERVER_URL;
this._timeout = -1;
this._readTimeout = -1;
this.batchMode = false;
this.queries = new ArrayList();
if ( this instanceof FacebookJaxbRestClient ) {
initJaxbSupport();
}
}
public String getApiKey() {
return _apiKey;
}
public String getSecret() {
return _secret;
}
public void beginPermissionsMode( String apiKey ) {
this.permissionsApiKey = apiKey;
}
public void endPermissionsMode() {
this.permissionsApiKey = null;
}
public JAXBContext getJaxbContext() {
return JAXB_CONTEXT;
}
public void setJaxbContext( JAXBContext context ) {
JAXB_CONTEXT = context;
}
/**
* The response format in which results to FacebookMethod calls are returned
*
* @return the format: either XML, JSON, or null (API default)
*/
public abstract String getResponseFormat();
/**
* Gets the session-token used by Facebook to authenticate a desktop application. If your application does not run in desktop mode, than this field is not relevent to
* you.
*
* @return the desktop-app session token.
*/
public String getSessionSecret() {
return cacheSessionSecret;
}
/**
* Allows the session-token to be manually overridden when running a desktop application. If your application does not run in desktop mode, then setting this field
* will have no effect. If you set an incorrect value here, your application will probably fail to run.
*
* @param key
* the new value to set. Incorrect values may cause your application to fail to run.
*/
public void setSessionSecret( String key ) {
cacheSessionSecret = key;
}
private static CharSequence delimit( Iterable iterable ) {
if ( iterable == null ) {
return null;
}
StringBuilder buffer = new StringBuilder();
boolean empty = true;
boolean notFirst = false;
for ( Object item : iterable ) {
if ( notFirst ) {
buffer.append( "," );
} else {
empty = false;
notFirst = true;
}
buffer.append( item.toString() );
}
if ( empty ) {
return null;
}
return buffer;
}
@Deprecated
protected Boolean cacheAppAdded; // to save making the users.isAppAdded api call, this will get prepopulated on canvas pages
@Deprecated
public Boolean getCacheAppAdded() {
return cacheAppAdded;
}
@Deprecated
public void setCacheAppAdded( Boolean cacheAppAdded ) {
this.cacheAppAdded = cacheAppAdded;
}
protected Boolean cacheAppUser; // to save making the users.isAppAdded api call, this will get prepopulated on canvas pages
public Boolean getCacheAppUser() {
return cacheAppUser;
}
public void setCacheAppUser( Boolean cacheAppUser ) {
this.cacheAppUser = cacheAppUser;
}
public String getCacheSessionSecret() {
return cacheSessionSecret;
}
public void setCacheSessionSecret( String cacheSessionSecret ) {
this.cacheSessionSecret = cacheSessionSecret;
}
public void setCacheSession( String cacheSessionKey, Long cacheUserId, Long cacheSessionExpires ) {
setCacheSessionKey( cacheSessionKey );
setCacheUserId( cacheUserId );
setCacheSessionExpires( cacheSessionExpires );
}
public Long getCacheSessionExpires() {
return cacheSessionExpires;
}
public void setCacheSessionExpires( Long cacheSessionExpires ) {
this.cacheSessionExpires = cacheSessionExpires;
}
public String getCacheSessionKey() {
return cacheSessionKey;
}
public void setCacheSessionKey( String cacheSessionKey ) {
this.cacheSessionKey = cacheSessionKey;
}
public Long getCacheUserId() {
return cacheUserId;
}
public void setCacheUserId( Long cacheUserId ) {
this.cacheUserId = cacheUserId;
}
public T friends_areFriends( long userId1, long userId2 ) throws FacebookException {
return callMethod( FacebookMethod.FRIENDS_ARE_FRIENDS, newPair( "uids1", userId1 ), newPair( "uids2", userId2 ) );
}
public T friends_areFriends( Collection userIds1, Collection userIds2 ) throws FacebookException {
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 callMethod( FacebookMethod.FRIENDS_ARE_FRIENDS, newPair( "uids1", delimit( userIds1 ) ), newPair( "uids2", delimit( userIds2 ) ) );
}
public boolean fbml_refreshRefUrl( String url ) throws FacebookException {
try {
return fbml_refreshRefUrl( new URL( url ) );
}
catch ( MalformedURLException ex ) {
throw runtimeException( ex );
}
}
/**
* Adds image parameters
*
* @param params
* @param images
*/
protected void handleFeedImages( List> params, Collection extends IPair extends Object,URL>> images ) {
if ( images != null && images.size() > 4 ) {
throw new IllegalArgumentException( "At most four images are allowed, got " + images.size() );
}
if ( null != images && !images.isEmpty() ) {
int image_count = 0;
for ( IPair extends Object,URL> image : images ) {
++image_count;
assert null != image.getFirst() : "Image URL must be provided";
String name = "image_" + image_count;
params.add( newPair( name, image.getFirst() ) );
if ( null != image.getSecond() ) {
params.add( newPair( name + "_link", image.getSecond() ) );
}
}
}
}
/**
* 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;
@Deprecated
public boolean feed_publishTemplatizedAction( Long actorId, CharSequence titleTemplate ) throws FacebookException {
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 extends IPair extends Object,URL>> images )
throws FacebookException {
return feed_publishTemplatizedAction( titleTemplate, titleData, bodyTemplate, bodyData, bodyGeneral, targetIds, images, null );
}
/**
* @deprecated Use the version that takes a Long for the actorId paramter.
*/
@Deprecated
public boolean feed_publishTemplatizedAction( Integer actorId, CharSequence titleTemplate, Map titleData, CharSequence bodyTemplate,
Map bodyData, CharSequence bodyGeneral, Collection targetIds, Collection extends IPair extends Object,URL>> images )
throws FacebookException {
return feed_publishTemplatizedAction( (long) ( actorId.intValue() ), titleTemplate, titleData, bodyTemplate, bodyData, bodyGeneral, targetIds, images );
}
public T groups_getMembers( Number groupId ) throws FacebookException {
assert ( null != groupId );
return callMethod( FacebookMethod.GROUPS_GET_MEMBERS, newPair( "gid", groupId ) );
}
private static String encode( CharSequence target ) {
if ( target == null ) {
return "";
}
String result = target.toString();
try {
result = URLEncoder.encode( result, "UTF8" );
}
catch ( UnsupportedEncodingException ex ) {
throw runtimeException( ex );
}
return result;
}
public T friends_getAppUsers() throws FacebookException {
return callMethod( FacebookMethod.FRIENDS_GET_APP_USERS );
}
public T fql_query( CharSequence query ) throws FacebookException {
assert ( null != query );
return callMethod( FacebookMethod.FQL_QUERY, newPair( "query", query ) );
}
private String generateSignature( List params, boolean requiresSession ) {
// String secret = ( isDesktop() && requiresSession ) ? cacheSessionSecret : _secret;
String secret = _secret;
return FacebookSignatureUtil.generateSignature( params, secret );
}
public T groups_get( Long userId, Collection groupIds ) throws FacebookException {
boolean hasGroups = ( null != groupIds && !groupIds.isEmpty() );
if ( null != userId ) {
return hasGroups ? callMethod( FacebookMethod.GROUPS_GET, newPair( "uid", userId ), newPair( "gids", delimit( groupIds ) ) ) : callMethod(
FacebookMethod.GROUPS_GET, newPair( "uid", userId ) );
} else {
return hasGroups ? callMethod( FacebookMethod.GROUPS_GET, newPair( "gids", delimit( groupIds ) ) ) : 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, Pair... paramPairs ) throws FacebookException {
return callMethod( method, Arrays.asList( paramPairs ), null, null );
}
/**
* 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 {
return callMethod( method, paramPairs, null, null );
}
protected T callMethod( IFacebookMethod method, Collection> paramPairs, String fileName, InputStream fileStream ) throws FacebookException {
rawResponse = null;
Map params = new TreeMap();
if ( permissionsApiKey != null ) {
params.put( "call_as_apikey", permissionsApiKey );
}
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 );
}
params.put( "call_id", Long.toString( System.currentTimeMillis() ) );
boolean includeSession = !method.requiresNoSession() && cacheSessionKey != null;
if ( includeSession ) {
params.put( "session_key", cacheSessionKey );
}
CharSequence oldVal;
for ( Pair p : paramPairs ) {
oldVal = params.put( p.first, FacebookSignatureUtil.toString( p.second ) );
if ( oldVal != null ) {
log.warn( String.format( "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() ), includeSession );
params.put( "sig", signature );
if ( batchMode ) {
// if we are running in batch mode, don't actually execute the query now, just add it to the list
boolean addToBatch = true;
if ( method.methodName().equals( FacebookMethod.USERS_GET_LOGGED_IN_USER.methodName() ) ) {
Exception trace = new Exception();
StackTraceElement[] traceElems = trace.getStackTrace();
int index = 0;
for ( StackTraceElement elem : traceElems ) {
if ( elem.getMethodName().indexOf( "_" ) != -1 ) {
StackTraceElement caller = traceElems[index + 1];
if ( ( caller.getClassName().equals( ExtensibleClient.class.getName() ) ) && ( !caller.getMethodName().startsWith( "auth_" ) ) ) {
addToBatch = false;
}
break;
}
index++ ;
}
}
if ( addToBatch ) {
queries.add( new BatchQuery( method, params ) );
}
return null;
}
boolean doHttps = isDesktop() && FacebookMethod.AUTH_GET_SESSION.equals( method );
boolean doEncode = true;
try {
rawResponse = method.takesFile() ? postFileRequest( method, params, fileName, fileStream ) : postRequest( method, params, doHttps );
return parseCallResult( new ByteArrayInputStream( rawResponse.getBytes( "UTF-8" ) ), method );
}
catch ( IOException ex ) {
throw runtimeException( ex );
}
}
private String postRequest( IFacebookMethod method, Map params, boolean doHttps ) throws IOException {
URL serverUrl = ( doHttps ) ? HTTPS_SERVER_URL : _serverUrl;
CharSequence paramString = ( null == params ) ? "" : delimit( params.entrySet(), "&", "=", true );
if ( log.isDebugEnabled() ) {
log.debug( method.methodName() + " POST: " + serverUrl.toString() + "?" + paramString );
}
HttpURLConnection conn = null;
OutputStream out = null;
InputStream in = null;
try {
conn = (HttpURLConnection) serverUrl.openConnection();
if ( _timeout != -1 ) {
conn.setConnectTimeout( _timeout );
}
if ( _readTimeout != -1 ) {
conn.setReadTimeout( _readTimeout );
}
conn.setRequestMethod( "POST" );
conn.setDoOutput( true );
conn.connect();
out = conn.getOutputStream();
out.write( paramString.toString().getBytes( "UTF-8" ) );
in = conn.getInputStream();
return getResponse( method, in );
}
finally {
close( in );
close( out );
disconnect( conn );
}
}
/**
* 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)
* @param doEncode
* whether to UTF8-encode the parameters
* @return an InputStream with the request response
* @see #photos_upload
*/
protected String postFileRequest( IFacebookMethod method, Map params, String fileName, InputStream fileStream ) throws IOException {
HttpURLConnection con = null;
OutputStream urlOut = null;
InputStream in = null;
try {
String boundary = Long.toString( System.currentTimeMillis(), 16 );
con = (HttpURLConnection) _serverUrl.openConnection();
if ( _timeout != -1 ) {
con.setConnectTimeout( _timeout );
}
if ( _readTimeout != -1 ) {
con.setReadTimeout( _readTimeout );
}
con.setDoInput( true );
con.setDoOutput( true );
con.setUseCaches( false );
con.setRequestProperty( "Content-Type", "multipart/form-data; boundary=" + boundary );
con.setRequestProperty( "MIME-version", "1.0" );
urlOut = con.getOutputStream();
DataOutputStream out = new DataOutputStream( urlOut );
for ( Map.Entry entry : params.entrySet() ) {
out.writeBytes( PREF + boundary + CRLF );
out.writeBytes( "Content-Type: text/plain;charset=utf-8" + CRLF );
// out.writeBytes( "Content-Transfer-Encoding: application/x-www-form-urlencoded" + CRLF );
// out.writeBytes( "Content-Type: text/plain;charset=utf-8" + CRLF );
// out.writeBytes( "Content-Transfer-Encoding: quoted-printable" + CRLF );
out.writeBytes( "Content-disposition: form-data; name=\"" + entry.getKey() + "\"" + CRLF );
out.writeBytes( CRLF );
byte[] valueBytes = entry.getValue().toString().getBytes( "UTF-8" );
out.write( valueBytes );
out.writeBytes( CRLF );
}
out.writeBytes( PREF + boundary + CRLF );
out.writeBytes( "Content-Type: image" + CRLF );
out.writeBytes( "Content-disposition: form-data; filename=\"" + fileName + "\"" + CRLF );
// out.writeBytes("Content-Transfer-Encoding: binary" + CRLF); // not necessary
// Write the file
out.writeBytes( CRLF );
byte buf[] = new byte[UPLOAD_BUFFER_SIZE];
int len = 0;
while ( len >= 0 ) {
out.write( buf, 0, len );
len = fileStream.read( buf );
}
out.writeBytes( CRLF + PREF + boundary + PREF + CRLF );
out.flush();
in = con.getInputStream();
return getResponse( method, in );
}
finally {
close( urlOut );
close( in );
disconnect( con );
}
}
private String getResponse( IFacebookMethod method, InputStream data ) throws IOException {
Reader in = new BufferedReader( new InputStreamReader( data, "UTF-8" ) );
StringBuilder buffer = new StringBuilder();
char[] buf = new char[1000];
int l = 0;
while ( l >= 0 ) {
buffer.append( buf, 0, l );
l = in.read( buf );
}
return buffer.toString();
}
/**
* 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;
public boolean fbml_refreshRefUrl( URL url ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.FBML_REFRESH_REF_URL, newPair( "url", url ) ) );
}
public T notifications_get() throws FacebookException {
return callMethod( FacebookMethod.NOTIFICATIONS_GET );
}
public T users_getStandardInfo( Iterable userIds, Collection fields ) throws FacebookException {
assert ( userIds != null );
assert ( fields != null );
assert ( !fields.isEmpty() );
return callMethod( FacebookMethod.USERS_GET_STANDARD_INFO, newPair( "uids", delimit( userIds ) ), newPair( "fields", delimit( fields ) ) );
}
public T users_getStandardInfo( Iterable userIds, Set fields ) throws FacebookException {
assert ( userIds != null );
assert ( fields != null );
assert ( !fields.isEmpty() );
return callMethod( FacebookMethod.USERS_GET_STANDARD_INFO, newPair( "uids", delimit( userIds ) ), newPair( "fields", delimit( fields ) ) );
}
public T users_getInfo( Iterable userIds, Collection fields ) throws FacebookException {
assert ( userIds != null );
assert ( fields != null );
assert ( !fields.isEmpty() );
return callMethod( FacebookMethod.USERS_GET_INFO, newPair( "uids", delimit( userIds ) ), newPair( "fields", delimit( fields ) ) );
}
public T users_getInfo( Iterable userIds, Set fields ) throws FacebookException {
assert ( userIds != null );
assert ( fields != null );
assert ( !fields.isEmpty() );
return callMethod( FacebookMethod.USERS_GET_INFO, newPair( "uids", delimit( userIds ) ), newPair( "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 {
if ( cacheUserId == null || cacheUserId == -1 || batchMode ) {
cacheUserId = extractLong( callMethod( FacebookMethod.USERS_GET_LOGGED_IN_USER ) );
}
return cacheUserId;
}
/**
* Call this function to get the user ID.
*
* @return The ID of the current session's user, or -1 if none.
* @deprecated please call auth_getSession(authToken), then you can call users_getLoggedInUser(), or getCacheUserId()
*/
@Deprecated
public long auth_getUserId( String authToken ) throws FacebookException {
/*
* Get the session information if we don't have it; this will populate the user ID as well.
*/
if ( null == cacheSessionKey ) {
auth_getSession( authToken );
}
return users_getLoggedInUser();
}
public boolean isDesktop() {
return _isDesktop;
}
@Deprecated
public boolean users_isAppAdded() throws FacebookException {
if ( cacheAppAdded == null ) {
cacheAppAdded = extractBoolean( callMethod( FacebookMethod.USERS_IS_APP_ADDED ) );
}
return cacheAppAdded;
}
public boolean users_isAppUser() throws FacebookException {
if ( cacheAppUser == null ) {
cacheAppUser = extractBoolean( callMethod( FacebookMethod.USERS_IS_APP_USER ) );
}
return cacheAppUser;
}
public boolean users_isAppUser( Long userId ) throws FacebookException {
if ( userId != null ) {
return extractBoolean( callMethod( FacebookMethod.USERS_IS_APP_USER_NOSESSION, newPair( "uid", userId ) ) );
} else {
return extractBoolean( callMethod( FacebookMethod.USERS_IS_APP_USER ) );
}
}
public boolean users_setStatus( String status ) throws FacebookException {
return users_setStatus( status, false, false );
}
public boolean users_clearStatus() throws FacebookException {
return users_setStatus( null, true );
}
@Deprecated
public URL notifications_send( Collection recipientIds, CharSequence notification, CharSequence email ) throws FacebookException {
notifications_send( recipientIds, notification );
return null;
}
public boolean fbml_refreshImgSrc( String imageUrl ) throws FacebookException {
try {
return fbml_refreshImgSrc( new URL( imageUrl ) );
}
catch ( MalformedURLException ex ) {
throw runtimeException( ex );
}
}
public void setIsDesktop( boolean isDesktop ) {
this._isDesktop = isDesktop;
}
protected static CharSequence delimit( Collection> entries, String delimiter, String 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;
}
public boolean fbml_refreshImgSrc( URL imageUrl ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.FBML_REFRESH_IMG_SRC, newPair( "url", imageUrl ) ) );
}
public T friends_get() throws FacebookException {
return callMethod( FacebookMethod.FRIENDS_GET );
}
public T friends_get( Long uid ) throws FacebookException {
if ( uid != null ) {
return callMethod( FacebookMethod.FRIENDS_GET_NOSESSION, newPair( "uid", uid ) );
} else {
return callMethod( FacebookMethod.FRIENDS_GET );
}
}
public String auth_createToken() throws FacebookException {
T d = callMethod( FacebookMethod.AUTH_CREATE_TOKEN );
return extractString( d );
}
public String getRawResponse() {
return rawResponse;
}
public Object getResponsePOJO() {
if ( rawResponse == null ) {
return null;
}
if ( JAXB_CONTEXT == null ) {
return null;
}
if ( ( getResponseFormat() != null ) && ( !"xml".equalsIgnoreCase( getResponseFormat() ) ) ) {
// 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!" );
}
try {
Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
return unmarshaller.unmarshal( new ByteArrayInputStream( rawResponse.getBytes( "UTF-8" ) ) );
}
catch ( Exception ex ) {
throw runtimeException( ex );
}
}
public boolean feed_PublishTemplatizedAction( TemplatizedAction action ) throws FacebookException {
return templatizedFeedHandler( action.getTitleTemplate(), action.getTitleParams(), action.getBodyTemplate(), action.getBodyParams(), action.getBodyGeneral(),
action.getPictures(), action.getTargetIds(), action.getPageActorId() );
}
public boolean feed_publishTemplatizedAction( String titleTemplate, String titleData, String bodyTemplate, String bodyData, String bodyGeneral,
Collection extends IPair extends Object,URL>> pictures, String targetIds ) throws FacebookException {
return templatizedFeedHandler( titleTemplate, titleData, bodyTemplate, bodyData, bodyGeneral, pictures, targetIds, null );
}
protected boolean templatizedFeedHandler( String titleTemplate, String titleData, String bodyTemplate, String bodyData, String bodyGeneral,
Collection extends IPair extends Object,URL>> pictures, String targetIds, Long pageId ) throws FacebookException {
assert ( pictures == null || pictures.size() <= 4 );
List> params = new ArrayList>( 15 );
// these are always required parameters
addParam( "title_template", titleTemplate, params );
// these are optional parameters
addParamIfNotBlank( "title_data", titleData, params );
boolean hasBody = addParamIfNotBlank( "body_template", bodyTemplate, params );
if ( hasBody ) {
addParamIfNotBlank( "body_data", bodyData, params );
}
addParamIfNotBlank( "body_general", bodyGeneral, params );
if ( pictures != null ) {
int count = 1;
for ( IPair picture : pictures ) {
String url = picture.getFirst().toString();
if ( url.startsWith( TemplatizedAction.UID_TOKEN ) ) {
url = url.substring( TemplatizedAction.UID_TOKEN.length() );
}
addParam( "image_" + count, url, params );
if ( picture.getSecond() != null ) {
addParam( "image_" + count + "_link", picture.getSecond().toString(), params );
}
count++ ;
}
}
addParamIfNotBlank( "target_ids", targetIds, params );
addParamIfNotBlank( "page_actor_id", pageId, params );
return extractBoolean( callMethod( FacebookMethod.FEED_PUBLISH_TEMPLATIZED_ACTION, params ) );
}
public boolean users_hasAppPermission( Permission perm ) throws FacebookException {
return users_hasAppPermission( perm, null );
}
public boolean users_hasAppPermission( Permission perm, Long userId ) throws FacebookException {
if ( userId != null ) {
return extractBoolean( callMethod( FacebookMethod.USERS_HAS_APP_PERMISSION_NOSESSION, newPair( "ext_perm", perm.getName() ), newPair( "uid", userId ) ) );
} else {
return extractBoolean( callMethod( FacebookMethod.USERS_HAS_APP_PERMISSION, newPair( "ext_perm", perm.getName() ) ) );
}
}
public boolean users_setStatus( String newStatus, boolean clear ) throws FacebookException {
return users_setStatus( newStatus, clear, false );
}
public T pages_getInfo( Collection pageIds, EnumSet fields ) throws FacebookException {
if ( pageIds == null || pageIds.isEmpty() ) {
throw new IllegalArgumentException( "pageIds cannot be empty or null" );
}
if ( fields == null || fields.isEmpty() ) {
throw new IllegalArgumentException( "fields cannot be empty or null" );
}
IFacebookMethod method = ( null == cacheSessionKey ) ? FacebookMethod.PAGES_GET_INFO_NOSESSION : FacebookMethod.PAGES_GET_INFO;
return callMethod( method, newPair( "page_ids", delimit( pageIds ) ), newPair( "fields", delimit( fields ) ) );
}
public T pages_getInfo( Collection pageIds, Set fields ) throws FacebookException {
if ( pageIds == null || pageIds.isEmpty() ) {
throw new IllegalArgumentException( "pageIds cannot be empty or null" );
}
if ( fields == null || fields.isEmpty() ) {
throw new IllegalArgumentException( "fields cannot be empty or null" );
}
IFacebookMethod method = null == cacheSessionKey ? FacebookMethod.PAGES_GET_INFO_NOSESSION : FacebookMethod.PAGES_GET_INFO;
return callMethod( method, newPair( "page_ids", delimit( pageIds ) ), newPair( "fields", delimit( fields ) ) );
}
public T pages_getInfo( Long userId, EnumSet fields ) throws FacebookException {
if ( fields == null || fields.isEmpty() ) {
throw new IllegalArgumentException( "fields cannot be empty or null" );
}
if ( userId == null ) {
userId = cacheUserId;
}
if ( userId == null ) {
return callMethod( FacebookMethod.PAGES_GET_INFO, newPair( "fields", delimit( fields ) ) );
}
return callMethod( FacebookMethod.PAGES_GET_INFO, newPair( "uid", userId ), newPair( "fields", delimit( fields ) ) );
}
public T pages_getInfo( Long userId, Set fields ) throws FacebookException {
if ( fields == null || fields.isEmpty() ) {
throw new IllegalArgumentException( "fields cannot be empty or null" );
}
if ( userId == null ) {
userId = cacheUserId;
}
if ( userId == null ) {
return callMethod( FacebookMethod.PAGES_GET_INFO, newPair( "fields", delimit( fields ) ) );
}
return callMethod( FacebookMethod.PAGES_GET_INFO, newPair( "uid", userId ), newPair( "fields", delimit( fields ) ) );
}
public boolean pages_isAppAdded( Long pageId ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.PAGES_IS_APP_ADDED, newPair( "page_id", pageId ) ) );
}
public boolean pages_isFan( Long pageId, Long userId ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.PAGES_IS_FAN, newPair( "page_id", pageId ), newPair( "uid", userId ) ) );
}
public boolean pages_isFan( Long pageId ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.PAGES_IS_FAN, newPair( "page_id", pageId ) ) );
}
public boolean pages_isAdmin( Long pageId ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.PAGES_IS_ADMIN, newPair( "page_id", pageId ) ) );
}
public boolean fbml_setRefHandle( String handle, String fbmlMarkup ) throws FacebookException {
if ( _isDesktop ) {
// this method cannot be called from a desktop app
throw new FacebookException( ErrorCode.GEN_PERMISSIONS_ERROR, "Desktop applications cannot use 'fbml_setReftHandle'" );
}
return extractBoolean( callMethod( FacebookMethod.FBML_SET_REF_HANDLE, newPair( "handle", handle ), newPair( "fbml", fbmlMarkup ) ) );
}
public void notifications_send( Collection recipientIds, CharSequence notification ) throws FacebookException {
notifications_send( recipientIds, notification.toString(), false );
}
public boolean users_setStatus( String newStatus, boolean clear, boolean statusIncludesVerb ) throws FacebookException {
Collection> params = new ArrayList>();
if ( newStatus != null ) {
params.add( newPair( "status", newStatus ) );
}
if ( clear ) {
params.add( newPair( "clear", "true" ) );
}
if ( statusIncludesVerb ) {
params.add( newPair( "status_includes_verb", "true" ) );
}
return extractBoolean( callMethod( FacebookMethod.USERS_SET_STATUS, params ) );
}
/**
* Send a notification message to the logged-in user.
*
* @param notification
* the FBML to be displayed on the notifications page; only a stripped-down set of FBML tags that result in text and links is allowed
* @return a URL, possibly null, to which the user should be redirected to finalize the sending of the email
* @see Developers Wiki: notifications.send
*/
public void notifications_send( CharSequence notification ) throws FacebookException {
Long currentUser = users_getLoggedInUser();
Collection coll = new ArrayList();
coll.add( currentUser );
notifications_send( coll, notification );
}
public T data_getCookies() throws FacebookException {
return data_getCookies( users_getLoggedInUser(), null );
}
public T data_getCookies( Long userId ) throws FacebookException {
return data_getCookies( userId, null );
}
public T data_getCookies( String name ) throws FacebookException {
return data_getCookies( users_getLoggedInUser(), name );
}
public T data_getCookies( Long userId, CharSequence name ) throws FacebookException {
if ( name == null ) {
return callMethod( FacebookMethod.DATA_GET_COOKIES, newPair( "uid", userId ) );
} else {
return callMethod( FacebookMethod.DATA_GET_COOKIES, newPair( "uid", userId ), newPair( "name", name ) );
}
}
public boolean data_setCookie( String name, String value ) throws FacebookException {
return data_setCookie( users_getLoggedInUser(), name, value, null, null );
}
public boolean data_setCookie( String name, String value, String path ) throws FacebookException {
return data_setCookie( users_getLoggedInUser(), name, value, null, path );
}
public boolean data_setCookie( Long userId, CharSequence name, CharSequence value ) throws FacebookException {
return data_setCookie( userId, name, value, null, null );
}
public boolean data_setCookie( Long userId, CharSequence name, CharSequence value, CharSequence path ) throws FacebookException {
return data_setCookie( userId, name, value, null, path );
}
public boolean data_setCookie( String name, String value, Long expires ) throws FacebookException {
return data_setCookie( users_getLoggedInUser(), name, value, expires, null );
}
public boolean data_setCookie( String name, String value, Long expires, String path ) throws FacebookException {
return data_setCookie( users_getLoggedInUser(), name, value, expires, path );
}
public boolean data_setCookie( Long userId, CharSequence name, CharSequence value, Long expires ) throws FacebookException {
return data_setCookie( userId, name, value, expires, null );
}
public boolean data_setCookie( Long userId, CharSequence name, CharSequence value, Long expires, CharSequence path ) throws FacebookException {
if ( ( name == null ) || ( "".equals( name ) ) ) {
throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "The cookie name cannot be null or empty!" );
}
if ( value == null ) {
value = "";
}
List> params = new ArrayList>( 5 );
addParam( "uid", userId, params );
addParam( "name", name, params );
addParam( "value", value, params );
addParamIfNotBlankZero( "expires", expires, params );
addParamIfNotBlank( "path", path, params );
T doc = callMethod( FacebookMethod.DATA_SET_COOKIE, params );
return extractBoolean( doc );
}
public String data_getUserPreference( int prefId ) throws FacebookException {
return extractString( callMethod( FacebookMethod.DATA_GET_USER_PREFERENCE, newPair( "pref_id", prefId ) ) );
}
public T data_getUserPreferences() throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_USER_PREFERENCES );
}
public void data_setUserPreference( int prefId, String value ) throws FacebookException {
if ( value != null && value.length() > 128 ) {
throw new FacebookException(
ErrorCode.GEN_INVALID_PARAMETER,
String
.format(
"Attempt to set a preference which hold a maximum of 128 characters to a value with %d characters. The Facebook API silently truncates this value to 128 characters which can lead to unpredictable results. If you want the truncation behaviour, please truncate the string in your Java code.",
value.length() ) );
}
callMethod( FacebookMethod.DATA_SET_USER_PREFERENCE, newPair( "pref_id", prefId ), newPair( "value", value ) );
}
public void data_setUserPreferences( Map values, boolean replace ) throws FacebookException {
JSONObject prefs = new JSONObject();
for ( Integer key : values.keySet() ) {
try {
prefs.put( key.toString(), values.get( key ) );
}
catch ( JSONException ex ) {
throw runtimeException( ex );
}
}
callMethod( FacebookMethod.DATA_SET_USER_PREFERENCES, newPair( "values", prefs.toString() ), newPairTF( "replace", replace ) );
}
public long data_createObject( String objectType, Map properties ) throws FacebookException {
return extractLong( callMethod( FacebookMethod.DATA_CREATE_OBJECT, newPair( "obj_type", objectType ), newPair( "properties", toJson( properties ) ) ) );
}
public void data_updateObject( long objectId, Map properties, boolean replace ) throws FacebookException {
callMethod( FacebookMethod.DATA_UPDATE_OBJECT, newPair( "obj_id", String.valueOf( objectId ) ), newPair( "properties", toJson( properties ) ), newPairTF(
"replace", replace ) );
}
public void data_deleteObject( long objectId ) throws FacebookException {
callMethod( FacebookMethod.DATA_DELETE_OBJECT, newPair( "obj_id", objectId ) );
}
public void data_deleteObjects( Collection objectIds ) throws FacebookException {
callMethod( FacebookMethod.DATA_DELETE_OBJECTS, newPair( "obj_ids", delimit( objectIds ) ) );
}
public T data_getObject( long objectId ) throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_OBJECT, newPair( "obj_id", objectId ) );
}
public T data_getObjects( Collection objectIds ) throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_OBJECTS, newPair( "obj_ids", delimit( objectIds ) ) );
}
public T data_getObjectProperty( long objectId, String propertyName ) throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_OBJECT_PROPERTY, newPair( "obj_id", objectId ), newPair( "prop_name", propertyName ) );
}
public void data_setObjectProperty( long objectId, String propertyName, String value ) throws FacebookException {
callMethod( FacebookMethod.DATA_SET_OBJECT_PROPERTY, newPair( "obj_id", objectId ), newPair( "prop_name", propertyName ), newPair( "value", value ) );
}
public void data_createObjectType( String name ) throws FacebookException {
callMethod( FacebookMethod.DATA_CREATE_OBJECT_TYPE, newPair( "name", name ) );
}
public void data_dropObjectType( String objectType ) throws FacebookException {
callMethod( FacebookMethod.DATA_DROP_OBJECT_TYPE, newPair( "obj_type", objectType ) );
}
public void data_renameObjectType( String objectType, String newName ) throws FacebookException {
callMethod( FacebookMethod.DATA_RENAME_OBJECT_TYPE, newPair( "obj_type", objectType ), newPair( "new_name", newName ) );
}
public void data_defineObjectProperty( String objectType, String propertyName, PropertyType propertyType ) throws FacebookException {
callMethod( FacebookMethod.DATA_DEFINE_OBJECT_PROPERTY, newPair( "obj_type", objectType ), newPair( "prop_name", propertyName ), newPair( "prop_type",
propertyType.getValue() ) );
}
public void data_undefineObjectProperty( String objectType, String propertyName ) throws FacebookException {
callMethod( FacebookMethod.DATA_UNDEFINE_OBJECT_PROPERTY, newPair( "obj_type", objectType ), newPair( "prop_name", propertyName ) );
}
public void data_renameObjectProperty( String objectType, String propertyName, String newPropertyName ) throws FacebookException {
callMethod( FacebookMethod.DATA_RENAME_OBJECT_PROPERTY, newPair( "obj_type", objectType ), newPair( "prop_name", propertyName ), newPair( "new_name",
newPropertyName ) );
}
public T data_getObjectTypes() throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_OBJECT_TYPES );
}
public T data_getObjectType( String objectType ) throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_OBJECT_TYPE, newPair( "obj_type", objectType ) );
}
public void data_defineAssociation( String associationName, AssociationType associationType, AssociationInfo associationInfo1, AssociationInfo associationInfo2,
String inverseName ) throws FacebookException {
List> params = new ArrayList>( 5 );
addParam( "name", associationName, params );
addParam( "assoc_type", associationType.getValue(), params );
JSONObject assocInfo1 = new JSONObject();
try {
assocInfo1.put( "alias", associationInfo1.getAlias() );
assocInfo1.put( "object_type", associationInfo1.getObjectType() );
assocInfo1.put( "unique", associationInfo1.isUnique() );
}
catch ( JSONException ex ) {
throw runtimeException( ex );
}
addParam( "assoc_info1", assocInfo1.toString(), params );
JSONObject assocInfo2 = new JSONObject();
try {
assocInfo2.put( "alias", associationInfo2.getAlias() );
assocInfo2.put( "object_type", associationInfo2.getObjectType() );
assocInfo2.put( "unique", associationInfo2.isUnique() );
}
catch ( JSONException ex ) {
throw runtimeException( ex );
}
addParam( "assoc_info2", assocInfo2, params );
addParamIfNotBlank( "inverse", inverseName, params );
callMethod( FacebookMethod.DATA_DEFINE_ASSOCIATION, params );
}
public void data_undefineAssociation( String name ) throws FacebookException {
callMethod( FacebookMethod.DATA_UNDEFINE_ASSOCIATION, newPair( "name", name ) );
}
public void data_renameAssociation( String name, String newName, String newAlias1, String newAlias2 ) throws FacebookException {
List> params = new ArrayList>( 4 );
addParam( "name", name, params );
addParam( "new_name", newName, params );
addParamIfNotBlank( "new_alias1", newAlias1, params );
addParamIfNotBlank( "new_alias2", newAlias2, params );
callMethod( FacebookMethod.DATA_RENAME_ASSOCIATION, params );
}
public T data_getAssociationDefinition( String name ) throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_ASSOCIATION_DEFINITION, newPair( "name", name ) );
}
public T data_getAssociationDefinitions() throws FacebookException {
return callMethod( FacebookMethod.DATA_GET_ASSOCIATION_DEFINITIONS );
}
public void data_setAssociation( String associationName, long object1Id, long object2Id, String data, Date associationTime ) throws FacebookException {
List> params = new ArrayList>( 5 );
addParam( "name", associationName, params );
addParam( "obj_id1", object1Id, params );
addParam( "obj_id2", object2Id, params );
addParamIfNotBlank( "data", data, params );
addParamSecondsIfNotBlank( "assoc_time", associationTime, params );
callMethod( FacebookMethod.DATA_SET_ASSOCIATION, params );
}
public void data_removeAssociation( String associationName, long object1Id, long object2Id ) throws FacebookException {
callMethod( FacebookMethod.DATA_REMOVE_ASSOCIATION, newPair( "name", associationName ), newPair( "obj_id1", object1Id ), newPair( "obj_id2", object2Id ) );
}
public void data_removeAssociatedObjects( String associationName, long objectId ) throws FacebookException {
callMethod( FacebookMethod.DATA_REMOVE_ASSOCIATED_OBJECTS, newPair( "name", associationName ), newPair( "obj_id", objectId ) );
}
public long data_getAssociatedObjectCount( String associationName, long objectId ) throws FacebookException {
return extractLong( callMethod( FacebookMethod.DATA_GET_ASSOCIATED_OBJECT_COUNT, newPair( "name", associationName ), newPair( "obj_id", objectId ) ) );
}
public boolean feed_publishTemplatizedAction( CharSequence titleTemplate ) throws FacebookException {
return feed_publishTemplatizedAction( titleTemplate, null );
}
public boolean feed_publishTemplatizedAction( CharSequence titleTemplate, Long pageActorId ) throws FacebookException {
return feed_publishTemplatizedAction( titleTemplate, null, null, null, null, null, null, pageActorId );
}
public boolean feed_publishTemplatizedAction( CharSequence titleTemplate, Map titleData, CharSequence bodyTemplate,
Map bodyData, CharSequence bodyGeneral, Collection targetIds, Collection extends IPair extends Object,URL>> images,
Long pageActorId ) throws FacebookException {
assert null != titleTemplate && !"".equals( titleTemplate );
List> params = new ArrayList>( 15 );
params.add( newPair( "title_template", titleTemplate ) );
if ( null != titleData && !titleData.isEmpty() ) {
JSONObject titleDataJson = new JSONObject();
try {
for ( String key : titleData.keySet() ) {
titleDataJson.put( key, titleData.get( key ) );
}
}
catch ( Exception ex ) {
throw runtimeException( ex );
}
params.add( newPair( "title_data", titleDataJson ) );
}
if ( null != bodyTemplate && !"".equals( bodyTemplate ) ) {
params.add( newPair( "body_template", bodyTemplate ) );
if ( null != bodyData && !bodyData.isEmpty() ) {
JSONObject bodyDataJson = new JSONObject();
try {
for ( String key : bodyData.keySet() ) {
bodyDataJson.put( key, bodyData.get( key ) );
}
}
catch ( Exception ex ) {
throw runtimeException( ex );
}
params.add( newPair( "body_data", bodyDataJson ) );
}
}
if ( null != bodyTemplate && !"".equals( bodyTemplate ) ) {
params.add( newPair( "body_template", bodyTemplate ) );
}
if ( null != targetIds && !targetIds.isEmpty() ) {
params.add( newPair( "target_ids", delimit( targetIds ) ) );
}
if ( bodyGeneral != null ) {
params.add( newPair( "body_general", bodyGeneral ) );
}
if ( pageActorId != null ) {
params.add( newPair( "page_actor_id", pageActorId ) );
}
handleFeedImages( params, images );
return extractBoolean( callMethod( FacebookMethod.FEED_PUBLISH_TEMPLATIZED_ACTION, params ) );
}
public T friends_getList( Long friendListId ) throws FacebookException {
if ( null != friendListId && 0L <= friendListId ) {
throw new IllegalArgumentException( "given invalid friendListId " + friendListId );
}
return callMethod( FacebookMethod.FRIENDS_GET, newPair( "flid", friendListId ) );
}
public T friends_getLists() throws FacebookException {
return callMethod( FacebookMethod.FRIENDS_GET_LISTS );
}
public void beginBatch() {
batchMode = true;
queries = new ArrayList();
}
protected String encodeMethods( List queries ) throws FacebookException {
JSONArray result = new JSONArray();
for ( BatchQuery query : queries ) {
if ( query.getMethod().takesFile() ) {
throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "File upload API calls cannot be batched: " + query.getMethod().methodName() );
}
result.put( delimit( query.getParams().entrySet(), "&", "=", true ) );
}
return result.toString();
}
public T batch_run( String methods, boolean serial ) throws FacebookException {
if ( !serial ) {
return callMethod( FacebookMethod.BATCH_RUN, newPair( "method_feed", methods ) );
} else {
return callMethod( FacebookMethod.BATCH_RUN, newPair( "method_feed", methods ), newPair( "serial_only", "1" ) );
}
}
public T application_getPublicInfo( Long applicationId, String applicationKey, String applicationCanvas ) throws FacebookException {
Pair pair = null;
if ( ( applicationId != null ) && ( applicationId > 0 ) ) {
pair = newPair( "application_id", applicationId );
} else if ( ( applicationKey != null ) && ( !"".equals( applicationKey ) ) ) {
pair = newPair( "application_api_key", applicationKey );
} else if ( ( applicationCanvas != null ) && ( !"".equals( applicationCanvas ) ) ) {
pair = newPair( "application_canvas_name", applicationCanvas );
} else {
// we need at least one of them to be valid
throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "You must specify at least/most one of {applicationId, applicationKey, applicationCanvas}" );
}
return callMethod( FacebookMethod.APPLICATION_GET_PUBLIC_INFO, pair );
}
public T application_getPublicInfoById( Long applicationId ) throws FacebookException {
return application_getPublicInfo( applicationId, null, null );
}
public T application_getPublicInfoByApiKey( String applicationKey ) throws FacebookException {
return application_getPublicInfo( null, applicationKey, null );
}
public T application_getPublicInfoByCanvasName( String applicationCanvas ) throws FacebookException {
return application_getPublicInfo( null, null, applicationCanvas );
}
public T permissions_checkGrantedApiAccess( String apiKey ) throws FacebookException {
return callMethod( FacebookMethod.PERM_CHECK_GRANTED_API_ACCESS, newPair( "permissions_apikey", apiKey ) );
}
public T permissions_checkAvailableApiAccess( String apiKey ) throws FacebookException {
return callMethod( FacebookMethod.PERM_CHECK_AVAILABLE_API_ACCESS, newPair( "permissions_apikey", apiKey ) );
}
public boolean permissions_grantApiAccess( String apiKey, Set methods ) throws FacebookException {
List> params = new ArrayList>();
if ( ( methods != null ) && ( !methods.isEmpty() ) ) {
JSONArray methodsJson = new JSONArray();
for ( FacebookMethod method : methods ) {
methodsJson.put( method.methodName() );
}
params.add( newPair( "method_arr", methodsJson ) );
}
params.add( newPair( "permissions_apikey", apiKey ) );
return extractBoolean( callMethod( FacebookMethod.PERM_GRANT_API_ACCESS, params ) );
}
public boolean permissions_grantFullApiAccess( String apiKey ) throws FacebookException {
return permissions_grantApiAccess( apiKey, null );
}
public boolean permissions_revokeApiAccess( String apiKey ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.PERM_REVOKE_API_ACCESS, newPair( "permissions_apikey", apiKey ) ) );
}
public String auth_promoteSession() throws FacebookException {
return extractString( callMethod( FacebookMethod.AUTH_PROMOTE_SESSION ) );
}
public boolean auth_revokeAuthorization() throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.AUTH_REVOKE_AUTHORIZATION ) );
}
public boolean auth_expireSession() throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.AUTH_EXPIRE_SESSION ) );
}
@Deprecated
public boolean users_isAppAdded( Long userId ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.USERS_IS_APP_ADDED_NOSESSION, newPair( "uid", userId ) ) );
}
public boolean users_setStatus( String status, Long userId ) throws FacebookException {
return users_setStatus( status, false, userId );
}
public boolean users_setStatus( String newStatus, boolean clear, Long userId ) throws FacebookException {
return users_setStatus( newStatus, clear, false, userId );
}
public boolean users_setStatus( String newStatus, boolean clear, boolean statusIncludesVerb, Long userId ) throws FacebookException {
Collection> params = new ArrayList>();
if ( newStatus != null ) {
params.add( newPair( "status", newStatus ) );
}
if ( clear ) {
params.add( newPair( "clear", "true" ) );
}
if ( statusIncludesVerb ) {
params.add( newPair( "status_includes_verb", "true" ) );
}
params.add( newPair( "uid", userId ) );
return extractBoolean( callMethod( FacebookMethod.USERS_SET_STATUS_NOSESSION, params ) );
}
public T feed_getRegisteredTemplateBundleByID( Long id ) throws FacebookException {
return callMethod( FacebookMethod.FEED_GET_TEMPLATE_BY_ID, newPair( "template_bundle_id", id ) );
}
public T feed_getRegisteredTemplateBundles() throws FacebookException {
return callMethod( FacebookMethod.FEED_GET_TEMPLATES );
}
public Boolean feed_publishUserAction( Long bundleId ) throws FacebookException {
return feed_publishUserAction( bundleId, null, null, null );
}
public Boolean feed_publishUserAction( Long bundleId, Map templateData, List targetIds, String bodyGeneral ) throws FacebookException {
return feed_publishUserAction( bundleId, templateData, null, targetIds, bodyGeneral, 0 );
}
public Long feed_registerTemplateBundle( String template ) throws FacebookException {
List temp = new ArrayList();
temp.add( template );
return feed_registerTemplateBundle( temp );
}
public Long feed_registerTemplateBundle( Collection templates ) throws FacebookException {
return feed_registerTemplateBundle( templates, null, null );
}
public Long feed_registerTemplateBundle( Collection templates, Collection shortTemplates, BundleStoryTemplate longTemplate )
throws FacebookException {
return feed_registerTemplateBundle( templates, shortTemplates, longTemplate, null );
}
public Long feed_registerTemplateBundle( Collection templates, Collection shortTemplates, BundleStoryTemplate longTemplate,
List actionLinks ) throws FacebookException {
Collection> params = new ArrayList>();
JSONArray templateArray = new JSONArray();
for ( String template : templates ) {
templateArray.put( template );
}
params.add( newPair( "one_line_story_templates", templateArray ) );
if ( shortTemplates != null && !shortTemplates.isEmpty() ) {
JSONArray shortArray = new JSONArray();
for ( BundleStoryTemplate template : shortTemplates ) {
shortArray.put( template.toJson() );
}
params.add( newPair( "short_story_templates", shortArray ) );
}
if ( longTemplate != null ) {
params.add( newPair( "full_story_template", longTemplate.toJsonString() ) );
}
if ( actionLinks != null && !actionLinks.isEmpty() ) {
JSONArray actionLinkArray = new JSONArray();
for ( BundleActionLink actionLink : actionLinks ) {
actionLinkArray.put( actionLink.toJson() );
}
params.add( newPair( "action_links", actionLinkArray ) );
}
return extractLong( callMethod( FacebookMethod.FEED_REGISTER_TEMPLATE, params ) );
}
@Deprecated
public Long feed_registerTemplateBundle( String template, String shortTemplate, String longTemplate ) throws FacebookException {
List templates = new ArrayList();
templates.add( template );
return feed_registerTemplateBundle( templates, null, null );
}
public T profile_getFBML() throws FacebookException {
return callMethod( FacebookMethod.PROFILE_GET_FBML );
}
public T profile_getFBML( Long userId ) throws FacebookException {
if ( userId != null ) {
return callMethod( FacebookMethod.PROFILE_GET_FBML_NOSESSION, newPair( "uid", userId ) );
} else {
return callMethod( FacebookMethod.PROFILE_GET_FBML );
}
}
public T profile_getFBML( int type ) throws FacebookException {
return callMethod( FacebookMethod.PROFILE_GET_FBML, newPair( "type", type ) );
}
public T profile_getFBML( int type, Long userId ) throws FacebookException {
if ( userId != null ) {
return callMethod( FacebookMethod.PROFILE_GET_FBML_NOSESSION, newPair( "type", type ), newPair( "uid", userId ) );
} else {
return callMethod( FacebookMethod.PROFILE_GET_FBML, newPair( "type", type ) );
}
}
public T profile_getInfo( Long userId ) throws FacebookException {
return callMethod( FacebookMethod.PROFILE_GET_INFO, newPair( "uid", userId ) );
}
public T profile_getInfoOptions( String field ) throws FacebookException {
return callMethod( FacebookMethod.PROFILE_GET_INFO_OPTIONS, newPair( "field", field ) );
}
public void profile_setInfo( Long userId, String title, boolean textOnly, List fields ) throws FacebookException {
Collection> params = new ArrayList>();
JSONArray json = new JSONArray();
params.add( newPair( "uid", userId ) );
params.add( newPair( "title", title ) );
if ( textOnly ) {
params.add( newPair( "type", "1" ) );
} else {
params.add( newPair( "type", "5" ) );
}
for ( ProfileInfoField field : fields ) {
try {
JSONObject innerJSON = new JSONObject();
JSONArray fieldItems = new JSONArray();
innerJSON.put( "field", field.getFieldName() );
for ( ProfileFieldItem item : field.getItems() ) {
JSONObject itemJSON = new JSONObject();
for ( String key : item.getMap().keySet() ) {
itemJSON.put( key, item.getMap().get( key ) );
}
fieldItems.put( itemJSON );
}
innerJSON.put( "items", fieldItems );
json.put( innerJSON );
}
catch ( Exception ex ) {
throw runtimeException( ex );
}
}
params.add( newPair( "info_fields", json ) );
callMethod( FacebookMethod.PROFILE_SET_INFO, params );
}
public void profile_setInfoOptions( ProfileInfoField field ) throws FacebookException {
JSONArray json = new JSONArray();
for ( ProfileFieldItem item : field.getItems() ) {
JSONObject itemJSON = new JSONObject();
for ( String key : item.getMap().keySet() ) {
try {
itemJSON.put( key, item.getMap().get( key ) );
}
catch ( Exception ex ) {
throw runtimeException( ex );
}
}
json.put( itemJSON );
}
Collection> params = new ArrayList>( 2 );
addParam( "field", field.getFieldName(), params );
addParam( "options", json.toString(), params );
callMethod( FacebookMethod.PROFILE_SET_INFO_OPTIONS, params );
}
public boolean profile_setFBML( CharSequence profileFbmlMarkup, CharSequence profileActionFbmlMarkup ) throws FacebookException {
return profile_setFBML( null, toString( profileFbmlMarkup ), toString( profileActionFbmlMarkup ), null, null );
}
public boolean profile_setFBML( CharSequence profileFbmlMarkup, CharSequence profileActionFbmlMarkup, Long profileId ) throws FacebookException {
return profile_setFBML( profileId, toString( profileFbmlMarkup ), toString( profileActionFbmlMarkup ), null, null );
}
public boolean profile_setFBML( CharSequence profileFbmlMarkup, CharSequence profileActionFbmlMarkup, CharSequence mobileFbmlMarkup ) throws FacebookException {
return profile_setFBML( null, toString( profileFbmlMarkup ), toString( profileActionFbmlMarkup ), toString( mobileFbmlMarkup ), null );
}
public boolean profile_setFBML( CharSequence profileFbmlMarkup, CharSequence profileActionFbmlMarkup, CharSequence mobileFbmlMarkup, Long profileId )
throws FacebookException {
return profile_setFBML( profileId, toString( profileFbmlMarkup ), toString( profileActionFbmlMarkup ), toString( mobileFbmlMarkup ), null );
}
public boolean profile_setMobileFBML( CharSequence fbmlMarkup ) throws FacebookException {
return profile_setFBML( null, null, null, toString( fbmlMarkup ), null );
}
public boolean profile_setMobileFBML( CharSequence fbmlMarkup, Long profileId ) throws FacebookException {
return profile_setFBML( profileId, null, null, toString( fbmlMarkup ), null );
}
public boolean profile_setProfileActionFBML( CharSequence fbmlMarkup ) throws FacebookException {
return profile_setFBML( null, null, toString( fbmlMarkup ), null, null );
}
public boolean profile_setProfileActionFBML( CharSequence fbmlMarkup, Long profileId ) throws FacebookException {
return profile_setFBML( profileId, null, toString( fbmlMarkup ), null, null );
}
public boolean profile_setProfileFBML( CharSequence fbmlMarkup ) throws FacebookException {
return profile_setFBML( null, toString( fbmlMarkup ), null, null, null );
}
public boolean profile_setProfileFBML( CharSequence fbmlMarkup, Long profileId ) throws FacebookException {
return profile_setFBML( profileId, toString( fbmlMarkup ), null, null, null );
}
public boolean profile_setFBML( Long userId, String profileFbml, String actionFbml, String mobileFbml ) throws FacebookException {
return profile_setFBML( userId, profileFbml, actionFbml, mobileFbml, null );
}
public boolean profile_setFBML( Long userId, String profileFbml, String actionFbml, String mobileFbml, String profileMain ) throws FacebookException {
Collection> params = new ArrayList>( 5 );
addParamIfNotBlank( "uid", userId, params );
addParamIfNotBlank( "profile", profileFbml, params );
addParamIfNotBlank( "profile_action", actionFbml, params );
addParamIfNotBlank( "mobile_fbml", mobileFbml, params );
addParamIfNotBlank( "profile_main", profileMain, params );
FacebookMethod method = ( isDesktop() || userId == null ) ? FacebookMethod.PROFILE_SET_FBML : FacebookMethod.PROFILE_SET_FBML_NOSESSION;
return extractBoolean( callMethod( method, params ) );
}
public void setServerUrl( String newUrl ) {
String base = newUrl;
if ( base.startsWith( "http" ) ) {
base = base.substring( base.indexOf( "://" ) + 3 );
}
try {
String url = "http://" + base;
_serverUrl = new URL( url );
setDefaultServerUrl( _serverUrl );
}
catch ( MalformedURLException ex ) {
throw runtimeException( ex );
}
}
public URL getDefaultServerUrl() {
return SERVER_URL;
}
public void setDefaultServerUrl( URL newUrl ) {
SERVER_URL = newUrl;
}
public Boolean liveMessage_send( Long recipient, String eventName, JSONObject message ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.LIVEMESSAGE_SEND, newPair( "recipient", recipient ), newPair( "event_name", eventName ), newPair( "message",
message ) ) );
}
public boolean feed_deactivateTemplateBundleByID( Long bundleId ) throws FacebookException {
return extractBoolean( callMethod( FacebookMethod.FEED_DEACTIVATE_TEMPLATE_BUNDLE, newPair( "template_bundle_id", bundleId ) ) );
}
public void notifications_send( Collection recipientIds, String notification, boolean isAppToUser ) throws FacebookException {
if ( null == notification || "".equals( notification ) ) {
throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "You cannot send an empty notification!" );
}
Pair type = newPair( "type", isAppToUser ? "app_to_user" : "user_to_user" );
if ( ( recipientIds != null ) && ( !recipientIds.isEmpty() ) ) {
callMethod( FacebookMethod.NOTIFICATIONS_SEND, newPair( "to_ids", delimit( recipientIds ) ), newPair( "notification", notification ), type );
} else {
callMethod( FacebookMethod.NOTIFICATIONS_SEND, newPair( "notification", notification ), type );
}
}
public Boolean feed_publishUserAction( Long bundleId, Map templateData, List images, List targetIds, String bodyGeneral,
int storySize ) throws FacebookException {
// validate maximum of 4 images
if ( images != null && images.size() > 4 ) {
throw new IllegalArgumentException( "Maximum of 4 images allowed per feed item." );
}
Collection> params = new ArrayList>();
params.add( newPair( "template_bundle_id", bundleId ) );
if ( targetIds != null && !targetIds.isEmpty() ) {
params.add( newPair( "target_ids", delimit( targetIds ) ) );
}
if ( bodyGeneral != null && !"".equals( bodyGeneral ) ) {
params.add( newPair( "body_general", bodyGeneral ) );
}
if ( storySize == 1 || storySize == 2 || storySize == 4 ) {
params.add( newPair( "story_size", storySize ) );
}
JSONObject jsonTemplateData = new JSONObject();
if ( templateData != null && !templateData.isEmpty() ) {
for ( String key : templateData.keySet() ) {
try {
jsonTemplateData.put( key, templateData.get( key ) );
}
catch ( Exception exception ) {
throw runtimeException( exception );
}
}
}
/*
* Associate images to "images" label in the form of:
*
* "images":[{"src":"http:\/\/www.facebook.com\/images\/image1.gif", "href":"http:\/\/www.facebook.com"}, {"src":"http:\/\/www.facebook.com\/images\/image2.gif",
* "href":"http:\/\/www.facebook.com"}]
*/
if ( images != null && !images.isEmpty() ) {
try {
// create images array
JSONArray jsonArray = new JSONArray();
for ( int i = 0; i < images.size(); i++ ) {
IFeedImage image = images.get( i );
JSONObject jsonImage = new JSONObject();
jsonImage.put( "src", image.getImageUrlString() );
jsonImage.put( "href", image.getLinkUrl().toExternalForm() );
jsonArray.put( i, jsonImage );
}
// associate to key label
jsonTemplateData.put( "images", jsonArray );
}
catch ( Exception exception ) {
throw runtimeException( exception );
}
}
// associate to param
if ( jsonTemplateData.length() > 0 ) {
params.add( newPair( "template_data", jsonTemplateData ) );
}
return extractBoolean( callMethod( FacebookMethod.FEED_PUBLISH_USER_ACTION, params ) );
}
// ========== HELPERS ==========
protected static void disconnect( HttpURLConnection conn ) {
if ( conn != null ) {
conn.disconnect();
}
}
protected static void close( Closeable c ) {
if ( c != null ) {
try {
c.close();
}
catch ( IOException ex ) {
log.warn( "Trouble closing connection", ex );
}
}
}
protected static RuntimeException runtimeException( Exception ex ) {
if ( ! ( ex instanceof RuntimeException ) ) {
return new RuntimeException( ex );
}
return (RuntimeException) ex;
}
/**
* Prints out the DOM tree.
*
* @param n
* the parent node to start printing from
* @param prefix
* string to append to output, should not be null
*/
protected static void printDom( Node n, String prefix, StringBuilder sb ) {
String outString = prefix;
if ( n.getNodeType() == Node.TEXT_NODE ) {
outString += "'" + n.getTextContent().trim() + "'";
} else {
outString += n.getNodeName();
}
sb.append( outString );
sb.append( "\n" );
NodeList children = n.getChildNodes();
int length = children.getLength();
for ( int i = 0; i < length; i++ ) {
printDom( children.item( i ), prefix + " ", sb );
}
}
protected static Pair newPair( String name, Object value ) {
return new Pair( name, String.valueOf( value ) );
}
@Deprecated
protected static Pair newPair( String name, boolean value ) {
return newPair10( name, value );
}
protected static Pair newPair10( String name, boolean value ) {
return newPair( name, value ? "1" : "0" );
}
protected static Pair newPairTF( String name, boolean value ) {
return newPair( name, value ? "true" : "false" );
}
protected static Pair newPair( String name, CharSequence value ) {
return new Pair( name, value );
}
protected static Pair newPair( String name, Long value ) {
return new Pair( name, Long.toString( value ) );
}
protected static Pair newPair( String name, Integer value ) {
return new Pair( name, Integer.toString( value ) );
}
protected static boolean addParam( String name, Long value, Collection> params ) {
params.add( newPair( name, value ) );
return true;
}
protected static boolean addParamIfNotBlank( String name, Long value, Collection> params ) {
if ( value != null ) {
return addParam( name, value, params );
}
return false;
}
protected static boolean addParamSecondsIfNotBlank( String name, Date value, Collection> params ) {
if ( value != null ) {
return addParam( name, value.getTime() / 1000, params );
}
return false;
}
protected static boolean addParamIfNotBlankZero( String name, Long value, Collection> params ) {
if ( value != null && value.longValue() != 0 ) {
return addParam( name, value, params );
}
return false;
}
protected static boolean addParamDelimitIfNotBlankEmpty( String name, Iterable value, Collection> params ) {
return addParamIfNotBlank( name, delimit( value ), params );
}
protected static boolean addParam( String name, Object value, Collection> params ) {
params.add( newPair( name, value ) );
return true;
}
protected static boolean addParam( String name, CharSequence value, Collection> params ) {
params.add( newPair( name, value ) );
return true;
}
protected static boolean addParamIfNotBlank( String name, CharSequence value, Collection> params ) {
if ( ( value != null ) && ( !"".equals( value ) ) ) {
params.add( newPair( name, value ) );
return true;
}
return false;
}
protected static String toString( CharSequence cs ) {
return cs == null ? null : cs.toString();
}
protected static JSONObject toJson( Map map ) {
return new JSONObject( map );
}
protected static JSONArray toJsonListOfStrings( Collection list ) {
return new JSONArray( list );
}
protected static JSONArray toJsonListOfMaps( Collection
© 2015 - 2024 Weber Informatics LLC | Privacy Policy