moved spaces to tabs for the twitter package

This commit is contained in:
Josh Long
2010-08-24 22:10:01 +00:00
parent d2f74acbfb
commit d2d4104d86
30 changed files with 1218 additions and 1271 deletions

View File

@@ -1,100 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-twitter</artifactId>
<packaging>jar</packaging>
<name>Spring Integration Twitter Support</name>
<dependencies>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.twitter4j</groupId>
<artifactId>twitter4j-core</artifactId>
<!--<version>[2.1,)</version>-->
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>nlog4j</artifactId>
<version>1.2.25</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.version}</version>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${org.easymock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>${org.easymock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.springsource.bundlor</groupId>
<artifactId>com.springsource.bundlor.maven</artifactId>
</plugin>
</plugins>
</build>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-twitter</artifactId>
<packaging>jar</packaging>
<name>Spring Integration Twitter Support</name>
<dependencies>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.twitter4j</groupId>
<artifactId>twitter4j-core</artifactId>
<!--<version>[2.1,)</version>-->
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>nlog4j</artifactId>
<version>1.2.25</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.version}</version>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${org.easymock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>${org.easymock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.springsource.bundlor</groupId>
<artifactId>com.springsource.bundlor.maven</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -16,18 +16,14 @@
package org.springframework.integration.twitter;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.context.Lifecycle;
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.twitter.oauth.OAuthConfiguration;
import org.springframework.util.Assert;
import twitter4j.RateLimitStatus;
import twitter4j.ResponseList;
import twitter4j.Twitter;
@@ -41,7 +37,7 @@ import java.util.List;
* class abstracts most of them for you. Implementers must take note of {@link org.springframework.integration.twitter.AbstractInboundTwitterEndpointSupport#runAsAPIRateLimitsPermit(org.springframework.integration.twitter.AbstractInboundTwitterEndpointSupport.ApiCallback)}
* which will invoke the instance of {@link org.springframework.integration.twitter.AbstractInboundTwitterEndpointSupport.ApiCallback} when the rate-limit API
* deems that its OK to do so. This class handles keeping tabs on that and on spacing out requests as required.
*
* <p/>
* Simialarly, this class handles keeping track on the latest inbound message its received and avoiding, where possible, redelivery of
* common messages. This functionality is enabled using the {@link org.springframework.integration.context.metadata.MetadataPersister} implementation
*
@@ -49,135 +45,135 @@ import java.util.List;
* @since 2.0
*/
public abstract class AbstractInboundTwitterEndpointSupport<T> extends AbstractEndpoint implements Lifecycle {
protected volatile OAuthConfiguration configuration;
protected final MessagingTemplate messagingTemplate = new MessagingTemplate();
private volatile MessageChannel requestChannel;
protected volatile long markerId = -1;
protected Twitter twitter;
private final Object markerGuard = new Object();
private final Object apiPermitGuard = new Object();
protected volatile OAuthConfiguration configuration;
protected final MessagingTemplate messagingTemplate = new MessagingTemplate();
private volatile MessageChannel requestChannel;
protected volatile long markerId = -1;
protected Twitter twitter;
private final Object markerGuard = new Object();
private final Object apiPermitGuard = new Object();
@SuppressWarnings("unused")
public void setConfiguration(OAuthConfiguration configuration) {
this.configuration = configuration;
}
@SuppressWarnings("unused")
public void setConfiguration(OAuthConfiguration configuration) {
this.configuration = configuration;
}
abstract protected void markLastStatusId(T statusId);
abstract protected void markLastStatusId(T statusId);
abstract protected List<T> sort(List<T> rl);
abstract protected List<T> sort(List<T> rl);
protected void forwardAll(ResponseList<T> tResponses) {
List<T> stats = new ArrayList<T>();
protected void forwardAll(ResponseList<T> tResponses) {
List<T> stats = new ArrayList<T>();
for (T t : tResponses)
stats.add(t);
for (T t : tResponses)
stats.add(t);
for (T twitterResponse : sort(stats))
forward(twitterResponse);
}
for (T twitterResponse : sort(stats))
forward(twitterResponse);
}
public long getMarkerId() {
return markerId;
}
public long getMarkerId() {
return markerId;
}
@Override
protected void doStart() {
try {
refresh();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doStart() {
try {
refresh();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected void forward(T status) {
synchronized (this.markerGuard) {
Message<T> twtMsg = MessageBuilder.withPayload(status).build();
messagingTemplate.send(requestChannel, twtMsg);
markLastStatusId(status);
}
}
protected void forward(T status) {
synchronized (this.markerGuard) {
Message<T> twtMsg = MessageBuilder.withPayload(status).build();
messagingTemplate.send(requestChannel, twtMsg);
markLastStatusId(status);
}
}
@SuppressWarnings("unchecked")
protected void runAsAPIRateLimitsPermit(ApiCallback cb)
throws Exception {
synchronized (this.apiPermitGuard) {
while (waitUntilPullAvailable()) {
if (logger.isDebugEnabled()) {
logger.debug("have room to make an API request now");
}
@SuppressWarnings("unchecked")
protected void runAsAPIRateLimitsPermit(ApiCallback cb)
throws Exception {
synchronized (this.apiPermitGuard) {
while (waitUntilPullAvailable()) {
if (logger.isDebugEnabled()) {
logger.debug("have room to make an API request now");
}
cb.run(this, twitter);
}
}
}
cb.run(this, twitter);
}
}
}
protected boolean handleReceivingRateLimitStatus(RateLimitStatus rateLimitStatus) {
try {
int secondsUntilReset = rateLimitStatus.getSecondsUntilReset();
int remainingHits = rateLimitStatus.getRemainingHits();
protected boolean handleReceivingRateLimitStatus(RateLimitStatus rateLimitStatus) {
try {
int secondsUntilReset = rateLimitStatus.getSecondsUntilReset();
int remainingHits = rateLimitStatus.getRemainingHits();
if (remainingHits == 0) {
logger.debug("rate status limit service returned 0 for the remaining hits value");
if (remainingHits == 0) {
logger.debug("rate status limit service returned 0 for the remaining hits value");
return false;
}
return false;
}
if (secondsUntilReset == 0) {
logger.debug("rate status limit service returned 0 for the seconds until reset period value");
if (secondsUntilReset == 0) {
logger.debug("rate status limit service returned 0 for the seconds until reset period value");
return false;
}
return false;
}
int secondsUntilWeCanPullAgain = secondsUntilReset / remainingHits;
long msUntilWeCanPullAgain = secondsUntilWeCanPullAgain * 1000;
int secondsUntilWeCanPullAgain = secondsUntilReset / remainingHits;
long msUntilWeCanPullAgain = secondsUntilWeCanPullAgain * 1000;
logger.debug("need to Thread.sleep() " + secondsUntilWeCanPullAgain + " seconds until the next timeline pull. Have " + remainingHits +
" remaining pull this rate period. The period ends in " + secondsUntilReset);
logger.debug("need to Thread.sleep() " + secondsUntilWeCanPullAgain + " seconds until the next timeline pull. Have " + remainingHits +
" remaining pull this rate period. The period ends in " + secondsUntilReset);
Thread.sleep(msUntilWeCanPullAgain);
} catch (Throwable throwable) {
logger.debug("encountered an error when" + " trying to refresh the timeline: " + ExceptionUtils.getFullStackTrace(throwable));
}
Thread.sleep(msUntilWeCanPullAgain);
} catch (Throwable throwable) {
logger.debug("encountered an error when" + " trying to refresh the timeline: " + ExceptionUtils.getFullStackTrace(throwable));
}
return true;
}
return true;
}
protected boolean waitUntilPullAvailable() throws Exception {
return this.handleReceivingRateLimitStatus(this.twitter.getRateLimitStatus());
}
protected boolean waitUntilPullAvailable() throws Exception {
return this.handleReceivingRateLimitStatus(this.twitter.getRateLimitStatus());
}
protected boolean hasMarkedStatus() {
return markerId > -1;
}
protected boolean hasMarkedStatus() {
return markerId > -1;
}
abstract protected void refresh() throws Exception;
abstract protected void refresh() throws Exception;
@Override
protected void onInit() throws Exception {
messagingTemplate.afterPropertiesSet();
Assert.notNull(this.configuration, "'configuration' can't be null");
this.twitter = this.configuration.getTwitter();
Assert.notNull(this.twitter, "'twitter' instance can't be null");
}
@Override
protected void onInit() throws Exception {
messagingTemplate.afterPropertiesSet();
Assert.notNull(this.configuration, "'configuration' can't be null");
this.twitter = this.configuration.getTwitter();
Assert.notNull(this.twitter, "'twitter' instance can't be null");
}
@Override
protected void doStop() {
}
@Override
protected void doStop() {
}
@SuppressWarnings("unused")
public void setRequestChannel(MessageChannel requestChannel) {
this.messagingTemplate.setDefaultChannel(requestChannel);
this.requestChannel = requestChannel;
}
@SuppressWarnings("unused")
public void setRequestChannel(MessageChannel requestChannel) {
this.messagingTemplate.setDefaultChannel(requestChannel);
this.requestChannel = requestChannel;
}
/**
* Hook for clients to run logic when the API rate limiting lets us
*
* Simply register your callback using #runAsAPIRateLimitsPermit
*
* @param <C>
*/
public static interface ApiCallback<C> {
void run(C t, Twitter twitter) throws Exception;
}
/**
* Hook for clients to run logic when the API rate limiting lets us
* <p/>
* Simply register your callback using #runAsAPIRateLimitsPermit
*
* @param <C>
*/
public static interface ApiCallback<C> {
void run(C t, Twitter twitter) throws Exception;
}
}

View File

@@ -30,23 +30,23 @@ import java.util.List;
* @author Josh Long
*/
abstract public class AbstractInboundTwitterStatusEndpointSupport extends AbstractInboundTwitterEndpointSupport<Status> {
private Comparator<Status> statusComparator = new Comparator<Status>() {
public int compare(Status status, Status status1) {
return status.getCreatedAt().compareTo(status1.getCreatedAt());
}
};
private Comparator<Status> statusComparator = new Comparator<Status>() {
public int compare(Status status, Status status1) {
return status.getCreatedAt().compareTo(status1.getCreatedAt());
}
};
@Override
protected void markLastStatusId(Status statusId) {
this.markerId = statusId.getId();
}
@Override
protected void markLastStatusId(Status statusId) {
this.markerId = statusId.getId();
}
@Override
protected List<Status> sort(List<Status> rl) {
List<Status> statusArrayList = new ArrayList<Status>();
statusArrayList.addAll(rl);
Collections.sort(statusArrayList, statusComparator);
@Override
protected List<Status> sort(List<Status> rl) {
List<Status> statusArrayList = new ArrayList<Status>();
statusArrayList.addAll(rl);
Collections.sort(statusArrayList, statusComparator);
return statusArrayList;
}
return statusArrayList;
}
}

View File

@@ -28,29 +28,29 @@ import twitter4j.Twitter;
* @author Josh Long
*/
public abstract class AbstractOutboundTwitterEndpointSupport extends AbstractEndpoint implements MessageHandler {
protected volatile OAuthConfiguration configuration;
protected volatile Twitter twitter;
protected volatile StatusUpdateSupport statusUpdateSupport = new StatusUpdateSupport();
protected volatile OAuthConfiguration configuration;
protected volatile Twitter twitter;
protected volatile StatusUpdateSupport statusUpdateSupport = new StatusUpdateSupport();
@SuppressWarnings("unused")
public void setConfiguration(OAuthConfiguration configuration) {
this.configuration = configuration;
}
@SuppressWarnings("unused")
public void setConfiguration(OAuthConfiguration configuration) {
this.configuration = configuration;
}
@Override
protected void onInit() throws Exception {
Assert.notNull(this.configuration, "'configuration' can't be null");
this.twitter = this.configuration.getTwitter();
Assert.notNull(this.twitter, "'twitter' can't be null");
}
@Override
protected void onInit() throws Exception {
Assert.notNull(this.configuration, "'configuration' can't be null");
this.twitter = this.configuration.getTwitter();
Assert.notNull(this.twitter, "'twitter' can't be null");
}
@Override
protected void doStart() {
}
@Override
protected void doStart() {
}
@Override
protected void doStop() {
}
@Override
protected void doStop() {
}
}

View File

@@ -31,33 +31,33 @@ import java.util.List;
* @author Josh Long
*/
public class InboundDMStatusEndpoint extends AbstractInboundTwitterEndpointSupport<DirectMessage> {
private Comparator<DirectMessage> dmComparator = new Comparator<DirectMessage>() {
public int compare(DirectMessage directMessage, DirectMessage directMessage1) {
return directMessage.getCreatedAt().compareTo(directMessage1.getCreatedAt());
}
};
private Comparator<DirectMessage> dmComparator = new Comparator<DirectMessage>() {
public int compare(DirectMessage directMessage, DirectMessage directMessage1) {
return directMessage.getCreatedAt().compareTo(directMessage1.getCreatedAt());
}
};
@Override
protected void markLastStatusId(DirectMessage dm) {
this.markerId = dm.getId();
}
@Override
protected void markLastStatusId(DirectMessage dm) {
this.markerId = dm.getId();
}
@Override
protected List<DirectMessage> sort(List<DirectMessage> rl) {
List<DirectMessage> dms = new ArrayList<DirectMessage>();
dms.addAll(rl);
Collections.sort(dms, dmComparator);
@Override
protected List<DirectMessage> sort(List<DirectMessage> rl) {
List<DirectMessage> dms = new ArrayList<DirectMessage>();
dms.addAll(rl);
Collections.sort(dms, dmComparator);
return dms;
}
return dms;
}
@Override
protected void refresh() throws Exception {
this.runAsAPIRateLimitsPermit(new ApiCallback<InboundDMStatusEndpoint>() {
public void run(InboundDMStatusEndpoint t, Twitter twitter)
throws Exception {
forwardAll((!hasMarkedStatus()) ? t.twitter.getDirectMessages() : t.twitter.getDirectMessages(new Paging(t.getMarkerId())));
}
});
}
@Override
protected void refresh() throws Exception {
this.runAsAPIRateLimitsPermit(new ApiCallback<InboundDMStatusEndpoint>() {
public void run(InboundDMStatusEndpoint t, Twitter twitter)
throws Exception {
forwardAll((!hasMarkedStatus()) ? t.twitter.getDirectMessages() : t.twitter.getDirectMessages(new Paging(t.getMarkerId())));
}
});
}
}

View File

@@ -25,13 +25,13 @@ import twitter4j.Twitter;
* @author Josh Long
*/
public class InboundMentionStatusEndpoint extends AbstractInboundTwitterStatusEndpointSupport {
@Override
protected void refresh() throws Exception {
this.runAsAPIRateLimitsPermit(new ApiCallback<InboundMentionStatusEndpoint>() {
public void run(InboundMentionStatusEndpoint ctx, Twitter twitter)
throws Exception {
forwardAll((!hasMarkedStatus()) ? twitter.getMentions() : twitter.getMentions(new Paging(ctx.getMarkerId())));
}
});
}
@Override
protected void refresh() throws Exception {
this.runAsAPIRateLimitsPermit(new ApiCallback<InboundMentionStatusEndpoint>() {
public void run(InboundMentionStatusEndpoint ctx, Twitter twitter)
throws Exception {
forwardAll((!hasMarkedStatus()) ? twitter.getMentions() : twitter.getMentions(new Paging(ctx.getMarkerId())));
}
});
}
}

View File

@@ -27,13 +27,13 @@ import twitter4j.Twitter;
* @since 2.0
*/
public class InboundUpdatedStatusEndpoint extends AbstractInboundTwitterStatusEndpointSupport {
@Override
protected void refresh() throws Exception {
this.runAsAPIRateLimitsPermit(new ApiCallback<InboundUpdatedStatusEndpoint>() {
public void run(InboundUpdatedStatusEndpoint t, Twitter twitter)
throws Exception {
forwardAll((!t.hasMarkedStatus()) ? twitter.getFriendsTimeline() : twitter.getFriendsTimeline(new Paging(t.getMarkerId())));
}
});
}
@Override
protected void refresh() throws Exception {
this.runAsAPIRateLimitsPermit(new ApiCallback<InboundUpdatedStatusEndpoint>() {
public void run(InboundUpdatedStatusEndpoint t, Twitter twitter)
throws Exception {
forwardAll((!t.hasMarkedStatus()) ? twitter.getFriendsTimeline() : twitter.getFriendsTimeline(new Paging(t.getMarkerId())));
}
});
}
}

View File

@@ -19,9 +19,7 @@ import org.springframework.integration.Message;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.MessageRejectedException;
import org.springframework.util.Assert;
import twitter4j.TwitterException;
@@ -33,29 +31,29 @@ import twitter4j.TwitterException;
* @see twitter4j.Twitter
*/
public class OutboundDMStatusMessageHandler extends AbstractOutboundTwitterEndpointSupport {
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException, MessageDeliveryException {
try {
String txt = (String) message.getPayload();
Object toUser =
message.getHeaders().containsKey(TwitterHeaders.TWITTER_DM_TARGET_USER_ID)?
message.getHeaders().get(TwitterHeaders.TWITTER_DM_TARGET_USER_ID) :
null;
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException, MessageDeliveryException {
try {
String txt = (String) message.getPayload();
Object toUser =
message.getHeaders().containsKey(TwitterHeaders.TWITTER_DM_TARGET_USER_ID) ?
message.getHeaders().get(TwitterHeaders.TWITTER_DM_TARGET_USER_ID) :
null;
Assert.notNull(txt, "the message payload must be a String to be used as the direct message body text");
Assert.notNull(txt, "the message payload must be a String to be used as the direct message body text");
Assert.notNull(toUser, "the header '" + TwitterHeaders.TWITTER_DM_TARGET_USER_ID + "' must be present");
Assert.notNull(toUser, "the header '" + TwitterHeaders.TWITTER_DM_TARGET_USER_ID + "' must be present");
Assert.state(toUser instanceof String || toUser instanceof Integer,
"the header '" + TwitterHeaders.TWITTER_DM_TARGET_USER_ID + "' must be either a String (a screenname) or an int (a user ID)");
Assert.state(toUser instanceof String || toUser instanceof Integer,
"the header '" + TwitterHeaders.TWITTER_DM_TARGET_USER_ID + "' must be either a String (a screenname) or an int (a user ID)");
if (toUser instanceof Integer) {
this.twitter.sendDirectMessage((Integer) toUser, txt);
} else if (toUser instanceof String) {
this.twitter.sendDirectMessage((String) toUser, txt);
}
} catch (TwitterException e) {
logger.debug(e);
throw new RuntimeException(e);
}
}
if (toUser instanceof Integer) {
this.twitter.sendDirectMessage((Integer) toUser, txt);
} else if (toUser instanceof String) {
this.twitter.sendDirectMessage((String) toUser, txt);
}
} catch (TwitterException e) {
logger.debug(e);
throw new RuntimeException(e);
}
}
}

View File

@@ -30,15 +30,15 @@ import twitter4j.StatusUpdate;
* @since 2.0
*/
public class OutboundUpdatedStatusMessageHandler extends AbstractOutboundTwitterEndpointSupport {
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException, MessageDeliveryException {
try {
StatusUpdate statusUpdate = this.statusUpdateSupport.fromMessage(message);
Assert.notNull(statusUpdate, "couldn't send message, unable to build a StatusUpdate instance correctly");
this.twitter.updateStatus(statusUpdate);
} catch (Throwable e) {
this.logger.debug(e);
throw new RuntimeException(e);
}
}
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException, MessageDeliveryException {
try {
StatusUpdate statusUpdate = this.statusUpdateSupport.fromMessage(message);
Assert.notNull(statusUpdate, "couldn't send message, unable to build a StatusUpdate instance correctly");
this.twitter.updateStatus(statusUpdate);
} catch (Throwable e) {
this.logger.debug(e);
throw new RuntimeException(e);
}
}
}

View File

@@ -16,9 +16,7 @@
package org.springframework.integration.twitter;
import org.springframework.integration.Message;
import org.springframework.util.StringUtils;
import twitter4j.GeoLocation;
import twitter4j.StatusUpdate;
@@ -28,62 +26,62 @@ import twitter4j.StatusUpdate;
*
* @author Josh Long
* @see twitter4j.StatusUpdate
* @see org.springframework.integration.twitter.TwitterHeaders
* @see org.springframework.integration.twitter.TwitterHeaders
* @since 2.0
*/
public class StatusUpdateSupport {
/**
* {@link StatusUpdate} instances are used to drive status updates.
*
* @param message the inbound messages
* @return a {@link StatusUpdate} that's been materialized from the inbound message
* @throws Throwable thrown if something goes wrong
*/
public StatusUpdate fromMessage(Message<?> message)
throws Throwable {
Object payload = message.getPayload();
StatusUpdate statusUpdate = null;
/**
* {@link StatusUpdate} instances are used to drive status updates.
*
* @param message the inbound messages
* @return a {@link StatusUpdate} that's been materialized from the inbound message
* @throws Throwable thrown if something goes wrong
*/
public StatusUpdate fromMessage(Message<?> message)
throws Throwable {
Object payload = message.getPayload();
StatusUpdate statusUpdate = null;
if (payload instanceof String) {
statusUpdate = new StatusUpdate((String) payload);
if (payload instanceof String) {
statusUpdate = new StatusUpdate((String) payload);
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_IN_REPLY_TO_STATUS_ID)) {
Long replyId = (Long) message.getHeaders().get(TwitterHeaders.TWITTER_IN_REPLY_TO_STATUS_ID);
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_IN_REPLY_TO_STATUS_ID)) {
Long replyId = (Long) message.getHeaders().get(TwitterHeaders.TWITTER_IN_REPLY_TO_STATUS_ID);
if ((replyId != null) && (replyId > 0)) {
statusUpdate.inReplyToStatusId(replyId);
}
}
if ((replyId != null) && (replyId > 0)) {
statusUpdate.inReplyToStatusId(replyId);
}
}
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_PLACE_ID)) {
String placeId = (String) message.getHeaders().get(TwitterHeaders.TWITTER_PLACE_ID);
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_PLACE_ID)) {
String placeId = (String) message.getHeaders().get(TwitterHeaders.TWITTER_PLACE_ID);
if (StringUtils.hasText(placeId)) {
statusUpdate.placeId(placeId);
}
}
if (StringUtils.hasText(placeId)) {
statusUpdate.placeId(placeId);
}
}
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_GEOLOCATION)) {
GeoLocation geoLocation = (GeoLocation) message.getHeaders().get(TwitterHeaders.TWITTER_GEOLOCATION);
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_GEOLOCATION)) {
GeoLocation geoLocation = (GeoLocation) message.getHeaders().get(TwitterHeaders.TWITTER_GEOLOCATION);
if (null != geoLocation) {
statusUpdate.location(geoLocation);
}
}
if (null != geoLocation) {
statusUpdate.location(geoLocation);
}
}
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_DISPLAY_COORDINATES)) {
Boolean displayCoords = (Boolean) message.getHeaders().get(TwitterHeaders.TWITTER_DISPLAY_COORDINATES);
if (message.getHeaders().containsKey(TwitterHeaders.TWITTER_DISPLAY_COORDINATES)) {
Boolean displayCoords = (Boolean) message.getHeaders().get(TwitterHeaders.TWITTER_DISPLAY_COORDINATES);
if (displayCoords != null) {
statusUpdate.displayCoordinates(displayCoords);
}
}
}
if (displayCoords != null) {
statusUpdate.displayCoordinates(displayCoords);
}
}
}
if (payload instanceof StatusUpdate) {
statusUpdate = (StatusUpdate) payload;
}
if (payload instanceof StatusUpdate) {
statusUpdate = (StatusUpdate) payload;
}
return statusUpdate;
}
return statusUpdate;
}
}

