Java tutorial
/* * Copyright 2007 Yusuke Yamamoto * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package mx.bigdata.t4j; import twitter4j.*; import twitter4j.auth.Authorization; import twitter4j.conf.Configuration; import twitter4j.auth.AccessToken; import twitter4j.auth.NullAuthorization; import twitter4j.auth.OAuthSupport; import twitter4j.auth.OAuthAuthorization; import twitter4j.internal.http.HttpClientWrapper; import twitter4j.internal.http.HttpClientWrapperConfiguration; import twitter4j.internal.http.HttpParameter; import twitter4j.internal.util.T4JInternalStringUtil; import twitter4j.internal.http.HttpResponse; import twitter4j.internal.json.DataObjectFactoryUtil; import java.net.SocketTimeoutException; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.EOFException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import static twitter4j.internal.http.HttpResponseCode.FORBIDDEN; import static twitter4j.internal.http.HttpResponseCode.NOT_ACCEPTABLE; /** * A java representation of the <a href="http://dev.twitter.com/pages/streaming_api_methods">Streaming API: Methods</a><br> * Note that this class is NOT compatible with Google App Engine as GAE * is not capable of handling requests longer than 30 seconds. * * @author Yusuke Yamamoto - yusuke at mac.com * @since Twitter4J 2.0.4 */ class TwitterStreamImpl implements TwitterStream { protected Authorization auth; protected Configuration conf; private final HttpClientWrapper http; private final static Logger logger = Logger.getLogger(TwitterStreamImpl.class.getName()); private final StreamListener streamListener; TwitterStreamImpl(Configuration conf, Authorization auth, StreamListener streamListener) { //super(conf, auth); this.conf = conf; this.auth = auth; init(); this.http = new HttpClientWrapper(new StreamingReadTimeoutConfiguration(conf)); this.streamListener = streamListener; } TwitterStreamImpl(Configuration conf, StreamListener streamListener) { //super(conf); this.conf = conf; init(); this.http = new HttpClientWrapper(new StreamingReadTimeoutConfiguration(conf)); this.streamListener = streamListener; } private void init() { if (null == auth) { // try to populate OAuthAuthorization if available in the configuration String consumerKey = conf.getOAuthConsumerKey(); String consumerSecret = conf.getOAuthConsumerSecret(); // try to find oauth tokens in the configuration if (null != consumerKey && null != consumerSecret) { OAuthAuthorization oauth = new OAuthAuthorization(conf); String accessToken = conf.getOAuthAccessToken(); String accessTokenSecret = conf.getOAuthAccessTokenSecret(); if (null != accessToken && null != accessTokenSecret) { oauth.setOAuthAccessToken(new AccessToken(accessToken, accessTokenSecret)); } this.auth = oauth; } else { this.auth = NullAuthorization.getInstance(); } } } /* Streaming API */ /** * {@inheritDoc} */ public TwitterStreamConsumer firehose(final int count) { ensureAuthorizationEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { return getFirehoseStream(count); } }, streamListener); } /** * {@inheritDoc} */ public StatusStream getFirehoseStream(int count) throws TwitterException { ensureAuthorizationEnabled(); return getCountStream("statuses/firehose.json", count); } /** * {@inheritDoc} */ public TwitterStreamConsumer links(final int count) { ensureAuthorizationEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { return getLinksStream(count); } }, streamListener); } /** * {@inheritDoc} */ public StatusStream getLinksStream(int count) throws TwitterException { ensureAuthorizationEnabled(); return getCountStream("statuses/links.json", count); } private StatusStream getCountStream(String relativeUrl, int count) throws TwitterException { ensureAuthorizationEnabled(); try { return new StatusStreamImpl(http.post(conf.getStreamBaseURL() + relativeUrl, new HttpParameter[] { new HttpParameter("count", String.valueOf(count)) }, auth)); } catch (IOException e) { throw new TwitterException(e); } } /** * {@inheritDoc} */ public TwitterStreamConsumer retweet() { ensureAuthorizationEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { return getRetweetStream(); } }, streamListener); } /** * {@inheritDoc} */ public StatusStream getRetweetStream() throws TwitterException { ensureAuthorizationEnabled(); try { return new StatusStreamImpl( http.post(conf.getStreamBaseURL() + "statuses/retweet.json", new HttpParameter[] {}, auth)); } catch (IOException e) { throw new TwitterException(e); } } /** * {@inheritDoc} */ public TwitterStreamConsumer sample() { ensureAuthorizationEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { return getSampleStream(); } }, streamListener); } /** * {@inheritDoc} */ public StatusStream getSampleStream() throws TwitterException { ensureAuthorizationEnabled(); try { return new StatusStreamImpl(http.post(conf.getStreamBaseURL() + "statuses/sample.json", new HttpParameter[] { new HttpParameter("delimited", "length") }, auth)); } catch (IOException e) { throw new TwitterException(e); } } /** * {@inheritDoc} */ public TwitterStreamConsumer user() { return user(null); } /** * {@inheritDoc} */ public TwitterStreamConsumer user(final String[] track) { ensureAuthorizationEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { return getUserStream(track); } }, streamListener); } /** * {@inheritDoc} */ public StatusStream getUserStream() throws TwitterException { return getUserStream(null); } /** * {@inheritDoc} */ public StatusStream getUserStream(String[] track) throws TwitterException { ensureAuthorizationEnabled(); try { List<HttpParameter> params = new ArrayList<HttpParameter>(); if (conf.isUserStreamRepliesAllEnabled()) { params.add(new HttpParameter("replies", "all")); } if (null != track) { params.add(new HttpParameter("track", T4JInternalStringUtil.join(track))); } return new StatusStreamImpl(http.post(conf.getUserStreamBaseURL() + "user.json", params.toArray(new HttpParameter[params.size()]), auth)); } catch (IOException e) { throw new TwitterException(e); } } /** * {@inheritDoc} */ public TwitterStreamConsumer site(final boolean withFollowings, final long[] follow) { ensureOAuthEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { try { return new StatusStreamImpl(getSiteStream(withFollowings, follow)); } catch (IOException e) { throw new TwitterException(e); } } }, streamListener); } InputStream getSiteStream(boolean withFollowings, long[] follow) throws TwitterException { ensureOAuthEnabled(); return http.post(conf.getSiteStreamBaseURL() + "site.json", new HttpParameter[] { new HttpParameter("with", withFollowings ? "followings" : "user"), new HttpParameter("follow", T4JInternalStringUtil.join(follow)) }, auth).asStream(); } /** * {@inheritDoc} */ public TwitterStreamConsumer filter(final FilterQuery query) { ensureAuthorizationEnabled(); ensureListenerIsSet(); return startHandler(new StatusStreamProvider() { public StatusStream getStream() throws TwitterException { return getFilterStream(query); } }, streamListener); } StatusStream getFilterStream(FilterQuery query) throws TwitterException { ensureAuthorizationEnabled(); try { List<HttpParameter> params = new ArrayList(Arrays.asList(query.asHttpParameterArray())); params.add(new HttpParameter("delimited", "length")); return new StatusStreamImpl(http.post(conf.getStreamBaseURL() + "statuses/filter.json", params.toArray(new HttpParameter[0]), auth)); } catch (IOException e) { throw new TwitterException(e); } } protected final void ensureAuthorizationEnabled() { if (!auth.isEnabled()) { throw new IllegalStateException("Authentication credentials are missing. " + "See http://twitter4j.org/configuration.html for the detail."); } } protected final void ensureOAuthEnabled() { if (!(auth instanceof OAuthAuthorization)) { throw new IllegalStateException("OAuth required. Authentication credentials are missing." + " See http://twitter4j.org/configuration.html for the detail."); } } /** * check if any listener is set. Throws IllegalStateException if no listener is set. * * @throws IllegalStateException when no listener is set. */ private void ensureListenerIsSet() { if (streamListener == null) { throw new IllegalStateException("No listener is set."); } } private TwitterStreamConsumer startHandler(StatusStreamProvider provider, StreamListener listener) { TwitterStreamConsumer handler = new TwitterStreamConsumerImpl(provider, listener); handler.start(); return handler; } private static final class StatusStreamImpl implements StatusStream { private final DataInputStream in; private final HttpResponse response; StatusStreamImpl(InputStream stream, HttpResponse response) throws IOException { this.in = new DataInputStream(stream); this.response = response; } StatusStreamImpl(InputStream stream) throws IOException { this(stream, null); } StatusStreamImpl(HttpResponse response) throws IOException { this(response.asStream(), response); } public DataInputStream getInputStream() { return in; } public void close() throws IOException { in.close(); if (response != null) { response.disconnect(); } } } } class StreamingReadTimeoutConfiguration implements HttpClientWrapperConfiguration { Configuration nestedConf; StreamingReadTimeoutConfiguration(Configuration httpConf) { this.nestedConf = httpConf; } public String getHttpProxyHost() { return nestedConf.getHttpProxyHost(); } public int getHttpProxyPort() { return nestedConf.getHttpProxyPort(); } public String getHttpProxyUser() { return nestedConf.getHttpProxyUser(); } public String getHttpProxyPassword() { return nestedConf.getHttpProxyPassword(); } public int getHttpConnectionTimeout() { return nestedConf.getHttpConnectionTimeout(); } public int getHttpReadTimeout() { // this is the trick that overrides connection timeout return nestedConf.getHttpStreamingReadTimeout(); } public int getHttpRetryCount() { return nestedConf.getHttpRetryCount(); } public int getHttpRetryIntervalSeconds() { return nestedConf.getHttpRetryIntervalSeconds(); } public int getHttpMaxTotalConnections() { return nestedConf.getHttpMaxTotalConnections(); } public int getHttpDefaultMaxPerRoute() { return nestedConf.getHttpDefaultMaxPerRoute(); } public Map<String, String> getRequestHeaders() { return nestedConf.getRequestHeaders(); } public boolean isPrettyDebugEnabled() { return nestedConf.isPrettyDebugEnabled(); } public boolean isGZIPEnabled() { return nestedConf.isGZIPEnabled(); } }