入門記1:動かしてみる。

あまり気負わないBuriの入門記もとい自分用メモ。(気負った割には忙しさにかまけて放置してしまったPythonに学んで。。。w)


元ネタは「基本的な開発の概要Buri-TECHSCORE-(http://www.techscore.com/tech/Seasar/Buri/3.html)」ですが、Buriは1.0を使います。バージョンの変化によるものか、ちょっとずつ差があるのでその差を埋めるためのメモがてら、動かしてみました。


まず、環境の準備。

Maven2を使うと楽です。加えて、Eclipseを使うと楽です。なので、Maven2用のプラグインq4eも必要です。それぞれの入手元はコチラ。あとデータベースも必要です。BuriはサンプルでDerbyを使っているようなので、Derbyもダウンロードしておかないといけません。
- Eclipse
- http://www.eclipse.org/europa/
- 僕はJavaEE Developersのパッケージを使ってます。
- Maven2
- http://maven.apache.org/
- 僕は2.0.8使いました。
- q4e
- http://code.google.com/p/q4e/
- Derby
- http://db.apache.org/derby/
- XPDL Editor JPEd
- http://sourceforge.net/projects/jped

さっそくtryburiというプロジェクトを作ります。(せっかくEclipseを使っているので、ここは右クリック→New→Project→Maven2 Project Creation Wizardでさくさくっと作っちゃいます)できたら記事の通りにpom.xmlのrepositoriesとdependenciesを書きます。


続いてデータベースを構築する為、ijを使ってCreate文を流します。

前述の記事のDocumentテーブルもファイルにしておくと楽でしょうね。(取り合えずファイル名は[docmanage.sql]として保存しておきました。)
なのでその実行は。。。

> cd D:\home\derby\db-derby-10.3.3.0-bin\bin
> ij
ij> connect 'jdbc:derby:D:\home\eclipse\workspace\tryburi\db\trybury;create=true;';
ij> run 'D:\home\eclipse\workspace\tryburi\db\createdb_derby.sql';
(ry
ij> run 'D:\home\eclipse\workspace\tryburi\db\docmanage.sql';
(ry

こんな感じです。Buri用のデータベースも必要なので一緒にCreateします。


続いてXPDLを書いてみます。

こんなの。


ファイル名は[docmanage.xpdl]で、src/main/resourcesの直下に置いておきます。(JPEdというエディタを使用しました)

細かな設定は。。。
- JPEd起動。
- Ctrl+NまたはFile→Newまたは新規作成っぽいアイコンで新規作成。
- 「newpkg」というノードが出来るので、右クリック→Propertiesを。
- PackageのProperties→GeneralにあるNameを「文書管理パッケージ」に。
- PackageのProperties→ApplicationsにId「docmanage_app1」Name「OgnlInvoker」とId「docmanage_app2」Name「AfterOgnlInvoker」の2つを追加。
- PackageのProperties→Workflow variablesにId「tryapp.dto.DocumentDto」Name「」Data type「Basic type -> String」を追加。(Dtoのクラス名以外はデフォルト)


以上で、パッケージに対しての設定が終了したので続いてプロセスの設定。

- メニューのPackage→Insert new processを選択。
- 「newpkg_wp1」というノードが出来るのでF2または右クリック→Properties。
- Workflow processのProperties→GeneralにあるNameを「文書管理プロセス」に。

これ以外の項目は、絵を描いていると勝手に埋まっていきます。


で、絵を書きます。人の絵を選んでキャンパスに移して、初めてフローが描ける状態になります。
人を置くことで出てきたレーンを右クリックするとまたPropertiesを選べるようになっていますので、IdをそのままにしてNameを「文書管理担当」とします。続いて見るからに「再生」って感じのアイコンを選んで、またキャンパスへ。

そんな要領で絵を書いて、XPDLの作成が完了。

とまぁ、このへんはBuriのリファレンスに書かれている通りです。


続いてJavaファイル。
冒頭の記事にあるように、DocumentDto、DocumentDao、DocumentBaoを作ります。というか作りました。


そして各種Diconファイル。

buri.diconパッケージにburi-user.diconを作るのですが、元になるdiconはリポジトリ上のsrc/test/resources/buri/diconにあるburi-user.diconをコピーしちゃうのが楽っぽいですね。今回作る上で必要最低限(と思われる。。。取り合えず、動きはした)のは以下のような感じです。前述したXPDLもちゃんと指定してますね。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
	"http://www.seasar.org/dtd/components23.dtd">
<components>
	<include path="buri/dicon/allDao.dicon" />
	<component class="org.escafe.buri.common.util.BuriConfigurationImpl">
	</component>
	<component name="BuriEngineConfig" class="org.escafe.buri.engine.impl.BuriEngineConfigImpl">
		<initMethod name="addResourceConfig">
			<arg>"docmanage.xpdl"</arg>
			<arg>"文書管理パッケージ"</arg>
		</initMethod>
	</component>
	<component name="ExcelBaseParticipantProvider" class="org.escafe.buri.common.participantprovider.impl.ExcelBaseParticipantProvider">
	</component>
	<component class="org.escafe.buri.common.participantprovider.impl.ExcelPrtiPrvidrParserImpl">
	</component>
</components>

あとはDaoを使うので、Daoとそれに必要なdiconファイル(app.dicon、jdbc.dao)、Dtoを作ればOKです。


記事の通り(コメントは消しましたが)テストコードを書いて走らせてみる、と。

public class DocumentBaoTest extends S2TestCase {

    private static final String DICON_PATH = "app.dicon";

    private DocumentBao bao;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        super.include(DICON_PATH);
    }
    public void testTx() {
        DocumentDto doc1 = new DocumentDto("文書A", "文書Aです。");
        DocumentDto doc2 = new DocumentDto("文書B", "文書Bです。");
        DocumentDto doc3 = new DocumentDto("文書C", "文書Cです。");
        // 1st
        this.bao.register(doc1);
        System.out.println(this.bao.getPublishings().size());
        assertEquals(1, this.bao.getPublishings().size());
        // 2nd
        this.bao.register(doc2);
        this.bao.register(doc3);
        assertEquals(3, this.bao.getPublishings().size());
        // 3rd
        this.bao.finishPublishing(doc1);
        assertEquals(2, this.bao.getPublishings().size());
        // 4th
        this.bao.finishPublishing(doc2);
        this.bao.finishPublishing(doc3);
        assertEquals(0, this.bao.getPublishings().size());
    }

}

ハイ、動きました。結果もオールグリーンになる筈です。


ここで作ったフローと、JUnitで作ったテストを見てみると、Buriの目指すものがぼんやりと見えてきます。データベースの正規化とIF撲滅といった凄いテーマが一緒に語られて、あるいはそこが確かにBuriの目指すものの本質なのかも知れないのですが、ここでBaoを通して行った事は、ステータスの遷移をフローに書いてそのフロー通りにBuriがステータスを更新してくれる、というものでした。

これを使えば、DocumentテーブルにSTATUSという列を作らなくても、必要な状態遷移は永続化されるということです。(BURISTATEというBuri固有のテーブルで、更新履歴が管理されているようです)また上記のような特定の状態のクエリも、便利にごにょごにょしてくているようです。複数のテーブルをJoinしたりする極めて汎用性の低いクエリが必要になった場合は、ぶり固有のテーブルで管理されている状態も合わせてJoinすることできっとどうにかできるでしょう。

これはBaoを使ったケースでしたが、Baoを作らずにBuriを利用する方法もあるので、次はそれに挑戦してみます。


しかし、BaoはどうやってDaoを呼び出してるんだ><