View File

@@ -18,16 +18,16 @@ package org.springframework.integration.twitter;
/**
* An enum to allow users to express interest in particular kinds of tweets.
*
* <p/>
* Contains header keys used by the various adapters.
*
* @author Josh Long
* @since 2.0
*/
public class TwitterHeaders {
public static final String TWITTER_IN_REPLY_TO_STATUS_ID = "TWITTER_IN_REPLY_TO_STATUS_ID";
public static final String TWITTER_PLACE_ID = "TWITTER_PLACE_ID";
public static final String TWITTER_GEOLOCATION = "TWITTER_GEOLOCATION";
public static final String TWITTER_DISPLAY_COORDINATES = "TWITTER_DISPLAY_COORDINATES";
public static final String TWITTER_DM_TARGET_USER_ID = "TWITTER_DM_TARGET_USER_ID";
public static final String TWITTER_IN_REPLY_TO_STATUS_ID = "TWITTER_IN_REPLY_TO_STATUS_ID";
public static final String TWITTER_PLACE_ID = "TWITTER_PLACE_ID";
public static final String TWITTER_GEOLOCATION = "TWITTER_GEOLOCATION";
public static final String TWITTER_DISPLAY_COORDINATES = "TWITTER_DISPLAY_COORDINATES";
public static final String TWITTER_DM_TARGET_USER_ID = "TWITTER_DM_TARGET_USER_ID";
}

