/* * Author: cbedford * Date: 11/4/13 * Time: 6:01 PM */ import com.restfb.Connection; import com.restfb.DefaultFacebookClient; import com.restfb.FacebookClient; import com.restfb.Parameter; import com.restfb.types.Post; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.commons.collections.buffer.CircularFifoBuffer; public class FacebookFeedItemProvider implements IFeedItemProvider { public static final SimpleDateFormat GMT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); private static final int TIME_OVERLAP = 1000 * 60; // one minute private static final int NUM_REMEMBERED_PREVIOUSLY_SEEN_ITEM_IDS = 1000; private final String queryString; private final FacebookClient facebookClient; private final ConcurrentLinkedQueue<String> itemQueue = new ConcurrentLinkedQueue<String>(); private final CircularFifoBuffer prevSeenItemIds = new CircularFifoBuffer(NUM_REMEMBERED_PREVIOUSLY_SEEN_ITEM_IDS); private volatile Date lastQueryTime = new Date(); //private volatile Date lastQueryTime = parseDate("2013-11-08T19:33:20-0800"); public FacebookFeedItemProvider(String authToken, String queryString) { facebookClient = new DefaultFacebookClient(authToken); this.queryString = queryString; } public static void main(String[] args) { Date startDate = parseDate("2013-11-08T19:33:20-0800"); FacebookFeedItemProvider provider = new FacebookFeedItemProvider(args[0], "Rizal"); Thread thread = new Thread(provider.getRunnableTask(), "facebookFeedItemProviderThread"); thread.start(); //System.out.println("Getting from queue"); while (true) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } String item = provider.itemQueue.poll(); if (item != null) { System.out.println("+++++++++++++ >>>: " + item); } else { //System.out.println("+++++++++++++ no queue item"); } } } private static Date parseDate(String dateString) { Date startDate = null; try { startDate = GMT_DATE_FORMAT.parse(dateString); System.out.println("result of parse is " + getFormattedDate(startDate)); } catch (ParseException e) { e.printStackTrace(); } return startDate; } @Override public Runnable getRunnableTask() { return new Runnable() { @Override public void run() { while (true) { // We set updatedLastQueryTime to some time before the time we start our search so we don't // miss any items posted while the search is being done. This means we can // double process some items. To avoid this we maintain a bounded queue of previously seen // item ids. If the number previously seen is more than the buffer bound we might double process, // but for our demo we won't worry about this. // //System.out.println("starting query from: " + getFormattedDate(lastQueryTime)); Date updatedLastQueryTime = new Date( new Date().getTime() - TIME_OVERLAP ); //Date updatedLastQueryTime = new Date(); Connection<Post> postStream = getPostStream(); List<Post> postList = postStream.getData(); if (postList.size() > 0) { for (Post p : postList) { //System.out.println("Post at : " + getFormattedDate(p.getCreatedTime()) + "\n" + p.getMessage() + " id = " + p.getId()); enqueueItemIfNotPreviouslySeen(p); } } lastQueryTime = updatedLastQueryTime; try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } private void enqueueItemIfNotPreviouslySeen(Post p) { String thisPostId = p.getId(); boolean sawBefore = false; Iterator iter = prevSeenItemIds.iterator(); while (iter.hasNext()) { String seenId = (String) iter.next(); if (thisPostId.equals(seenId)) { sawBefore = true; break; } } if (! sawBefore) { prevSeenItemIds.add(thisPostId); itemQueue.offer(p.getMessage()); } // on the other hand, if we saw it before then we do thing.. .just ignore } }; } private Connection<Post> getPostStream() { return facebookClient.fetchConnection( "search", Post.class, Parameter.with("q", queryString), Parameter.with("since", lastQueryTime), Parameter.with("type", "post")); } @Override public Object getNextItemIfAvailable() { return itemQueue.poll(); } private static String getFormattedDate(Date date) { String str; SimpleDateFormat sdf = GMT_DATE_FORMAT; return sdf.format(date); } }