昨日作った簡単なRSSリーダーのソース、動かすためにはWicket 1.4-rc1、ROME、ROME Fetcher、JDOMが必要。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>(); } }
アプリケーションクラスとフィルターマッピングは省略