View File

@@ -19,14 +19,10 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.twitter.*;
import org.springframework.integration.twitter.oauth.OAuthConfigurationFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -36,128 +32,134 @@ import org.w3c.dom.Element;
*/
@SuppressWarnings("unused")
public class TwitterNamespaceHandler extends org.springframework.beans.factory.xml.NamespaceHandlerSupport {
public static final String DIRECT_MESSAGES = "direct-messages";
public static final String MENTIONS = "mentions";
public static final String FRIENDS = "friends";
public static final String DIRECT_MESSAGES = "direct-messages";
public static final String MENTIONS = "mentions";
public static final String FRIENDS = "friends";
public void init() {
// twitter connections
registerBeanDefinitionParser("twitter-connection", new TwitterConnectionParser());
public void init() {
// twitter connections
registerBeanDefinitionParser("twitter-connection", new TwitterConnectionParser());
// inbound
registerBeanDefinitionParser("inbound-update-channel-adapter", new TwitterUpdatedStatusInboundEndpointParser());
registerBeanDefinitionParser("inbound-dm-channel-adapter", new TwitterDMInboundEndpointParser());
registerBeanDefinitionParser("inbound-mention-channel-adapter", new TwitterMentionInboundEndpointParser());
// inbound
registerBeanDefinitionParser("inbound-update-channel-adapter", new TwitterUpdatedStatusInboundEndpointParser());
registerBeanDefinitionParser("inbound-dm-channel-adapter", new TwitterDMInboundEndpointParser());
registerBeanDefinitionParser("inbound-mention-channel-adapter", new TwitterMentionInboundEndpointParser());
// outbound
registerBeanDefinitionParser("outbound-update-channel-adapter", new TwitterUpdatedStatusOutboundEndpointParser());
registerBeanDefinitionParser("outbound-dm-channel-adapter", new TwitterDMOutboundEndpointParser());
}
// outbound
registerBeanDefinitionParser("outbound-update-channel-adapter", new TwitterUpdatedStatusOutboundEndpointParser());
registerBeanDefinitionParser("outbound-dm-channel-adapter", new TwitterDMOutboundEndpointParser());
}
private static void configureTwitterConnection(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String ref = element.getAttribute("twitter-connection");
private static void configureTwitterConnection(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String ref = element.getAttribute("twitter-connection");
if (org.springframework.util.StringUtils.hasText(ref)) {
builder.addPropertyReference("twitterConnection", ref);
} else {
for (String attribute : new String[] { "consumer-key", "consumer-secret", "access-token", "access-token-secret" }) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, attribute);
}
}
}
if (org.springframework.util.StringUtils.hasText(ref)) {
builder.addPropertyReference("twitterConnection", ref);
} else {
for (String attribute : new String[]{"consumer-key", "consumer-secret", "access-token", "access-token-secret"}) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, attribute);
}
}
}
// twitter:twitter-connection
private static class TwitterConnectionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class getBeanClass(Element element) {
return OAuthConfigurationFactoryBean.class;
}
// twitter:twitter-connection
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
configureTwitterConnection(element, parserContext, builder);
}
private static class TwitterConnectionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class getBeanClass(Element element) {
return OAuthConfigurationFactoryBean.class;
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
configureTwitterConnection(element, parserContext, builder);
}
// twitter:inbound-mention-channel-adapter
private static class TwitterMentionInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return InboundMentionStatusEndpoint.class.getName();
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
// twitter:inbound-mention-channel-adapter
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "requestChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
}
}
private static class TwitterMentionInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return InboundMentionStatusEndpoint.class.getName();
}
// twitter:inbound-dm-channel-adapter
private static class TwitterDMInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return InboundDMStatusEndpoint.class.getName();
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "requestChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
}
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "requestChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
}
}
// twitter:inbound-dm-channel-adapter
// twitter:inbound-update-channel-adapter
private static class TwitterUpdatedStatusInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return InboundUpdatedStatusEndpoint.class.getName();
}
private static class TwitterDMInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return InboundDMStatusEndpoint.class.getName();
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "requestChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
}
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "requestChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
}
}
// twitter:outbound-update-channel-adapter
private static class TwitterUpdatedStatusOutboundEndpointParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OutboundUpdatedStatusMessageHandler.class.getName());
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
return builder.getBeanDefinition();
}
}
// twitter:inbound-update-channel-adapter
// twitter:outbound-dm-channel-adapter
private static class TwitterDMOutboundEndpointParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OutboundDMStatusMessageHandler.class.getName());
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
return builder.getBeanDefinition();
}
}
private static class TwitterUpdatedStatusInboundEndpointParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return InboundUpdatedStatusEndpoint.class.getName();
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "channel", "requestChannel");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
}
}
// twitter:outbound-update-channel-adapter
private static class TwitterUpdatedStatusOutboundEndpointParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OutboundUpdatedStatusMessageHandler.class.getName());
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
return builder.getBeanDefinition();
}
}
// twitter:outbound-dm-channel-adapter
private static class TwitterDMOutboundEndpointParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OutboundDMStatusMessageHandler.class.getName());
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "twitter-connection", "configuration");
return builder.getBeanDefinition();
}
}
}

