マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

簡単なRSSリーダーのソース

昨日作った簡単なRSSリーダーのソース、動かすためにはWicket 1.4-rc1ROMEROME FetcherJDOMが必要。ListViewの作成部分はRSS Readerを作る その2 - フィードの取得と表示をパクってます。まずはHTMLから、ファイル名はHomePage.html

<html>
    <head>
        <title>Wicket Homepage</title>
    </head>
    <body>
        <span wicket:id="feedback"></span>
        <table style="width:100%; height: 100%;">
            <tr>
                <td style="width:30%; height:100%; vertical-align:top">
                    <a wicket:id="javaLink">Javaカテゴリ</a><br />
                    <a wicket:id="wicketLink">Wicketカテゴリ</a><br />
                </td>
                
                <!-- ListViewの親コンポーネント -->
                <td style="width:70%; height:100%; text-align:left; vertical-align:top" wicket:id="parent">
                <!-- ListViewの部分 -->
                    <dl wicket:id="entryList">
                        <dt><a href="http://test.com" wicket:id="entryLink">Entry Title</a> <span wicket:id="publishDate">2009/1/27</span></dt>
                        <dd><span wicket:id="entryDesc">Entry Description</span></dd>
                    </dl>
                </td>
            </tr>
        </table>
    </body>
</html>

次に対応するJavaのソース、ファイル名はHomePage.java

package example;

import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.panel.FeedbackPanel;

import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;

import org.apache.wicket.ajax.AjaxRequestTarget;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.fetcher.FeedFetcher;
import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
import com.sun.syndication.fetcher.FetcherException;
import com.sun.syndication.io.FeedException;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;

import java.net.URL;
import java.io.IOException;

/**
 * Homepage
 */
public class HomePage extends WebPage {

    private static final long serialVersionUID = 1L;

    //現在表示しているフィードのURL
    private String feedURL = "";

    // TODO Add any page properties or variables here

    /**
     * Constructor that is invoked when page is invoked without a session.
     * 
     * @param parameters
     *            Page parameters
     */
    public HomePage(final PageParameters parameters) {
        // TODO Add your page's components here
        
        //エラーメッセージを表示するFeedbackPanel
        final FeedbackPanel feedback = new FeedbackPanel("feedback");
        //Ajaxで更新可能にする
        feedback.setOutputMarkupId(true);
        
        //フィードに含まれるエントリの一覧を表示するListView
        ListView listView = createListView();
        //ListViewの親コンポーネント(AjaxでListViewを更新するのに必要)
        final WebMarkupContainer parent = new WebMarkupContainer("parent");
        //Ajaxで更新可能にする
        parent.setOutputMarkupId(true);
        
        //キーワードJavaのフィードを取得してくるAjaxLink
        AjaxLink javaLink = new AjaxLink("javaLink"){
            public void onClick(AjaxRequestTarget target){
                //フィードのURLを書き換える
                feedURL = "http://k.hatena.ne.jp/keywordblog/Java?mode=rss";
                //ListViewを更新
                target.addComponent(parent);
                //FeedbackPanelを更新
                target.addComponent(feedback);
            }
        };

        //キーワードWicketのフィードを取得してくるAjaxLink
        AjaxLink wicketLink = new AjaxLink("wicketLink"){
            public void onClick(AjaxRequestTarget target){
                //フィードのURLを書き換える
                feedURL = "http://k.hatena.ne.jp/keywordblog/Wicket?mode=rss";
                //ListViewを更新する
                target.addComponent(parent);
                //FeedbackPanelを更新する
                target.addComponent(feedback);
            }
        };
        
        add(feedback);
        add(wicketLink);
        add(javaLink);
        parent.add(listView);
        add(parent);
    }
    
    //フィードのエントリ一覧を表示するListViewを作成する
    private ListView createListView(){
        IModel<List<SyndEntry>> entryListModel = new LoadableDetachableModel<List<SyndEntry>>(){
            protected List<SyndEntry> load(){
                //エントリの一覧を返す
                return getEntryList();
            }
        };
        
        ListView listView = new ListView( "entryList", entryListModel) {
            @Override
            protected void populateItem(ListItem item) {
                final SyndEntry entry = (SyndEntry)item.getModelObject();
                item.add(new ExternalLink("entryLink", entry.getLink(), entry.getTitle()));
                
                Date updateDate = entry.getUpdatedDate();
                if(updateDate == null) updateDate = entry.getPublishedDate();
                
                //時間を日本時間に合わせる
                SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm");
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(updateDate);
                calendar.add(Calendar.HOUR_OF_DAY, 9);
                updateDate = calendar.getTime();

                item.add( new Label("publishDate", format.format( updateDate)));
                
                String description = entry.getDescription().getValue();
                
                //ディスクリプションに含まれるタグを取り除く
                description = description.replaceAll("<[^>]+>", "");
                
                 item.add(new Label("entryDesc", description));
            }
        };

        return listView;        
    }
    
    private List<SyndEntry> getEntryList(){
        if(feedURL.trim().length() == 0){
            //フィードのURLが空文字列なら空のリストを返す
            return new ArrayList<SyndEntry>();
        }
        
        try{
            //フィードのURLからフィードのエントリ一覧を取得し返す
            FeedFetcher fetcher = new HttpURLFeedFetcher();
            SyndFeed feed = fetcher.retrieveFeed(new URL(feedURL));
            return feed.getEntries();
        }catch(FetcherException e){
            error("フィードの取得に失敗しました: " + e.getMessage());
        }catch(IOException e){
            error("フィードの取得に失敗しました: " + e.getMessage());
        }catch(FeedException e){
            error("フィードの取得に失敗しました: " + e.getMessage());
        }
        
        return new ArrayList<SyndEntry>();
    }
}

アプリケーションクラスとフィルターマッピングは省略