jp.gihyo.wicket.page.ajax.AjaxTimeline.java Source code

Java tutorial

Introduction

Here is the source code for jp.gihyo.wicket.page.ajax.AjaxTimeline.java

Source

/*
 *  Copyright 2009 Tsutomu YANO.
 * 
 *  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.
 *  under the License.
 */

package jp.gihyo.wicket.page.ajax;

import jp.gihyo.wicket.page.*;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.List;
import jp.gihyo.wicket.AppSession;
import jp.gihyo.wicket.component.PagingLink;
//import org.apache.wicket.PageParameters;
//import org.apache.wicket.RedirectToUrlException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.flow.RedirectToUrlException;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.string.StringValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import twitter4j.Paging;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;

/**
 *
 * @author Tsutomu YANO
 */
public class AjaxTimeline extends WebPage {
    private static final long serialVersionUID = -1289967315883152057L;

    private static final Logger LOGGER = LoggerFactory.getLogger(AjaxTimeline.class);
    private static final int ITEMS_PER_PAGE = 20;
    private int currentPageNumber = 1;
    private FeedbackPanel feedback;

    public AjaxTimeline(PageParameters parameters) {
        super(parameters);
        if (!AppSession.get().isLoggedIn()) {
            throw new RedirectToUrlException(getRequestCycle().urlFor(Login.class, null).toString());
        }

        //this.currentPageNumber = parameters.getAsInteger("page", 1);
        StringValue page = parameters.get("page");
        if (!page.isEmpty()) {
            this.currentPageNumber = page.toInteger();
        }
        constructPage();
    }

    private void constructPage() {
        final TweetForm form = new TweetForm("tweetForm");
        add(form);

        feedback = new FeedbackPanel("feedback");
        feedback.setOutputMarkupId(true);
        add(feedback);

        IModel<List<Status>> statusModel = new LoadableDetachableModel<List<Status>>() {
            @Override
            protected List<Status> load() {
                try {
                    Twitter twitter = AppSession.get().getTwitterSession();
                    return twitter.getFriendsTimeline(new Paging(currentPageNumber, ITEMS_PER_PAGE));
                } catch (TwitterException ex) {
                    AjaxTimeline.this.error(getString("canNotRetrieveFriendTimeline"));
                    return Collections.emptyList();
                }
            }
        };

        ListView<Status> timeline = new ListView<Status>("statusView", statusModel) {
            @Override
            protected void populateItem(final ListItem<Status> item) {
                final Status status = item.getModelObject();
                String userUrl = "http://twitter.com/" + status.getUser().getScreenName();
                ExternalLink imageLink = new ExternalLink("imageLink", userUrl);

                //ImageR|?[lg?A<img>^Osrc??X`?X
                WebMarkupContainer userImage = new WebMarkupContainer("userImage");
                userImage.add(new SimpleAttributeModifier("src", status.getUser().getProfileImageURL().toString()));

                imageLink.add(userImage);
                item.add(imageLink);

                ExternalLink screenNameLink = new ExternalLink("screenName", userUrl,
                        status.getUser().getScreenName());
                item.add(screenNameLink);

                Label content = new Label("tweetContent", status.getText());
                item.add(content);

                ExternalLink tweetLink = new ExternalLink("tweetLink", userUrl + "/status/" + status.getId(), null);
                item.add(tweetLink);

                Label time = new Label("tweetTime",
                        new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(status.getCreatedAt()));
                tweetLink.add(time);

                Label clientName = new Label("clientName", status.getSource());
                item.add(clientName.setEscapeModelStrings(false));

                /*
                 * YXe?[^XCo^\xNX?B
                 * ?\bh?A??[JNX`?B
                 * ??[JNX?ANXOstatus?ANZX?B
                 */
                class FavorateLabel extends Label {
                    private static final long serialVersionUID = -2194580825236126312L;
                    private Status targetStatus;
                    private boolean needRefresh;

                    public FavorateLabel(String id) {
                        super(id);
                        this.targetStatus = status;

                        setDefaultModel(new AbstractReadOnlyModel<String>() {
                            @Override
                            public String getObject() {
                                try {
                                    if (needRefresh) {
                                        targetStatus = getCurrentStatus(status.getId());
                                        needRefresh = false;
                                    }
                                    return targetStatus == null ? "" : targetStatus.isFavorited() ? "unfav" : "fav";
                                } catch (TwitterException ex) {
                                    LOGGER.error("Can not fetch current status for status id = " + status.getId(),
                                            ex);
                                    return "error";
                                }
                            }
                        });
                    }

                    public void setNeedRefresh(boolean needRefresh) {
                        this.needRefresh = needRefresh;
                    }
                }

                //CNx
                final FavorateLabel favName = new FavorateLabel("favName");
                favName.setOutputMarkupId(true);

                /*
                 * AjaxCN?B
                 * Xe?[^XCo^o^?Ao^???s?B
                 * o^???AAjaxg?Ay?[WS?ACo^Xe?[^X
                 * Nx??B
                 */
                AjaxLink<Void> favLink = new AjaxLink<Void>("favLink") {
                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        try {
                            Status currentStatus = getCurrentStatus(status.getId());
                            Twitter twitterSession = AppSession.get().getTwitterSession();
                            if (currentStatus.isFavorited()) {
                                twitterSession.destroyFavorite(currentStatus.getId());
                                info(getString("favorateRemoved"));
                            } else {
                                twitterSession.createFavorite(currentStatus.getId());
                                info(getString("favorateRegistered"));
                            }
                            favName.setNeedRefresh(true);
                            target.addComponent(feedback); //o^?bZ?[W\?AtB?[hobNpl?X?V?B
                            target.addComponent(favName);
                        } catch (TwitterException ex) {
                            String message = getString("catNotCreateFavorite") + ": " + ex.getStatusCode();
                            error(message);
                            LOGGER.error(message, ex);
                        }
                    }
                };
                item.add(favLink);
                favLink.add(favName);

                //AJAX LINK
                item.add(new AjaxLink<Void>("replyLink") {
                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        String targetScreenName = status.getUser().getScreenName();
                        form.insertText(target, "@" + targetScreenName + " ");
                    }
                });

                //Q?l?AreplyLinkJavaScriptp
                //                item.add(new Link<Void>("replyLink") {
                //                    @Override
                //                    public void onClick() {
                //                    }
                //
                //                    @Override
                //                    protected CharSequence getOnClickScript(CharSequence url) {
                //                        return "getElementById('" + form.getTextAreaId() + "').value = '@" + status.getUser().getScreenName() + " ';" +
                //                               "getElementById('" + form.getTextAreaId() + "').focus(); return false;";
                //                    }
                //                });
            }
        };

        //ListView\e?s????BreuseItemsv?peB??A
        //y?[W\?Ay?[WTu~bg?AXgeIuWFNg\??B
        //twitterey?[We?X??AXg????AXge?
        //Xe?[^Xu?A??dv?B
        timeline.setReuseItems(true);
        add(timeline);

        /*
         * y?[WO?EirQ?[^
         */
        add(new PagingLink("paging", AjaxTimeline.class, new AbstractReadOnlyModel<Integer>() {
            @Override
            public Integer getObject() {
                return getCurrentPage();
            }
        }));
    }

    public int getCurrentPage() {
        return currentPageNumber;
    }

    protected Status getCurrentStatus(long statusId) throws TwitterException {
        Twitter twitterSession = AppSession.get().getTwitterSession();
        Paging paging = new Paging(1, 1);
        paging.setMaxId(statusId);
        List<Status> statusList = twitterSession.getFriendsTimeline(paging);
        return statusList.size() > 0 ? statusList.get(0) : null;
    }

    static class TweetForm extends Form<AjaxTimeline> {
        private static final long serialVersionUID = -6873087998089286302L;
        private String tweet;
        private TextArea<String> updateText;

        public TweetForm(String id) {
            super(id);
            constructForm();
        }

        private void constructForm() {
            updateText = new TextArea<String>("tweetText", new PropertyModel<String>(this, "tweet"));
            updateText.setOutputMarkupId(true);
            add(updateText);

            add(new Button("post") {
                @Override
                public void onSubmit() {
                    if (tweet != null && tweet.length() > 0) {
                        try {
                            Twitter twitterSession = AppSession.get().getTwitterSession();
                            twitterSession.updateStatus(tweet);
                            setResponsePage(AjaxTimeline.class);
                        } catch (TwitterException ex) {
                            String message = getString("updateFailed");
                            LOGGER.error(message, ex);
                            error(message);
                        }
                    }
                }
            });
        }

        public void insertText(String text) {
            updateText.setModelObject(text);
        }

        public void insertText(AjaxRequestTarget target, String text) {
            insertText(text);
            target.addComponent(updateText);
            target.focusComponent(updateText);
        }

        public String getTextAreaId() {
            return updateText.getMarkupId();
        }
    }

}