blob: a0269a54116fdb722ce4b0b3c385cab4da2a8f4b [file] [log] [blame]
/*
*/
package org.taverna.server.master.notification;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Properties;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.conf.Configuration;
import twitter4j.conf.PropertyConfiguration;
import twitter4j.auth.AuthorizationFactory;
/**
* Super simple-minded twitter dispatcher. You need to tell it your consumer key
* and secret as part of the connection parameters, for example via a dispatcher
* URN of "<tt>twitter:fred:bloggs</tt>" where <tt>fred</tt> is the key and
* <tt>bloggs</tt> is the secret.
*
* @author Donal Fellows
*/
public class TwitterDispatcher extends RateLimitedDispatcher {
@Override
public String getName() {
return "twitter";
}
public static final int MAX_MESSAGE_LENGTH = 140;
public static final char ELLIPSIS = '\u2026';
private String token = "";
private String secret = "";
public void setAccessToken(String token) {
this.token = valid(token, "");
}
public void setAccessSecret(String secret) {
this.secret = valid(secret, "");
}
private Properties getConfig() throws NotConfiguredException {
if (token.isEmpty() || secret.isEmpty())
throw new NotConfiguredException();
Properties p = new Properties();
p.setProperty(ACCESS_TOKEN_PROP, token);
p.setProperty(ACCESS_SECRET_PROP, secret);
return p;
}
public static final String ACCESS_TOKEN_PROP = "oauth.accessToken";
public static final String ACCESS_SECRET_PROP = "oauth.accessTokenSecret";
private Twitter getTwitter(String key, String secret) throws Exception {
if (key.isEmpty() || secret.isEmpty())
throw new NoCredentialsException();
Properties p = getConfig();
p.setProperty("oauth.consumerKey", key);
p.setProperty("oauth.consumerSecret", secret);
Configuration config = new PropertyConfiguration(p);
TwitterFactory factory = new TwitterFactory(config);
Twitter t = factory.getInstance(AuthorizationFactory
.getInstance(config));
// Verify that we can connect!
t.getOAuthAccessToken();
return t;
}
// TODO: Get secret from credential manager
@Override
public void dispatch(String messageSubject, String messageContent,
String targetParameter) throws Exception {
// messageSubject ignored
String[] target = targetParameter.split(":", 2);
if (target == null || target.length != 2)
throw new Exception("missing consumer key or secret");
String who = target[0];
if (!isSendAllowed(who))
return;
Twitter twitter = getTwitter(who, target[1]);
if (messageContent.length() > MAX_MESSAGE_LENGTH)
messageContent = messageContent
.substring(0, MAX_MESSAGE_LENGTH - 1) + ELLIPSIS;
twitter.updateStatus(messageContent);
}
@Override
public boolean isAvailable() {
try {
// Try to create the configuration and push it through as far as
// confirming that we can build an access object (even if it isn't
// bound to a user)
new TwitterFactory(new PropertyConfiguration(getConfig()))
.getInstance();
return true;
} catch (Exception e) {
return false;
}
}
/**
* Indicates that the dispatcher has not been configured with service
* credentials.
*
* @author Donal Fellows
*/
@SuppressWarnings("serial")
public static class NotConfiguredException extends Exception {
NotConfiguredException() {
super("not configured with xAuth key and secret; "
+ "dispatch not possible");
}
}
/**
* Indicates that the user did not supply their credentials.
*
* @author Donal Fellows
*/
@SuppressWarnings("serial")
public static class NoCredentialsException extends Exception {
NoCredentialsException() {
super("no consumer key and secret present; "
+ "dispatch not possible");
}
}
}