Jakarta Commons Digesterを使う

  Jakarta Commons Digester は、Javaのオープンソースのクラスライブラリを開発している Jakartaプロジェクトの中の、Jakarta Commonsライブラリ群の一員です。 これは、XMLファイルを読み込んで、その内容からJavaBeanクラスを生成する機能を提供します。 もともとこのDigesterは、 Jakarta TomcatやApache Strutsなど、 JakartaプロジェクトのWebアプリケーション関係のソフトウェアにおいて、 それらの設定情報をXMLファイル(server.xml、struts-config.xmlなど) に書いておき、これをロードするためのライブラリでしたが、 汎用性を持たせその他の私たちのアプリケーションからも利用できるように拡張され、 独立したものです。 そこで、私たちが普段Digesterを利用する主用途も、 アプリケーションの設定をXMLファイルに書いておき、 それをロードするのに使う、といった感じになりましょう。 このページでは、J2SE SDK 1.4.2_03、Digester 1.5で試した経緯をご紹介します。

 なお、付属のサンプルなどを読むと、以下の例よりも簡単でスマートな書き方がまだありそうですが、 どうもうまくいきませんでした。 追ってよりスマスマな例の動作確認ができたら、追加で載せていきたいと思います。


XML文書から1つのBeanを作成する

 Digesterを使うのに決まった作法というのはありませんが、 まずはXMLファイルと、それをロードして格納するJavaBeanクラスを定義するところから始めることになるでしょう。 ここでご紹介するサンプルはこれまたポピュラーな使い道ですが、 アプリケーションからデータベースに接続する際の接続情報 (ホスト名、ポート番号、データベース識別子、JDBCドライバのクラス名、 ログオンユーザ名、ログオンパスワード)を設定するファイル、 「loader-config1.xml」です。

<?xml version="1.0" encoding="Shift_JIS"?>
<loader-config>

<query-def>
<name>Q1</name>
<hostname>falcon.center.nsnhnkmmkk.co.jp</hostname>
<port>1521</port>
<driver-spec>oracle-thin</driver-spec>
<username>IKURA</username>
<password>TARAKO</password>
<database>ORCL</database>
<query>
SELECT ORDER_NO, LINE_NO, ITEM_ID, ORDER_DATE
  FROM ORDERS WHERE VENDOR_ID = ?
</query>
<input-data-file-name>test.dat</input-data-file-name>
</query-def>

</loader-config>

そのBeanクラスです。

package test.giacomo;

/**
 * データベース接続情報を保持するわりと汎用的なBeanクラスです。
 */
public class LoaderConfigBean {
    private String name;
    private String driverSpec;
    private String hostName;
    private String port;
    private String database;
    private String userName;
    private String password;
    private String query;
    private String inputDataFileName;

    /**
     * @return
     */
    public String getDatabase() {
        return database;
    }

    /**
     * @return
     */
    public String getDriverSpec() {
        return driverSpec;
    }

    /**
     * @return
     */
    public String getHostName() {
        return hostName;
    }

    /**
     * @return
     */
    public String getInputDataFileName() {
        return inputDataFileName;
    }

    /**
     * @return
     */
    public String getName() {
        return name;
    }

    /**
     * @return
     */
    public String getPassword() {
        return password;
    }

    /**
     * @return
     */
    public String getPort() {
        return port;
    }

    /**
     * @return
     */
    public String getQuery() {
        return query;
    }

    /**
     * @return
     */
    public String getUserName() {
        return userName;
    }

    /**
     * @param string
     */
    public void setDatabase(String string) {
        database = string;
    }

    /**
     * @param string
     */
    public void setDriverSpec(String string) {
        driverSpec = string;
    }

    /**
     * @param string
     */
    public void setHostName(String string) {
        hostName = string;
    }

    /**
     * @param string
     */
    public void setInputDataFileName(String string) {
        inputDataFileName = string;
    }

    /**
     * @param string
     */
    public void setName(String string) {
        name = string;
    }

    /**
     * @param string
     */
    public void setPassword(String string) {
        password = string;
    }

    /**
     * @param string
     */
    public void setPort(String string) {
        port = string;
    }

    /**
     * @param string
     */
    public void setQuery(String string) {
        query = string;
    }

    /**
     * @param string
     */
    public void setUserName(String string) {
        userName = string;
    }

}