View File

@@ -18,12 +18,9 @@ package org.springframework.integration.twitter.oauth;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;
@@ -42,172 +39,173 @@ import java.util.Properties;
* @since 2.0
*/
abstract public class AbstractOAuthAccessTokenBasedFactoryBean<T> implements InitializingBean, FactoryBean<T> {
protected OAuthConfiguration configuration;
protected final Object monitor = new Object();
protected volatile T twitter;
protected volatile AccessTokenInitialRequestProcessListener accessTokenInitialRequestProcessListener;
protected volatile boolean initialized = false;
protected OAuthConfiguration configuration;
protected final Object monitor = new Object();
protected volatile T twitter;
protected volatile AccessTokenInitialRequestProcessListener accessTokenInitialRequestProcessListener;
protected volatile boolean initialized = false;
/**
* Nasty little bit of circular indirection here: the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration} hosts the String values for authentication,
* which we need to build up this instance, but the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration} in turn needs references to the instances provided by
* this {@link org.springframework.beans.factory.FactoryBean}. So, they collaborate and guard each others state. Ultimately, clients should use {@link org.springframework.integration.twitter.oauth.OAuthConfiguration}
* to correctly any implementations of this factory bean as well as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration} reference itself.
*
* @param configuration the configuration object
*/
protected AbstractOAuthAccessTokenBasedFactoryBean(OAuthConfiguration configuration) {
this.configuration = configuration;
}
/**
* Nasty little bit of circular indirection here: the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration} hosts the String values for authentication,
* which we need to build up this instance, but the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration} in turn needs references to the instances provided by
* this {@link org.springframework.beans.factory.FactoryBean}. So, they collaborate and guard each others state. Ultimately, clients should use {@link org.springframework.integration.twitter.oauth.OAuthConfiguration}
* to correctly any implementations of this factory bean as well as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration} reference itself.
*
* @param configuration the configuration object
*/
protected AbstractOAuthAccessTokenBasedFactoryBean(OAuthConfiguration configuration) {
this.configuration = configuration;
}
/**
* This probably doesn't belong here. It's more for support for running the {@link OAuthAccessTokenBasedTwitterFactoryBean#main(String[])} or
* {@link OAuthAccessTokenBasedTwitterFactoryBean#main(String[])} methods that run the user through a command line tool to approve a user for the first
* time if the user hasn't obtained her {@code accessToken } yet
*
* @param resource the resource where properties file lives
* @return returns a fully configured {@link java.util.Properties} instance
* @throws Exception thrown if anythign goes wrong
*/
@SuppressWarnings("unused")
protected static Properties fromResource(Resource resource)
throws Exception {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(resource);
propertiesFactoryBean.setSingleton(true);
propertiesFactoryBean.afterPropertiesSet();
/**
* This probably doesn't belong here. It's more for support for running the {@link OAuthAccessTokenBasedTwitterFactoryBean#main(String[])} or
* {@link OAuthAccessTokenBasedTwitterFactoryBean#main(String[])} methods that run the user through a command line tool to approve a user for the first
* time if the user hasn't obtained her {@code accessToken } yet
*
* @param resource the resource where properties file lives
* @return returns a fully configured {@link java.util.Properties} instance
* @throws Exception thrown if anythign goes wrong
*/
@SuppressWarnings("unused")
protected static Properties fromResource(Resource resource)
throws Exception {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(resource);
propertiesFactoryBean.setSingleton(true);
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
return propertiesFactoryBean.getObject();
}
/**
* provides lifecycle for initiation of the reference. By the time this method is left we should have a fully configured twitter connection that can connect and make calls
* @throws Exception
*/
public void afterPropertiesSet() throws Exception {
synchronized (this.monitor) {
if (this.accessTokenInitialRequestProcessListener == null) {
accessTokenInitialRequestProcessListener = new ConsoleBasedAccessTokenInitialRequestProcessListener();
}
/**
* provides lifecycle for initiation of the reference. By the time this method is left we should have a fully configured twitter connection that can connect and make calls
*
* @throws Exception
*/
public void afterPropertiesSet() throws Exception {
synchronized (this.monitor) {
if (this.accessTokenInitialRequestProcessListener == null) {
accessTokenInitialRequestProcessListener = new ConsoleBasedAccessTokenInitialRequestProcessListener();
}
Assert.notNull(this.configuration.getConsumerKey(), "'consumerKey' mustn't be null");
Assert.notNull(this.configuration.getConsumerSecret(), "'consumerSecret' mustn't be null");
Assert.notNull(this.configuration.getConsumerKey(), "'consumerKey' mustn't be null");
Assert.notNull(this.configuration.getConsumerSecret(), "'consumerSecret' mustn't be null");
AccessToken accessTokenObj;
AccessToken accessTokenObj;
if (StringUtils.hasText(this.configuration.getAccessToken()) && StringUtils.hasText(this.configuration.getAccessTokenSecret())) {
accessTokenObj = new AccessToken(this.configuration.getAccessToken(), this.configuration.getAccessTokenSecret());
} else {
accessTokenObj = initialAuthorizationWizard();
}
if (StringUtils.hasText(this.configuration.getAccessToken()) && StringUtils.hasText(this.configuration.getAccessTokenSecret())) {
accessTokenObj = new AccessToken(this.configuration.getAccessToken(), this.configuration.getAccessTokenSecret());
} else {
accessTokenObj = initialAuthorizationWizard();
}
establishTwitterObject(accessTokenObj);
establishTwitterObject(accessTokenObj);
Assert.notNull(accessTokenObj, "'accessTokenObj' can't be null");
Assert.notNull(accessTokenObj, "'accessTokenObj' can't be null");
this.initialized = true;
}
}
this.initialized = true;
}
}
@SuppressWarnings("unused")
public void setAccessTokenInitialRequestProcessListener(AccessTokenInitialRequestProcessListener accessTokenInitialRequestProcessListener) {
this.accessTokenInitialRequestProcessListener = accessTokenInitialRequestProcessListener;
}
@SuppressWarnings("unused")
public void setAccessTokenInitialRequestProcessListener(AccessTokenInitialRequestProcessListener accessTokenInitialRequestProcessListener) {
this.accessTokenInitialRequestProcessListener = accessTokenInitialRequestProcessListener;
}
public abstract void establishTwitterObject(AccessToken accessToken)
throws Exception;
public abstract void establishTwitterObject(AccessToken accessToken)
throws Exception;
/**
* because we are not able to dereference the {@link twitter4j.Twitter} or {@link twitter4j.AsyncTwitter} instances, we need to ask subclasses to call
* us how to call {@link twitter4j.AsyncTwitter#getOAuthRequestToken()} or {@link twitter4j.Twitter#getOAuthRequestToken()} for us.This method
* will never be evaluated as long as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessToken}
* and {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessTokenSecret} beans are not null.
*
* @return the {@link twitter4j.http.RequestToken} as vended by the service. Ths will contain a verification URl required to obtain an access key and secret.
* @throws Exception thrown if anything should go wrong
*/
public abstract RequestToken getOAuthRequestToken()
throws Exception;
/**
* because we are not able to dereference the {@link twitter4j.Twitter} or {@link twitter4j.AsyncTwitter} instances, we need to ask subclasses to call
* us how to call {@link twitter4j.AsyncTwitter#getOAuthRequestToken()} or {@link twitter4j.Twitter#getOAuthRequestToken()} for us.This method
* will never be evaluated as long as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessToken}
* and {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessTokenSecret} beans are not null.
*
* @return the {@link twitter4j.http.RequestToken} as vended by the service. Ths will contain a verification URl required to obtain an access key and secret.
* @throws Exception thrown if anything should go wrong
*/
public abstract RequestToken getOAuthRequestToken()
throws Exception;
/**
* Only used if the impementation is trying to get an {@link twitter4j.http.AccessToken} for the first time. This method
* will never be evaluated as long as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessToken}
* and {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessTokenSecret} beans are not null.
*
* @param token the initiating {@link twitter4j.http.RequestToken}
* @param pin the string returned from the verification URL
* @return returns the {@link twitter4j.http.AccessToken} fetched from the twitter service.
* @throws Exception thrown if anything should go wrong
*/
public abstract AccessToken getOAuthAccessToken(RequestToken token, String pin)
throws Exception;
/**
* Only used if the impementation is trying to get an {@link twitter4j.http.AccessToken} for the first time. This method
* will never be evaluated as long as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessToken}
* and {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessTokenSecret} beans are not null.
*
* @param token the initiating {@link twitter4j.http.RequestToken}
* @param pin the string returned from the verification URL
* @return returns the {@link twitter4j.http.AccessToken} fetched from the twitter service.
* @throws Exception thrown if anything should go wrong
*/
public abstract AccessToken getOAuthAccessToken(RequestToken token, String pin)
throws Exception;
/**
* Only used if the impementation is trying to get an {@link twitter4j.http.AccessToken} for the first time. This method
* will never be evaluated as long as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessToken}
* and {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessTokenSecret} beans are not null.
*
* @return returns the {@link twitter4j.http.AccessToken} fetched from the twitter service.
* @throws Exception thrown if anything should go wrong
*/
public abstract AccessToken getOAuthAccessToken() throws Exception;
/**
* Only used if the impementation is trying to get an {@link twitter4j.http.AccessToken} for the first time. This method
* will never be evaluated as long as the {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessToken}
* and {@link org.springframework.integration.twitter.oauth.OAuthConfiguration#accessTokenSecret} beans are not null.
*
* @return returns the {@link twitter4j.http.AccessToken} fetched from the twitter service.
* @throws Exception thrown if anything should go wrong
*/
public abstract AccessToken getOAuthAccessToken() throws Exception;
/**
* @return returns the freshly created {@link twitter4j.http.AccessToken} object from the service
* @throws Exception for just about any deviation from the expected
*/
private AccessToken initialAuthorizationWizard() throws Exception {
Assert.notNull(this.accessTokenInitialRequestProcessListener, "'accessTokenInitialRequestProcessListener' can't be null");
/**
* @return returns the freshly created {@link twitter4j.http.AccessToken} object from the service
* @throws Exception for just about any deviation from the expected
*/
private AccessToken initialAuthorizationWizard() throws Exception {
Assert.notNull(this.accessTokenInitialRequestProcessListener, "'accessTokenInitialRequestProcessListener' can't be null");
try {
RequestToken requestToken = getOAuthRequestToken();
String pin = this.accessTokenInitialRequestProcessListener.openUrlAndReturnPin(requestToken.getAuthorizationURL());
AccessToken at = StringUtils.hasText(pin) ? getOAuthAccessToken(requestToken, pin) : getOAuthAccessToken();
this.accessTokenInitialRequestProcessListener.persistReturnedAccessToken(at);
try {
RequestToken requestToken = getOAuthRequestToken();
String pin = this.accessTokenInitialRequestProcessListener.openUrlAndReturnPin(requestToken.getAuthorizationURL());
AccessToken at = StringUtils.hasText(pin) ? getOAuthAccessToken(requestToken, pin) : getOAuthAccessToken();
this.accessTokenInitialRequestProcessListener.persistReturnedAccessToken(at);
return at;
} catch (Throwable th) {
this.accessTokenInitialRequestProcessListener.failure(th);
}
return at;
} catch (Throwable th) {
this.accessTokenInitialRequestProcessListener.failure(th);
}
return null;
}
return null;
}
/**
* Responsibility of subclasses to call this because we cant dereference the generic type appropriately. The responsibility is
* to call {@link twitter4j.Twitter#verifyCredentials()} or {@link twitter4j.AsyncTwitter#verifyCredentials()} as appropriate
*
* @throws Exception if there's an inability to authenticate
*/
public abstract void verifyCredentials() throws Exception;
/**
* Responsibility of subclasses to call this because we cant dereference the generic type appropriately. The responsibility is
* to call {@link twitter4j.Twitter#verifyCredentials()} or {@link twitter4j.AsyncTwitter#verifyCredentials()} as appropriate
*
* @throws Exception if there's an inability to authenticate
*/
public abstract void verifyCredentials() throws Exception;
/**
* Rubber meets the road: builds up a reference to the twitter4j.(Async)Twitter instance
*
* @return the instance
* @throws Exception thrown in case some condition isn't met correctly in construction
*/
public T getObject() throws Exception {
if (!initialized) {
afterPropertiesSet();
}
/**
* Rubber meets the road: builds up a reference to the twitter4j.(Async)Twitter instance
*
* @return the instance
* @throws Exception thrown in case some condition isn't met correctly in construction
*/
public T getObject() throws Exception {
if (!initialized) {
afterPropertiesSet();
}
return this.twitter;
}
return this.twitter;
}
/**
* this method is delegated to implementations because we can't correctly dereference the generic type's class
*
* @return a class
*/
abstract public Class<?> getObjectType();
/**
* this method is delegated to implementations because we can't correctly dereference the generic type's class
*
* @return a class
*/
abstract public Class<?> getObjectType();
/**
* Standard {@link org.springframework.beans.factory.FactoryBean} method. Implementations may override if there's a specific method
*
* @return whether or not this is a singleton
*/
public boolean isSingleton() {
return true;
}
/**
* Standard {@link org.springframework.beans.factory.FactoryBean} method. Implementations may override if there's a specific method
*
* @return whether or not this is a singleton
*/
public boolean isSingleton() {
return true;
}
}

View File

@@ -26,14 +26,15 @@ import twitter4j.http.AccessToken;
* @author Josh Long
*/
public interface AccessTokenInitialRequestProcessListener {
String openUrlAndReturnPin(String urlToOpen) throws Exception;
String openUrlAndReturnPin(String urlToOpen) throws Exception;
void persistReturnedAccessToken(AccessToken accessToken)
throws Exception;
void persistReturnedAccessToken(AccessToken accessToken)
throws Exception;
/**
* Callback in case something goes wrong at any point in the process. Up to client to intervene
* @param t the exception thrown (if any). Could be null if none available
*/
void failure(Throwable t);
/**
* Callback in case something goes wrong at any point in the process. Up to client to intervene
*
* @param t the exception thrown (if any). Could be null if none available
*/
void failure(Throwable t);
}

View File

@@ -19,11 +19,12 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import twitter4j.http.AccessToken;
import java.io.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -35,33 +36,33 @@ import java.util.Properties;
* @author Josh Long
*/
public class ConsoleBasedAccessTokenInitialRequestProcessListener implements AccessTokenInitialRequestProcessListener {
public String openUrlAndReturnPin(String urlToOpen)
throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Open the following URL and grant access to your account:");
System.out.println(urlToOpen);
System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
public String openUrlAndReturnPin(String urlToOpen)
throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Open the following URL and grant access to your account:");
System.out.println(urlToOpen);
System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
return StringUtils.trim(br.readLine());
}
return StringUtils.trim(br.readLine());
}
public void persistReturnedAccessToken(AccessToken accessToken)
throws Exception {
Map<String, String> output = new HashMap<String, String>();
output.put(OAuthConfigurationFactoryBean.WELL_KNOWN_CONSUMER_ACCESS_TOKEN, accessToken.getToken());
output.put(OAuthConfigurationFactoryBean.WELL_KNOWN_CONSUMER_ACCESS_TOKEN_SECRET, accessToken.getTokenSecret());
public void persistReturnedAccessToken(AccessToken accessToken)
throws Exception {
Map<String, String> output = new HashMap<String, String>();
output.put(OAuthConfigurationFactoryBean.WELL_KNOWN_CONSUMER_ACCESS_TOKEN, accessToken.getToken());
output.put(OAuthConfigurationFactoryBean.WELL_KNOWN_CONSUMER_ACCESS_TOKEN_SECRET, accessToken.getTokenSecret());
File accessTokenCreds = new File(SystemUtils.getJavaIoTmpDir(), "twitter-accesstoken.properties");
FileOutputStream fileOutputStream = new FileOutputStream(accessTokenCreds);
Properties props = new Properties();
props.putAll(output);
props.store(fileOutputStream, "oauth-access-token");
IOUtils.closeQuietly(fileOutputStream);
File accessTokenCreds = new File(SystemUtils.getJavaIoTmpDir(), "twitter-accesstoken.properties");
FileOutputStream fileOutputStream = new FileOutputStream(accessTokenCreds);
Properties props = new Properties();
props.putAll(output);
props.store(fileOutputStream, "oauth-access-token");
IOUtils.closeQuietly(fileOutputStream);
System.out.println("The oauth accesstoken credentials have been written to " + accessTokenCreds.getAbsolutePath());
}
System.out.println("The oauth accesstoken credentials have been written to " + accessTokenCreds.getAbsolutePath());
}
public void failure(Throwable t) {
System.err.println("Exception occurred when trying to retrieve credentials: " + ExceptionUtils.getFullStackTrace(t));
}
public void failure(Throwable t) {
System.err.println("Exception occurred when trying to retrieve credentials: " + ExceptionUtils.getFullStackTrace(t));
}
}

View File

@@ -17,75 +17,71 @@ package org.springframework.integration.twitter.oauth;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.core.io.FileSystemResource;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;
import java.io.File;
import java.util.Properties;
public class OAuthAccessTokenBasedTwitterFactoryBean extends AbstractOAuthAccessTokenBasedFactoryBean<Twitter> {
protected OAuthAccessTokenBasedTwitterFactoryBean(OAuthConfiguration configuration) {
super(configuration);
}
protected OAuthAccessTokenBasedTwitterFactoryBean(OAuthConfiguration configuration) {
super(configuration);
}
@Override
public void establishTwitterObject(AccessToken accessToken)
throws Exception {
this.twitter = new TwitterFactory().getOAuthAuthorizedInstance(this.configuration.getConsumerKey(), this.configuration.getConsumerSecret(), accessToken);
}
@Override
public void establishTwitterObject(AccessToken accessToken)
throws Exception {
this.twitter = new TwitterFactory().getOAuthAuthorizedInstance(this.configuration.getConsumerKey(), this.configuration.getConsumerSecret(), accessToken);
}
@Override
public RequestToken getOAuthRequestToken() throws Exception {
return twitter.getOAuthRequestToken();
}
@Override
public RequestToken getOAuthRequestToken() throws Exception {
return twitter.getOAuthRequestToken();
}
@Override
public void verifyCredentials() throws Exception {
this.twitter.verifyCredentials();
}
@Override
public void verifyCredentials() throws Exception {
this.twitter.verifyCredentials();
}
@Override
public AccessToken getOAuthAccessToken(RequestToken token, String pin)
throws Exception {
return this.twitter.getOAuthAccessToken(token, pin);
}
@Override
public AccessToken getOAuthAccessToken(RequestToken token, String pin)
throws Exception {
return this.twitter.getOAuthAccessToken(token, pin);
}
@Override
public AccessToken getOAuthAccessToken() throws Exception {
return this.twitter.getOAuthAccessToken();
}
@Override
public AccessToken getOAuthAccessToken() throws Exception {
return this.twitter.getOAuthAccessToken();
}
@Override
public Class<?> getObjectType() {
return Twitter.class;
}
@Override
public Class<?> getObjectType() {
return Twitter.class;
}
public static void main(String[] args) throws Throwable {
File propsFile = new File(new File(SystemUtils.getUserHome(), "Desktop"), "twitter.properties");
FileSystemResource fileSystemResource = new FileSystemResource(propsFile);
Properties properties = fromResource(fileSystemResource);
public static void main(String[] args) throws Throwable {
File propsFile = new File(new File(SystemUtils.getUserHome(), "Desktop"), "twitter.properties");
FileSystemResource fileSystemResource = new FileSystemResource(propsFile);
Properties properties = fromResource(fileSystemResource);
OAuthConfigurationFactoryBean oAuthConfigurationFactoryBean = new OAuthConfigurationFactoryBean();
oAuthConfigurationFactoryBean.bootstrapFromProperties(properties);
OAuthConfigurationFactoryBean oAuthConfigurationFactoryBean = new OAuthConfigurationFactoryBean();
oAuthConfigurationFactoryBean.bootstrapFromProperties(properties);
OAuthConfiguration configuration = oAuthConfigurationFactoryBean.getObject();
OAuthConfiguration configuration = oAuthConfigurationFactoryBean.getObject();
Twitter twitter = configuration.getTwitter();
Twitter twitter = configuration.getTwitter();
System.out.println("Used the " + OAuthAccessTokenBasedTwitterFactoryBean.class.getName() + " and arrived at " + ToStringBuilder.reflectionToString(twitter));
System.out.println("Used the " + OAuthAccessTokenBasedTwitterFactoryBean.class.getName() + " and arrived at " + ToStringBuilder.reflectionToString(twitter));
ResponseList<Status> friendsTimeline = twitter.getFriendsTimeline();
System.out.println("Friends' timeline " + friendsTimeline);
Thread.sleep(10000);
}
ResponseList<Status> friendsTimeline = twitter.getFriendsTimeline();
System.out.println("Friends' timeline " + friendsTimeline);
Thread.sleep(10000);
}
}

