Bean⇔XML

Webアプリケーションの設定をXMLファイルで定義しておくのはよくあることだったが
基本的に読み込みのみでアプリケーション初期化時に解析すればよかった。
設定変更もXMLファイルを直でいじってもらいアプリケーション再起動だった。
それをWeb画面から変更してそれをXMLの設定ファイルにも反映してほしいといわれた。
なのでBeanなどに保持した設定をXMLに書き戻す必要が出てきた。
そこでcommons-betwixtを使ってみる。
こんな設定情報を保持するBeanがあったとする。

public class Application implements Serializable {
    private int pageSize;
    private String cvsroot;
    private String pass;
    private String user;
    private String tempDir;
    private String uploadDir;
    private int maxSize;

    public Application() {
        super();
    }

    public String getCvsroot() {
        return cvsroot;
    }
    public int getPageSize() {
        return pageSize;
    }
    public String getPass() {
        return pass;
    }
    public String getUser() {
        return user;
    }
    public int getMaxSize() {
        return maxSize;
    }
    public String getTempDir() {
        return tempDir;
    }
    public String getUploadDir() {
        return uploadDir;
    }

    public void setCvsroot(String string) {
        cvsroot = string;
    }
    public void setPageSize(int i) {
        pageSize = i;
    }
    public void setPass(String string) {
        pass = string;
    }
    public void setUser(String string) {
        user = string;
    }
    public void setMaxSize(int i) {
        maxSize = i;
    }
    public void setTempDir(String string) {
        tempDir = string;
    }
    public void setUploadDir(String string) {
        uploadDir = string;
    }

    public String toString() {
        StringBuffer buff = new StringBuffer("Application[");
        buff.append("pageSize = ");
        buff.append(getPageSize());
        buff.append(", cvsroot = ");
        buff.append(getCvsroot());
        buff.append(", user = ");
        buff.append(getUser());
        buff.append(", pass = ");
        buff.append(getPass());
        buff.append(", tempDir = ");
        buff.append(getTempDir());
        buff.append(", uploadDir = ");
        buff.append(getUploadDir());
        buff.append(", maxSize = ");
        buff.append(getMaxSize());
        buff.append("]");
        return buff.toString();
    }
}

同じパッケージにApplication.betwixt(クラス名 + .betwixt)というファイル名で


    
        
        
        
        
        
        
            
            
            
        
    

と定義する。
ファイルの読み込み、書き出しは

public class BetWixtTest {

    public static void main(String[] args) throws Exception {
        //ファイル書き出しテスト。
        BeanWriter writer = new BeanWriter(new FileOutputStream("application.xml"));
        writer.enablePrettyPrint();
        writer.setWriteIDs(false);

        //適当なデータを設定しておく。
        Application appli = new Application();
        appli.setPageSize(20);
        appli.setCvsroot(":pserver:akira@cvsserver:/usr/local/cvs");
        appli.setUser("akira");
        appli.setPass("password");
        appli.setTempDir("/temp");
        appli.setUploadDir("/upload");
        appli.setMaxSize(1024000000);
        System.out.println(appli);

        //書き出し。
        writer.write(appli);
        writer.close();

        //ファイル読み込みテスト。
        BeanReader reader = new BeanReader();
        reader.getXMLIntrospector().setAttributesForPrimitives(false);
        reader.setMatchIDs(false);

        //ここでrootエレメント名とクラス名を結びつける。
        reader.registerBeanClass("test-application", Application.class);
        //上で書き出したファイルを指定する。
        FileInputStream is = new FileInputStream("application.xml");
        //解析。
        Application appli2 = (Application) reader.parse(is);
        System.out.println(appli2); 
    }
}

実行結果。

Application[pageSize = 20, cvsroot = :pserver:akira@cvsserver:/usr/local/cvs, user = akira, pass = password, tempDir = /temp, uploadDir = /upload, maxSize = 1024000000]
Application[pageSize = 20, cvsroot = :pserver:akira@cvsserver:/usr/local/cvs, user = akira, pass = password, tempDir = /temp, uploadDir = /upload, maxSize = 1024000000]

吐かれたapplication.xmlファイルの内容。


  20
  :pserver:akira@cvsserver:/usr/local/cvs
  akira
  password
  
    1024000000
    /temp
    /upload
  

吐かれたapplication.xmlファイルとApplication.betwixtを見比べればわかるけど
XML構造をそのまま設定ファイルに書けるので非常に書き方がわかりやすく直感的。
本家のドキュメントにも書かれているとおりでもいいけど
自分好みのXMLフォーマットに指定できるところが強み。
読み込みにはcommons-digesterを使用しているため以下の依存関係がある。

commons-logging-1.0.2
commons-collections-2.1
commons-digester-1.5
commons-beanutils-1.6.1