com.twitter.hbc.twitter4j.BaseTwitter4jClient Maven / Gradle / Ivy
The newest version!
/**
* Copyright 2013 Twitter, Inc.
* 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 com.twitter.hbc.twitter4j;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.twitter.hbc.core.Client;
import com.twitter.hbc.core.StatsReporter;
import com.twitter.hbc.core.endpoint.StreamingEndpoint;
import com.twitter.hbc.twitter4j.message.DisconnectMessage;
import com.twitter.hbc.twitter4j.message.StallWarningMessage;
import com.twitter.hbc.twitter4j.parser.JSONObjectParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import twitter4j.*;
import twitter4j.conf.ConfigurationBuilder;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import static com.twitter.hbc.twitter4j.parser.JSONObjectParser.parseFriendList;
class BaseTwitter4jClient implements Twitter4jClient {
private final static Logger logger = LoggerFactory.getLogger(BaseTwitter4jClient.class);
protected final Client client;
private final BlockingQueue messageQueue;
private final ExecutorService executorService;
private final PublicObjectFactory factory;
protected BaseTwitter4jClient(Client client, BlockingQueue blockingQueue, ExecutorService executorService) {
this.client = Preconditions.checkNotNull(client);
this.messageQueue = Preconditions.checkNotNull(blockingQueue);
this.executorService = Preconditions.checkNotNull(executorService);
this.factory = new PublicObjectFactory(new ConfigurationBuilder().build());
}
@Override
public void connect() {
client.connect();
}
@Override
public void reconnect() {
client.reconnect();
}
/**
* Forks off a runnable with the executor provided. Multiple calls are allowed, but the listeners must be
* threadsafe.
*/
@Override
public void process() {
if (client.isDone() || executorService.isTerminated()) {
throw new IllegalStateException("Client is already stopped");
}
Runnable runner = new Runnable() {
@Override
public void run() {
try {
while (!client.isDone()) {
String msg = messageQueue.take();
try {
parseMessage(msg);
} catch (Exception e) {
logger.warn("Exception thrown during parsing msg " + msg, e);
onException(e);
}
}
} catch (Exception e) {
onException(e);
}
}
};
executorService.execute(runner);
}
/**
* Stops the client, and shuts down the executor service
*/
@Override
public void stop() {
client.stop();
executorService.shutdown();
}
@Override
public void stop(int millis) {
client.stop(millis);
executorService.shutdown();
}
@Override
public boolean isDone() {
return client.isDone();
}
@Override
public String getName() {
return client.getName();
}
@Override
public StreamingEndpoint getEndpoint() {
return client.getEndpoint();
}
@Override
public StatsReporter.StatsTracker getStatsTracker() {
return client.getStatsTracker();
}
protected void parseMessage(String msg) throws JSONException, TwitterException, IOException {
JSONObject json = new JSONObject(msg);
long sitestreamUser = getSitestreamUser(json);
processMessage(sitestreamUser, preprocessMessage(json));
}
/**
* @return the user id of the message if its for a sitestreams connection. -1 otherwise
*/
protected long getSitestreamUser(JSONObject json) throws JSONException {
return -1;
}
/**
* Removes the sitestreams envelope, if necessary
*/
protected JSONObject preprocessMessage(JSONObject json) throws JSONException {
return json;
}
@VisibleForTesting
void processMessage(long sitestreamUser, JSONObject json) throws JSONException, TwitterException, IOException {
JSONObjectType.Type type = JSONObjectType.determine(json);
switch (type) {
case STATUS:
processStatus(sitestreamUser, json);
break;
case LIMIT:
processLimit(sitestreamUser, json);
break;
case DELETE:
processDelete(sitestreamUser, json);
break;
case SCRUB_GEO:
processScrubGeo(sitestreamUser, json);
break;
case DIRECT_MESSAGE:
case SENDER:
processDirectMessage(sitestreamUser, json);
break;
case FRIENDS:
processFriends(sitestreamUser, json);
break;
case FAVORITE:
processFavorite(sitestreamUser, json);
break;
case UNFAVORITE:
processUnfavorite(sitestreamUser, json);
break;
case FOLLOW:
processFollow(sitestreamUser, json);
break;
case UNFOLLOW:
processUnfollow(sitestreamUser, json);
break;
case USER_LIST_MEMBER_ADDED:
processUserListMemberAddition(sitestreamUser, json);
break;
case USER_LIST_MEMBER_DELETED:
processUserListMemberDeletion(sitestreamUser, json);
break;
case USER_LIST_SUBSCRIBED:
processUserListSubscription(sitestreamUser, json);
break;
case USER_LIST_UNSUBSCRIBED:
processUserListUnsubscription(sitestreamUser, json);
break;
case USER_LIST_CREATED:
processUserListCreation(sitestreamUser, json);
break;
case USER_LIST_UPDATED:
processUserListUpdated(sitestreamUser, json);
break;
case USER_LIST_DESTROYED:
processUserListDestroyed(sitestreamUser, json);
break;
case BLOCK:
processBlock(sitestreamUser, json);
break;
case UNBLOCK:
processUnblock(sitestreamUser, json);
break;
case USER_UPDATE:
processUserUpdate(sitestreamUser, json);
break;
case DISCONNECTION:
processDisconnectMessage(json);
break;
case STALL_WARNING:
processStallWarning(json);
break;
case UNKNOWN:
default:
if (JSONObjectParser.isRetweetMessage(json)) {
processRetweet(sitestreamUser, json);
} else if (JSONObjectParser.isControlStreamMessage(json)) {
processControlStream(json);
} else {
onUnknownMessageType(json.toString());
}
}
}
private void processStatus(long sitestreamUser, JSONObject json) throws TwitterException {
Status status = factory.createStatus(json);
onStatus(sitestreamUser, status);
}
private void processDirectMessage(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
DirectMessage dm = factory.newDirectMessage(json.getJSONObject("direct_message"));
onDirectMessage(sitestreamUser, dm);
}
private void processDelete(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
JSONObject deletionNotice = json.getJSONObject("delete");
if (deletionNotice.has("status")) {
onDelete(sitestreamUser, JSONObjectParser.parseStatusDelete(json));
} else if (deletionNotice.has("direct_message")) {
JSONObject dm = deletionNotice.getJSONObject("direct_message");
final long statusId = dm.getLong("id");
final long userId = dm.getLong("user_id");
onDeleteDirectMessage(sitestreamUser, statusId, userId);
}
}
private void processStallWarning(JSONObject json) throws JSONException {
JSONObject warning = json.getJSONObject("warning");
String code = ((String) warning.opt("code"));
String message = ((String) warning.opt("message"));
int percentFull = warning.getInt("percent_full");
onStallWarning(new StallWarningMessage(code, message, percentFull));
}
private void processLimit(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
onTrackLimitationNotice(sitestreamUser, JSONObjectParser.parseTrackLimit(json));
}
private void processScrubGeo(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
JSONObject scrubGeo = json.getJSONObject("scrub_geo");
long userId = scrubGeo.getLong("user_id");
long upToStatusId = scrubGeo.getLong("up_to_status_id");
onScrubGeo(sitestreamUser, userId, upToStatusId);
}
private void processFriends(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
onFriends(sitestreamUser, parseFriendList(json));
}
private void processFavorite(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
Status status = factory.createStatus(JSONObjectParser.parseEventTargetObject(json));
onFavorite(sitestreamUser, source, target, status);
}
private void processUnfavorite(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
Status status = factory.createStatus(JSONObjectParser.parseEventTargetObject(json));
onUnfavorite(sitestreamUser, source, target, status);
}
private void processRetweet(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
Status status = factory.createStatus(JSONObjectParser.parseEventTargetObject(json));
onRetweet(sitestreamUser, source, target, status);
}
private void processFollow(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
onFollow(sitestreamUser, source, target);
}
private void processUnfollow(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
onUnfollow(sitestreamUser, source, target);
}
private void processUserListMemberAddition(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User addedUser = factory.createUser(JSONObjectParser.parseEventSource(json));
User owner = factory.createUser(JSONObjectParser.parseEventTarget(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListMemberAddition(sitestreamUser, addedUser, owner, userList);
}
private void processUserListMemberDeletion(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User deletedMember = factory.createUser(JSONObjectParser.parseEventSource(json));
User owner = factory.createUser(JSONObjectParser.parseEventTarget(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListMemberDeletion(sitestreamUser, deletedMember, owner, userList);
}
private void processUserListSubscription(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User owner = factory.createUser(JSONObjectParser.parseEventTarget(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListSubscription(sitestreamUser, source, owner, userList);
}
private void processUserListUnsubscription(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User owner = factory.createUser(JSONObjectParser.parseEventTarget(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListUnsubscription(sitestreamUser, source, owner, userList);
}
private void processUserListCreation(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListCreation(sitestreamUser, source, userList);
}
private void processUserListUpdated(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListUpdate(sitestreamUser, source, userList);
}
private void processUserListDestroyed(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
UserList userList = factory.createAUserList(JSONObjectParser.parseEventTargetObject(json));
onUserListDeletion(sitestreamUser, source, userList);
}
private void processUserUpdate(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
onUserProfileUpdate(sitestreamUser, factory.createUser(JSONObjectParser.parseEventSource(json)));
}
private void processBlock(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
onBlock(sitestreamUser, source, target);
}
private void processUnblock(long sitestreamUser, JSONObject json) throws TwitterException, JSONException {
User source = factory.createUser(JSONObjectParser.parseEventSource(json));
User target = factory.createUser(JSONObjectParser.parseEventTarget(json));
onUnblock(sitestreamUser, source, target);
}
private void processControlStream(JSONObject json) throws JSONException {
onControlStreamMessage(JSONObjectParser.getStreamId(json));
}
private void processDisconnectMessage(JSONObject json) throws JSONException {
onDisconnectMessage(JSONObjectParser.parseDisconnectMessage(json));
}
protected void onStatus(long sitestreamUser, final Status status) {
logger.info("Unhandled event: onStatus");
}
protected void onDelete(long sitestreamUser, StatusDeletionNotice delete) {
logger.info("Unhandled event: onDelete");
}
protected void onTrackLimitationNotice(long sitestreamUser, final int limit) {
logger.info("Unhandled event: onTrackLimitationNotice");
}
protected void onScrubGeo(long sitestreamUser, long userId, long upToStatusId) {
logger.info("Unhandled event: onScrubGeo");
}
protected void onDeleteDirectMessage(long sitestreamUser, long directMessageId, long userId) {
logger.info("Unhandled event: onDeleteDirectMessage");
}
protected void onDirectMessage(long sitestreamUser, final DirectMessage directMessage) {
logger.info("Unhandled event: onDirectMessage");
}
protected void onFriends(long sitestreamUser, final long[] json) {
logger.info("Unhandled event: onFriends");
}
protected void onFavorite(long sitestreamUser, final User source, final User target, final Status targetObject) {
logger.info("Unhandled event: onFavorite");
}
protected void onUnfavorite(long sitestreamUser, final User source, final User target, final Status targetObject) {
logger.info("Unhandled event: onUnfavorite");
}
protected void onRetweet(long sitestreamUser, User source, User target, Status tweet) {
logger.info("Unhandled event: onRetweet");
}
protected void onFollow(long sitestreamUser, final User source, final User target) throws TwitterException {
logger.info("Unhandled event: onFollow");
}
protected void onUnfollow(long sitestreamUser, final User source, final User target) throws TwitterException {
logger.info("Unhandled event: onUnfollow");
}
protected void onUserListMemberAddition(long sitestreamUser, final User addedMember, final User owner, final UserList userList) {
logger.info("Unhandled event: onUserListMemberAddition");
}
protected void onUserListMemberDeletion(long sitestreamUser, final User deletedMember, final User owner, final UserList userList) {
logger.info("Unhandled event: onUserListMemberDeletion");
}
protected void onUserListSubscription(long sitestreamUser, final User subscriber, final User owner, final UserList userList) {
logger.info("Unhandled event: onUserListSubscription");
}
protected void onUserListUnsubscription(long sitestreamUser, final User deletedMember, final User owner, final UserList userList) {
logger.info("Unhandled event: onUserListUnsubscription");
}
protected void onUserListCreation(long sitestreamUser, final User source, final UserList userList) {
logger.info("Unhandled event: onUserListCreation");
}
protected void onUserListUpdate(long sitestreamUser, User source, UserList userList) {
logger.info("Unhandled event: onUserListUpdate");
}
protected void onUserListDeletion(long sitestreamUser, final User source, final UserList userList) {
logger.info("Unhandled event: onUserListDeletion");
}
protected void onUserProfileUpdate(long sitestreamUser, User source) {
logger.info("Unhandled event: onUserProfileUpdate");
}
protected void onBlock(long sitestreamUser, User source, User target) {
logger.info("Unhandled event: onBlock");
}
protected void onUnblock(long sitestreamUser, User source, User target) {
logger.info("Unhandled event: onUnblock");
}
protected void onControlStreamMessage(String streamId) {
logger.info("Unhandled event: onControlStreamMessage");
}
protected void onDisconnectMessage(DisconnectMessage disconnectMessage) {
logger.info("Unhandled event: onDisconnectMessage - {}", disconnectMessage.toString());
}
protected void onException(Exception e) {
logger.info("Exception caught", e);
}
protected void onStallWarning(StallWarningMessage stallWarning) {
logger.info("Unhandled event: onStallWarning - {}", stallWarning);
}
protected void onUnknownMessageType(String msg) {
logger.info("Unknown message (first 50 chars): " + msg.substring(0, Math.min(msg.length(), 50)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy