/* * © Copyright IBM Corp. 2011 * * 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 com.ibm.xsp.extlib.sbt.twitter; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; import org.w3c.dom.Document; import com.ibm.commons.util.StringUtil; import com.ibm.jscript.IValue; import com.ibm.sbt.services.client.ClientService; import com.ibm.sbt.services.client.ClientService.HandlerJson; import com.ibm.sbt.services.client.ClientService.HandlerXml; import com.ibm.sbt.services.endpoints.Endpoint; import com.ibm.sbt.services.endpoints.EndpointFactory; import com.ibm.sbt.util.DataNavigator; import com.ibm.sbt.util.JsonNavigator; import com.ibm.sbt.util.XmlNavigator; import com.ibm.xsp.FacesExceptionEx; import com.ibm.xsp.extlib.sbt.model.RestDataBlockAccessor; import com.ibm.xsp.extlib.sbt.model.RestDataSource; import com.ibm.xsp.extlib.sbt.model.RestObjectDataSource; import com.ibm.xsp.extlib.sbt.services.client.TwitterService; /** * @author doconnor * @author tony.mcguckin@ie.ibm.com * */ public class TwitterDataSource extends RestObjectDataSource { /** * @author doconnor * */ public static class TwitterDataBlockAccessor extends RestDataBlockAccessor { private static final String VERSION = "1.1"; private static final String FORMAT = "json"; private static final String TWTR_MENTIONS = VERSION + "/statuses/mentions_timeline." + FORMAT; private static final String TWTR_RT_OF_ME = VERSION + "/statuses/retweets_of_me." + FORMAT; private static final String TWTR_TIME_LINE = VERSION + "/statuses/home_timeline." + FORMAT; private static final String TWTR_PUBLIC_TIME_LINE = VERSION + "/statuses/sample." + FORMAT; private String feedType; private String hashTag; private String searchEndpoint; /** * */ public TwitterDataBlockAccessor() { } /** * @param ds */ public TwitterDataBlockAccessor(RestDataSource ds) { super(ds); this.hashTag = ((TwitterDataSource)ds).getHashTag(); this.feedType = ((TwitterDataSource)ds).getFeedType(); this.searchEndpoint = ((TwitterDataSource)ds).getSearchEndpoint(); } protected String getUrl(){ String url = TWTR_TIME_LINE; if(StringUtil.equals("mentions", this.feedType)){ url = TWTR_MENTIONS; } else if(StringUtil.equals("publicTimeLine", this.feedType)){ url = TWTR_PUBLIC_TIME_LINE; } else if(StringUtil.equals("rtOfMe", this.feedType)){ url = TWTR_RT_OF_ME; } return url; } /* * (non-Javadoc) * * @see com.ibm.xsp.extlib.model.DataBlockAccessor#loadBlock(int, int) */ @Override protected Block loadBlock(int index, int blockSize) { String statusUrl = getUrl(); try { Endpoint provider = findEndpointBean(); Map<String, String> params = getParameters(index, blockSize); List<TwitterEntry> entries = new ArrayList<TwitterEntry>(); String svcUrl= getServiceUrl(); if(StringUtil.isEmpty(hashTag)){ ClientService svc = createClientService(provider, svcUrl); HandlerJson json = new HandlerJson(); ArrayList collection = (ArrayList)svc.get(statusUrl, json).getData(); if(collection != null){ int vc = collection.size(); for(int i = 0; i < vc; i++) { Object o = collection.get(i); if(o != null){ JsonNavigator nav = new JsonNavigator(o); TwitterEntry entry = new TwitterEntry(); //entry.setTweetContent(nav.stringValue("text")); entry.setTitle(nav.stringValue("text")); entry.setAuthor(nav.get("user").stringValue("name")); entries.add(entry); } } } } else{ //TODO change this to JSON to be consistent //http://search.twitter.com/search.json?q=%40twitterapi ClientService svc = createClientService(provider, "search.json"); if(hashTag.indexOf('#') != 0){ hashTag = "#" + hashTag; } params.put("q", hashTag); //TODO - Padraic HandlerJson json= new HandlerJson(); ArrayList collection = (ArrayList)svc.get(null,params, json).getData(); if(collection != null){ int vc = collection.size(); for(int i = 0; i < vc; i++) { Object o = collection.get(i); if(o != null){ JsonNavigator nav = new JsonNavigator(o); TwitterEntry entry = new TwitterEntry(); //entry.setTweetContent(nav.stringValue("text")); entry.setTitle(nav.stringValue("text")); entry.setAuthor(nav.get("user").stringValue("name")); entries.add(entry); } } } // Date date = null; // DateFormat dateFormat = DateFormat.getDateTimeInstance(); // // for(int i = 0; i < dn.getCount(); i++){ // TwitterEntry entry = new TwitterEntry(); // DataNavigator entryNav = dn.get(i); // // String title = entryNav.stringValue("title"); // entry.setTitle(title); // // String content = entryNav.stringValue("content"); // entry.setContent(content); // // String author = entryNav.stringValue("author/name"); // entry.setAuthor(author); // // String authorLink = entryNav.stringValue("author/uri"); // entry.setAuthorLink(authorLink); // // String publishedDate = entryNav.stringValue("published"); // entry.setPublishedDate(publishedDate); // // String updatedDate = entryNav.stringValue("updated"); // entry.setUpdatedDate(updatedDate); // // // 2 links available: // // we determine the difference based on the rel attribute... // //DataNavigator linkNav = entryNav.get("link[@rel='image']/@href"); // DataNavigator linkNav = entryNav.get("link"); //$NON-NLS-1$ // String image = null; // String tweetLink = null; // if(null != linkNav){ // linkNav = linkNav.selectEq("@rel", "image"); //$NON-NLS-1$ //$NON-NLS-2$ // if(null != linkNav){ // image = linkNav.stringValue("@href"); //$NON-NLS-1$ // } // linkNav = entryNav.get("link"); // linkNav = linkNav.selectEq("@rel", "alternate"); //$NON-NLS-1$ //$NON-NLS-2$ // if(null != linkNav){ // tweetLink = linkNav.stringValue("@href"); //$NON-NLS-1$ // } // } // entry.setImage(image); // entry.setTweetLink(tweetLink); // // entries.add(entry); // } } TwitterEntry[] data = entries.toArray(new TwitterEntry[0]); return new ArrayBlock(index, data); } catch (Exception ex) { throw new FacesExceptionEx(ex, "Error calling twitter service with url {0}", statusUrl); } } public Endpoint findSearchEndpointBean() { String name = searchEndpoint; String def = null; if(StringUtil.isEmpty(name)) { def = ((TwitterDataSource)getDataSource()).getSearchEndpoint(); } Endpoint ep = EndpointFactory.getEndpoint(name, def); return ep; } protected TwitterService createClientService(Endpoint ep, String url){ return new TwitterService(ep); } protected Map<String, String>getParameters(int index, int blockSize){ // twitter api expects 1 based indexing ++index; Map<String, String> params = new HashMap<String, String>(); params.put("page", String.valueOf(index)); params.put("count", String.valueOf(blockSize)); return params; } /* (non-Javadoc) * @see com.ibm.xsp.extlib.sbt.model.RestDataBlockAccessor#writeExternal(java.io.ObjectOutput) */ @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); out.writeObject(feedType); out.writeObject(hashTag); out.writeObject(searchEndpoint); } /* (non-Javadoc) * @see com.ibm.xsp.extlib.sbt.model.RestDataBlockAccessor#readExternal(java.io.ObjectInput) */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); feedType = (String)in.readObject(); hashTag = (String)in.readObject(); searchEndpoint = (String)in.readObject(); } } private String hashTag; private String feedType; private String searchEndpoint; /** * */ public TwitterDataSource() { } /* * (non-Javadoc) * * @see com.ibm.xsp.extlib.sbt.model.RestObjectDataSource#createAccessor() */ @Override protected RestDataBlockAccessor createAccessor() { return new TwitterDataBlockAccessor(this); } /* (non-Javadoc) * @see com.ibm.xsp.extlib.sbt.model.RestDataSource#getDefaultEndpoint() */ @Override public String getDefaultEndpoint() { return "twitter"; } public String getHashTag() { if (null != hashTag) { return hashTag; } ValueBinding valueBinding = getValueBinding("hashTag"); if (valueBinding != null) { String value = (String)valueBinding.getValue(getFacesContext()); return value; } return null; } public void setHashTag(String hashTag) { this.hashTag = hashTag; } public String getFeedType() { if (null != feedType) { return feedType; } ValueBinding valueBinding = getValueBinding("feedType"); if (valueBinding != null) { String value = (String)valueBinding.getValue(getFacesContext()); return value; } return null; } public void setFeedType(String feedType) { this.feedType = feedType; } @Override public Object saveState(FacesContext context) { if (isTransient()) { return null; } Object[] state = new Object[4]; state[0] = super.saveState(context); state[1] = hashTag; state[2] = feedType; state[3] = searchEndpoint; return state; } @Override public void restoreState(FacesContext context, Object state) { Object[] values = (Object[])state; super.restoreState(context, values[0]); this.hashTag = (String)values[1]; this.feedType = (String)values[2]; this.searchEndpoint = (String)values[3]; } /* (non-Javadoc) * @see com.ibm.xsp.extlib.sbt.model.RestDataSource#getServiceUrl() */ @Override public String getServiceUrl() { String url = super.getServiceUrl(); if(StringUtil.isEmpty(url)){ url = "http://api.twitter.com"; } return url; } /** * @return the searchEndpoint */ public String getSearchEndpoint() { return searchEndpoint; } /** * @param searchEndpoint the searchEndpoint to set */ public void setSearchEndpoint(String searchEndpoint) { this.searchEndpoint = searchEndpoint; } }