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

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

やる気復活?

次の授業が始まるまで時間があったので、研究室のパソコンでWicketを使ったプログラムを作ってみた。ここ数週間やる気が全くでなくて困っていたが、ちょっとやる気が復活してきたかもしれない。作ってみたのは一言掲示板で、WicketのexamplesにあったGuestBookに名前欄とファイルに保存昨日を加えたようなもの。要Java 1.6。まずはHTMLから

LineBoardPage.html

<html>
    <head>
        <title>一言掲示板</title>
    </head>
    <body>
        <div wicket:id="feedback">エラーメッセージ</div>
        <form wicket:id="inputForm">
            名前:<input type="text" wicket:id="inputName" /><br />
            内容:<input type="text" wicket:id="inputMessage" /><br />
            <input type="submit" value="書き込む" wicket:id="submit"/>
        </form>
        <hr>
        <dl wicket:id="lineList">
            <dt>
                名前:<span wicket:id="name">d-kami</span>
                <span wicket:id="date">2008/04/24</span>
            </dt>
            <dd wicket:id="message">一行コメント</dd>
        </dl>
    </body>
</html>

上のHTMLに対応したWebPage、LineBoardPage.java

package lineboard;

import java.io.File;
import java.io.FileOutputStream;

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

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.wicket.protocol.http.WebApplication;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.panel.FeedbackPanel;

import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.LoadableDetachableModel;

public class LineBoardPage extends WebPage{
    
    public LineBoardPage(){
        //書き込み保存用のファイルのパスを求める
        String path = ((WebApplication)this.getApplication()).getServletContext().getRealPath("comment.xml");
        final File file = new File(path);
        
        //エラーメッセージ表示
        FeedbackPanel feedback = new FeedbackPanel("feedback");
        add(feedback);
        
        //フォームの構築
        Form form = new Form("inputForm");
        final TextField nameField = new TextField("inputName", new Model());
        final TextField messageField = new TextField("inputMessage", new Model());
        
        Button submitButton = new Button("submit"){
            @Override
            public void onSubmit(){
                String name = nameField.getModelObjectAsString();
                String message = messageField.getModelObjectAsString();
                
                Comment comment = new Comment(name, message);                

                synchronized(LineBoardPage.this){
                    //過去に書き込まれたコメントを読み込む
                    CommentList commentList = readCommentList(file);
                
                    //書き込まれた内容を追加してXML形式で保存
                    commentList.addComment(name, message);
                    writeCommentList(commentList, file);
                }
            }
        };
        
        form.add(nameField);
        form.add(messageField);
        form.add(submitButton);
        add(form);
        
        LoadableDetachableModel model = new LoadableDetachableModel(){
            @Override
            protected Object load(){
                CommentList commentList = null;
                synchronized(LineBoardPage.this){
                    commentList = readCommentList(file);
                }
                
                return commentList.getCommentList();
            }
        };
        
        //コメントを表示するListView
        ListView lineListView = new ListView("lineList", model){
            @Override
            protected void populateItem(ListItem item){
                Comment comment = (Comment)item.getModelObject();
                item.add(new Label("name", comment.getName()));
                item.add(new Label("date", comment.getDate()));
                item.add(new Label("message", comment.getMessage()));
                
                nameField.setModelObject("");
                messageField.setModelObject("");
            }
        };
        
        add(lineListView);
    }
    
    //XML形式のfileからCommentListを読み込む
    private CommentList readCommentList(File file){
        CommentList commentList;
        
        try{
            JAXBContext context = JAXBContext.newInstance(CommentList.class);                    
            Unmarshaller unmarshaller = context.createUnmarshaller();
            commentList = (CommentList)unmarshaller.unmarshal(file);
        }catch(Exception e){
            e.printStackTrace();
            
            //例外がでたら新しいコメントリストを作る
            commentList = new CommentList();
        }
        
        return commentList;
    }
    
    //fileにCommentListをXML形式で書き込む
    private void writeCommentList(CommentList commentList, File file){
        try{
            JAXBContext context = JAXBContext.newInstance(CommentList.class);                    
            Marshaller marshaller = context.createMarshaller();
            marshaller.marshal(commentList, new FileOutputStream(file));
        }catch(Exception e){
            //例外がでたらメッセージを表示
            error(e);
            e.printStackTrace();
        }
    }
    
    //Commentのリストを格納する暮らす
    @XmlRootElement(name="CommentList")
    static class CommentList{
        @XmlElement(name="Comment")
        private List<Comment> list;
        
        public CommentList(){
            list = new ArrayList<Comment>();
        }
        
        public List<Comment> getCommentList(){
            return new ArrayList(list);
        }
        
        public void addComment(String name, String message){
            list.add(0, new Comment(name, message));
        }
    }
    
    //コメントを表すクラス
    @XmlRootElement(name="Comment")
    static class Comment{
        @XmlElement(name="Name")
        private String name;
        
        @XmlElement(name="message")
        private String message;
        
        @XmlElement(name="date")
        private String date;
        
        public Comment(String name, String message){
            this.name = name;
            this.message = message;
            
            //日付はコンストラクタを呼び出した時刻にする
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm");
            this.date = format.format(new Date());
        }
        
        //JAXB用のコンストラクタ
        private Comment(){
            
        }
        
        public String getName(){
            return this.name;
        }
        
        public String getMessage(){
            return this.message;
        }
        
        public String getDate(){
            return this.date;
        }
    }

アプリケーションクラス、LineBoardApplication.java

package lineboard;

import org.apache.wicket.protocol.http.WebApplication;

public class LineBoardApplication extends WebApplication{
    @Override
    public Class getHomePage(){
        return LineBoardPage.class;
    }
}

最後にフィルタマッピング、web.xml

    <filter>
        <filter-name>LineBoard</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>lineboard.LineBoardApplication</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>LineBoard</filter-name>
        <url-pattern>/LineBoard/*</url-pattern>
    </filter-mapping>