001package org.openimaj.picslurper; 002 003import java.io.FileNotFoundException; 004import java.io.IOException; 005import java.io.InputStream; 006 007import org.apache.http.HttpResponse; 008import org.apache.http.HttpVersion; 009import org.apache.http.auth.AuthScope; 010import org.apache.http.auth.UsernamePasswordCredentials; 011import org.apache.http.client.ClientProtocolException; 012import org.apache.http.client.methods.HttpGet; 013import org.apache.http.conn.scheme.Scheme; 014import org.apache.http.conn.scheme.SchemeRegistry; 015import org.apache.http.conn.ssl.SSLSocketFactory; 016import org.apache.http.impl.client.DefaultHttpClient; 017import org.apache.http.impl.conn.PoolingClientConnectionManager; 018import org.apache.http.params.BasicHttpParams; 019import org.apache.http.params.HttpConnectionParams; 020import org.apache.http.params.HttpProtocolParams; 021import org.apache.log4j.Logger; 022 023/** 024 * Factory provides input streams to twitter, managing the disconnection of old 025 * streams 026 * 027 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 028 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk), 029 * 030 */ 031public class TwitterInputStreamFactory { 032 private static final Logger logger = Logger.getLogger(TwitterInputStreamFactory.class); 033 private static final String TWITTER_SAMPLE_URL = "https://stream.twitter.com/1/statuses/sample.json"; 034 private static TwitterInputStreamFactory staticFactory; 035 private InputStream inputStream; 036 private PoolingClientConnectionManager manager; 037 private BasicHttpParams params; 038 private SchemeRegistry registry; 039 040 /** 041 * @return a new source of twitter input streams 042 */ 043 public static TwitterInputStreamFactory streamFactory() { 044 if (staticFactory == null) { 045 try { 046 staticFactory = new TwitterInputStreamFactory(); 047 } catch (Exception e) { 048 e.printStackTrace(); 049 System.err.println("Error creating TwitterInputStreamFactory: " + e.getMessage()); 050 return null; 051 } 052 } 053 return staticFactory; 054 } 055 056 private TwitterInputStreamFactory() throws FileNotFoundException, IOException { 057 PicSlurper.loadConfig(); 058 this.params = new BasicHttpParams(); 059 HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 060 HttpProtocolParams.setContentCharset(params, "utf-8"); 061 HttpConnectionParams.setConnectionTimeout(params, 1000); 062 HttpConnectionParams.setSoTimeout(params, 1000); 063 this.registry = new SchemeRegistry(); 064 registry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); 065 } 066 067 private void reconnect() throws ClientProtocolException, IOException { 068 logger.debug("Reconnecting, closing expired clients"); 069 070 logger.debug("Constructing new client"); 071 DefaultHttpClient client = new DefaultHttpClient(manager, params); 072 073 UsernamePasswordCredentials twitterUserPassword = new UsernamePasswordCredentials( 074 System.getProperty("twitter.user"), 075 System.getProperty("twitter.password") 076 ); 077 client.getCredentialsProvider().setCredentials(new AuthScope("stream.twitter.com", 443), twitterUserPassword); 078 HttpGet get = new HttpGet(TWITTER_SAMPLE_URL); 079 HttpResponse resp = client.execute(get); 080 logger.debug("Done!"); 081 this.inputStream = resp.getEntity().getContent(); 082 } 083 084 /** 085 * @return Attempt to disconnect any previous streams and reconnect 086 * @throws IOException 087 */ 088 public InputStream nextInputStream() throws IOException { 089 logger.debug("Attempting to get next input twitter input stream!"); 090 if (this.inputStream != null) { 091 logger.debug("Closing old stream..."); 092 manager.shutdown(); 093 this.inputStream.close(); 094 } 095 this.manager = new PoolingClientConnectionManager(registry); 096 reconnect(); 097 return this.inputStream; 098 } 099}