/*
* Copyright (C) 2013 Chris Lacy
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.tweetalib.android;
import android.util.Log;
import org.appdotnet4j.model.AdnUser;
import org.asynctasktex.AsyncTaskEx;
import org.socialnetlib.android.AppdotnetApi;
import org.tweetalib.android.model.TwitterUser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.User;
public class TwitterFetchUser {
private FetchUserWorkerCallbacks mCallbacks;
private final HashMap<Long, TwitterUser> mUserIdHashMap;
private final HashMap<String, TwitterUser> mUserScreenNameHashMap;
private Integer mFetchUserCallbackHandle;
private final HashMap<Integer, FinishedCallback> mFinishedCallbackMap;
/*
*
*/
public void clearCallbacks() {
if (mFinishedCallbackMap != null) {
mFinishedCallbackMap.clear();
}
}
/*
*
*/
public interface FetchUserWorkerCallbacks {
public AppdotnetApi getAppdotnetApi();
public Twitter getTwitterInstance();
}
/*
*
*/
public interface FinishedCallbackInterface {
public void finished(TwitterFetchResult result, TwitterUser user);
}
/*
*
*/
public abstract class FinishedCallback implements FinishedCallbackInterface {
static final int kInvalidHandle = -1;
public FinishedCallback() {
mHandle = kInvalidHandle;
}
private int mHandle;
}
/*
*
*/
public TwitterFetchUser() {
mFinishedCallbackMap = new HashMap<Integer, FinishedCallback>();
mFetchUserCallbackHandle = 0;
mUserIdHashMap = new HashMap<Long, TwitterUser>();
mUserScreenNameHashMap = new HashMap<String, TwitterUser>();
}
/*
*
*/
public void setWorkerCallbacks(FetchUserWorkerCallbacks callbacks) {
mCallbacks = callbacks;
}
/*
*
*/
FinishedCallback getFetchStatusesCallback(Integer callbackHandle) {
return mFinishedCallbackMap.get(callbackHandle);
}
/*
*
*/
void removeFetchStatusesCallback(FinishedCallback callback) {
if (mFinishedCallbackMap.containsValue(callback)) {
mFinishedCallbackMap.remove(callback.mHandle);
}
}
/*
*
*/
Twitter getTwitterInstance() {
return mCallbacks.getTwitterInstance();
}
AppdotnetApi getAppdotnetApi() {
return mCallbacks.getAppdotnetApi();
}
/*
*
*/
public void setUser(TwitterUser twitterUser) {
if (twitterUser == null) {
return;
}
if (!mUserIdHashMap.containsKey(twitterUser.getId())) {
mUserIdHashMap.put(twitterUser.getId(), twitterUser);
}
if (!mUserScreenNameHashMap.containsKey(twitterUser.getScreenName())) {
mUserScreenNameHashMap
.put(twitterUser.getScreenName(), twitterUser);
}
}
public void setUser(User user, boolean forceUpdate) {
Long userId = Long.valueOf(user.getId());
TwitterUser twitterUser = new TwitterUser(user);
if (forceUpdate || !mUserIdHashMap.containsKey(userId)) {
mUserIdHashMap.put(userId, twitterUser);
}
if (forceUpdate
|| !mUserIdHashMap.containsKey(twitterUser.getScreenName())) {
mUserScreenNameHashMap
.put(twitterUser.getScreenName(), twitterUser);
}
}
public void setUser(AdnUser user, boolean forceUpdate) {
Long userId = Long.valueOf(user.mId);
TwitterUser twitterUser = new TwitterUser(user);
if (forceUpdate || !mUserIdHashMap.containsKey(userId)) {
mUserIdHashMap.put(userId, twitterUser);
}
if (forceUpdate
|| !mUserIdHashMap.containsKey(twitterUser.getScreenName())) {
mUserScreenNameHashMap
.put(twitterUser.getScreenName(), twitterUser);
}
}
/*
*
*/
public TwitterUser getUser(Long userId, FinishedCallback callback,
ConnectionStatus connectionStatus) {
TwitterUser user = mUserIdHashMap.get(userId);
if (callback != null) {
trigger(userId, callback, connectionStatus);
}
return user;
}
public TwitterUser getUser(String screenName, FinishedCallback callback,
ConnectionStatus connectionStatus) {
TwitterUser user = mUserScreenNameHashMap.get(screenName);
if (callback != null) {
trigger(screenName, callback, connectionStatus);
}
return user;
}
public List<TwitterUser> getCachedUsers() {
return new ArrayList<TwitterUser>(mUserIdHashMap.values());
}
public TwitterUser getCachedUser(Long userId) {
if (!mUserIdHashMap.containsKey(userId)) {
return null;
}
return mUserIdHashMap.get(userId);
}
/*
*
*/
public void verifyUser(FinishedCallback callback,
ConnectionStatus connectionStatus) {
if (connectionStatus != null && !connectionStatus.isOnline()) {
if (callback != null) {
callback.finished(new TwitterFetchResult(false,
connectionStatus.getErrorMessageNoConnection()), null);
}
return;
}
mFinishedCallbackMap.put(mFetchUserCallbackHandle, callback);
new FetchUserTask().execute(AsyncTaskEx.PRIORITY_HIGH, "Validate User",
new FetchUserTaskInput(mFetchUserCallbackHandle,
connectionStatus));
mFetchUserCallbackHandle += 1;
}
/*
*
*/
private void trigger(Long userId, FinishedCallback callback,
ConnectionStatus connectionStatus) {
if (connectionStatus != null && !connectionStatus.isOnline()) {
if (callback != null) {
callback.finished(new TwitterFetchResult(false,
connectionStatus.getErrorMessageNoConnection()), null);
}
return;
}
assert (!mFinishedCallbackMap.containsValue(callback));
mFinishedCallbackMap.put(mFetchUserCallbackHandle, callback);
new FetchUserTask().execute(AsyncTaskEx.PRIORITY_HIGH, "Fetch User",
new FetchUserTaskInput(userId, mFetchUserCallbackHandle,
connectionStatus));
mFetchUserCallbackHandle += 1;
}
private void trigger(String screenName, FinishedCallback callback,
ConnectionStatus connectionStatus) {
if (connectionStatus != null && !connectionStatus.isOnline()) {
if (callback != null) {
callback.finished(new TwitterFetchResult(false,
connectionStatus.getErrorMessageNoConnection()), null);
}
return;
}
assert (!mFinishedCallbackMap.containsValue(callback));
mFinishedCallbackMap.put(mFetchUserCallbackHandle, callback);
new FetchUserTask().execute(AsyncTaskEx.PRIORITY_HIGH, "Fetch User",
new FetchUserTaskInput(screenName, mFetchUserCallbackHandle,
connectionStatus));
mFetchUserCallbackHandle += 1;
}
/*
*
*/
public void cancel(FinishedCallback callback) {
removeFetchStatusesCallback(callback);
}
/*
*
*/
class FetchUserTaskInput {
FetchUserTaskInput(Long userId, Integer callbackHandle,
ConnectionStatus connectionStatus) {
mCallbackHandle = callbackHandle;
mUserId = userId;
mConnectionStatus = connectionStatus;
}
FetchUserTaskInput(String screenName, Integer callbackHandle,
ConnectionStatus connectionStatus) {
mCallbackHandle = callbackHandle;
mScreenName = screenName;
mConnectionStatus = connectionStatus;
}
FetchUserTaskInput(Integer callbackHandle,
ConnectionStatus connectionStatus) {
mCallbackHandle = callbackHandle;
mVerifyCredentials = true;
mConnectionStatus = connectionStatus;
}
final Integer mCallbackHandle;
Boolean mVerifyCredentials;
Long mUserId;
String mScreenName;
final ConnectionStatus mConnectionStatus;
}
/*
*
*/
class FetchUserTaskOutput {
FetchUserTaskOutput(TwitterFetchResult fetchResult,
Integer callbackHandle, TwitterUser user) {
mFetchResult = fetchResult;
mCallbackHandle = callbackHandle;
mUser = user;
}
final TwitterFetchResult mFetchResult;
final Integer mCallbackHandle;
final TwitterUser mUser;
}
/*
*
*/
class FetchUserTask extends
AsyncTaskEx<FetchUserTaskInput, Void, FetchUserTaskOutput> {
@Override
protected FetchUserTaskOutput doInBackground(
FetchUserTaskInput... inputArray) {
TwitterUser result = null;
FetchUserTaskInput input = inputArray[0];
if (input.mConnectionStatus != null && !input.mConnectionStatus.isOnline()) {
return new FetchUserTaskOutput(new TwitterFetchResult(false,
input.mConnectionStatus.getErrorMessageNoConnection()),
input.mCallbackHandle, null);
}
String errorDescription = null;
Twitter twitter = getTwitterInstance();
if (twitter != null) {
try {
User user = null;
if (input.mVerifyCredentials != null
&& input.mVerifyCredentials.booleanValue()) {
Log.d("api-call", "verifyCredentials");
user = twitter.verifyCredentials();
} else {
Log.d("api-call", "showUser");
if (input.mUserId != null) {
user = twitter.showUser(input.mUserId);
} else if (input.mScreenName != null) {
user = twitter.showUser(input.mScreenName);
}
}
result = new TwitterUser(user);
setUser(result);
} catch (TwitterException e) {
e.printStackTrace();
errorDescription = e.getErrorMessage();
Log.e("api-call", errorDescription, e);
if (e.getRateLimitStatus() != null && e.getRateLimitStatus().getRemaining() <= 0) {
errorDescription += "\nTry again in " + e.getRateLimitStatus().getSecondsUntilReset()
+ " " + "seconds";
}
}
} else {
AppdotnetApi api = getAppdotnetApi();
if (api != null && input.mUserId != null) {
result = api.getAdnUser(input.mUserId);
setUser(result);
}
}
return new FetchUserTaskOutput(new TwitterFetchResult(
errorDescription == null, errorDescription),
input.mCallbackHandle, result);
}
@Override
protected void onPostExecute(FetchUserTaskOutput output) {
FinishedCallback callback = getFetchStatusesCallback(output.mCallbackHandle);
if (callback != null) {
callback.finished(output.mFetchResult, output.mUser);
removeFetchStatusesCallback(callback);
}
super.onPostExecute(output);
}
}
}