View File

@@ -25,71 +25,74 @@ import twitter4j.Twitter;
* client should store this bean and simply lookup the Twitter configuration from there
*/
public class OAuthConfiguration {
//
// private AsyncTwitter asyncTwitter;
private Twitter twitter;
private volatile String consumerKey;
private volatile String consumerSecret;
private volatile String accessToken;
private volatile String accessTokenSecret;
//
// private AsyncTwitter asyncTwitter;
private Twitter twitter;
private volatile String consumerKey;
private volatile String consumerSecret;
private volatile String accessToken;
private volatile String accessTokenSecret;
public OAuthConfiguration(String consumerKey, String consumerSecret, String accessToken, String accessTokenSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.accessToken = accessToken;
this.accessTokenSecret = accessTokenSecret;
}
public OAuthConfiguration(String consumerKey, String consumerSecret, String accessToken, String accessTokenSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.accessToken = accessToken;
this.accessTokenSecret = accessTokenSecret;
}
/** package friendly */
/* void setAsyncTwitter(AsyncTwitter asyncTwitter) {
this.asyncTwitter = asyncTwitter;
}*/
/** package friendly */
/* void setAsyncTwitter(AsyncTwitter asyncTwitter) {
this.asyncTwitter = asyncTwitter;
}*/
/** package friendly */
void setTwitter(Twitter twitter) {
this.twitter = twitter;
}
/**
* package friendly
*/
void setTwitter(Twitter twitter) {
this.twitter = twitter;
}
/**
* @return
*/
public Twitter getTwitter() {
return twitter;
}
/**
* @return
*/
public Twitter getTwitter() {
return twitter;
}
/*
public AsyncTwitter getAsyncTwitter() {
return asyncTwitter;
}*/
public String getConsumerKey() {
return consumerKey;
}
/*
public AsyncTwitter getAsyncTwitter() {
return asyncTwitter;
}*/
public void setConsumerKey(String consumerKey) {
this.consumerKey = consumerKey;
}
public String getConsumerKey() {
return consumerKey;
}
public String getConsumerSecret() {
return consumerSecret;
}
public void setConsumerKey(String consumerKey) {
this.consumerKey = consumerKey;
}
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public String getConsumerSecret() {
return consumerSecret;
}
public String getAccessToken() {
return accessToken;
}
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getAccessToken() {
return accessToken;
}
public String getAccessTokenSecret() {
return accessTokenSecret;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public void setAccessTokenSecret(String accessTokenSecret) {
this.accessTokenSecret = accessTokenSecret;
}
public String getAccessTokenSecret() {
return accessTokenSecret;
}
public void setAccessTokenSecret(String accessTokenSecret) {
this.accessTokenSecret = accessTokenSecret;
}
}

View File

@@ -16,9 +16,7 @@
package org.springframework.integration.twitter.oauth;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.Assert;
import twitter4j.Twitter;
import java.util.Properties;
@@ -31,73 +29,73 @@ import java.util.Properties;
* @since 2.0
*/
public class OAuthConfigurationFactoryBean implements FactoryBean<OAuthConfiguration> {
public static final String WELL_KNOWN_CONSUMER_KEY = "twitter.oauth.consumerKey";
public static final String WELL_KNOWN_CONSUMER_KEY_SECRET = "twitter.oauth.consumerSecret";
public static final String WELL_KNOWN_CONSUMER_ACCESS_TOKEN = "twitter.oauth.accessToken";
public static final String WELL_KNOWN_CONSUMER_ACCESS_TOKEN_SECRET = "twitter.oauth.accessTokenSecret";
private volatile String consumerKey;
private volatile String consumerSecret;
private volatile String accessToken;
private volatile String accessTokenSecret;
private Twitter twitter;
private volatile OAuthConfiguration oAuthConfiguration;
private final Object guard = new Object();
public static final String WELL_KNOWN_CONSUMER_KEY = "twitter.oauth.consumerKey";
public static final String WELL_KNOWN_CONSUMER_KEY_SECRET = "twitter.oauth.consumerSecret";
public static final String WELL_KNOWN_CONSUMER_ACCESS_TOKEN = "twitter.oauth.accessToken";
public static final String WELL_KNOWN_CONSUMER_ACCESS_TOKEN_SECRET = "twitter.oauth.accessTokenSecret";
private volatile String consumerKey;
private volatile String consumerSecret;
private volatile String accessToken;
private volatile String accessTokenSecret;
private Twitter twitter;
private volatile OAuthConfiguration oAuthConfiguration;
private final Object guard = new Object();
private Twitter twitter(OAuthConfiguration oAuthConfiguration)
throws Exception {
OAuthAccessTokenBasedTwitterFactoryBean twitterFactoryBean = new OAuthAccessTokenBasedTwitterFactoryBean(oAuthConfiguration);
twitterFactoryBean.afterPropertiesSet();
twitterFactoryBean.verifyCredentials();
private Twitter twitter(OAuthConfiguration oAuthConfiguration)
throws Exception {
OAuthAccessTokenBasedTwitterFactoryBean twitterFactoryBean = new OAuthAccessTokenBasedTwitterFactoryBean(oAuthConfiguration);
twitterFactoryBean.afterPropertiesSet();
twitterFactoryBean.verifyCredentials();
return twitterFactoryBean.getObject();
}
return twitterFactoryBean.getObject();
}
protected void bootstrapFromProperties(Properties props)
throws Throwable {
Assert.notNull(props, "'properties' must not be null");
this.setAccessToken(props.getProperty(WELL_KNOWN_CONSUMER_ACCESS_TOKEN));
this.setAccessTokenSecret(props.getProperty(WELL_KNOWN_CONSUMER_ACCESS_TOKEN_SECRET));
this.setConsumerKey(props.getProperty(WELL_KNOWN_CONSUMER_KEY));
this.setConsumerSecret(props.getProperty(WELL_KNOWN_CONSUMER_KEY_SECRET));
}
protected void bootstrapFromProperties(Properties props)
throws Throwable {
Assert.notNull(props, "'properties' must not be null");
this.setAccessToken(props.getProperty(WELL_KNOWN_CONSUMER_ACCESS_TOKEN));
this.setAccessTokenSecret(props.getProperty(WELL_KNOWN_CONSUMER_ACCESS_TOKEN_SECRET));
this.setConsumerKey(props.getProperty(WELL_KNOWN_CONSUMER_KEY));
this.setConsumerSecret(props.getProperty(WELL_KNOWN_CONSUMER_KEY_SECRET));
}
public OAuthConfiguration getObject() throws Exception {
return build();
}
public OAuthConfiguration getObject() throws Exception {
return build();
}
public Class<?> getObjectType() {
return OAuthConfiguration.class;
}
public Class<?> getObjectType() {
return OAuthConfiguration.class;
}
public boolean isSingleton() {
return true;
}
public boolean isSingleton() {
return true;
}
public void setConsumerKey(String consumerKey) {
this.consumerKey = consumerKey;
}
public void setConsumerKey(String consumerKey) {
this.consumerKey = consumerKey;
}
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public void setAccessTokenSecret(String accessTokenSecret) {
this.accessTokenSecret = accessTokenSecret;
}
public void setAccessTokenSecret(String accessTokenSecret) {
this.accessTokenSecret = accessTokenSecret;
}
private OAuthConfiguration build() throws Exception {
synchronized (this.guard) {
if (oAuthConfiguration == null) {
oAuthConfiguration = new OAuthConfiguration(this.consumerKey, this.consumerSecret, this.accessToken, this.accessTokenSecret);
twitter = this.twitter(oAuthConfiguration);
oAuthConfiguration.setTwitter(twitter);
}
}
private OAuthConfiguration build() throws Exception {
synchronized (this.guard) {
if (oAuthConfiguration == null) {
oAuthConfiguration = new OAuthConfiguration(this.consumerKey, this.consumerSecret, this.accessToken, this.accessTokenSecret);
twitter = this.twitter(oAuthConfiguration);
oAuthConfiguration.setTwitter(twitter);
}
}
return this.oAuthConfiguration;
}
return this.oAuthConfiguration;
}
}

View File

@@ -16,204 +16,196 @@
-->
<xsd:schema xmlns="http://www.springframework.org/schema/integration/twitter"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:integration="http://www.springframework.org/schema/integration"
targetNamespace="http://www.springframework.org/schema/integration/twitter"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:integration="http://www.springframework.org/schema/integration"
targetNamespace="http://www.springframework.org/schema/integration/twitter"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"/>
<xsd:element name="twitter-connection">
<xsd:annotation>
<xsd:documentation>
Sets up an instance of OAuthConfiguration which all adapters need to function properly
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="consumer-key" type="xsd:string" use="required"/>
<xsd:attribute name="consumer-secret" type="xsd:string" use="required"/>
<xsd:attribute name="access-token" type="xsd:string" use="required"/>
<xsd:attribute name="access-token-secret" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="twitter-connection">
<xsd:annotation>
<xsd:documentation>
Sets up an instance of OAuthConfiguration which all adapters need to function properly
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="consumer-key" type="xsd:string" use="required"/>
<xsd:attribute name="consumer-secret" type="xsd:string" use="required"/>
<xsd:attribute name="access-token" type="xsd:string" use="required"/>
<xsd:attribute name="access-token-secret" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!--
This defines the beans we have for working with Twitter
-->
<xsd:element name="inbound-mention-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing mentions of your handle)
from twitter and sends Messages whose payloads are Status objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute use="required" name="twitter-connection" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<!-- <xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="password" type="xsd:string" use="required"/>-->
</xsd:complexType>
</xsd:element>
<!--
This defines the beans we have for working with Twitter
-->
<xsd:element name="inbound-mention-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing mentions of your handle)
from twitter and sends Messages whose payloads are Status objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute use="required" name="twitter-connection" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<!-- <xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="password" type="xsd:string" use="required"/>-->
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-dm-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes direct messages and forwards them to Spring Integration
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<!--<xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="password" type="xsd:string" use="required"/>-->
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-update-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing your friends' timeline updates)
from twitter and sends Messages whose payloads are Tweet objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<!--
OUTBOUND
-->
<xsd:element name="outbound-dm-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing your friends' timeline updates)
from twitter and sends Messages whose payloads are Tweet objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="outbound-update-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing your friends' timeline updates)
from twitter and sends Messages whose payloads are Tweet objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-dm-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes direct messages and forwards them to Spring Integration
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<!--<xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="password" type="xsd:string" use="required"/>-->
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-update-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing your friends' timeline updates)
from twitter and sends Messages whose payloads are Tweet objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<!--
OUTBOUND
-->
<xsd:element name="outbound-dm-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing your friends' timeline updates)
from twitter and sends Messages whose payloads are Tweet objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="outbound-update-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures an inbound channel adapter that consumes message (representing your friends' timeline updates)
from twitter and sends Messages whose payloads are Tweet objects.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="twitter-connection" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.twitter.oauth.OAuthConfiguration"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -4,20 +4,15 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.twitter.oauth.OAuthConfiguration;
import org.springframework.test.context.ContextConfiguration;
import twitter4j.Status;
import twitter4j.Twitter;
import java.util.Collection;
/**
* This class is used to simply demonstrating correctly factory-ing a {@link twitter4j.Twitter} instance
*
@@ -25,21 +20,21 @@ import java.util.Collection;
*/
@ContextConfiguration(locations = "twitter_connection_using_ns.xml")
public class SimpleTwitterTestClient {
private Twitter twitter;
@Autowired
private volatile OAuthConfiguration oAuthConfiguration;
private Twitter twitter;
@Autowired
private volatile OAuthConfiguration oAuthConfiguration;
@Before
public void begin() throws Exception {
this.twitter = oAuthConfiguration.getTwitter();
}
@Before
public void begin() throws Exception {
this.twitter = oAuthConfiguration.getTwitter();
}
@Test
@Ignore
public void testConnectivity() throws Throwable {
Collection<Status> responses;
Assert.assertNotNull(this.twitter);
Assert.assertNotNull(responses = this.twitter.getFriendsTimeline());
Assert.assertTrue(responses.size() > 0);
}
@Test
@Ignore
public void testConnectivity() throws Throwable {
Collection<Status> responses;
Assert.assertNotNull(this.twitter);
Assert.assertNotNull(responses = this.twitter.getFriendsTimeline());
Assert.assertTrue(responses.size() > 0);
}
}

View File

@@ -17,9 +17,7 @@ package org.springframework.integration.twitter;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
@@ -27,22 +25,22 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
/**
* @author Josh Long
*/
@ContextConfiguration(locations = {
"/receiving_dms_using_ns.xml"}
@ContextConfiguration(locations = {
"/receiving_dms_using_ns.xml"}
)
public class TestRecievingUsingNamespace extends AbstractJUnit4SpringContextTests {
@Autowired
private TwitterAnnouncer twitterAnnouncer;
@Autowired
private TwitterAnnouncer twitterAnnouncer;
@Test
@Ignore
public void testIt() throws Throwable {
long ctr = 0;
long s = 1000;
@Test
@Ignore
public void testIt() throws Throwable {
long ctr = 0;
long s = 1000;
while (ctr < (s * 60 * 3)) {
Thread.sleep(s);
ctr += s;
}
}
while (ctr < (s * 60 * 3)) {
Thread.sleep(s);
ctr += s;
}
}
}

View File

@@ -17,48 +17,42 @@ package org.springframework.integration.twitter;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.util.StringUtils;
import twitter4j.GeoLocation;
/**
* @author Josh Long
*/
@ContextConfiguration(locations = {
"/sending_dms_using_ns.xml"}
@ContextConfiguration(locations = {
"/sending_dms_using_ns.xml"}
)
public class TestSendingDMsUsingNamespace extends AbstractJUnit4SpringContextTests {
private volatile MessagingTemplate messagingTemplate = new MessagingTemplate();
@Value("#{out}")
private MessageChannel channel;
private volatile MessagingTemplate messagingTemplate = new MessagingTemplate();
@Value("#{out}")
private MessageChannel channel;
@Test
@Ignore
public void testSendingATweet() throws Throwable {
String dmUsr = System.getProperties().getProperty("twitter.dm.user");
MessageBuilder<String> mb = MessageBuilder.withPayload("'Hello world!', from the Spring Integration outbound Twitter adapter")
.setHeader(TwitterHeaders.TWITTER_GEOLOCATION, new GeoLocation(-76.226823, 23.642465)) // antarctica
.setHeader(TwitterHeaders.TWITTER_DISPLAY_COORDINATES, true);
@Test
@Ignore
public void testSendingATweet() throws Throwable {
String dmUsr = System.getProperties().getProperty("twitter.dm.user");
MessageBuilder<String> mb = MessageBuilder.withPayload("'Hello world!', from the Spring Integration outbound Twitter adapter")
.setHeader(TwitterHeaders.TWITTER_GEOLOCATION, new GeoLocation(-76.226823, 23.642465)) // antarctica
.setHeader(TwitterHeaders.TWITTER_DISPLAY_COORDINATES, true);
if (StringUtils.hasText(dmUsr)) {
mb.setHeader(TwitterHeaders.TWITTER_DM_TARGET_USER_ID, dmUsr);
}
if (StringUtils.hasText(dmUsr)) {
mb.setHeader(TwitterHeaders.TWITTER_DM_TARGET_USER_ID, dmUsr);
}
Message<String> m = mb.build();
Message<String> m = mb.build();
this.messagingTemplate.send(this.channel, m);
}
this.messagingTemplate.send(this.channel, m);
}
}

View File

@@ -17,42 +17,35 @@ package org.springframework.integration.twitter;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.util.StringUtils;
import twitter4j.GeoLocation;
/**
* @author Josh Long
*/
@ContextConfiguration(locations = {
"/sending_updates_using_ns.xml"}
@ContextConfiguration(locations = {
"/sending_updates_using_ns.xml"}
)
public class TestSendingUpdatesUsingNamespace extends AbstractJUnit4SpringContextTests {
private MessagingTemplate messagingTemplate = new MessagingTemplate();
@Value("#{out}")
private MessageChannel channel;
private MessagingTemplate messagingTemplate = new MessagingTemplate();
@Value("#{out}")
private MessageChannel channel;
@Test
@Ignore
public void testSendingATweet() throws Throwable {
MessageBuilder<String> mb = MessageBuilder.withPayload("'Hello world!', from the Spring Integration outbound Twitter adapter")
.setHeader(TwitterHeaders.TWITTER_IN_REPLY_TO_STATUS_ID, 21927437001L)
.setHeader(TwitterHeaders.TWITTER_GEOLOCATION, new GeoLocation(-76.226823, 23.642465)) // antarctica
.setHeader(TwitterHeaders.TWITTER_DISPLAY_COORDINATES, true);
Message<String> m = mb.build();
this.messagingTemplate.send(this.channel, m);
}
@Test
@Ignore
public void testSendingATweet() throws Throwable {
MessageBuilder<String> mb = MessageBuilder.withPayload("'Hello world!', from the Spring Integration outbound Twitter adapter")
.setHeader(TwitterHeaders.TWITTER_IN_REPLY_TO_STATUS_ID, 21927437001L)
.setHeader(TwitterHeaders.TWITTER_GEOLOCATION, new GeoLocation(-76.226823, 23.642465)) // antarctica
.setHeader(TwitterHeaders.TWITTER_DISPLAY_COORDINATES, true);
Message<String> m = mb.build();
this.messagingTemplate.send(this.channel, m);
}
}

View File

@@ -1,22 +1,21 @@
package org.springframework.integration.twitter;
import org.springframework.stereotype.Component;
import twitter4j.DirectMessage;
import twitter4j.Status;
@Component
public class TwitterAnnouncer {
public void dm(DirectMessage directMessage) {
System.out.println("A direct message has been received from " + directMessage.getSenderScreenName() + " with text " + directMessage.getText());
}
public void dm(DirectMessage directMessage) {
System.out.println("A direct message has been received from " + directMessage.getSenderScreenName() + " with text " + directMessage.getText());
}
public void mention(Status s) {
System.out.println("A tweet mentioning (or replying) to " + "you was received having text " + s.getText() + " from " + s.getSource());
}
public void mention(Status s) {
System.out.println("A tweet mentioning (or replying) to " + "you was received having text " + s.getText() + " from " + s.getSource());
}
public void friendsTimelineUpdated(Status t) {
System.out.println("Received " + t.getText() + " from " + t.getSource());
}
public void friendsTimelineUpdated(Status t) {
System.out.println("Received " + t.getText() + " from " + t.getSource());
}
}

View File

@@ -17,49 +17,47 @@
-->
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<channel id="inbound_dm"/>
<channel id="inbound_dm"/>
<twitter:inbound-dm-channel-adapter
channel="inbound_dm" twitter-connection="tc"
/>
<twitter:inbound-dm-channel-adapter
channel="inbound_dm" twitter-connection="tc"
/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<service-activator input-channel="inbound_dm"
ref="twitterAnnouncer"
method="dm"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<service-activator input-channel="inbound_dm"
ref="twitterAnnouncer"
method="dm"/>
</beans:beans>

View File

@@ -17,44 +17,43 @@
-->
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<channel id="inbound_tweets"/>
<channel id="inbound_tweets"/>
<twitter:inbound-mention-channel-adapter twitter-connection="tc" channel="inbound_tweets"/>
<twitter:inbound-mention-channel-adapter twitter-connection="tc" channel="inbound_tweets" />
<service-activator input-channel="inbound_tweets" ref="twitterAnnouncer" method="mention"/>
<service-activator input-channel="inbound_tweets" ref="twitterAnnouncer" method="mention"/>
</beans:beans>

View File

@@ -17,50 +17,50 @@
-->
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<channel id="inbound_tweets"/>
<channel id="inbound_tweets"/>
<twitter:inbound-update-channel-adapter
twitter-connection="tc"
channel="inbound_tweets"
/>
<twitter:inbound-update-channel-adapter
twitter-connection="tc"
channel="inbound_tweets"
/>
<service-activator input-channel="inbound_tweets"
ref="twitterAnnouncer"
method="friendsTimelineUpdated"/>
<service-activator input-channel="inbound_tweets"
ref="twitterAnnouncer"
method="friendsTimelineUpdated"/>
</beans:beans>

View File

@@ -17,47 +17,41 @@
-->
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<channel id="out"/>
<twitter:outbound-dm-channel-adapter twitter-connection="tc" channel="out"/>
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<channel id="out"/>
<twitter:outbound-dm-channel-adapter twitter-connection="tc" channel="out"/>
</beans:beans>

View File

@@ -17,47 +17,41 @@
-->
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<channel id="out"/>
<twitter:outbound-update-channel-adapter twitter-connection="tc" channel="out"/>
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<channel id="out"/>
<twitter:outbound-update-channel-adapter twitter-connection="tc" channel="out"/>
</beans:beans>

View File

@@ -17,39 +17,39 @@
-->
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/integration/twitter http://www.springframework.org/schema/integration/twitter/spring-integration-twitter.xsd">
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:component-scan
base-package="org.springframework.integration.twitter"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<context:property-placeholder
location="file://${user.home}/Desktop/twitter.properties"
ignore-unresolvable="true"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<beans:bean class="org.springframework.integration.twitter.SimpleTwitterTestClient"/>
<twitter:twitter-connection
id="tc"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
/>
<beans:bean class="org.springframework.integration.twitter.SimpleTwitterTestClient"/>
</beans:beans>