Java tutorial
/* * Copyright (C) 2013-2014 Tan Jung * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package illab.nabal.proxy; import illab.nabal.agent.Operation; import illab.nabal.agent.dto.WeiboPost; import illab.nabal.agent.dto.WeiboProfile; import illab.nabal.exception.NetworkException; import illab.nabal.exception.SystemException; import illab.nabal.settings.SnsProperties; import illab.nabal.settings.SocialNetwork; import illab.nabal.settings.SystemProperties; import illab.nabal.util.ParameterHelper; import illab.nabal.util.StringHelper; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONObject; import android.content.Context; import android.text.TextUtils; /** * Implementations of Weibo APIs. * * @version 1.0, 02/10/14 * @author <a href="mailto:tanito.jung@gmail.com">Tan Jung</a> */ class WeiboProxy extends AbstractProxy implements WeiboDelegate { //private final static String TAG = "WeiboProxy"; /** * Weibo web domain. */ private final static String WEB_HOME_URL = "http://weibo.com/"; /** * Dummy integer parameter for unspecified count. */ private final static int UNSPECIFIED_COUNT = 0; /** * Dummy integer parameter for unspecified cursor. */ private final static int UNSPECIFIED_CURSOR = -1; /** * Dummy integer parameter for unspecified page. */ private final static int UNSPECIFIED_PAGE = 0; /** * Dummy integer parameter for unspecified post ID. */ private final static long UNSPECIFIED_POST_ID = -1L; /** * Weibo network context. */ private final WeiboContext mWeiboContext; /** * Constructor for Weibo covert op proxy. * * @param context * @param systemProperties * @param snsProperties */ WeiboProxy(Context context, SystemProperties systemProperties, SnsProperties snsProperties) { mContext = context; mWeiboContext = (WeiboContext) (mNetworkContext = new WeiboContext(mContext, new NetworkSessionListener(), systemProperties, snsProperties)); } /** * Constructor for Weibo proxy. * * @param alias * @param context * @param systemProperties * @param snsProperties */ WeiboProxy(String alias, Context context, SystemProperties systemProperties, SnsProperties snsProperties) { mContext = context; mWeiboContext = (WeiboContext) (mNetworkContext = new WeiboContext(alias, mContext, new NetworkSessionListener(), systemProperties, snsProperties)); } /** * Inject a Weibo session. * * @param accessToken */ void injectSession(String accessToken) { mWeiboContext.injectSession(accessToken); } /* START OF ***************** API implementations ***********************/ @Override public void getMyProfile(final Operation<WeiboDelegate, WeiboProfile> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getProfileByUid("")); } catch (Exception e) { onFail(e); } } }); } @Override public void getProfileByUid(final Operation<WeiboDelegate, WeiboProfile> operation, final String userUid) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getProfileByUid(userUid)); } catch (Exception e) { onFail(e); } } }); } @Override public void getProfileByDomain(final Operation<WeiboDelegate, WeiboProfile> operation, final String domainName) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getProfileByDomain(domainName)); } catch (Exception e) { onFail(e); } } }); } @Override public void getFriendCount(final Operation<WeiboDelegate, JSONArray> operation, final String[] userUids) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getFriendCount(userUids)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllMyFriendUids(final Operation<WeiboDelegate, JSONObject> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFriendUids(UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyFriendUids(final Operation<WeiboDelegate, JSONObject> operation, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFriendUids(count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllMyFriends(final Operation<WeiboDelegate, List<WeiboProfile>> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFriends(UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyFriends(final Operation<WeiboDelegate, List<WeiboProfile>> operation, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFriends(count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllMyBilateralFriendUids(final Operation<WeiboDelegate, JSONObject> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyBilateralFriendUids(UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyBilateralFriendUids(final Operation<WeiboDelegate, JSONObject> operation, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyBilateralFriendUids(count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllMyBilateralFriends(final Operation<WeiboDelegate, List<WeiboProfile>> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyBilateralFriends(UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyBilateralFriends(final Operation<WeiboDelegate, List<WeiboProfile>> operation, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyBilateralFriends(count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllCommonFriends(final Operation<WeiboDelegate, List<WeiboProfile>> operation, final String userUid) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getCommonFriends(userUid, UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getCommonFriends(final Operation<WeiboDelegate, List<WeiboProfile>> operation, final String userUid, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getCommonFriends(userUid, count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllMyFollowerUids(final Operation<WeiboDelegate, JSONObject> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFollowerUids(UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyFollowerUids(final Operation<WeiboDelegate, JSONObject> operation, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFollowerUids(count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getAllMyFollowers(final Operation<WeiboDelegate, List<WeiboProfile>> operation) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFollowers(UNSPECIFIED_COUNT, UNSPECIFIED_CURSOR)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyFollowers(final Operation<WeiboDelegate, List<WeiboProfile>> operation, final int count, final int cursor) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMyFollowers(count, cursor)); } catch (Exception e) { onFail(e); } } }); } @Override public void getRelationship(final Operation<WeiboDelegate, JSONObject> operation, final String sourceUserUid, final String targetUserUid) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getRelationship(sourceUserUid, targetUserUid)); } catch (Exception e) { onFail(e); } } }); } @Override public void followUser(final Operation<WeiboDelegate, WeiboProfile> operation, final String userUid) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(followUser(userUid)); } catch (Exception e) { onFail(e); } } }); } @Override public void unfollowUser(final Operation<WeiboDelegate, WeiboProfile> operation, final String userUid) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(unfollowUser(userUid)); } catch (Exception e) { onFail(e); } } }); } @Override public void remarkFriend(final Operation<WeiboDelegate, WeiboProfile> operation, final String userUid, final String remark) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(remarkFriend(userUid, remark)); } catch (Exception e) { onFail(e); } } }); } @Override public void getHomeTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final int count, final int page, final int feature) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult( getHomeTimeline(UNSPECIFIED_POST_ID, UNSPECIFIED_POST_ID, count, page, feature)); } catch (Exception e) { onFail(e); } } }); } @Override public void getHomeTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page, final int feature) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getHomeTimeline(sincePostId, maxPostId, count, page, feature)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final int count, final int page, final int feature, final boolean needUserData) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getUserTimeline("", UNSPECIFIED_POST_ID, UNSPECIFIED_POST_ID, count, page, feature, needUserData)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMyTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page, final int feature, final boolean needUserData) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult( getUserTimeline("", sincePostId, maxPostId, count, page, feature, needUserData)); } catch (Exception e) { onFail(e); } } }); } @Override public void getUserTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final String userUid, final int count, final int page, final int feature, final boolean needUserData) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getUserTimeline(userUid, UNSPECIFIED_POST_ID, UNSPECIFIED_POST_ID, count, page, feature, needUserData)); } catch (Exception e) { onFail(e); } } }); } @Override public void getUserTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final String userUid, final long sincePostId, final long maxPostId, final int count, final int page, final int feature, final boolean needUserData) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult( getUserTimeline(userUid, sincePostId, maxPostId, count, page, feature, needUserData)); } catch (Exception e) { onFail(e); } } }); } @Override public void getRepostTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long originalPostId, final int count, final int page, final int authorFilter) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getRepostTimeline(originalPostId, UNSPECIFIED_POST_ID, UNSPECIFIED_POST_ID, count, page, authorFilter)); } catch (Exception e) { onFail(e); } } }); } @Override public void getRepostTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long originalPostId, final long sincePostId, final long maxPostId, final int count, final int page, final int authorFilter) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult( getRepostTimeline(originalPostId, sincePostId, maxPostId, count, page, authorFilter)); } catch (Exception e) { onFail(e); } } }); } @Override public void getRepostsByMe(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getRepostsByMe(sincePostId, maxPostId, count, page)); } catch (Exception e) { onFail(e); } } }); } @Override public void getMentions(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page, final int authorFilter, final int sourceFilter, final int typeFilter) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getMentions(sincePostId, maxPostId, count, page, authorFilter, sourceFilter, typeFilter)); } catch (Exception e) { onFail(e); } } }); } @Override public void getBilateralFriendTimeline(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page, final int feature) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getBilateralFriendTimeline(sincePostId, maxPostId, count, page, feature)); } catch (Exception e) { onFail(e); } } }); } @Override public void getPost(final Operation<WeiboDelegate, WeiboPost> operation, final long postId) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getPost(postId)); } catch (Exception e) { onFail(e); } } }); } @Override public void postStatus(final Operation<WeiboDelegate, WeiboPost> operation, final String status, final float latitude, final float longitude, final JSONArray annotations) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(postStatus(status, latitude, longitude, annotations)); } catch (Exception e) { onFail(e); } } }); } @Override public void repostStatus(final Operation<WeiboDelegate, WeiboPost> operation, final long originalPostId, final String status, final int commentOption) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(repostStatus(originalPostId, status, commentOption)); } catch (Exception e) { onFail(e); } } }); } @Override public void deleteStatus(final Operation<WeiboDelegate, WeiboPost> operation, final long postId) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(deleteStatus(postId)); } catch (Exception e) { onFail(e); } } }); } @Override public void postPhoto(final Operation<WeiboDelegate, WeiboPost> operation, final String absolutePathOfPhoto, final String status, final float latitude, final float longitude, final JSONArray annotations) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(postPhoto(absolutePathOfPhoto, status, latitude, longitude, annotations)); } catch (Exception e) { onFail(e); } } }); } @Override public void postPhotoFromUrl(final Operation<WeiboDelegate, WeiboPost> operation, final String photoUrl, final String status, final float latitude, final float longitude, final JSONArray annotations) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(postPhotoFromUrl(photoUrl, status, latitude, longitude, annotations)); } catch (Exception e) { onFail(e); } } }); } @Override public void getComments(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long parentPostId, final long sincePostId, final long maxPostId, final int count, final int page, final int authorFilter) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation .onResult(getComments(parentPostId, sincePostId, maxPostId, count, page, authorFilter)); } catch (Exception e) { onFail(e); } } }); } @Override public void getCommentsByMe(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page, final int sourceFilter) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(getCommentsByMe(sincePostId, maxPostId, count, page, sourceFilter)); } catch (Exception e) { onFail(e); } } }); } @Override public void getCommentsToMe(final Operation<WeiboDelegate, List<WeiboPost>> operation, final long sincePostId, final long maxPostId, final int count, final int page, final int authorFilter, final int sourceFilter) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult( getCommentsToMe(sincePostId, maxPostId, count, page, authorFilter, sourceFilter)); } catch (Exception e) { onFail(e); } } }); } @Override public void postComment(final Operation<WeiboDelegate, WeiboPost> operation, final long parentPostId, final String comment, final int commentOption) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(postComment(parentPostId, comment, commentOption)); } catch (Exception e) { onFail(e); } } }); } @Override public void deleteComment(final Operation<WeiboDelegate, WeiboPost> operation, final long commentId) { requestJob(new ProxyJob() { public void onFail(Exception e) { operation.onFail(e); } public void run() { try { operation.onResult(deleteComment(commentId)); } catch (Exception e) { onFail(e); } } }); } /** * Get a Weibo profile corresponding to given UID. * * @param userUid * @return WeiboProfile * @throws Exception */ private WeiboProfile getProfileByUid(String userUid) throws Exception { String apiUri = "/users/show.json"; // if no user UID is assigned, use the current user's UID String uid = userUid; if (StringHelper.isEmpty(uid) == true) { uid = mWeiboContext.getUid(); } return populateProfileBean(getResponseJson( getHttpGet(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", uid)))); } /** * Get a Weibo profile corresponding to given Weibo URL. * * @param domainName * @return WeiboProfile * @throws Exception */ private WeiboProfile getProfileByDomain(String domainName) throws Exception { String apiUri = "/users/domain_show.json"; // throw an exception if no domain name is given if (domainName == null || domainName.length() == 0) { throw new SystemException("Invalid domain name."); } // get rid of host in case full URL is given // (e.g. http://weibo.com/myweibodomain -> myweibodomain) String domain = domainName.replace(WEB_HOME_URL, ""); return populateProfileBean(getResponseJson( getHttpGet(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("domain", domain)))); } /** * Get Weibo users' friend count. * * @param userUids * @return JSONArray * @throws Exception */ private JSONArray getFriendCount(String[] userUids) throws Exception { String apiUri = "/users/counts.json"; // throw an exception if no user UID is given if (userUids == null || userUids.length == 0) { throw new SystemException("Invalid user UIDs."); } // join user UIDs and make a CSV String commaSeparatedUids = TextUtils.join(",", userUids); return getJsonArray(getResponseString( getHttpGet(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uids", commaSeparatedUids)))); } /** * Get UIDs of my Weibo friends. * * @param count how many friends per page * @param cursor where to start indexing pages * @return JSONObject * @throws Exception */ private JSONObject getMyFriendUids(int count, int cursor) throws Exception { String apiUri = "/friendships/friends/ids.json"; List<NameValuePair> params = ParameterHelper .addAllParams(new BasicNameValuePair("access_token", mWeiboContext.getAccessToken())); // set page parameters setProfilePageParams(params, count, cursor); return getResponseJson(getHttpGet(apiUri, params)); } /** * Get my Weibo friends. * * @param count how many friends per page * @param cursor where to start indexing pages * @return list of WeiboProfile objects * @throws Exception */ private List<WeiboProfile> getMyFriends(int count, int cursor) throws Exception { String apiUri = "/friendships/friends.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", mWeiboContext.getUid())); // set page parameters setProfilePageParams(params, count, cursor); return populateProfileList(getResponseJson(getHttpGet(apiUri, params))); } /** * Get UIDs of my bilateral Weibo friends. * * @param count how many friends per page * @param cursor where to start indexing pages * @return JSONObject * @throws Exception */ private JSONObject getMyBilateralFriendUids(int count, int cursor) throws Exception { String apiUri = "/friendships/friends/bilateral/ids.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", mWeiboContext.getUid())); // set page parameters setProfilePageParams(params, count, cursor); return getResponseJson(getHttpGet(apiUri, params)); } /** * Get my bilateral Weibo friends. * * @param count how many friends per page * @param cursor where to start indexing pages * @return list of WeiboProfile objects * @throws Exception */ private List<WeiboProfile> getMyBilateralFriends(int count, int cursor) throws Exception { String apiUri = "/friendships/friends/bilateral.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", mWeiboContext.getUid())); // set page parameters setProfilePageParams(params, count, cursor); return populateProfileList(getResponseJson(getHttpGet(apiUri, params))); } /** * Get common friends between given UID. * * @param count how many friends per page * @param cursor where to start indexing pages * @return list of WeiboProfile objects * @throws Exception */ private List<WeiboProfile> getCommonFriends(String userUid, int count, int cursor) throws Exception { String apiUri = "/friendships/friends/in_common.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", mWeiboContext.getUid()), new BasicNameValuePair("suid", userUid)); // set page parameters setProfilePageParams(params, count, cursor); return populateProfileList(getResponseJson(getHttpGet(apiUri, params))); } /** * Get UIDs of my Weibo followers. * * @param count how many followers per page * @param cursor where to start indexing pages * @return JSONObject * @throws Exception */ private JSONObject getMyFollowerUids(int count, int cursor) throws Exception { String apiUri = "/friendships/followers/ids.json"; List<NameValuePair> params = ParameterHelper .addAllParams(new BasicNameValuePair("access_token", mWeiboContext.getAccessToken())); // set page parameters setProfilePageParams(params, count, cursor); return getResponseJson(getHttpGet(apiUri, params)); } /** * Get my Weibo followers. * * @param count how many followers per page * @param cursor where to start indexing pages * @return list of WeiboProfile objects * @throws Exception */ private List<WeiboProfile> getMyFollowers(int count, int cursor) throws Exception { String apiUri = "/friendships/followers.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", mWeiboContext.getUid())); // set page parameters setProfilePageParams(params, count, cursor); return populateProfileList(getResponseJson(getHttpGet(apiUri, params))); } /** * Get relationship of two Weibo users. * * @param sourceUserUid * @param targetUserUid * @return JSONObject * @throws Exception */ private JSONObject getRelationship(String sourceUserUid, String targetUserUid) throws Exception { String apiUri = "/friendships/show.json"; if (StringHelper.isAllFull(sourceUserUid, targetUserUid) == false) { throw new SystemException("Invalid user UIDs."); } return getResponseJson( getHttpGet(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("source_id", sourceUserUid), new BasicNameValuePair("target_id", targetUserUid))); } /** * Follow a Weibo user. * * @param userUid * @return WeiboProfile * @throws Exception */ private WeiboProfile followUser(String userUid) throws Exception { String apiUri = "/friendships/create.json"; return populateProfileBean(getResponseJson( getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", userUid)))); } /** * Unfollow a Weibo user. * * @param userUid * @return WeiboProfile * @throws Exception */ private WeiboProfile unfollowUser(String userUid) throws Exception { String apiUri = "/friendships/destroy.json"; return populateProfileBean(getResponseJson( getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", userUid)))); } /** * Update a remark of a Weibo friend. * * @param userUid * @param remark * @return WeiboProfile * @throws Exception */ private WeiboProfile remarkFriend(String userUid, String remark) throws Exception { String apiUri = "/friendships/remark/update.json"; return populateProfileBean(getResponseJson( getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", userUid), new BasicNameValuePair("remark", remark)))); } /** * Get home timeline of posts posted by me and my Weibo friends. * * @param sincePostId * @param maxPostId * @param count * @param page * @param feature * @return list of WeiboPost objects * @throws Exception */ private List<WeiboPost> getHomeTimeline(long sincePostId, long maxPostId, int count, int page, int feature) throws Exception { String apiUri = "/statuses/home_timeline.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("feature", "" + feature)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("statuses", getResponseJson(getHttpGet(apiUri, params))); } /** * Get user's timeline. * * @param userUid * @param sincePostId * @param maxPostId * @param count * @param page * @param feature * @param needUserData * @return list of WeiboPost objects * @throws Exception */ private List<WeiboPost> getUserTimeline(String userUid, long sincePostId, long maxPostId, int count, int page, int feature, boolean needUserData) throws Exception { String apiUri = "/statuses/user_timeline.json"; // if no user UID is assigned, use the current user's UID String uid = userUid; if (StringHelper.isEmpty(uid) == true) { uid = mWeiboContext.getUid(); } List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("uid", uid), new BasicNameValuePair("feature", "" + feature), new BasicNameValuePair("trim_user", (needUserData) ? "0" : "1")); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("statuses", getResponseJson(getHttpGet(apiUri, params))); } /** * Get repost timeline. * * @param originalPostId * @param sincePostId * @param maxPostId * @param count * @param page * @param authorFilter * @return list of WeiboPost objects * @throws Exception */ private List<WeiboPost> getRepostTimeline(long originalPostId, long sincePostId, long maxPostId, int count, int page, int authorFilter) throws Exception { String apiUri = "/statuses/repost_timeline.json"; // throw an exception if original post ID is invalid if (originalPostId <= 0) { throw new SystemException("Invalid original post Id."); } List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("id", "" + originalPostId), new BasicNameValuePair("filter_by_author", "" + authorFilter)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("reposts", getResponseJson(getHttpGet(apiUri, params))); } /** * Get reposted posts by me. * * @param sincePostId * @param maxPostId * @param count * @param page * @return list of posts reposted by me * @throws Exception */ private List<WeiboPost> getRepostsByMe(long sincePostId, long maxPostId, int count, int page) throws Exception { String apiUri = "/statuses/repost_by_me.json"; List<NameValuePair> params = ParameterHelper .addAllParams(new BasicNameValuePair("access_token", mWeiboContext.getAccessToken())); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("reposts", getResponseJson(getHttpGet(apiUri, params))); } /** * Get posts mentioned me. * * @param sincePostId * @param maxPostId * @param count * @param page * @param authorFilter * @param sourceFilter * @param typeFilter * @return list of posts mentioned me * @throws Exception */ private List<WeiboPost> getMentions(long sincePostId, long maxPostId, int count, int page, int authorFilter, int sourceFilter, int typeFilter) throws Exception { String apiUri = "/statuses/mentions.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("filter_by_author", "" + authorFilter), new BasicNameValuePair("filter_by_source", "" + sourceFilter), new BasicNameValuePair("filter_by_type", "" + typeFilter)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("statuses", getResponseJson(getHttpGet(apiUri, params))); } /** * Get posts from bialteral friends. * * @param sincePostId * @param maxPostId * @param count * @param page * @param feature * @return list of WeiboPost objects * @throws Exception */ private List<WeiboPost> getBilateralFriendTimeline(long sincePostId, long maxPostId, int count, int page, int feature) throws Exception { String apiUri = "/statuses/bilateral_timeline.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("feature", "" + feature)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("statuses", getResponseJson(getHttpGet(apiUri, params))); } /** * Get a Weibo post. * * @param postId * @return a Weibo post corresponding to given post ID * @throws Exception */ private WeiboPost getPost(long postId) throws Exception { String apiUri = "/statuses/show.json"; return populatePostBean(getResponseJson( getHttpGet(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("id", "" + postId)))); } /** * Post a Weibo post. * * @param message * @param latitude from -90.0 to +90.0; +: North latitude;Default is 0.0 * @param longitude from -180.0 to +180.0; +: East longitude;Default is 0.0 * @param annotations notes/metadatas for your application * @return a WeiboPost object cotaining content you've just posted * @throws Exception */ private WeiboPost postStatus(String message, float latitude, float longitude, JSONArray annotations) throws Exception { String apiUri = "/statuses/update.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("status", message), new BasicNameValuePair("lat", "" + latitude), new BasicNameValuePair("long", "" + longitude)); if (annotations != null && annotations.length() > 0) { params.add(new BasicNameValuePair("annotations", annotations.toString())); } return populatePostBean(getResponseJson(getHttpPost(apiUri, params))); } /** * Repost a Weibo post. * * @param originalPostId * @param message * @param commentOption * @return a WeiboPost object cotaining content you've just reposted * @throws Exception */ private WeiboPost repostStatus(long originalPostId, String message, int commentOption) throws Exception { String apiUri = "/statuses/repost.json"; // throw an exception if original post ID is invalid if (originalPostId <= 0) { throw new SystemException("Invalid original post Id."); } return populatePostBean(getResponseJson(getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("id", "" + originalPostId), new BasicNameValuePair("status", message), new BasicNameValuePair("is_comment", "" + commentOption)))); } /** * Delete a Weibo post. * * @param postId * @return a WeiboPost object cotaining post data you've just deleted * @throws Exception */ private WeiboPost deleteStatus(long postId) throws Exception { String apiUri = "/statuses/destroy.json"; // throw an exception if post ID is invalid if (postId <= 0) { throw new SystemException("Invalid post Id."); } return populatePostBean(getResponseJson( getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("id", "" + postId)))); } /** * Post a photo. * * @param absolutePathOfPhoto * @param message * @param latitude * @param longitude * @param annotations * @return a WeiboPost object cotaining post data you've just created * @throws Exception */ private WeiboPost postPhoto(String absolutePathOfPhoto, String message, float latitude, float longitude, JSONArray annotations) throws Exception { String apiUri = "/statuses/upload.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("status", message), new BasicNameValuePair("lat", "" + latitude), new BasicNameValuePair("long", "" + longitude)); if (annotations != null && annotations.length() > 0) { params.add(new BasicNameValuePair("annotations", annotations.toString())); } return populatePostBean(getResponseJson(getMultipartHttpPost(apiUri, params, "pic", absolutePathOfPhoto))); } /** * Post a photo. * * @param photoUrl * @param message * @param latitude * @param longitude * @param annotations * @return a WeiboPost object cotaining post data you've just created * @throws Exception */ private WeiboPost postPhotoFromUrl(String photoUrl, String message, float latitude, float longitude, JSONArray annotations) throws Exception { String apiUri = "/statuses/upload_url_text.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("url", photoUrl), new BasicNameValuePair("status", message), new BasicNameValuePair("lat", "" + latitude), new BasicNameValuePair("long", "" + longitude)); if (annotations != null && annotations.length() > 0) { params.add(new BasicNameValuePair("annotations", annotations.toString())); } return populatePostBean(getResponseJson(getHttpPost(apiUri, params))); } /** * Get comments. * * @param parentPostId * @param sincePostId * @param maxPostId * @param count * @param page * @param authorFilter * @return list of comments attached to given post ID * @throws Exception */ private List<WeiboPost> getComments(long parentPostId, long sincePostId, long maxPostId, int count, int page, int authorFilter) throws Exception { String apiUri = "/comments/show.json"; // throw an exception if parent post ID is invalid if (parentPostId <= 0) { throw new SystemException("Invalid parent post Id."); } List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("id", "" + parentPostId), new BasicNameValuePair("filter_by_author", "" + authorFilter)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("comments", getResponseJson(getHttpGet(apiUri, params))); } /** * Get comments by me. * * @param sincePostId * @param maxPostId * @param count * @param page * @param sourceFilter * @return list of comments created by me * @throws Exception */ private List<WeiboPost> getCommentsByMe(long sincePostId, long maxPostId, int count, int page, int sourceFilter) throws Exception { String apiUri = "/comments/by_me.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("filter_by_source", "" + sourceFilter)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("comments", getResponseJson(getHttpGet(apiUri, params))); } /** * Get comments by me. * * @param sincePostId * @param maxPostId * @param count * @param page * @param authorFilter * @param sourceFilter * @return list of comments created to me * @throws Exception */ private List<WeiboPost> getCommentsToMe(long sincePostId, long maxPostId, int count, int page, int authorFilter, int sourceFilter) throws Exception { String apiUri = "/comments/to_me.json"; List<NameValuePair> params = ParameterHelper.addAllParams( new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("filter_by_author", "" + authorFilter), new BasicNameValuePair("filter_by_source", "" + sourceFilter)); // set page parameters setTimelinePageParams(params, sincePostId, maxPostId, count, page); return populatePostList("comments", getResponseJson(getHttpGet(apiUri, params))); } /** * Post a comment to a Weibo post. * * @param parentPostId * @param comment * @param commentOption * @return a WeiboPost object cotaining comment data you've just created * @throws Exception */ private WeiboPost postComment(long parentPostId, String comment, int commentOption) throws Exception { String apiUri = "/comments/create.json"; // throw an exception if parent post ID is invalid if (parentPostId <= 0) { throw new SystemException("Invalid parent post Id."); } return populatePostBean(getResponseJson( getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("id", "" + parentPostId), new BasicNameValuePair("comment", comment), new BasicNameValuePair("comment_ori", "" + commentOption)))); } /** * Delete a comment. * * @param commentId * @return a WeiboPost object cotaining comment data you've just deleted * @throws Exception */ private WeiboPost deleteComment(long commentId) throws Exception { String apiUri = "/comments/destroy.json"; // throw an exception if comment ID is invalid if (commentId <= 0) { throw new SystemException("Invalid comment Id."); } return populatePostBean(getResponseJson( getHttpPost(apiUri, new BasicNameValuePair("access_token", mWeiboContext.getAccessToken()), new BasicNameValuePair("cid", "" + commentId)))); } /* END OF ****************** API implementations ************************/ /** * Set count and cursor parameters for Weibo profile list. * * @param params * @param count * @param cursor * @return params */ private List<NameValuePair> setProfilePageParams(List<NameValuePair> params, int count, int cursor) { // page capacity must be greater than 0 if (count > UNSPECIFIED_COUNT) { params.add(new BasicNameValuePair("count", "" + count)); } // if cursor is given if (cursor > UNSPECIFIED_CURSOR) { params.add(new BasicNameValuePair("cursor", "" + cursor)); } return params; } /** * Set since_id, max_id, count and page parameters for Weibo timeline. * * @param params * @param sincePostId * @param maxPostId * @param count * @param page * @return params */ private List<NameValuePair> setTimelinePageParams(List<NameValuePair> params, long sincePostId, long maxPostId, int count, int page) { // if since_id is given if (sincePostId > UNSPECIFIED_POST_ID) { params.add(new BasicNameValuePair("since_id", "" + sincePostId)); } // if max_id is given if (maxPostId > UNSPECIFIED_POST_ID) { params.add(new BasicNameValuePair("max_id", "" + maxPostId)); } // page capacity must be greater than 0 if (count > UNSPECIFIED_COUNT) { params.add(new BasicNameValuePair("count", "" + count)); } // page number must be greater than 0 if (page > UNSPECIFIED_PAGE) { params.add(new BasicNameValuePair("page", "" + page)); } return params; } /** * Get WeiboProfile list from JSON array. * * @param responseJson * @return profileList * @throws Exception */ private List<WeiboProfile> populateProfileList(JSONObject responseJson) throws Exception { JSONArray profileJsonArray = responseJson.optJSONArray("users"); // profile list must not be empty if (profileJsonArray == null || profileJsonArray.length() == 0) { throw new NetworkException("Profile list is empty.", responseJson.toString()); } // iterate profile list and populate WeiboProfile beans List<WeiboProfile> profileList = new ArrayList<WeiboProfile>(); for (int i = 0; i < profileJsonArray.length(); i++) { profileList.add(populateProfileBean(profileJsonArray.getJSONObject(i))); } return profileList; } /** * Set Weibo profile data to a WeiboProfile bean. * * @param profileJson * @return a WeiboProfile bean * @throws Exception */ private WeiboProfile populateProfileBean(JSONObject profileJson) throws Exception { // throw an exception if JSON is invalid if (profileJson == null || profileJson.has("idstr") == false) { if (profileJson == null) { throw new NetworkException("Profile JSON is null and cannot populate a Profile bean."); } else { throw new NetworkException("Invalid profile JSON.", profileJson.toString()); } } // set profile data WeiboProfile weiboProfile = new WeiboProfile(); weiboProfile.setSnsUid(SocialNetwork.WEIBO); weiboProfile.setProfileJson(profileJson); weiboProfile.setUid(profileJson.optString("idstr")); weiboProfile.setUserName(profileJson.optString("screen_name")); weiboProfile.setFullName(profileJson.optString("name")); weiboProfile.setProfilePageUrl(WEB_HOME_URL + profileJson.optString("profile_url")); weiboProfile.setSmallProfilePhotoUrl(profileJson.optString("profile_image_url")); weiboProfile.setLargeProfilePhotoUrl(profileJson.optString("avatar_hd")); // set last post data if (profileJson.has("status") == true) { JSONObject postJson = profileJson.getJSONObject("status"); WeiboPost lastPost = new WeiboPost(); lastPost.setSnsUid(SocialNetwork.WEIBO); lastPost.setPostJson(postJson); lastPost.setPostId(postJson.optLong("id")); lastPost.setPosterUid(profileJson.optString("idstr")); lastPost.setPosterUserName(profileJson.optString("screen_name")); lastPost.setPosterFullName(profileJson.optString("name")); lastPost.setTextContent(postJson.optString("text")); lastPost.setRepostCount(postJson.optInt("reposts_count")); lastPost.setCommentCount(postJson.optInt("comments_count")); lastPost.setLikeCount(postJson.optInt("attitudes_count")); lastPost.setCreatedDate(postJson.optString("created_at")); weiboProfile.setLastPost(lastPost); } return weiboProfile; } /** * Get WeiboPost list from JSON array. * * @param keyName * @param responseJson * @return postList * @throws Exception */ private List<WeiboPost> populatePostList(String keyName, JSONObject responseJson) throws Exception { JSONArray postJsonArray = responseJson.optJSONArray(keyName); // post list must not be empty if (postJsonArray == null || postJsonArray.length() == 0) { throw new NetworkException("Post list is empty.", responseJson.toString()); } // iterate post list and populate WeiboPost beans List<WeiboPost> postList = new ArrayList<WeiboPost>(); for (int i = 0; i < postJsonArray.length(); i++) { postList.add(populatePostBean(postJsonArray.getJSONObject(i))); } return postList; } /** * Set Weibo post data to a WeiboPost bean. * * @param postJson * @return weiboPost * @throws Exception */ private WeiboPost populatePostBean(JSONObject postJson) throws Exception { // throw an exception if JSON is invalid if (postJson == null || postJson.has("id") == false) { if (postJson == null) { throw new NetworkException("Post JSON is null and cannot populate a Post bean."); } else { throw new NetworkException("Invalid post JSON.", postJson.toString()); } } // set post data WeiboPost weiboPost = new WeiboPost(); weiboPost.setSnsUid(SocialNetwork.WEIBO); weiboPost.setPostJson(postJson); weiboPost.setPostId(postJson.optLong("id")); weiboPost.setTextContent(postJson.optString("text")); weiboPost.setRepostCount(postJson.optInt("reposts_count")); weiboPost.setCommentCount(postJson.optInt("comments_count")); weiboPost.setLikeCount(postJson.optInt("attitudes_count")); weiboPost.setCreatedDate(postJson.optString("created_at")); // set poster profile bean if (postJson.has("user") == true) { WeiboProfile posterProfile = populateProfileBean(postJson.getJSONObject("user")); weiboPost.setPosterUid(posterProfile.getUid()); weiboPost.setPosterFullName(posterProfile.getFullName()); weiboPost.setPosterUserName(posterProfile.getUserName()); weiboPost.setPosterProfile(posterProfile); } // if user data is not provided, look up uid else { weiboPost.setPosterUid(postJson.optString("uid")); } // set image URLs if current post has attached images if (postJson.has("thumbnail_pic") == true) { weiboPost.setThumbnailPhotoUrl(postJson.optString("thumbnail_pic")); weiboPost.setMidSizePhotoUrl(postJson.optString("bmiddle_pic")); weiboPost.setFullSizePhotoUrl(postJson.optString("original_pic")); } // set original post if current post is a repost if (postJson.has("retweeted_status") == true) { weiboPost.setOriginalPost(populatePostBean(postJson.getJSONObject("retweeted_status"))); } // set parent post if current post is a comment if (postJson.has("status") == true) { weiboPost.setOriginalPost(populatePostBean(postJson.getJSONObject("status"))); } return weiboPost; } }