次に、Digesterを使って、XMLファイルをBeanクラスにロードする処理を記述します。 Digesterを使うには、DigesterのJARファイル(commons-digester.jar)のほかに、 同じJakarta CommonsプロジェクトのCollections、Logging、BeanUtils のクラスライブラリも必要なので、全てのJARファイルを入手し、 CLASSPATHを通しておく必要があります。

package test.giacomo;

import java.io.File;
import org.apache.commons.digester.Digester;

/**
 * XMLファイルを読んで、1つのLoaderConfigBeanを作成して返します。
 */
public class LoaderConfigTester1 {
    private static final String xmlConfigFile = "./loader-config1.xml";

    public void test(){
        Digester digester = new Digester();

        digester.addObjectCreate("loader-config/query-def",
                                 "test.giacomo.LoaderConfigBean");
        digester.addCallMethod("loader-config/query-def/name", "setName", 0);
        digester.addCallMethod("loader-config/query-def/driver-spec", "setDriverSpec", 0);
        digester.addCallMethod("loader-config/query-def/hostname", "setHostName", 0);
        digester.addCallMethod("loader-config/query-def/port", "setPort", 0);
        digester.addCallMethod("loader-config/query-def/database", "setDatabase", 0);
        digester.addCallMethod("loader-config/query-def/username", "setUserName", 0);
        digester.addCallMethod("loader-config/query-def/password", "setPassword", 0);
        digester.addCallMethod("loader-config/query-def/query", "setQuery", 0);
        digester.addCallMethod("loader-config/query-def/input-data-file-name", "setInputDataFileName", 0);
        try {
            LoaderConfigBean c2 = (LoaderConfigBean) digester.parse(new File(xmlConfigFile));
            System.out.println(c2.getQuery());
        } catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args){
        LoaderConfigTester1 my = new LoaderConfigTester1();
        my.test();
    }
}


XML文書からBeanのリストを作成する

 上の例では、「query-def」要素が2つ以上あった場合、 最後の1つに対するBean1個しか作ることができません。 これを改良して、Beanのリストを保持することができるようにしたサンプルです。

package test.giacomo;

import java.util.List;
import java.util.ArrayList;

public class LoaderConfigBeanStore {
    private ArrayList objList;
    
    public LoaderConfigBeanStore(){ objList = new ArrayList(); }
    
    public void add(LoaderConfigBean b){ objList.add(b); }
    
    public List getObjList(){ return objList; }
}

package test.giacomo;

import java.io.File;
import java.util.List;
import java.util.Iterator;
import org.apache.commons.digester.Digester;

/**
 * XMLファイルを読んで、LoaderConfigBeanのリストを作成し、
 * LoaderConfigBeanStoreオブジェクトにして返します。
 */
public class LoaderConfigTester2 {
    private static final String xmlConfigFile = "./loader-config2.xml";

    public void test() {
        Digester digester = new Digester();

        digester.addObjectCreate("loader-config", LoaderConfigBeanStore.class);
        digester.addObjectCreate("loader-config/query-def", LoaderConfigBean.class);
        digester.addSetNext("loader-config/query-def", "add");
        digester.addBeanPropertySetter("loader-config/query-def/name");
        digester.addBeanPropertySetter("loader-config/query-def/host-name");
        digester.addBeanPropertySetter("loader-config/query-def/port");
        digester.addBeanPropertySetter("loader-config/query-def/driver-spec", "driverSpec");
        digester.addBeanPropertySetter("loader-config/query-def/user-name");
        digester.addBeanPropertySetter("loader-config/query-def/password");
        digester.addBeanPropertySetter("loader-config/query-def/database");
        digester.addBeanPropertySetter("loader-config/query-def/query");
        digester.addBeanPropertySetter(
            "loader-config/query-def/input-data-file-name",
            "inputDataFileName");

        LoaderConfigBeanStore store = null;
        try {
            store = (LoaderConfigBeanStore) digester.parse(new File(xmlConfigFile));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (store != null) {
            List objList = store.getObjList();
            for (Iterator iter = objList.iterator(); iter.hasNext();) {
                LoaderConfigBean b = (LoaderConfigBean) iter.next();
                System.out.println(b.getName());
                System.out.println(b.getQuery());
            }
        }
    }

    public static void main(String[] args) {
        LoaderConfigTester2 my = new LoaderConfigTester2();
        my.test();
    }
}

Java kowaza Top

(first uploaded 2004/05/27 last updated 2004/05/30, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル