jaroslav@931: /** jaroslav@931: * Back 2 Browser Bytecode Translator jaroslav@931: * Copyright (C) 2012 Jaroslav Tulach jaroslav@931: * jaroslav@931: * This program is free software: you can redistribute it and/or modify jaroslav@931: * it under the terms of the GNU General Public License as published by jaroslav@931: * the Free Software Foundation, version 2 of the License. jaroslav@931: * jaroslav@931: * This program is distributed in the hope that it will be useful, jaroslav@931: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@931: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@931: * GNU General Public License for more details. jaroslav@931: * jaroslav@931: * You should have received a copy of the GNU General Public License jaroslav@931: * along with this program. Look for COPYING file in the top folder. jaroslav@931: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@931: */ jaroslav@931: package org.apidesign.bck2brwsr.demo.twitter; jaroslav@931: jaroslav@931: import java.util.Arrays; jaroslav@931: import java.util.List; jaroslav@1024: import net.java.html.json.ComputedProperty; jaroslav@1024: import net.java.html.json.Context; jaroslav@1024: import net.java.html.json.Function; jaroslav@1024: import net.java.html.json.Model; jaroslav@1024: import net.java.html.json.OnPropertyChange; jaroslav@1024: import net.java.html.json.OnReceive; jaroslav@1024: import net.java.html.json.Property; jaroslav@931: jaroslav@931: /** Controller class for access to Twitter. jaroslav@931: * jaroslav@931: * @author Jaroslav Tulach jaroslav@931: */ jaroslav@1024: @Model(className="TwitterModel", properties={ jaroslav@961: @Property(name="savedLists", type=Tweeters.class, array = true), jaroslav@931: @Property(name="activeTweetersName", type=String.class), jaroslav@956: @Property(name="activeTweeters", type=String.class, array = true), jaroslav@931: @Property(name="userNameToAdd", type=String.class), jaroslav@961: @Property(name="currentTweets", type=Tweet.class, array = true) jaroslav@931: }) jaroslav@931: public class TwitterClient { jaroslav@931: @Model(className = "Tweeters", properties = { jaroslav@931: @Property(name="name", type = String.class), jaroslav@931: @Property(name="userNames", type = String.class, array = true) jaroslav@931: }) jaroslav@931: static class Twttrs { jaroslav@931: } jaroslav@947: @Model(className = "Tweet", properties = { jaroslav@947: @Property(name = "from_user", type = String.class), jaroslav@947: @Property(name = "from_user_id", type = int.class), jaroslav@947: @Property(name = "profile_image_url", type = String.class), jaroslav@947: @Property(name = "text", type = String.class), jaroslav@948: @Property(name = "created_at", type = String.class), jaroslav@947: }) jaroslav@947: static final class Twt { jaroslav@956: @ComputedProperty static String html(String text) { jaroslav@956: StringBuilder sb = new StringBuilder(320); jaroslav@956: for (int pos = 0;;) { jaroslav@956: int http = text.indexOf("http", pos); jaroslav@956: if (http == -1) { jaroslav@956: sb.append(text.substring(pos)); jaroslav@956: return sb.toString(); jaroslav@956: } jaroslav@956: int spc = text.indexOf(' ', http); jaroslav@956: if (spc == -1) { jaroslav@956: spc = text.length(); jaroslav@956: } jaroslav@956: sb.append(text.substring(pos, http)); jaroslav@956: String url = text.substring(http, spc); jaroslav@956: sb.append("").append(url).append(""); jaroslav@956: pos = spc; jaroslav@956: } jaroslav@956: } jaroslav@956: jaroslav@956: @ComputedProperty static String userUrl(String from_user) { jaroslav@956: return "http://twitter.com/" + from_user; jaroslav@956: } jaroslav@947: } jaroslav@947: @Model(className = "TwitterQuery", properties = { jaroslav@947: @Property(array = true, name = "results", type = Twt.class) jaroslav@947: }) jaroslav@947: public static final class TwttrQr { jaroslav@947: } jaroslav@947: jaroslav@954: @OnReceive(url="{root}/search.json?{query}&callback={me}", jsonp="me") jaroslav@947: static void queryTweets(TwitterModel page, TwitterQuery q) { jaroslav@947: page.getCurrentTweets().clear(); jaroslav@947: page.getCurrentTweets().addAll(q.getResults()); jaroslav@947: } jaroslav@947: jaroslav@955: @OnPropertyChange("activeTweetersName") jaroslav@955: static void changeTweetersList(TwitterModel model) { jaroslav@955: Tweeters people = findByName(model.getSavedLists(), model.getActiveTweetersName()); jaroslav@956: model.getActiveTweeters().clear(); jaroslav@956: model.getActiveTweeters().addAll(people.getUserNames()); jaroslav@955: } jaroslav@955: jaroslav@956: @OnPropertyChange({ "activeTweeters", "activeTweetersCount" }) jaroslav@947: static void refreshTweets(TwitterModel model) { jaroslav@956: StringBuilder sb = new StringBuilder(); jaroslav@956: sb.append("rpp=25&q="); jaroslav@956: String sep = ""; jaroslav@956: for (String p : model.getActiveTweeters()) { jaroslav@956: sb.append(sep); jaroslav@956: sb.append("from:"); jaroslav@956: sb.append(p); jaroslav@956: sep = " OR "; jaroslav@947: } jaroslav@956: model.queryTweets("http://search.twitter.com", sb.toString()); jaroslav@931: } jaroslav@931: jaroslav@1024: private static final Context DEFAULT = Context.findDefault(TwitterClient.class); jaroslav@931: static { jaroslav@1024: final TwitterModel model = new TwitterModel(DEFAULT); jaroslav@931: final List svdLst = model.getSavedLists(); jaroslav@956: svdLst.add(newTweeters("API Design", "JaroslavTulach")); jaroslav@956: svdLst.add(newTweeters("Celebrities", "JohnCleese", "MCHammer", "StephenFry", "algore", "StevenSanderson")); jaroslav@956: svdLst.add(newTweeters("Microsoft people", "BillGates", "shanselman", "ScottGu")); jaroslav@956: svdLst.add(newTweeters("NetBeans", "GeertjanW","monacotoni", "NetBeans", "petrjiricka")); jaroslav@956: svdLst.add(newTweeters("Tech pundits", "Scobleizer", "LeoLaporte", "techcrunch", "BoingBoing", "timoreilly", "codinghorror")); jaroslav@931: jaroslav@931: model.setActiveTweetersName("NetBeans"); jaroslav@947: jaroslav@931: model.applyBindings(); jaroslav@931: } jaroslav@931: jaroslav@931: @ComputedProperty jaroslav@956: static boolean hasUnsavedChanges(List activeTweeters, List savedLists, String activeTweetersName) { jaroslav@955: Tweeters tw = findByName(savedLists, activeTweetersName); jaroslav@955: if (activeTweeters == null) { jaroslav@955: return false; jaroslav@931: } jaroslav@956: return !tw.getUserNames().equals(activeTweeters); jaroslav@956: } jaroslav@956: jaroslav@956: @ComputedProperty jaroslav@956: static int activeTweetersCount(List activeTweeters) { jaroslav@956: return activeTweeters.size(); jaroslav@950: } jaroslav@950: jaroslav@931: @ComputedProperty jaroslav@955: static boolean userNameToAddIsValid( jaroslav@956: String userNameToAdd, String activeTweetersName, List savedLists, List activeTweeters jaroslav@955: ) { jaroslav@956: return userNameToAdd != null && jaroslav@931: userNameToAdd.matches("[a-zA-Z0-9_]{1,15}") && jaroslav@956: !activeTweeters.contains(userNameToAdd); jaroslav@931: } jaroslav@931: jaroslav@1024: @Function jaroslav@931: static void deleteList(TwitterModel model) { jaroslav@931: final List sl = model.getSavedLists(); jaroslav@956: sl.remove(findByName(sl, model.getActiveTweetersName())); jaroslav@931: if (sl.isEmpty()) { jaroslav@1024: final Tweeters t = new Tweeters(DEFAULT); jaroslav@931: t.setName("New"); jaroslav@931: sl.add(t); jaroslav@931: } jaroslav@931: model.setActiveTweetersName(sl.get(0).getName()); jaroslav@931: } jaroslav@931: jaroslav@1024: @Function jaroslav@931: static void saveChanges(TwitterModel model) { jaroslav@931: Tweeters t = findByName(model.getSavedLists(), model.getActiveTweetersName()); jaroslav@931: int indx = model.getSavedLists().indexOf(t); jaroslav@955: if (indx != -1) { jaroslav@956: t.setName(model.getActiveTweetersName()); jaroslav@956: t.getUserNames().clear(); jaroslav@956: t.getUserNames().addAll(model.getActiveTweeters()); jaroslav@955: } jaroslav@931: } jaroslav@931: jaroslav@1024: @Function jaroslav@931: static void addUser(TwitterModel model) { jaroslav@931: String n = model.getUserNameToAdd(); jaroslav@956: model.getActiveTweeters().add(n); jaroslav@931: } jaroslav@1024: @Function jaroslav@931: static void removeUser(String data, TwitterModel model) { jaroslav@956: model.getActiveTweeters().remove(data); jaroslav@931: } jaroslav@931: jaroslav@931: private static Tweeters findByName(List list, String name) { jaroslav@931: for (Tweeters l : list) { jaroslav@931: if (l.getName() != null && l.getName().equals(name)) { jaroslav@931: return l; jaroslav@931: } jaroslav@931: } jaroslav@1024: return list.isEmpty() ? new Tweeters(DEFAULT) : list.get(0); jaroslav@931: } jaroslav@955: jaroslav@956: private static Tweeters newTweeters(String listName, String... userNames) { jaroslav@1024: Tweeters t = new Tweeters(DEFAULT); jaroslav@955: t.setName(listName); jaroslav@955: t.getUserNames().addAll(Arrays.asList(userNames)); jaroslav@955: return t; jaroslav@955: } jaroslav@931: }