<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>ITEMAN Blog</title>
  <link rel="alternate" type="text/html" href="http://iteman.jp/blog/" />
  <link rel="self" type="application/atom+xml" href="http://iteman.jp/blog/atom.xml" />
  <id>tag:iteman.jp,2008-08-02:/blog//3</id>
  <updated>2009-12-28T02:26:33Z</updated>
<subtitle>アイテマンブログ</subtitle>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.3-ja</generator>

  <entry>
    <title>MakeGood 0.2.0, Stagehand_TestRunner 2.10.0 をリリースしました</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/12/makegood-020-stagehand-testrun.html" />
    <id>tag:iteman.jp,2009:/blog//3.91</id>

    <published>2009-12-28T02:24:55Z</published>
    <updated>2009-12-28T02:26:33Z</updated>

    <summary>先日 MakeGood 0.2.0, Stagehand_TestRunner 2.10.0 をリリースしました。Stagehand_TestRunner 2.10.0 では SimpleTest サポートが大幅に強化され、JUnit XML ファイル出力をはじめ、これまで PHPUnit のみサポートされていた機能のほとんどが使えるようになりました。MakeGood 0.2.0 ではこの成果を使って SimpleTest がサポートされました。...</summary>
    <author>
      <name>KUBO Atsuhiro</name>
      <uri>http://twitter.com/iteman</uri>
    </author>
    
    <category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="makegood" label="MakeGood" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pdt" label="PDT" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pieceframework" label="Piece Framework" scheme="http://www.sixapart.com/ns/types#tag" /><category term="stagehand_testrunner" label="Stagehand_TestRunner" scheme="http://www.sixapart.com/ns/types#tag" /><category term="tdd" label="TDD" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  先日 <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> 0.2.0, <a href="http://redmine.piece-framework.com/projects/show/stagehand-testrunner" target="_blank">Stagehand_TestRunner</a> 2.10.0 をリリースしました。<a href="http://redmine.piece-framework.com/projects/show/stagehand-testrunner" target="_blank">Stagehand_TestRunner</a> 2.10.0 では <a href="http://simpletest.org/" target="_blank">SimpleTest</a> サポートが大幅に強化され、<a href="http://www.junit.org/" target="_blank">JUnit</a> XML ファイル出力をはじめ、これまで <a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> のみサポートされていた機能のほとんどが使えるようになりました。<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> 0.2.0 ではこの成果を使って <a href="http://simpletest.org/" target="_blank">SimpleTest</a> がサポートされました。
</p>]]>
      <![CDATA[<h2>MakeGood 0.2.0</h2>
<a href="http://iteman.jp/blog/assets_c/2009/12/selects-testing-framework-560.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/12/selects-testing-framework-560.html','popup','width=939,height=598,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/12/selects-testing-framework-thumb-500x318-560.png" width="500" height="318" alt="selects-testing-framework.png" class="mt-image-none" style="" /></a>
<p>
  ご覧のとおりプロジェクトのプロパティから <a href="http://simpletest.org/" target="_blank">SimpleTest</a> が選択できるようになりました。プロジェクトで <a href="http://simpletest.org/" target="_blank">SimpleTest</a> を使う場合はここで選択します。
</p>
<p>
  次のリリースでは結果ビューのグリーンバー・レッドバーの部分をリアルタイムに更新する機能を提供予定です。
</p>

<h2>Stagehand_TestRunner 2.10.0</h2>
<p>
  <a href="http://simpletest.org/" target="_blank">SimpleTest</a> サポートの強化ですが、具体的には以下の 3 つの機能が使えるようになっています。
</p>
<ul>
  <li>指定されたファイルの指定されたテストのみの実行</li>
  <li>指定されたクラスのテストのみの実行</li>
  <li><a href="http://www.junit.org/" target="_blank">JUnit</a> XML フォーマットによる、指定されたファイルへのテスト結果のロギング</li>
</ul>
<p>
  これらは <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> の <a href="http://simpletest.org/" target="_blank">SimpleTest</a> サポートのために実装されたものですが、最後の <strong>JUnit XML フォーマットによる、指定されたファイルへのテスト結果のロギング</strong> は <a href="http://hudson-ci.org/" target="_blank">Hudson</a>, <a href="http://cruisecontrol.sourceforge.net/" target="_blank">CruiseControl</a> などの <a href="http://www.objectclub.jp/community/XP-jp/xp_relate/cont-j" target="_blank">継続的インテグレーション</a> サーバとの統合を可能にします。こちらについては、またの機会に。
</p>

<h2>参考文献</h2>
<ul>
  <li><a href="http://redmine.piece-framework.com/wiki/makegood/Ja_Overview" target="_blank">MakeGood - Eclipse PDT でテスト駆動開発を行うためのテストランナー - Piece Framework</a></li>
  <li><a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner - テスト駆動開発のためのテストランナー - Piece Framework</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>Eclipse + PHP + TDD = MakeGood! - MakeGood の特徴と使い方</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/11/eclipse-php-tdd-makegood.html" />
    <id>tag:iteman.jp,2009:/blog//3.90</id>

    <published>2009-11-26T03:48:10Z</published>
    <updated>2009-11-26T03:56:29Z</updated>

    <summary>まっつんです。先日の 関西オープンソース 2009 でご紹介させていただいた Piece Framework の新しいプロダクト MakeGood ですが、今月 23 日にようやく最初のバージョンをリリースすることができました。早速皆様に使っていただけるよう、今回の記事では MakeGood の特徴と使い方をご紹介いたします。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="makegood" label="MakeGood" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pdt" label="PDT" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pieceframework" label="Piece Framework" scheme="http://www.sixapart.com/ns/types#tag" /><category term="stagehand_testrunner" label="Stagehand_TestRunner" scheme="http://www.sixapart.com/ns/types#tag" /><category term="tdd" label="TDD" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。先日の <a href="http://k-of.jp/2009/" target="_blank">関西オープンソース 2009 </a> でご紹介させていただいた <a href="http://piece-framework.com/" target="_blank">Piece Framework</a> の新しいプロダクト <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> ですが、今月 23 日にようやく最初のバージョンをリリースすることができました。早速皆様に使っていただけるよう、今回の記事では <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> の特徴と使い方をご紹介いたします。
</p>]]>
      <![CDATA[<h2>MakeGood とは？</h2>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> とは <a href="http://eclipse.org/pdt/" target="_blank">PDT</a> にユニットテスト実行機能 (<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> のみのサポート) を付与する <a href="http://eclipse.org/" target="_blank">Eclipse</a> プラグインであり、快適な <a href="http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA" target="_blank">テスト駆動開発</a> (TDD: Test Driven Development) のための環境の提供を目標とするプロダクトです。バージョン 0.1.0 現在、以下のような特徴があります。
</p>
<ul>
  <li>PHP Explorer および Package Explorer からのテストの実行</li>
  <li>PHP Editor からのテストの実行</li>
  <li>テスト実行時にシステムインクルードパスが使用可能</li>
</ul>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> のインストールと構成については、<a href="http://redmine.piece-framework.com/wiki/makegood/Ja_InstallationAndConfigurationGuide" target="_blank">インストール・構成ガイド</a> をご覧ください。
</p>

<h2>PHP Explorer および Package Explorer からのテストの実行</h2>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> を導入すると、PHP Explorer/Package Explorer と、PHP Editor からのテストの実行ができるようになります。PHP Explorer/Package Explorer からテストを実行するには、リソースを選択し、コンテキストメニューから <strong>テストの実行</strong> を選択します。
</p>
<p>
  選択可能なリソースは以下のとおりです。
</p>
<ul>
  <li>フォルダー</li>
  <li>ファイル</li>
  <li>クラス (PHP Explorer のみ)</li>
  <li>メソッド (PHP Explorer のみ)</li>
</ul>
<p>
  選択されたリソースの配下にあるテストはすべて実行されます。これは特定のフォルダー以下にあるテストをすべて実行したい場合などに便利です。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/11/run-tests-on-explorer-550.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/11/run-tests-on-explorer-550.html','popup','width=1440,height=869,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/11/run-tests-on-explorer-thumb-500x301-550.png" width="500" height="301" alt="run-tests-on-explorer.png" class="mt-image-none" style="" /></a>
<blockquote class="note"><strong>ノート</strong>: プロジェクトで <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> を初めて実行する場合、プリロードスクリプトを選択する画面が表示されます。プリロードスクリプトは、インクルードパス, オートローディング、エラーハンドリングなど、テスト実行の準備を行うスクリプトです。スクリプトは、テストランナー本体がロードされる前に評価されます。プリロードスクリプトを使わない場合は空のままで <strong>OK</strong> ボタンをクリックしてください。詳細については <a href="http://redmine.piece-framework.com/wiki/makegood/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%BB%E6%A7%8B%E6%88%90%E3%82%AC%E3%82%A4%E3%83%89#%E3%83%97%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%AE%E4%BD%BF%E7%94%A8" target="_blank">こちら</a> をご覧ください。</blockquote>

<h2>PHP Editor からのテストの実行</h2>
<p>
  PHP Editor からテストを実行するには、PHP Editor 内で右クリックを行い、コンテキストメニューから <strong>テストの実行</strong> または <strong>このファイルに関連するテストの実行</strong> を選択します。
</p>
<img alt="context-menu-on-editor.png" src="http://iteman.jp/blog/images/context-menu-on-editor.png" width="703" height="103" class="mt-image-none" style="" />
<p>
  <strong>テストの実行</strong> には編集中のファイルがテストコードの場合に有効となる 3 種類のサブメニュー、<strong>コンテキスト</strong>, <strong>クラス</strong>, <strong>ファイル</strong> があり、それぞれ異なる振る舞いを示します。
</p>
<p>
  <strong>このファイルに関連するテストの実行</strong> は、編集中のファイルがプロダクションコードの場合も有効であり、そのファイルに含まれるクラスとそのすべての派生クラスに依存するテストを実行します。
</p>
<p>
  以下はこれらの振る舞いをまとめたものです。
</p>
<h5>テストコードを編集中の場合</h5>
<table>
  <thead>
    <tr>
      <th>メニュー</th>
      <th>実行されるテスト</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>テストの実行 - コンテキスト</td>
      <td>カーソルがある位置の最小の単位 (メソッド、クラス、ファイル) のテスト</td>
    </tr>
    <tr>
      <td>テストの実行 - クラス</td>
      <td>カーソルがある位置のクラスに含まれるテスト</td>
    </tr>
    <tr>
      <td>テストの実行 - ファイル</td>
      <td>ファイルに含まれるすべてのテスト</td>
    </tr>
    <tr>
      <td>このファイルに関連するテストの実行</td>
      <td>ファイルに含まれるすべてのテストおよび派生クラスのテスト</td>
    </tr>
  </tbody>
</table>
<h5>プロダクションコードを編集中の場合</h5>
<table>
  <thead>
    <tr>
      <th>メニュー</th>
      <th>実行されるテスト</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>テストの実行 - コンテキスト</td>
      <td>-</td>
    </tr>
    <tr>
      <td>テストの実行 - クラス</td>
      <td>-</td>
    </tr>
    <tr>
      <td>テストの実行 - ファイル</td>
      <td>-</td>
    </tr>
    <tr>
      <td>このファイルに関連するテストの実行</td>
      <td>ファイルに含まれるすべてのクラスおよび派生クラスに依存するテスト</td>
    </tr>
  </tbody>
</table>
<p>
  <strong>プロダクションコードからテストを実行することができる</strong> という点は、<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> 0.1.0 の大きな特徴といえます。テストコードとプロダクションコード、どちらからもテストを実行できるので、素早いフィードバックを得ることができます。
</p>

<h2>キーバインディングによる操作の実行</h2>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> では、それぞれの操作についてキーバインディングを設定することができます。キーバインディングを駆使することで、テストの度にコンテキストメニューを開くことなく素早くテストを実行することができます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/11/keybinding-554.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/11/keybinding-554.html','popup','width=1281,height=869,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/11/keybinding-thumb-500x339-554.png" width="500" height="339" alt="keybinding.png" class="mt-image-none" style="" /></a>

<h2>テスト実行時にシステムインクルードパスが使用可能</h2>
<p>
  <a href="http://eclipse.org/pdt/" target="_blank">PDT</a> の PHP 実行環境では、<a href="http://www.php.net/manual/ja/configuration.file.php" target="_blank">設定ファイル</a> で定義されたインクルードパス (システムインクルードパス) はすべて破棄され、プロジェクトに対して設定されたインクルードパスのみが有効となります。とはいえ、システムインクルードパスを使用したい場合もあるでしょう。そこで <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> では <a href="http://eclipse.org/pdt/" target="_blank">PDT</a> を拡張し、システムインクルードパスを使用できるようにしました。
</p>
<p>
  システムインクルードパスを使用するには、プロジェクトプロパティの <strong>PHP Include Path</strong> を開き、<strong>システムインクルードパスの追加</strong> ボタンをクリックします。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/11/use-system-include-path-557.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/11/use-system-include-path-557.html','popup','width=942,height=582,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/11/use-system-include-path-thumb-500x308-557.png" width="500" height="308" alt="use-system-include-path.png" class="mt-image-none" style="" /></a>
<blockquote class="note"><strong>ノート</strong>: システムインクルードパスを設定すると、PHP Explorer の <strong>PHP Include Path</strong> に <strong>プロジェクト名/.project</strong> という要素が追加されます。ここは <strong>システムインクルードパス</strong> と表示したいところですが、0.1.0 では実装を見送りました。</blockquote>

<h2>おわりに</h2>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> の実装にあたっては多くの技術的課題がありました。それらを克服し、0.1.0 をリリースすることができたことを大変嬉しく思います。次のバージョンでは <a href="http://simpletest.org/" target="_blank">SimpleTest</a> のサポート、テスト実行のリアルタイムな進捗リポートといった機能を追加する予定です。
</p>
<p>
  <a href="http://eclipse.org/" target="_blank">Eclipse</a> で PHP の開発を行っている方はもちろん、普段はテキストエディタをお使いの方も、この機会に是非お試しください。皆様のご意見、ご感想、パッチなどお待ちしております。
</p>

<h2>参考文献</h2>
<ul>
  <li><a href="http://redmine.piece-framework.com/wiki/makegood/Ja_Overview" target="_blank">MakeGood - PDT でテスト駆動開発を行うためのテストランナー - Piece Framework</a></li>
  <li><a href="http://redmine.piece-framework.com/wiki/makegood/Ja_InstallationAndConfigurationGuide" target="_blank">MakeGood - インストール・構成ガイド - Piece Framework</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>Piece Framework Development Inside: PDT の問題 - MakeGood</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/11/stagehand-testrunner-eclipse-1.html" />
    <id>tag:iteman.jp,2009:/blog//3.85</id>

    <published>2009-10-31T17:27:38Z</published>
    <updated>2009-10-31T17:34:32Z</updated>

    <summary>まっつんです。今回の記事は Piece Framework の開発ブログ Piece Framework Development Inside の第 1 回です。このシリーズでは、Piece Framework の開発における設計・実装の判断、悩み、技術解説などを書いていきたいと思います。 今回は、間もなくリリース予定の新プロダクト MakeGood を題材に、PDT (PHP Development Tools) の問題についていくつか書いてみます。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="makegood" label="MakeGood" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pdt" label="PDT" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pieceframework" label="Piece Framework" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pieceframeworkdevelopmentinside" label="Piece Framework Development Inside" scheme="http://www.sixapart.com/ns/types#tag" /><category term="stagehand_testrunner" label="Stagehand_TestRunner" scheme="http://www.sixapart.com/ns/types#tag" /><category term="プラグイン" label="プラグイン" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。今回の記事は <a href="http://piece-framework.com/" target="_blank">Piece Framework</a> の開発ブログ <strong>Piece Framework Development Inside</strong> の第 1 回です。このシリーズでは、<a href="http://piece-framework.com/" target="_blank">Piece Framework</a> の開発における設計・実装の判断、悩み、技術解説などを書いていきたいと思います。
</p>
<p>
  今回は、間もなくリリース予定の新プロダクト <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> を題材に、<a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> (PHP Development Tools) の問題についていくつか書いてみます。
</p>]]>
      <![CDATA[<h2>MakeGood とは？</h2>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> は <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> を使った <a href="http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA" target="_blank">テスト駆動開発</a> (TDD: Test Driven Development) を快適に行うための <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> プラグインです。間もなくリリース予定の 0.1.0 (alpha) では、パッケージエクスプローラーおよび PHP エクスプローラーそしてエディター上からのテストの実行と結果の表示がサポートされています。
</p>
<p>
  <strong>make good</strong> には「成し遂げる」「成功する」などの意味があり、<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> を使ってよりよいアプリケーションを作成し、プロジェクトを成功させてほしいという思いが込められています。
</p>

<h2>PDT の問題</h2>
<p>
  <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> の PHP 開発環境として <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> はデファクトスタンダードとなっています。<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> は PHP の実行環境やエディター、PHP エクスプローラーなど多くの部分で <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> に依存しています。そのため、筆者は <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> のソースコードを見る機会が多いのですが、現在の <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> の設計・実装にはいくつか問題があると考えています。
</p>

<h3>プラグインの依存関係が循環している</h3>
<p>
  <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> には、PHP の実行を担当する <strong>org.eclipse.php.debug.core</strong> プラグインと、PHP 実行時のユーザインターフェイスを担当する <strong>org.eclipse.php.debug.ui</strong> プラグインがあります。これらのプラグインはお互いに依存しています。これにより、2 つのプラグインは実質的に 1 つのプラグインとなり、<a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> およびそれに依存するプラグインの保守性は低下します。プラグイン、パッケージ、クラスといったコンポーネントの粒度に関わらず、依存関係を循環させないことは大切です。
</p>
<h6>循環したプラグインの依存関係</h6>
<a href="http://iteman.jp/blog/assets_c/2009/11/cyclic-dependencies-541.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/11/cyclic-dependencies-541.html','popup','width=807,height=249,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/11/cyclic-dependencies-thumb-500x154-541.png" width="500" height="154" alt="cyclic-dependencies.png" class="mt-image-none" style="" /></a>
<p>
  今回のケースは、非循環依存関係の原則 (ADP: Acyclic Dependencies Principle) に違反していますので、依存関係逆転の原則 (DIP: The Dependency Inversion Principle) を適用することで依存関係の循環を断つことができます、具体的には、<strong>org.eclipse.php.debug.core</strong> プラグインで拡張ポイントを定義し、<strong>org.eclipse.php.debug.ui</strong> プラグインはその拡張ポイントを利用します。
</p>
<h6>依存関係逆転の原則を適用したプラグインの依存関係</h6>
<a href="http://iteman.jp/blog/assets_c/2009/11/cyclic-dependencies-improvement-by-dip-544.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/11/cyclic-dependencies-improvement-by-dip-544.html','popup','width=807,height=249,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/11/cyclic-dependencies-improvement-by-dip-thumb-500x154-544.png" width="500" height="154" alt="cyclic-dependencies-improvement-by-dip.png" class="mt-image-none" style="" /></a>
<blockquote class="note"><strong>ノート</strong>: 書籍 <a href="http://www.amazon.co.jp/gp/product/4797347783?ie=UTF8&tag=iteman-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4797347783">アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技</a><img src="http://www.assoc-amazon.jp/e/ir?t=iteman-22&l=as2&o=9&a=4797347783" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> には、これらの原則の詳細が記述されています。</blockquote>

<h3>インターナルパッケージが多い</h3>
<p>
  <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> において、パッケージ名の一部に <strong>internal</strong> が付与されているものは <strong>インターナルパッケージ</strong> と呼ばれています。基本的に <strong>インターナルパッケージ</strong> はプラグインの内部でのみ使用されることが想定されていますが、エクスポートされている場合は他のプラグインから利用することもできます。<strong>インターナルパッケージ</strong> の使用には、将来のバージョンでサポートされなくなるリスクがあります。
</p>
<p>
  <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> のほとんどのパッケージは、このようなエクスポートされたインターナルパッケージです。開発者の意志を尊重し、なるべくインターナルパッケージを使用しないというのが筆者の基本的な考えですが、それでは <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> の機能を実現することができないため、今回は必要に応じてインターナルパッケージを使用しています。
</p>

<h3>1 つのメソッドが複数の処理を行う</h3>
<p>
  <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> は <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> の PHP 実行環境を利用します。<a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> は選択されている PHP スクリプトを引数として PHP を実行しますが、<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> では選択されている PHP スクリプトを PHP の引数とせず、バックエンドである <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> のコマンドに渡す必要があります。
</p>
<p>
  筆者は、必要な設定を組み立ててから PHP を実行している <strong>PHPExeLaunchShortcut</strong> クラスを継承することにしました。このクラスで組み立てられた設定に、<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> の設定を追加して PHP を実行すれば、目的を達成できると考えたからです。
</p>
<p>
  しかし、この試みは上手くいきませんでした。これらの処理は <strong>searchAndLaunch</strong> という 1 つのメソッドに記述されているため、<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> の設定を追加するフックがないのです。また、<strong>searchAndLaunch</strong> はスタティックメソッドとして宣言されているため、オーバーライドすることもできません。
</p>
<p>
  今回は、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> が提供しているリスナーを利用して PHP が実行される前にフックを行い、そこに必要な処理を差し込むことで解決しました。
</p>

<h2>おわりに</h2>
<p>
  <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> については拡張に関すること以外にも変更してほしい仕様などがいくつか出てきています。今後は、要望を出したり、パッチを作成することで、筆者も <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> に貢献していければと考えています。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.eclipse.org/" target="_blank">Eclipse</a> (Eclipse Modeling Tools)</th><td>3.5</td>
    </tr>
    <tr>
      <th><a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a></th><td>2.1.1</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://www.amazon.co.jp/gp/product/4797347783?ie=UTF8&tag=iteman-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4797347783">アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技</a><img src="http://www.assoc-amazon.jp/e/ir?t=iteman-22&l=as2&o=9&a=4797347783" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>11 月 7 日 (土) 関西オープンソース 2009 ユーザ企画 「Eclipse + PHP + TDD = MakeGood!」のご案内</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/10/11-7-2009-eclipse-php-tdd-make.html" />
    <id>tag:iteman.jp,2009:/blog//3.89</id>

    <published>2009-10-31T07:31:10Z</published>
    <updated>2009-10-31T10:56:49Z</updated>

    <summary>11 月 6 日 (金), 7 日 (土) に大阪南港の ATC にて 関西オープンソース 2009 が開催されます。私たちも 7 日の 15:00 から Eclipse + PHP + TDD = MakeGood! と題したセッションでお話しいたします。...</summary>
    <author>
      <name>KUBO Atsuhiro</name>
      <uri>http://twitter.com/iteman</uri>
    </author>
    
    <category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="makegood" label="MakeGood" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pdt" label="PDT" scheme="http://www.sixapart.com/ns/types#tag" /><category term="php" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pieceframework" label="Piece Framework" scheme="http://www.sixapart.com/ns/types#tag" /><category term="stagehand_testrunner" label="Stagehand_TestRunner" scheme="http://www.sixapart.com/ns/types#tag" /><category term="tdd" label="TDD" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  11 月 6 日 (金), 7 日 (土) に大阪南港の <a href="http://www.atc-co.com/index.php" target="_blank">ATC</a> にて <a href="http://k-of.jp/2009/" target="_blank">関西オープンソース 2009</a> が開催されます。私たちも 7 日の 15:00 から <strong>Eclipse + PHP + TDD = MakeGood!</strong> と題したセッションでお話しいたします。
</p>]]>
      <![CDATA[<p>
  今回のセッションでは、間もなくリリース予定の<a href="http://piece-framework.com/" target="_blank">Piece Framework</a> の新しいプロダクト <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> をご紹介いたします。<a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> は <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a> を使った <a href="http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA" target="_blank">テスト駆動開発</a> (TDD: Test Driven Development) を快適に行うための <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> プラグインであり、パッケージエクスプローラーおよび PHP エクスプローラーそしてエディター上からのテストの実行と結果の表示をサポートします。
</p>

<p>皆様のご参加をお待ちしております。以下、セッションの情報です。</p>

<h2>Eclipse + PHP + TDD = MakeGood!</h2>

<p><a href="http://www.eclipse.org/" target="_blank">Eclipse</a> + PHP による快適な TDD をサポートする <a href="http://piece-framework.com/" target="_blank">Piece Framework</a> の新プロダクト <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> をデモを交えてご紹介いたします。</p>

<table>
  <tr>
    <th>発表者</th>
    <td>久保敦啓、松藤秀治</td>
  </tr>
  <tr>
    <th>対象</th>
    <td>PHP 開発者</td>
  </tr>
  <tr>
    <th>日時</th>
    <td>11 月 7 日 (土) 15:00 - 15:50</td>
  </tr>
  <tr>
    <th>定員</th>
    <td>30 名程度</td>
  </tr>
  <tr>
    <th>参加費用</th>
    <td>無料</td>
  </tr>
  <tr>
    <th>参加方法</th>
    <td>事前申し込みは不要です。直接会場にお越しください。</td>
  </tr>
  <tr>
    <th>会場</th>
    <td>
      大阪南港 ATC ITM 棟 9F - セミナールーム 3<br />
      〒559-0034 大阪市住之江区南港北 2-1-10<br />
      <br />
      会場へのアクセスは <a href="http://k-of.jp/2009/access/" target="_blank">KOF2009：関西オープンソース2009 会場への行きかた</a> をご覧ください。
    </td>
  </tr>
  <tr>
    <th>主催</th>
    <td>
      株式会社アイテマン/<a href="http://piece-framework.com/" target="_blank">Piece Project</a><br />
      ※本ユーザ企画の主催です。
    </td>
  </tr>
</table>

<h2>参考サイト</h2>
<ul>
  <li><a href="http://k-of.jp/2009/" target="_blank">KOF2009：関西オープンソース2009</a></a></li>
  <li><a href="http://www.atc-co.com/index.php" target="_blank">大阪南港の複合型大型モール ATC（ショッピング・イベント情報）</a></li>
  <li><a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood - 概要 - Piece Framework</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>PHP で快適なテスト駆動開発を - Stagehand_TestRunner の特徴と使い方を知る</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/10/php---stagehand-testrunner.html" />
    <id>tag:iteman.jp,2009:/blog//3.86</id>

    <published>2009-10-05T13:17:03Z</published>
    <updated>2009-10-31T06:22:35Z</updated>

    <summary>先日、今年の 1 月以来となる Stagehand_TestRunner の最新バージョン 2.7.0 のリリースを行いました。コマンドラインのテストランナーを提供するこのプロダクトは、テスト駆動開発 (TDD: Test Driven Development) をより快適にすることを目的としています。 今回は Stagehand_TestRunner の特徴と使い方をご紹介いたします。...</summary>
    <author>
      <name>KUBO Atsuhiro</name>
      <uri>http://twitter.com/iteman</uri>
    </author>
    
    <category term="pear" label="PEAR" scheme="http://www.sixapart.com/ns/types#tag" /><category term="php" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pieceframework" label="Piece Framework" scheme="http://www.sixapart.com/ns/types#tag" /><category term="stagehand_testrunner" label="Stagehand_TestRunner" scheme="http://www.sixapart.com/ns/types#tag" /><category term="tdd" label="TDD" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  先日、今年の 1 月以来となる <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> の最新バージョン <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_ReleaseNotes_2_7_0" target="_blank">2.7.0</a> のリリースを行いました。コマンドラインのテストランナーを提供するこのプロダクトは、<a href="http://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA" target="_blank">テスト駆動開発</a> (TDD: Test Driven Development) をより快適にすることを目的としています。
</p>
<p>
  今回は <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> の特徴と使い方をご紹介いたします。
</p>]]>
      <![CDATA[<h2>Stagehand_TestRunner とは？</h2>
<p>
  <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> とは、<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> や <a href="http://simpletest.org/" target="_blank">SimpleTest</a> といった PHP のテスティングフレームワーク向けに書かれたテストの実行に特化した <a href="http://piece-framework.com/" target="_blank">Piece Framework</a> のプロダクトで、下記のような特徴があります。
</p>
<ul>
  <li>指定されたディレクトリに含まれるテストの実行</li>
  <li>指定されたファイルに含まれるテストの実行</li>
  <li>指定されたファイルの指定されたテストのみの実行 (<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> のみ)</li>
  <li>テスト結果の色付け</li>
  <li>指定された PHP スクリプトのテスト実行前のプリロード</li>
  <li>指定されたディレクトリの変更の監視および変更検出時のテストの実行</li>
  <li><a href="http://growl.info/" target="_blank">Growl</a> へのテスト結果の通知</li>
  <li><a href="http://www.junit.org/" target="_blank">JUnit</a> XML フォーマットによる、指定されたファイルへのテスト結果のロギング (<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> および <a href="http://qa.php.net/write-test.php" target="_blank">PHPT</a>)</li>
  <li>詳細な進捗リポートの出力 (<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> および <a href="http://qa.php.net/write-test.php" target="_blank">PHPT</a>)</li>
  <li><a href="http://www.phpunit.de/" target="_blank">PHPUnit</a>, <a href="http://qa.php.net/write-test.php" target="_blank">PHPT</a>, <a href="http://simpletest.org/" target="_blank">SimpleTest</a>, <a href="http://www.phpspec.org/" target="_blank">PHPSpec</a> のサポート</li>
</ul>
<p>
  これらの特徴は、TDD による PHP アプリケーションの開発を強力にサポートします。
</p>

<h2>Stagehand_TestRunner のインストール</h2>
<p>
  <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> は <a href="http://pear.php.net/manual/ja/guide.users.commandline.installing.php" target="_blank">PEAR パッケージ</a> として提供されており、<a href="http://piece-framework.com/" target="_blank">Piece Framework</a> の <a href="http://pear.php.net/manual/ja/guide.users.commandline.channels.php" target="_blank">PEAR チャネル</a>、<a href="http://pear.piece-framework.com/" target="_blank">pear.piece-framework.com</a> からインストールすることができます。
</p>
<pre class="prettyprint lang-sh">pear channel-discover pear.piece-framework.com
pear install piece/stagehand_testrunner</pre>
<p>
  今回のバージョンから、新たに多くのパッケージへの依存が追加されました。中には beta バージョンのパッケージも含まれているため、PEAR の構成 Preferred Package State (preferred_state) が stable になっている場合は、手作業でそれぞれの依存パッケージをインストールする必要があります。これが面倒な場合は、一時的に Preferred Package State (preferred_state) を beta に変更してからインストールを行ってください。
</p>
<p>
  ちなみにこれらの依存パッケージの多くは、<a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> から再利用可能なコードを分離することによって作成されたものです。これらのパッケージについては後日改めてご紹介いたします。
</p>
<p>
  次に先述の特徴を実現するコマンドラインを解説します。
</p>

<h2>指定されたディレクトリに含まれるテストの実行</h2>
<pre class="prettyprint lang-sh">phpunitrunner DIRECTORY
phpunitrunner -R DIRECTORY</pre>
<p>
  指定されたディレクトリをスキャンし、テストを実行します。-R オプションを指定した場合、下位ディレクトリを再帰的にスキャンします。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/10/runs-tests-in-the-specified-directory-529.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/10/runs-tests-in-the-specified-directory-529.html','popup','width=709,height=554,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/10/runs-tests-in-the-specified-directory-thumb-500x390-529.png" width="500" height="390" alt="runs-tests-in-the-specified-directory.png" class="mt-image-none" style="" /></a>

<h2>指定されたファイルに含まれるテストの実行</h2>
<pre class="prettyprint lang-sh">phpunitrunner FILE</pre>
<p>
  指定されたファイルに対してのみテストを実行します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/10/runs-tests-in-the-specified-file-532.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/10/runs-tests-in-the-specified-file-532.html','popup','width=709,height=498,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/10/runs-tests-in-the-specified-file-thumb-500x351-532.png" width="500" height="351" alt="runs-tests-in-the-specified-file.png" class="mt-image-none" style="" /></a>

<h2>指定されたファイルの指定されたテストのみの実行 (PHPUnit のみ)</h2>
<pre class="prettyprint lang-sh">phpunitrunner -m METHOD1,METHOD2,... FILE</pre>
<p>
  指定されたファイルに含まれる指定されたテストメソッドを実行します。カンマによって複数のメソッドを指定することができます。
</p>
<p>
  これまでバージョンでは、特定のテストのみを実行したい場合それ以外のテストをコメントアウトするといった泥臭い作業が必要でした。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/10/runs-only-the-specified-tests-in-the-specified-file-535.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/10/runs-only-the-specified-tests-in-the-specified-file-535.html','popup','width=707,height=328,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/10/runs-only-the-specified-tests-in-the-specified-file-thumb-500x231-535.png" width="500" height="231" alt="runs-only-the-specified-tests-in-the-specified-file.png" class="mt-image-none" style="" /></a>

<h2>テスト結果の色付け</h2>
<pre class="prettyprint lang-sh">phpunitrunner -c DIRECTORY_OR_FILE</pre>
<blockquote class="note"><strong>ノート</strong>: この機能をご利用いただくには、<a href="http://pear.php.net/package/Console_Color" target="_blank">Console_Color</a> 1.0.2 以降が必要となります。この機能は Windows ではご利用いただけません。</blockquote>
<p>
  結果の色付けによって、テストにパスしたかどうかがわかりやすくなります。
</p>
<p>
  先述のスクリーンショットはすべて -c オプション付きで実行されたものです。
</p>

<h2>指定された PHP スクリプトのテスト実行前のプリロード</h2>
<pre class="prettyprint lang-sh">phpunitrunner -p FILE DIRECTORY_OR_FILE</pre>
<p>
  include_path, オートローディング、エラーハンドリングなど、テストの実行のための準備を行うためのスクリプトを指定することができます。指定されたスクリプトは、テストランナー本体がロードされるよりも前に実行されます。
</p>
<p>
  実際の例を見てみましょう。下記は、<a href="http://piece-framework.com/" target="_blank">Piece Framework</a> のプロダクト、<a href="http://redmine.piece-framework.com/projects/show/stagehand-accesscontrol" target="_blank">Stagehand_AccessControl</a> のスクリプトです。
</p>
<h6><a href="http://github.com/piece/stagehand-accesscontrol/blob/master/tests/prepare.php" target="_blank">tests/prepare.php</a></h6>
<pre class="prettyprint lang-php">&lt;?php
error_reporting(E_ALL | E_STRICT);

set_include_path(realpath(dirname(__FILE__) . '/../src') . PATH_SEPARATOR .
                 get_include_path()
                 );

require_once 'PHPUnit/Framework.php';
require_once 'Stagehand/Autoload.php';

$loader = Stagehand_Autoload::legacyLoader();
$loader-&gt;addNamespace('Stagehand');
Stagehand_Autoload::register($loader);

Stagehand_LegacyError_PHPError::enableConversion();</pre>

<h2>指定されたディレクトリの変更の監視および変更検出時のテストの実行</h2>
<pre class="prettyprint lang-sh">phpunitrunner -a DIRECTORY
phpunitrunner -a -w DIRECTORY1,DIRECTORY2,... DIRECTORY
</pre>
<p>
  指定されたディレクトリについて、ファイルの追加および削除、更新日時の変更の監視を行います。変更が検出されると、直ちにテストが実行されます。
</p>
<p>
  デフォルトの監視対象はテストディレクトリですが、-w オプションによって監視対象のディレクトリを追加することができます。これによって、テストコードだけでなくプロダクトコードや構成ファイルなども監視することができます。
</p>
<p>
  実際のスキャンにかかった時間によって監視間隔が調整されます。下限は 5 秒です。
</p>

<h2>Growl へのテスト結果の通知</h2>
<pre class="prettyprint lang-sh">phpunitrunner -g DIRECTORY_OR_FILE
phpunitrunner -g --growl-password=PASSWORD DIRECTORY_OR_FILE</pre>
<blockquote class="note"><strong>ノート</strong>: この機能をご利用いただくには、<a href="http://pear.php.net/package/Net_Growl" target="_blank">Net_Growl</a> 0.7.0 以降が必要となります。</blockquote>
<p>
  <a href="http://growl.info/" target="_blank">Growl</a> に対してテストの結果を通知します。パスワードが必要な場合、--growl-password オプションによってパスワードを指定することができます。
</p>

<h2>JUnit XML フォーマットによる、指定されたファイルへのテスト結果のロギング (PHPUnit および PHPT)</h2>
<pre class="prettyprint lang-sh">phpunitrunner --log-junit=FILE DIRECTORY_OR_FILE</pre>
<p>
  指定されたファイルにテストの結果を <a href="http://www.junit.org/" target="_blank">JUnit</a> XML フォーマットで書き込みます。
</p>
<p>
  この機能は、筆者らが現在開発中のプロダクト <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> との連携用として追加されたものですが、<a href="http://www.objectclub.jp/community/XP-jp/xp_relate/cont-j" target="_blank">継続的インテグレーション</a> (CI: Continuous Integration) ツールとの連携にも役立つでしょう。
</p>

<h2>詳細な進捗リポートの出力 (PHPUnit および PHPT)</h2>
<pre class="prettyprint lang-sh">phpunitrunner -v DIRECTORY_OR_FILE</pre>
<p>
  この機能によって、PHP の Fatal error などでテストの実行が途中で終了する場合に、問題を引き起こしているテストを簡単に特定することができます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/10/prints-detailed-progress-report-538.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/10/prints-detailed-progress-report-538.html','popup','width=709,height=404,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/10/prints-detailed-progress-report-thumb-500x284-538.png" width="500" height="284" alt="prints-detailed-progress-report.png" class="mt-image-none" style="" /></a>

<h2>PHPUnit, PHPT, SimpleTest, PHPSpec のサポート</h2>
<blockquote class="note"><strong>ノート</strong>: それぞれのテスティングフレームワークをご利用いただくには、それぞれのプロダクトが必要となります。ただし、<a href="http://qa.php.net/write-test.php" target="_blank">PHPT</a> については、<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> が必要となります。</blockquote>
<p>
  テスティングフレームワークと <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> コマンドとの対応関係は下記のとおりです。
</p>
<table>
  <thead>
    <tr>
      <th></th>
      <th>UNIX</th>
      <th>Windows</th>
    </tr>
  <thead>
  <tbody>
    <tr>
      <th><a href="http://www.phpunit.de/" target="_blank">PHPUnit</a></th>
      <td>phpunitrunner</td>
      <td>phpunitrunner.bat</td>
    </tr>
    <tr>
      <th><a href="http://qa.php.net/write-test.php" target="_blank">PHPT</a></th>
      <td>phptrunner</td>
      <td>phptrunner.bat</td>
    </tr>
    <tr>
      <th><a href="http://simpletest.org/" target="_blank">SimpleTest</a></th>
      <td>simpletestrunner</td>
      <td>simpletestrunner.bat</td>
    </tr>
    <tr>
      <th><a href="http://www.phpspec.org/" target="_blank">PHPSpec</a></th>
      <td>phpspecrunner</td>
      <td>phpspecrunner.bat</td>
    </tr>
  </tbody>
</table>

<h2>おわりに</h2>
<p>
  <a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> は TDD を最大限にサポートできるように設計されており、より便利なツールにするべく日々改良を続けています。また、<a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner</a> をバックエンドとする <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> ベースのテストランナー <a href="http://redmine.piece-framework.com/projects/show/makegood" target="_blank">MakeGood</a> のリリースも計画中です。
</p>
<p>
  PHP で TDD を行っている方、これから行いたい方、<a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> や <a href="http://simpletest.org/" target="_blank">SimpleTest</a> を直接お使いの方も、この機会に是非お試しください。皆様のご意見、ご感想、パッチなどお待ちしております。
</p>

<h2>参考文献</h2>
<ul>
  <li><a href="http://redmine.piece-framework.com/wiki/stagehand-testrunner/Ja_Overview" target="_blank">Stagehand_TestRunner - テスト駆動開発のためのテストランナー - Piece Framework</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>Redmine でシンプルな ToDo リストを実現する Redmine Todo Lists plugin</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/09/redmine-todo-redmine-todo-list.html" />
    <id>tag:iteman.jp,2009:/blog//3.82</id>

    <published>2009-09-10T09:36:00Z</published>
    <updated>2010-02-12T17:12:39Z</updated>

    <summary>最終更新日: 2010 年 2 月 13 日 Redmine や Trac などのプロジェクト管理システムを使う場合、チケットという単位で機能や不具合、タスクなどを扱うことになります。また、コーディング規約など常に気を付ける必要があることについては Wiki ページに書かれているのではないでしょうか。 では、チケットや Wiki ですべて問題ないかというと、そんなことはありません。例えば、チケットとして登録するには粒度が小さすぎるものや漠然としたもの、プロジェクトをまたがって確認したいものがあるでしょう。また、ソフトウェア開発を行っている場合、チケットとして登録済みのある機能を実現するために、実装する必要があることや気づいたことをその都度メモしたり、更新したいと思うかもしれません。このような要求は ToDo リストで管理できると便利です。 そこで、専用の ToDo リストプラグインの出番となります。今回は Redmine のプラグイン Redmine Todo Lists plugin をご紹介します。...</summary>
    <author>
      <name>KUBO Atsuhiro</name>
      <uri>http://twitter.com/iteman</uri>
    </author>
    
    <category term="redmine" label="Redmine" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  <strong>最終更新日</strong>: 2010 年 2 月 13 日
</p>
<p>
  <a href="http://www.redmine.org/" target="_blank">Redmine</a> や <a href="http://trac.edgewall.org/" target="_blank">Trac</a> などのプロジェクト管理システムを使う場合、チケットという単位で機能や不具合、タスクなどを扱うことになります。また、コーディング規約など常に気を付ける必要があることについては Wiki ページに書かれているのではないでしょうか。
</p>
<p>
  では、チケットや Wiki ですべて問題ないかというと、そんなことはありません。例えば、チケットとして登録するには粒度が小さすぎるものや漠然としたもの、プロジェクトをまたがって確認したいものがあるでしょう。また、ソフトウェア開発を行っている場合、チケットとして登録済みのある機能を実現するために、実装する必要があることや気づいたことをその都度メモしたり、更新したいと思うかもしれません。このような要求は ToDo リストで管理できると便利です。
</p>
<p>
  そこで、専用の ToDo リストプラグインの出番となります。今回は <a href="http://www.redmine.org/" target="_blank">Redmine</a> のプラグイン <a href="http://github.com/dalyons/redmine-todos-scrum-plugin/tree/master" target="_blank">Redmine Todo Lists plugin</a> をご紹介します。
</p>]]>
      <![CDATA[<h2>Redmine Todo Lists plugin</h2>
<p>
  <a href="http://github.com/dalyons/redmine-todos-scrum-plugin/tree/master" target="_blank">Redmine Todo Lists plugin</a> は <a href="http://github.com/dalyons" target="_blank">David Lyons</a> 氏によって開発が進められているオープンソース (<a href="http://www.gnu.org/licenses/gpl-2.0.html" target="_blank">GPLv2</a>) の ToDo リストプラグインです。主な機能は下記の通りです。
</p>
<ul>
  <li>個人の ToDo の操作</li>
  <li>プロジェクト毎の ToDo の操作</li>
  <li>ToDo とチケットの関連付け</li>
  <li>担当者への ToDo の割り当て</li>
</ul>
<p>
  このプラグインは 2 種類の主要なページ、<strong>マイ Todo リストページ</strong> と <strong>プロジェクトの ToDo リストページ</strong> を提供します。上記のうち、<strong>個人の ToDo の操作</strong> のみがマイ Todo リストの機能であり、その他はプロジェクトの ToDo リストの機能となっています。では、それぞれについて見ていきましょう。
</p>
<blockquote class="note"><strong>ノート</strong>: インストール方法については <a href="http://github.com/dalyons/redmine-todos-scrum-plugin/tree" target="_blank">http://github.com/dalyons/redmine-todos-scrum-plugin/tree</a> をご覧ください。</blockquote>
<blockquote class="note"><strong>ノート</strong>: <a href="http://github.com/dalyons/redmine-todos-scrum-plugin" target="_blank">オリジナルバージョン</a> は、<a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> 2.2.1 以降のみサポートするようになりました。<strike>その関係で筆者の環境 (<a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> 2.1.2) では正常に動作しなくなったため、代わりに <a href="http://github.com/nowhereman/redmine-todos-scrum-plugin" target="_blank">nowhereman 氏のバージョン</a> を使用しています。</strike>(2009/11/2)</blockquote>
<blockquote class="note"><strong>ノート</strong>: 動作環境については <a href="http://github.com/dalyons/redmine-todos-scrum-plugin" target="_blank">Redmine Todo Lists plugin</a> の News の項をご参照ください。(2010/2/13)</blockquote>

<h2>マイ Todo リスト</h2>
<p>
  プラグインが問題なくインストールされている場合、<a href="http://www.redmine.org/" target="_blank">Redmine</a> にログインすると、左上のメニューに <strong>マイ Todo リスト</strong> というリンクが表示されます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-global-menu-499.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-global-menu-499.html','popup','width=1091,height=764,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-global-menu-thumb-500x350-499.png" width="500" height="350" alt="redmine-todos-scrum-plugin-global-menu.png" class="mt-image-none" style="" /></a>
<p>
  このリンクをクリックすると自分に関連する ToDo リストを操作することができるページが表示されます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-my-todos-502.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-my-todos-502.html','popup','width=1236,height=626,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-my-todos-thumb-500x253-502.png" width="500" height="253" alt="redmine-todos-scrum-plugin-my-todos.png" class="mt-image-none" style="" /></a>
<p>
  ここでは <strong>個人の ToDo の操作</strong> を行うことができます。特定のプロジェクトに関係しないような ToDo はここで扱うことになります。
</p>
<p>
  また、プロジェクト名をクリックするとプロジェクトの ToDo リストページに進みます。
</p>

<h2>プロジェクトの ToDo リスト</h2>
<blockquote class="note"><strong>ノート</strong>: プロジェクト毎の ToDo リストを有効にするには、プロジェクトの設定で <strong>Todoリスト</strong> モジュールを有効にする必要があります。</blockquote>
<a href="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-project-todos-505.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-project-todos-505.html','popup','width=1236,height=626,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-project-todos-thumb-500x253-505.png" width="500" height="253" alt="redmine-todos-scrum-plugin-project-todos.png" class="mt-image-none" style="" /></a>
<p>
  プロジェクトの ToDo リストページでは、<strong>プロジェクト毎の ToDo の操作</strong> を行うことができます。ToDo リストという意味では個人のものと違いはありませんが、ここでは ToDo の作成時に <strong>ToDo とチケットの関連付け</strong>, <strong>担当者への ToDo の割り当て</strong> も合わせて行うことになります。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-issues-508.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-issues-508.html','popup','width=1091,height=764,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/redmine-todos-scrum-plugin-issues-thumb-500x350-508.png" width="500" height="350" alt="redmine-todos-scrum-plugin-issues.png" class="mt-image-none" style="" /></a>
<blockquote class="note"><strong>ノート</strong>: <strike>この記事の執筆時点では、表示されるチケットの件名の末尾の日本語が化ける不具合があります。筆者が作成した<a href="http://github.com/iteman/redmine-todos-scrum-plugin/commit/85e050f0ee275938e7640244b2ea33c76e0c0aba" target="_blank">パッチ</a>を適用することでこの不具合を解決することができます。</strike></blockquote>
<p>
  作成された ToDo は担当者のマイ Todo リストにも表示されます。ToDo はプロジェクトメンバーの誰に対しても割り当てることができますし、プロジェクトの ToDo はプロジェクトメンバーなら誰でもを操作することができます。
</p>

<h2>おわりに</h2>
<p>
  <a href="http://github.com/dalyons/redmine-todos-scrum-plugin/tree/master" target="_blank">Redmine Todo Lists plugin</a> を使い始めてしばらく経ちますが、極めてシンプルで使いやすく、現時点の完成度も筆者にとって満足いくものです。ToDo リストの管理にお困りの方は是非試してみてください。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://github.com/dalyons/redmine-todos-scrum-plugin/tree" target="_blank">Redmine Todo Lists plugin</a></th><td>git master HEAD</td>
    </tr>
    <tr>
      <th><a href="http://www.redmine.org/" target="_blank">Redmine</a></td><td>0.8.4</td>
    </tr>
    <tr>
      <th><a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a></th><td>2.1.2</td>
    </tr>
  </tbody>
</table>

<h2>更新履歴</h2>
<ul>
  <li>2010/2/13: 最新の状況に合わせて内容を見直した。</li>
  <li>2009/11/2: 最新の状況に合わせて内容を見直した。</li>
  <li>2009/9/10: 公開</li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 8: Web Velocity によるポテトバーガー注文アプリケーションの実装 第 2 回 (最終回)</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/09/-8-web-velocity-2.html" />
    <id>tag:iteman.jp,2009:/blog//3.84</id>

    <published>2009-09-03T10:32:56Z</published>
    <updated>2009-09-03T10:33:10Z</updated>

    <summary>まっつんです。今回は Web Velocity と Ruby on Rails (以下、Rails) を比較しながら、 ポテトバーガー注文アプリケーション を実装していきます。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="rails" label="Rails" scheme="http://www.sixapart.com/ns/types#tag" /><category term="seaside" label="Seaside" scheme="http://www.sixapart.com/ns/types#tag" /><category term="smalltalk" label="Smalltalk" scheme="http://www.sixapart.com/ns/types#tag" /><category term="webvelocity" label="Web Velocity" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ8" label="まっつんチャレンジ 8" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ポテトバーガー注文アプリケーション" label="ポテトバーガー注文アプリケーション" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。今回は <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> と <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> (以下、Rails) を比較しながら、 <a href="http://example.piece-framework.com/conversation/order.php" target="_blank">ポテトバーガー注文アプリケーション</a> を実装していきます。
</p>]]>
      <![CDATA[<h2>ポテトバーガー注文アプリケーションとは？</h2>
<p>
  最初に今回実装する <a href="http://example.piece-framework.com/conversation/order.php" target="_blank">ポテトバーガー注文アプリケーション</a> について簡単に説明します。
</p>
<p>
  <a href="http://example.piece-framework.com/conversation/order.php" target="_blank">ポテトバーガー注文アプリケーション</a> は PHP のアプリケーションフレームワーク <a href="http://piece-framework.com/" target="_blank">Piece Framework</a> のクィックスタートドキュメント「<a href="http://redmine.piece-framework.com/wiki/piece-unity/Piece_Framework_%E3%81%A7%E4%BD%9C%E3%82%8B%E5%AF%BE%E8%A9%B1%E7%9A%84%E3%81%AA%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3" target="_blank">Piece Framework で作る対話的なアプリケーション</a>」で題材となっている、対話的にポテトバーガーを注文するアプリケーションで、メインメニューの選択、サイドメニューの選択、確認、完了の 4 ページで構成されています。
</p>
<p>
  ページの遷移やデータベースアクセスといった Web アプリケーションで必ず出てくる処理が盛り込まれているため、このアプリケーションは評価対象のフレームワークの特徴を掴むためにもってこいの題材といえるでしょう。
</p>

<h2>リポジトリとアプリケーションの作成</h2>
<p>
  <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> では、最初にアプリケーションを格納するためのリポジトリを作成します。リポジトリの保存先には一般的な RDBMS を使うことができます。今回は <a href="http://www.postgresql.org" target="_blank">PostgreSQL</a> を使うことにし、リポジトリ用とアプリケーション用の 2 つのデータベースを作成します。データベースの情報は以下のとおりです。
</p>
<h6>リポジトリ用データベース</h6>
<table>
  <tbody>
    <tr>
      <th>データベース</th><td>repos</td>
    </tr>
    <tr>
      <th>ユーザ</th><td>repos</td>
    </tr>
    <tr>
      <th>パスワード</th><td>repos</td>
    </tr>
  </tbody>
</table>
<h6>アプリケーション用データベース</h6>
<table>
  <tbody>
    <tr>
      <th>データベース</th><td>piece_conversation</td>
    </tr>
    <tr>
      <th>ユーザ</th><td>piece</td>
    </tr>
    <tr>
      <th>パスワード</th><td>piece</td>
    </tr>
  </tbody>
</table>
<blockquote class="note"><strong>ノート</strong>: <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> では、<a href="http://www.postgresql.org" target="_blank">PostgreSQL</a> 以外にも <a href="http://www.oracle.com" target="_blank">Oracle</a> や <a href="http://www.mysql.com" target="_blank">MySQL</a> などさまざまな RDBMS を利用することができます。</blockquote>
<p>
  それではリポジトリを作成しましょう。<strong>[New]</strong> -> <strong>[Repositry]</strong> をクリックすると、<strong>Add Repository</strong> ダイアログが表示されるので、以下のように入力します。
</p>
<table>
  <tbody>
    <tr>
      <th>Name</th><td>Repos</td>
    </tr>
    <tr>
      <th>Platform</th><td>PostgreSQL</td>
    </tr>
    <tr>
      <th>Address</th><td>localhost</td>
    </tr>
    <tr>
      <th>Port</th><td>5432</td>
    </tr>
    <tr>
      <th>Database</th><td>repos</td>
    </tr>
    <tr>
      <th>Schema</th><td>public</td>
    </tr>
    <tr>
      <th>Username</th><td>repos</td>
    </tr>
    <tr>
      <th>Password</th><td>repos</td>
    </tr>
  </tbody>
</table>
<p>
  <strong>[Repositories]</strong> -> <strong>[Repos]</strong> をクリックし、作成したリポジトリを選択します。続いてアプリケーションを作成しましょう。<strong>[New]</strong> -> <strong>[Application]</strong> をクリックすると、<strong>Create Application</strong> ダイアログが表示されるので、以下のように入力します。
</p>
<table>
  <tbody>
    <tr>
      <th>Name</th><td>Conversation</td>
    </tr>
    <tr>
      <th>Generate - Schema</th><td>オン</td>
    </tr>
  </tbody>
</table>

<h2>ドメインモデルとテーブルの作成</h2>
<p>
  <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> では、<a href="http://rubyonrails.org/" target="_blank">Rails</a> と同様にデータへアクセスするためのアーキテクチャとして <a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?ActiveRecord" target="_blank">Active Record</a> が採用されています。<a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?ActiveRecord" target="_blank">Active Record</a> の性質上ドメインモデルとテーブルの構造は深く関係します。そのため <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> では、ドメインモデルの作成時にテーブル生成メソッドも合わせて作成できるようになっています。
</p>
<p>
  それでは Order ドメインモデルを作成しましょう。<strong>[New]</strong> -> <strong>[New Model]</strong> をクリックすると、<strong>Create Persistent Model</strong> ダイアログが表示されるので、orders テーブルのジェネレータのみ生成するようにします。
</p>
<table>
  <tbody>
    <tr>
      <th>Name</th><td>order</td>
    </tr>
    <tr>
      <th>Database Generation - #tableForOrder</th><td>オン</td>
    </tr>
    <tr>
      <th>上記以外</th><td>オフ</td>
    </tr>
  </tbody>
</table>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-create-persistent-model-472.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-create-persistent-model-472.html','popup','width=939,height=683,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-create-persistent-model-thumb-500x363-472.png" width="500" height="363" alt="web-velocity-2-create-persistent-model.png" class="mt-image-none" style="" /></a>
<p>
  次にデータベースの接続情報を設定するため、<strong>[Database]</strong> をクリックし、以下のように入力します。
</p>
<table>
  <tbody>
    <tr>
      <th>Platform</th><td>PostgreSQL</td>
    </tr>
    <tr>
      <th>Address</th><td>localhost</td>
    </tr>
    <tr>
      <th>Port</th><td>5432</td>
    </tr>
    <tr>
      <th>Database</th><td>piece_conversation</td>
    </tr>
    <tr>
      <th>Schema</th><td>public</td>
    </tr>
    <tr>
      <th>Username</th><td>piece</td>
    </tr>
    <tr>
      <th>Password</th><td>piece</td>
    </tr>
  </tbody>
</table>
<p>
  入力が完了したら、<strong>[Test Login]</strong> をクリックし、データベースに接続できることを確認します。
</p>
<p>
  続いて orders テーブルを生成するためのコードを追加します。<strong>[Go to Schema1]</strong> をクリックし、<strong>Source Code</strong> をクリックします。テーブル生成メソッドとして tableForORDERS が定義されているので、それを以下のように変更します。
</p>
<h6>Schema1 tables - tableForORDERS メソッド</h6>
<pre class="prettyprint">tableForORDERS: aTable

    (aTable createFieldNamed: 'id' type: platform serial) bePrimaryKey.
    (aTable createFieldNamed: 'main' type: platform integer) beNullable: false.
    (aTable createFieldNamed: 'side' type: platform integer) beNullable: false.
    (aTable createFieldNamed: 'created_at' type: platform timestamp) beNullable: false.
    (aTable createFieldNamed: 'updated_at' type: platform timestamp) beNullable: false.</pre>
<p>
  これで orders テーブルを生成する準備が整いました。<strong>[Mappings]</strong> をクリックし、<strong>[Recreate all tables]</strong> をクリックすると、確認ダイアログが表示され、orders テーブルが生成されます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-order-table-475.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-order-table-475.html','popup','width=667,height=468,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-order-table-thumb-500x350-475.png" width="500" height="350" alt="web-velocity-2-order-table.png" class="mt-image-none" style="" /></a>
<p>
  このように <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> はテーブルを定義する機能を提供しています。これは <a href="http://rubyonrails.org/" target="_blank">Rails</a> のマイグレーションに似ていますが、<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> はテーブルの変更点のみを定義する方法を提供しておらず、毎回テーブルを再作成する必要がある点が異なっています。
</p>
<p>
  それでは、テーブルのフィールドとドメインモデルのプロパティのマッピングを定義しましょう。<strong>[Classes]</strong> -> <strong>[Order]</strong> をクリックし、<strong>[Mappings]</strong> をクリックします。<strong>Add instance variable named:xxxx</strong> リンクをクリックするとマッピングを定義することができます。今回は、すべてのフィールドに対してそれぞれ対応するプロパティをマッピングし、それらのアクセサメソッドも作成します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-mappings-478.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-mappings-478.html','popup','width=957,height=683,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-mappings-thumb-500x356-478.png" width="500" height="356" alt="web-velocity-2-mappings.png" class="mt-image-none" style="" /></a>

<h2>ユーザインターフェイスの作成</h2>
<p>
  最後にユーザインターフェイスを作成します。<strong>[New]</strong> -> <strong>[New Component]</strong> をクリックすると、<strong>Create Web Component</strong> ダイアログが表示されるので、以下のように入力します。
</p>

<table>
  <tbody>
    <tr>
      <th>Name</th><td>OrderUI</td>
    </tr>
    <tr>
      <th>Register as application</th><td>オン</td>
    </tr>
    <tr>
      <th>Configure for Glorp</th><td>オン</td>
    </tr>
    <tr>
      <th>Use tamplate</th><td>オフ</td>
    </tr>
  </tbody>
</table>
<p>
  Glorp は <a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?ActiveRecord" target="_blank">Active Record</a> ベースのデータアクセスフレームワークです。当初、筆者は <strong>Configure for Glorp</strong> を <strong>オフ</strong> にしていたことが原因で注文データを orders テーブルに登録することができず、原因究明に半日を費やすことになりました。
</p>
<p>
  次にインスタンス変数を定義します。<strong>[Variables]</strong> をクリックし、Instance Variables の横の <strong>[Add Variable...]</strong> をクリックします。
</p>
<table>
  <thead>
    <tr>
      <th>Name</th><th>Description</th><th>Create accessors</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>order</td><td>&lt;Order&gt; domain model.</td><td>オフ</td>
    </tr>
    <tr>
      <td>currentState</td><td>&lt;String&gt; current state.</td><td>オフ</td>
    </tr>
    <tr>
      <td>message</td><td>&lt;String&gt; validation result.</td><td>オフ</td>
    </tr>
  </tbody>
</table>
<p>
  次に、デフォルトのエントリポイントを削除し、新たに別のエントリポイントを登録します。<strong>[Component]</strong> をクリックし、既存の Conversation/OrderUI の <strong>[Remove]</strong> をクリックして削除します。そして <strong>[Add Entry Point...]</strong> をクリックし、<strong>Conversation/order</strong> エントリポイントを追加します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-entry-point-481.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-entry-point-481.html','popup','width=985,height=678,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-entry-point-thumb-500x344-481.png" width="500" height="344" alt="web-velocity-2-entry-point.png" class="mt-image-none" style="" /></a>
<p>
  それでは <strong>[Source Code]</strong> をクリックし、コードを追加していきましょう。まず、初期化コードの追加を行います。
</p>
<h6>OrderUI - initialize-release initialize メソッド</h6>
<pre class="prettyprint">initialize

    super initialize.

    order := Order new bePersistent.
    currentState := 'MainMenu'.
    message := ''.</pre>
<p>
  次に HTML 表示コードを追加します。最初に renderContentOn メソッドが呼び出されるので、このメソッドで各ページのステートに応じたメソッドを呼び出すようにしています。
</p>
<h6>OrderUI - rendering renderContentOn メソッド</h6>
<pre class="prettyprint">renderContentOn: html

    currentState = 'MainMenu' ifTrue: [
        self renderMainMenu: html.
    ].
    currentState = 'SideMenu' ifTrue: [
        self renderSideMenu: html.
    ].
    currentState = 'Confirmation' ifTrue: [
        self renderConfirmation: html.
    ].
    currentState = 'Finish' ifTrue: [
        self renderFinish: html.
    ].</pre>
<h6>OrderUI - rendering renderMainMenu メソッド</h6>
<pre class="prettyprint">renderMainMenu: html

    html heading
        level: 3;
        with: 'メインメニューは何になさいますか？'.
    html break.
    html text: message.
    html break.
    html anchor
        callback: [ self validateForMainMenu: 1 ];
        with: 'ジャーマンポテトバーガー (650円)'.
    html break.
    html anchor
        callback: [ self validateForMainMenu: 2 ];
        with: 'ポテトコロッケバーガー (600円)'.
    html break.
    html anchor
        callback: [ self validateForMainMenu: 3 ];
        with: '肉じゃがバーガー (700円)'.
    html break.</pre>
<h6>OrderUI - rendering renderSideMenu メソッド</h6>
<pre class="prettyprint">renderSideMenu: html

    html heading
        level: 3;
        with: 'サイドメニューは何になさいますか？'.
    html break.
    html text: message.
    html break.
    html anchor
        callback: [ self validateForSideMenu: 1 ];
        with: 'フライドポテト'.
    html break.
    html anchor
        callback: [ self validateForSideMenu: 2 ];
        with: 'ポテトサラダ'.
    html break.
    html anchor
        callback: [ self validateForSideMenu: 3 ];
        with: 'スイートポテト'.
    html break.</pre>
<h6>OrderUI - rendering renderConfirmation メソッド</h6>
<pre class="prettyprint">renderConfirmation: html

    |mainMenu sideMenu price|

    mainMenu := #('ジャーマンポテトバーガー'
                  'ポテトコロッケバーガー'
                  '肉じゃがバーガー'
                  ) at: order main.
    sideMenu := #('フライドポテト'
                  'ポテトサラダ'
                  'スイートポテト'
                  ) at: order side.
    price := #('650円'
               '600円'
               '700円'
               ) at: order main.

    html heading
        level: 3;
        with: '注文内容は以上で宜しいですか？'.
    html break.
    html text: 'メインメニュー：', mainMenu.
    html break.
    html text: 'サイドメニュー：', sideMenu.
    html break.
    html text: '小計：', price.
    html break.
    html anchor
        callback: [ self register ];
        with: 'OK'.
    html space.
    html anchor
        callback: [ currentState := 'MainMenu' ];
        with: '選び直す'.</pre>
<h6>OrderUI - rendering renderFinish メソッド</h6>
<pre class="prettyprint">renderFinish: html

    html heading
        level: 3;
        with: 'ご注文ありがとうございました。'.
    html break.</pre>
<p>
  最後にバリデーションとデータベースアクセスのためのメソッドをそれぞれ追加します。
</p>
<h6>OrderUI - private validateForMainMenu メソッド</h6>
<pre class="prettyprint">validateForMainMenu: mainMenu

    message := ''.
    (mainMenu &gt;= 1) &amp; (mainMenu &lt;= 3) ifTrue: [
        order main: mainMenu.
        currentState := 'SideMenu'.
    ] ifFalse: [
        message := '正しいメインメニューを選択してください。'.
        currentState := 'MainMenu'.
    ]</pre>
<h6>OrderUI - private validateForSideMenu メソッド</h6>
<pre class="prettyprint">validateForSideMenu: sideMenu

    message := ''.
    (sideMenu &gt;= 1) &amp; (sideMenu &lt;= 3) ifTrue: [
        order side: sideMenu.
        currentState := 'Confirmation'.
    ] ifFalse: [
        message := '正しいサイドメニューを選択してください。'.
        currentState := 'SideMenu'.
    ]</pre>
<h6>OrderUI - private register メソッド</h6>
<pre class="prettyprint">register

    order createdAt: Timestamp now.
    order updatedAt: Timestamp now.
    order commitUnitOfWork.

    currentState := 'Finish'.</pre>
<p>
  <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> では、データを保存するアーキテクチャとして <a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?UnitofWork" target="_blank">Unit of Work</a> が採用されています。ステートフルを特徴とする <a href="http://www.seaside.st" target="_blank">Seaside</a> アプリケーションでは、その利点を生かすために、ビジネストランザクションが複数のリクエストにまたがるような実装を行うことも多いのではないかと思います。このような場合に並行性の問題を解決する <a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?UnitofWork" target="_blank">Unit of Work</a> は非常に有効なアーキテクチャであると言えます。
</p>
<blockquote class="note"><strong>ノート</strong>: <a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?UnitofWork" target="_blank">Unit of Work</a> を使用せずにデータを保存することもできます。</blockquote>

<h2>動作確認</h2>
<p>
  以上でアプリケーションの実装は完了です。<strong>[Browse]</strong> -> <strong>[/Conversation/order]</strong> をクリックして、動作確認を行いましょう。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-main-menu-484.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-main-menu-484.html','popup','width=985,height=678,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-main-menu-thumb-500x344-484.png" width="500" height="344" alt="web-velocity-2-main-menu.png" class="mt-image-none" style="" /></a>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-side-menu-487.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-side-menu-487.html','popup','width=985,height=678,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-side-menu-thumb-500x344-487.png" width="500" height="344" alt="web-velocity-2-side-menu.png" class="mt-image-none" style="" /></a>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-confirmation-490.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-confirmation-490.html','popup','width=985,height=678,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-confirmation-thumb-500x344-490.png" width="500" height="344" alt="web-velocity-2-confirmation.png" class="mt-image-none" style="" /></a>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-finish-493.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-finish-493.html','popup','width=985,height=678,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-2-finish-thumb-500x344-493.png" width="500" height="344" alt="web-velocity-2-finish.png" class="mt-image-none" style="" /></a>
<p>
  問題なく動作することが確認できました。
</p>

<h2>おわりに</h2>
<p>
  <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> は、<a href="http://www.seaside.st" target="_blank">Seaside</a> と<a href="http://rubyonrails.org/" target="_blank">Rails</a> それぞれの特徴と利点を上手く組み合わせているという印象を受けました。また、コードリポジトリがデータベースであることや、ブラウザベースの開発環境が提供されていることなど、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> や IDE の観点からも興味深いフレームワークであると言えます。
</p>
<p>
  しかし残念ながら、現時点では完成度が高いとは言えません。開発環境では親クラスのコードの検索ができないことをはじめ、苦労することが数多くありました。また、スタティックメソッドに不正なコードがあるとアプリケーションをロードすることができないため、それを修正することができず、一つ前のバージョンに戻さなければなりませんでした。
</p>
<p>
  このようにいくつかの問題はあるものの、まだリリースされたばかりという点もあり今後が楽しみなフレームワークです。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">WebVelocity Lite</a></th><td>1.0</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity by Cincom</a></li>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?ActiveRecord" target="_blank">PofEAA's Wiki - ActiveRecode</a></li>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/PofEAA/?UnitofWork" target="_blank">PofEAA's Wiki - UnitofWork</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 8: Web Velocity によるポテトバーガー注文アプリケーションの実装 第 1 回</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/09/-8-webvelocity-1.html" />
    <id>tag:iteman.jp,2009:/blog//3.83</id>

    <published>2009-09-01T08:06:44Z</published>
    <updated>2009-09-01T08:09:05Z</updated>

    <summary>まっつんです。ここのところマイナー路線が続きアクセス数激減のまっつんチャレンジシリーズですが、めげずに今回もマイナーなフレームワークを取り上げます。今回は皆様お待ちかねの Web Velocity によるポテトバーガー注文アプリケーションの実装にチャレンジしたいと思います。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="seaside" label="Seaside" scheme="http://www.sixapart.com/ns/types#tag" /><category term="smalltalk" label="Smalltalk" scheme="http://www.sixapart.com/ns/types#tag" /><category term="webvelocity" label="Web Velocity" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ8" label="まっつんチャレンジ 8" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ポテトバーガー注文アプリケーション" label="ポテトバーガー注文アプリケーション" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。ここのところマイナー路線が続きアクセス数激減のまっつんチャレンジシリーズですが、めげずに今回もマイナーなフレームワークを取り上げます。今回は皆様お待ちかねの <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> によるポテトバーガー注文アプリケーションの実装にチャレンジしたいと思います。
</p>
]]>
      <![CDATA[<h2>Web Velocity とは？</h2>
<p>
  <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> は、長年に渡って Smalltalk のプロダクトを提供している企業である <a href="http://www.cincom.com" target="_blank">Cincom</a> が開発した Web アプリケーションフレームワークです。<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> は、Smalltalk で実装された継続ベースの Web アプリケーションフレームワーク <a href="http://www.seaside.st" target="_blank">Seaside</a> を拡張したものとなっています。
</p>
<blockquote class="note"><strong>ノート</strong>: <a href="http://www.seaside.st" target="_blank">Seaside</a> については「<a href="http://mt.iteman.jp/mt-search.cgi?blog_id=3&tag=%E3%81%BE%E3%81%A3%E3%81%A4%E3%82%93%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%202&limit=20&IncludeBlogs=3" target="_blank">まっつんチャレンジ 2: Seasideによるユーザ登録アプリケーションの実装</a>」で取り上げています。</blockquote>
<p>
  <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> の最大の特徴はブラウザベースの開発環境です。Smalltalk では実行環境と開発環境との両方がひとつの仮想マシンによって提供されています。これは OS に依存しない環境を容易に準備できるという利点がある反面、新たな環境を学習するコストがかかるという欠点もあります。<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> は、ブラウザベースの開発環境を提供することで実行環境と開発環境を分離し、仮想マシンの利点を生かしつつ欠点を抑えています。
</p>

<h2>Web Velocity のインストール</h2>
<p>
  それでは <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> をインストールしましょう。以下のサイトからダウンロードすることができます。
</p>
<blockquote class="note"><a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">http://www.web-velocity.com/WVAccess/Main</a></blockquote>
<pre class="prettyprint lang-sh">sudo dpkg -i webvelocity-1.732-1_i386.deb</pre> 
<blockquote class="note"><strong>ノート</strong>: ダウンロードできる <a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity Lite</a> は評価を目的として作られており、商業目的で利用するためには <a href="http://www.cincom.com" target="_blank">Cincom 社</a>に連絡する必要があります。</blockquote>

<h2>Hello World アプリケーションの実装</h2>
<p>
  手始めに Hello World アプリケーションを実装してみましょう。まず、<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> を起動します。
</p>
<pre class="prettyprint lang-sh">webvelocity start</pre>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-server-console-451.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-server-console-451.html','popup','width=747,height=428,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-server-console-thumb-500x286-451.png" width="500" height="286" alt="web-velocity-1-server-console.png" class="mt-image-none" style="" /></a>
<p>
  ブラウザで <strong>http://localhost:7777</strong> にアクセスすると、<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> の開発環境が表示されます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-browser-454.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-browser-454.html','popup','width=1016,height=677,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-browser-thumb-500x333-454.png" width="500" height="333" alt="web-velocity-1-browser.png" class="mt-image-none" style="" /></a>
<p>
  <strong>[New]</strong> -> <strong>[Application]</strong> をクリックし、Hello World アプリケーションを作成します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-create-application-457.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-create-application-457.html','popup','width=1016,height=677,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-create-application-thumb-500x333-457.png" width="500" height="333" alt="web-velocity-1-create-application.png" class="mt-image-none" style="" /></a>
<p>
  <strong>[New]</strong> -> <strong>[New Component]</strong> をクリックし、Hello コンポーネントを作成します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-create-web-component-460.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-create-web-component-460.html','popup','width=1016,height=677,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-create-web-component-thumb-500x333-460.png" width="500" height="333" alt="web-velocity-1-create-web-component.png" class="mt-image-none" style="" /></a>
<p>
  コードを追加するために <strong>[SourceCode]</strong> をクリックします。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-source-code-463.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-source-code-463.html','popup','width=1016,height=677,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-source-code-thumb-500x333-463.png" width="500" height="333" alt="web-velocity-1-source-code.png" class="mt-image-none" style="" /></a>
<p>
  <strong>Instance Methods</strong> の <strong>rendering</strong> をクリックし、"Hello World!" を表示するためのコードを追加します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-rendering-466.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-rendering-466.html','popup','width=1016,height=677,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-rendering-thumb-500x333-466.png" width="500" height="333" alt="web-velocity-1-rendering.png" class="mt-image-none" style="" /></a>
<p>
  それでは動作確認を行いましょう。<strong>[Browse]</strong> -> <strong>/HelloWorld/Hello</strong> をクリックします。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-hello-world-469.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-hello-world-469.html','popup','width=1016,height=677,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/09/web-velocity-1-hello-world-thumb-500x333-469.png" width="500" height="333" alt="web-velocity-1-hello-world.png" class="mt-image-none" style="" /></a>
<p>
  問題なく表示が行われました。
</p>

<h2>おわりに</h2>
<p>
  ブラウザベースの開発環境は <a href="http://www.seaside.st" target="_blank">Seaside</a> のものと比べると格段に使いやすいものになっています。また、<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> では開発時の多くの作業が動画で公開されており、評価するには十分な環境が整っていると言えるでしょう。
</p>
<p>
  <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> 以降に開発された多くのフレームワークがそうであるように、<a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity</a> も <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> に影響を受けているようです。次回は <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> との関連を見ながらポテトバーガー注文アプリケーションを実装したいと思います。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity Lite</a></th><td>1.0</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://www.web-velocity.com/WVAccess/Main" target="_blank">Web Velocity by Cincom</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>次世代の Eclipse, e4 を使ってみた</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/08/-eclipse---e4.html" />
    <id>tag:iteman.jp,2009:/blog//3.81</id>

    <published>2009-08-25T19:28:59Z</published>
    <updated>2009-08-25T19:28:37Z</updated>

    <summary>まっつんです。先日、次世代の Eclipse として開発が進められている e4 のバージョン 0.9 がリリースされました。 今やオープンソースの開発プラットフォームとして不動の地位を築いている Eclipse ですが、その次世代バージョンとはどのようなものなのでしょうか？...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="css" label="CSS" scheme="http://www.sixapart.com/ns/types#tag" /><category term="e4" label="e4" scheme="http://www.sixapart.com/ns/types#tag" /><category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="javascript" label="JavaScript" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ジェネレーティブプログラミング" label="ジェネレーティブプログラミング" scheme="http://www.sixapart.com/ns/types#tag" /><category term="プラグイン" label="プラグイン" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。先日、次世代の <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> として開発が進められている <a href="http://www.eclipse.org/e4" target="_blank">e4</a> のバージョン 0.9 がリリースされました。
</p>
<p>
  今やオープンソースの開発プラットフォームとして不動の地位を築いている <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> ですが、その次世代バージョンとはどのようなものなのでしょうか？
</p>]]>
      <![CDATA[<h2>プラグインの開発をより簡単に</h2>
<p>
  <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> の歴史はプラグインの歴史といっても過言ではありません。
</p>
<p>
  バージョン 1.0 から 2.1 までの <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> は、プラグインの統合に主眼が置かれていました。現在のプラグインシステムの基礎はこの頃に築かれたと言えます。
</p>
<p>
  <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> 3.0 以降 では、プラグインシステムのアーキテクチャとして <a href="http://www.osgi.org/Main/HomePage" target="_blank">OSGi</a> が採用されました。これによって、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> を組み込みアプリケーションやリッチクライアントアプリケーションの開発・実行プラットフォームとしても利用できるようになりました。
</p>
<p>
  このようにプラグインというコンポーネントをベースに発展してきた <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> ですが、プラグインの開発は容易ではありません。プラグイン開発は多くの開発者にとって本質的ではありませんが、学ばなければならない <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> 独自の機能が数多くあることがプラグイン開発を困難にしています。また、プラグイン開発に使うことができるプログラミング言語が Java のみである、という点もプラグイン開発を困難にしているといえるでしょう。
</p>
<p>
  プラグイン、つまり <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> ベースのアプリケーションの開発をより簡単に行えるようにすることは、<a href="http://www.eclipse.org/e4" target="_blank">e4</a> の主要なゴールの 1 つとなっています。
</p>

<h2>Web ベースの技術の採用</h2>
<p>
  <a href="http://www.eclipse.org/e4" target="_blank">e4</a> ではプラグイン開発をより簡単にするための手段として、主に 2 つの Web ベースの技術を採用しています。
</p>
<p>
  1 つは CSS です。<a href="http://www.eclipse.org/e4" target="_blank">e4</a> では、ウィジェットのフォントサイズや背景色などユーザインタフェースに関する情報を CSS で定義します。<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> のわかりにくいユーザインタフェースはプラグイン開発を困難にしている要因の 1 つです。CSS の導入はこれを改善するものとなるでしょう。
</p>
<p>
  もう 1 つは JavaScript です。<a href="http://www.eclipse.org/e4" target="_blank">e4</a> では、プラグイン開発に JavaScript を使うことができます。この機能を実現するため、JavaScript ベースのプラグインと OSGi Framework の仲介を行う <strong>e4 JS Framework</strong> が新たに実装されました。<strong>e4 JS Framework</strong> 自身は Java ベースのプラグインであり、<a href="https://developer.mozilla.org/ja/Rhino" target="_blank">Rhino</a> を利用して JavaScript を JavaVM 上で動作させています。
</p>
<p>
  これは JavaVM 上で動作するどんなプログラミング言語でもプラグイン開発を行うことができる可能性を示しています。今後、多くのプログラミング言語がサポートされれば、プラグイン開発はさらに活発になるでしょう。
</p>

<h2>サンプルアプリケーションを動かす</h2>
<p>
  それでは <a href="http://www.eclipse.org/e4" target="_blank">e4</a> をインストールしてサンプルアプリケーションを動かしてみましょう。<a href="http://www.eclipse.org/e4" target="_blank">e4</a> は以下のサイトからダウンロードすることができます。
</p>
<blockquote class="note"><a href="http://download.eclipse.org/e4/downloads/drops/R-0.9-200907291930/index.html" target="_blank">http://download.eclipse.org/e4/downloads/drops/R-0.9-200907291930/index.html</a></blockquote>
<pre class="prettyprint lang-sh">tar xzf eclipse-e4-SDK-incubation-0.9-linux-gtk.tar.gz</pre>
<p>
  インストールが完了したら、<a href="http://www.eclipse.org/e4" target="_blank">e4</a> を起動します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/08/e4-platform-439.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/08/e4-platform-439.html','popup','width=910,height=594,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/08/e4-platform-thumb-500x326-439.png" width="500" height="326" alt="e4-platform.png" class="mt-image-none" style="" /></a>
<p>
  サンプルアプリケーションのプロジェクトを生成するため、<strong>[e4] -> [Generate e4 Example Project]</strong> をクリックします。
</p>
<p>
  次に生成された <strong>org.eclipse.e4.examples.psf</strong> プロジェクトの e4-examples.psf を右クリックし、<strong>[Import Project Set]</strong> をクリックします。CVS リポジトリのユーザ名とパスワードを入力するダイアログが表示されるので、ユーザ名に anonymous と入力します。
</p>
<p>
  以上の操作で 2 つのプロジェクトがダウンロードされます。
</p>
<ul>
  <li>org.eclipse.e4.demo.contacts</li>
  <li>org.eclipse.e4.demo.e4photo</li>
</ul>
<p>
  今回は <strong>org.eclipse.e4.demo.contacts</strong> プロジェクトを使って、CSS によるユーザインタフェースの変更を試してみましょう。
</p>
<p>
  <strong>org.eclipse.e4.demo.contacts</strong> プロジェクトの <strong>contacts.product</strong> を右クリックし、<strong>[Run As] -> [Eclipse Application]</strong> をクリックすると、Contacts アプリケーションが起動します。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/08/e4-dark-theme-442.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/08/e4-dark-theme-442.html','popup','width=910,height=594,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/08/e4-dark-theme-thumb-500x326-442.png" width="500" height="326" alt="e4-dark-theme.png" class="mt-image-none" style="" /></a>
<p>
  <strong>[Theme]</strong> メニューでテーマを変更することができます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/08/e4-bright-theme-445.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/08/e4-bright-theme-445.html','popup','width=910,height=594,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/08/e4-bright-theme-thumb-500x326-445.png" width="500" height="326" alt="e4-bright-theme.png" class="mt-image-none" style="" /></a>
<p>
  次に <strong>org.eclipse.e4.demo.contacts</strong> プロジェクト の <strong>bright-gradient.css</strong> でアプリケーションの背景色を変更してみましょう。
</p>
<h6>org.eclipse.e4.demo.contacts/css/bright-gradient.css</h6>
<pre class="prettyprint">--- a/org.eclipse.e4.demo.contacts/css/bright-gradient.css 2009-08-25 14:10:16.000000000 +0900
+++ b/org.eclipse.e4.demo.contacts/css/bright-gradient.css 2009-08-25 14:10:32.000000000 +0900
@@ -36,7 +36,7 @@
 }
 
 #DetailsView {
-   background-color: #e8e8e8 #cccccc 60%;
+   background-color: #00ffff #cccccc 60%;
 }
 
 Table {</pre>
<p>
  テーマを再び選択するとアプリケーションの背景色に反映されます。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/08/e4-changed-bright-theme-448.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/08/e4-changed-bright-theme-448.html','popup','width=910,height=594,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/08/e4-changed-bright-theme-thumb-500x326-448.png" width="500" height="326" alt="e4-changed-bright-theme.png" class="mt-image-none" style="" /></a>

<h2>おわりに</h2>
<p>
  <a href="http://www.eclipse.org/e4" target="_blank">e4</a> プロジェクトは、デスクトップアプリケーションと Web アプリケーションのそれぞれの利点を認識し、その両立を目指しています。また、コンポーネント (プラグイン) を充実させ、それらを組み合わせることでアプリケーションを構築することも視野に入れています。
</p>
<p>
  後者はまさに書籍 <a href="http://www.amazon.co.jp/gp/product/479811331X?ie=UTF8&tag=iteman-22&linkCode=as2&camp=247&creative=1211&creativeASIN=479811331X">ジェネレーティブプログラミング (IT Architects'Archive CLASSIC MODER)</a><img src="http://www.assoc-amazon.jp/e/ir?t=iteman-22&l=as2&o=9&a=479811331X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> に書かれているソフトウェアの自動生産の技術であり、そのような観点からも興味深いプロジェクトと言えます。
</p>
<p>
  CSS というユーザインタフェースデザイン用の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の導入や、Java 以外のプログラミング言語によるプラグイン開発など、より工学的で自由度の高いプラットフォームに進化しているという印象を受けました。
</p>
<p>
  操作性や動作も従来の <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> と遜色ありませんので、今使っているプラグインが動くのであれば、メインの開発環境として使ってみようかなと考えています。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.eclipse.org/e4" target="_blank">e4</a></th><td>0.9</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://www.eclipse.org/e4" target="_blank">e4 Project</a></li>
  <li><a href="http://wiki.eclipse.org/E4" target="_blank">E4 - Eclipsepedia</a></li>
  <li><a href="http://www.eclipse.org/e4/resources/e4-whitepaper.php" target="_blank">White Paper: e4 Technical Overview</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 7: 言語ワークベンチによる DSL エディタ の実装 MPS 編</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/08/-6-dsl-mps-1.html" />
    <id>tag:iteman.jp,2009:/blog//3.78</id>

    <published>2009-08-14T06:37:56Z</published>
    <updated>2009-11-01T19:09:52Z</updated>

    <summary>まっつんです。今回は JetBrains の Meta Programming System を使って、DSL エディタの実装を行い、最後に Meta Programming System と TMF の比較を行いたいと思います。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="dsl" label="DSL" scheme="http://www.sixapart.com/ns/types#tag" /><category term="mps" label="MPS" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ジェネレーティブプログラミング" label="ジェネレーティブプログラミング" scheme="http://www.sixapart.com/ns/types#tag" /><category term="言語ワークベンチ" label="言語ワークベンチ" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。今回は <a href="http://www.jetbrains.com/" target="_blank">JetBrains</a> の <a href="http://www.jetbrains.com/mps/index.html" target="_blank">Meta Programming System</a> を使って、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装を行い、最後に <a href="http://www.jetbrains.com/mps/index.html" target="_blank">Meta Programming System</a> と <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> の比較を行いたいと思います。
</p>]]>
      <![CDATA[<h2>MPS とは？</h2>
<p>
  <a href="http://www.jetbrains.com/mps/index.html" target="_blank">Meta Programming System</a> (MPS) は、<a href="http://www.jetbrains.com/idea/index.html" target="_blank">IntelliJ IDEA</a> や <a href="http://www.jetbrains.com/teamcity/index.html" target="_blank">TeamCity</a> といったプロダクトで知られる <a href="http://www.jetbrains.com/" target="_blank">JetBrains</a> によって、<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache License, Version 2.0</a> で提供されているオープンソースソフトウェアで、その名が示す通り <strong>メタプログラミング</strong> のためのシステムです。
</p>
<p>
  書籍 <a href="http://www.amazon.co.jp/gp/product/479811331X?ie=UTF8&tag=iteman-22&linkCode=as2&camp=247&creative=1211&creativeASIN=479811331X">ジェネレーティブプログラミング (IT Architects'Archive CLASSIC MODER)</a><img src="http://www.assoc-amazon.jp/e/ir?t=iteman-22&l=as2&o=9&a=479811331X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> によると、<strong>メタプログラミング</strong> とは 「<strong>他のプログラムや自分自身を記述したり、操作するプログラムを記述する</strong>」 プログラミングを指します。
</p>
<p>
  <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> は 2003 年に研究プロジェクトとして開始されました。2004 年に発表された論文「<a href="http://www.jetbrains.com/mps/docs/Language_Oriented_Programming.pdf" target="_blank">Language Oriented Programming:The Next Programming Paradigm</a>」ではそのコンセプトの詳細を知ることができます。2006 年からは内部のいくつかのプロダクトの開発に使われ始め、それらで得られた知見とフィードバックをもとにさらに開発が進められ、ついに先日バージョン 1.0 がリリースされました。
</p>
<p>
  <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> の中核にあるのは <strong>言語指向プログラミング (LOP: Language Oriented Programming)</strong> という聞き慣れないパラダイムです。
</p>

<h2>言語指向プログラミング</h2>
<p>
  <strong>言語指向プログラミング</strong> とは、ドメインに特化した言語を設計し、その言語を使用してアプリケーションを構築するプログラミングスタイルのことを指します。既に数多くのプログラミング言語が存在しているいま、なぜ新しい言語を設計する必要があるのでしょうか？
</p>
<p>
  プログラマはある問題に対して、解決策を頭の中の言語で考えます。そして、その解決策をプログラミング言語に変換 (プログラミング) します。頭の中の言語は非常に豊かな表現力を持っています。それに比べてプログラミング言語の表現力はいかにも乏しいものです。これはプログラミング言語に汎用の表現が求められることに起因しています。よって、頭の中の言語をプログラミング言語に変換するためには多くの時間と労力が必要になります。
</p>
<p>
  この問題は既存のプログラムのコードを読み理解しようとするときにも表れます。プログラマは、プログラミング言語で書かれた表現力の乏しいコードから、プログラムの意図を発掘する必要があります。プログラムのコードは書かれる時間よりも読まれる時間の方が圧倒的に多いため、このことはプログラムの保守コストを増大させる原因となっています。
</p>
<blockquote class="note"><strong>ノート</strong>: プログラミング言語で書かれたコードから当初の意図を完全に復元することは常に可能でしょうか？<a href="http://www.amazon.co.jp/gp/product/479811331X?ie=UTF8&tag=iteman-22&linkCode=as2&camp=247&creative=1211&creativeASIN=479811331X">ジェネレーティブプログラミング (IT Architects'Archive CLASSIC MODER)</a><img src="http://www.assoc-amazon.jp/e/ir?t=iteman-22&l=as2&o=9&a=479811331X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> には、プログラミング言語で書かれたコードから当初の設計情報が失われることについての記述があります。</blockquote>
<p>
  問題空間を表現するための言語である <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の場合、プログラミング言語で書かれたコードでは失われるであろう多くの設計情報をそのまま保存できる可能性が高くなります。上手く設計された <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> は意図を的確に表現することができます。これは新しい言語を設計することに対する大きな根拠となります。
</p>

<h2>DSL の仕様</h2>
<p>
  今回の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の仕様は以下の通りです。これは「<a href="http://mt.iteman.jp/mt-search.cgi?blog_id=3&tag=%E3%81%BE%E3%81%A3%E3%81%A4%E3%82%93%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%206&limit=20&IncludeBlogs=3" target="_blank">まっつんチャレンジ 6: 言語ワークベンチによる DSL エディタ の実装 TMF 編</a>」とまったく同じものです。
</p>
<ul>
  <li>Windows の INI ファイルなどで利用されている name = value 形式のテキストフォーマットであること</li>
  <li>value には文字列または他の name の参照を記述できること</li>
  <li>+ 演算子によって複数の要素を連結できること</li>
</ul>
<p>
  この <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の使用例は以下のようになります。
</p>
<pre class="prettyprint">foo = &quot;AAA&quot;
bar = &quot;BBB&quot;
baz = &quot;CCC&quot;
qux = foo + bar + baz   // &quot;AAABBBCCC&quot;</pre>

<h2>MPS のインストール</h2>
<p>
  そろそろ <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装に入りましょう。最初に、以下のサイトから <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> のダウンロードを行います。
</p>
<blockquote class="note"><a href="http://www.jetbrains.com/mps/download/index.html" target="_blank">http://www.jetbrains.com/mps/download/index.html</a></blockquote>
<p>
  次に、ダウンロードしたアーカイブを適当なディレクトリに展開しましょう。
</p>
<pre class="prettyprint lang-sh">tar xvzf MPS-linux-1.0.1.tar.gz</pre>

<h2>プロジェクトの作成</h2>
<p>
  次に、プロジェクトを作成します。<strong>[File] -> [New Project...]</strong> をクリックし、プロジェクトの情報を以下のように入力します。
</p>
<table>
  <thead>
    <tr>
      <th>項目</th>
      <th>値</th>
      <th>説明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Name</td><td>mydsl</td><td>プロジェクトの名称</td>
    </tr>
    <tr>
      <td>Language Namespace</td><td>jp.iteman.mydsl</td><td>言語のネームスペース</td>
    </tr>
  </tbody>
</table>
<p>
  <img alt="mps2-project.png" src="http://iteman.jp/blog/images/mps2-project.png" width="358" height="340" class="mt-image-none" style="" />
</p>
<p>
  Logical View から見える部分ツリー毎に以下のような役割があります。
</p>
<table>
  <tbody>
    <tr>
      <th>
        "S" アイコン
      </th>
      <td>
        <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> を利用したソリューション
      </td>
    </tr>
    <tr>
      <th>
        "L" アイコン
      </th>
      <td>
        <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の定義
      </td>
    </tr>
    <tr>
      <th>
        Modules Pool
      </th>
      <td>
        再利用可能なソリューションや <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a>
      </td>
    </tr>
  </tbody>
</table>

<h2>DSL の構造を定義する</h2>
<p>
  <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> では、<strong>コンセプト</strong> を定義し、それらを組み合わせることによって <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 全体の構造を定義します。コンセプトは拡張したり、プロパティを保持したりできるので、オブジェクト指向言語における振る舞い (メソッド) を持たないクラスと考えると理解しやすいでしょう。
</p>
<p>
  それでは <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の構造を定義していきましょう。最初にトップレベルのコンセプトとなる <strong>Ini コンセプト</strong> を定義します。<strong>Ini コンセプト</strong> は複数の <strong>Config コンセプト</strong> を保持します。</p>
<p>
  <img alt="mps2-concept-ini.png" src="http://iteman.jp/blog/images/mps2-concept-ini.png" width="440" height="466" class="mt-image-none" style="" />
</p>
<p>
  <strong>Config コンセプト</strong> はひとつの <strong>Expression コンセプト</strong> を保持します。<a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> が提供するコンセプトである <strong>Expression コンセプト</strong> は「2 + 3」のような式表現をサポートします。
</p>
<p>
  <img alt="mps2-concept-config.png" src="http://iteman.jp/blog/images/mps2-concept-config.png" width="439" height="469" class="mt-image-none" style="" />
</p>
<p>
  <strong>Expression コンセプト</strong> が定義しているのは数値や文字列といったプリミティブな型の式表現であり、この場合他のコンセプトを参照することはできません。<strong>Expression コンセプト</strong> を継承した <strong>ConfigReference コンセプト</strong> を定義することで、<strong>Config コンセプト</strong> を式から参照できるようになります。
</p>
<p>
  <img alt="mps2-concept-config-reference.png" src="http://iteman.jp/blog/images/mps2-concept-config-reference.png" width="443" height="469" class="mt-image-none" style="" />
</p>
<p>
  <strong>ConfigReference コンセプト</strong> はひとつの <strong>Config コンセプト</strong> の参照を保持します。
</p>
<p>
  これで「foo = "AAA" + bar」のような <strong>Config コンセプト</strong> への参照を含んだ表現が可能になります。
</p>

<h2>DSL エディタを定義する</h2>
<p>
  次にコンセプト毎に <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタ上での表現を定義します。
</p>
<p>
  <strong>Ini コンセプト</strong> については、最初に名称を入力し、次に空行を挿入したあと、<strong>Config コンセプト</strong> を入力するように定義を行います。
</p>
<p>
  <img alt="mps2-editor-ini.png" src="http://iteman.jp/blog/images/mps2-editor-ini.png" width="448" height="467" class="mt-image-none" style="" />
</p>
<p>
  <strong>Config コンセプト</strong> については、name = value 形式の文字列を入力するように定義を行います。
</p>
<p>
  <img alt="mps2-editor-config.png" src="http://iteman.jp/blog/images/mps2-editor-config.png" width="443" height="470" class="mt-image-none" style="" />
</p>
<p>
  <strong>ConfigReference コンセプト</strong> については、参照された <strong>Config コンセプト</strong> の名称を表示するように定義を行います。
</p>
<p>
  <img alt="mps2-editor-config-reference.png" src="http://iteman.jp/blog/images/mps2-editor-config-reference.png" width="444" height="468" class="mt-image-none" style="" />
</p>
<p>
  以上で <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの定義は完了です。
</p>

<h2>DSL エディタを実行する</h2>
<p>
  <strong>jp.iteman.mydsl</strong> を右クリックし、<strong>[Generate Language]</strong> をクリックすると、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタが生成されます。
</p>
<p>
  次にソリューションの <strong>sandbox</strong> を右クリックし、<strong>[Create Root Node] -> [jp.iteman.mydsl] -> [Ini]</strong> をクリックすると <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタが起動し、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> を編集することができるようになります。
</p>
<a href="http://iteman.jp/blog/assets_c/2009/08/mps2-execution-436.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/08/mps2-execution-436.html','popup','width=1238,height=900,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/08/mps2-execution-thumb-500x363-436.png" width="500" height="363" alt="mps2-execution.png" class="mt-image-none" style="" /></a>

<h2>MPS と TMF の比較</h2>
<p>
  今回と前回のチャレンジで <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> と <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a>それぞれによる <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装が完了しましたので、両者を比較してみたいと思います。
</p>
<h3>保存形</h3>
<p>
  <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> と <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> の最も大きな違いは、目に見える部分ではなく <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の保存形にあります。<a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> が抽象構文木 (AST: Abstract Syntax Tree) を保存するのに対して、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のテキスト表現をそのまま保存します。
</p>
<p>
  プログラムがテキスト表現で保存されることに、筆者を含めて多くの開発者は違和感を感じないのではないでしょうか。しかし、コンパイラやエディタを実装する立場からすると、テキスト表現から AST に変換する必要があります。パーサやレキサが技術的に確立されているとはいえ、これは手間のかかる処理であることに変わりありません。
</p>
<p>
  このような観点から、AST を保存形として用いることは非常に効率的であると言えるでしょう。
</p>
<blockquote class="note"><strong>ノート</strong>: AST ではなくランタイムのオブジェクト表現 (セマンティックモデル) そのものを保存する方法もあります。例えば、<a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> の保存形は <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルです。これは AST よりもさらに効率的な方法といえる可能性があります。</blockquote>

<h3>DSL の定義</h3>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の定義についても両者の間に大きな違いが見られます。
</p>
<p>
  <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> では、言語を構成するコンセプトを定義し、それらを組み合わせることで <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の構造 (抽象形) を定義します。次にテキスト表現の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のグラマーを、コンセプト毎に定義します。
</p>
<p>
  これに対して、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> では、テキスト表現の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のグラマー (文法) をグラマー言語を使って定義します。
</p>
<p>
  つまり、<a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> では <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の構造と表現を個別に定義しますが、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> では構造と表現の定義が一体となっています。
</p>
<p>
  この構造と表現が一体となっていることにより、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> では <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の抽象形として <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルを使用することができません。そのため、<a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> と抽象形を共有することができず、同一の抽象形をグラフィカルなエディタとテキストエディタの双方から同時に操作するといった機能の実装が困難となっています。
</p>

<h3>DSL エディタ</h3>
<p>
  一見すると、どちらもテキストエディタであり大きな違いはないように見えますが、使用してみると大きな違いがわかります。
</p>
<p>
  <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> のエディタは <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> のテキストエディタを拡張したものです。使い勝手は通常のテキストエディタと変わりありません。
</p>
<p>
  しかし、<a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> のエディタでは、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の構造に基づいた <strong>セル</strong> 単位で編集を行います。そのため、固定の文字列として定義されている <strong>Ini</strong> や <strong>=</strong> を編集することはできません。コンセプトやエディタを定義するためのエディタも同じ振る舞いを示します。また、先述のとおり保存形として AST が採用されているので、エディタで表示されているテキスト表現はどのファイルにも保存されることはありません。今回のソースコード表示にテキストではなくスクリーンショットを使ったのはこのためです。
</p>

<h2>おわりに</h2>
<p>
  今回と前回のチャレンジで <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> と <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> という 2 つの言語ワークベンチを見てきました。
</p>
<p>
  ご覧いただいたように、現時点の完成度は <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> の方がかなり上といえるでしょう。一方の <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> に寄贈されて 1 年程度ということもあり、まだまだこれからという感じがしますが、<a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> や <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> と連携できる要素は持っているので、大きな可能性を秘めていると言えるでしょう。
</p>
<p>
  ところで、今回と前回のチャレンジででは <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の保存形を使った処理系については紹介しませんでした。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> や <a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a> のサンプルには、テンプレート言語を利用して静的にプログラミング言語のソースコードを生成する方法がみられますが、動的 (実行時) に保存形を読み込みセマンティックモデルを生成する方法もあります。処理系についてはまたの機会にご紹介したいと思います。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.jetbrains.com/mps/index.html" target="_blank">MPS</a></th><td>1.0</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">Martin Fowler's Bliki in Japanese - 言語ワークベンチ</a></li>
  <li><a href="http://www.jetbrains.com/mps/index.html" target="_blank">JetBrains :: Meta Programming System -- Language Oriented Programming environment and DSL creation tool</a></li>
  <li><a href="http://www.jetbrains.com/mps/docs/tutorial.html" target="_blank">JetBrains :: Meta Programming System - Tutorial</a></li>
  <li><a href="http://www.jetbrains.com/mps/docs/Language_Oriented_Programming.pdf" target="_blank">Language Oriented Programming:The Next Programming Paradigm</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 6: 言語ワークベンチによる DSL エディタ の実装 TMF 編 第 2 回 (最終回)</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/07/-6-dsl-tmf-2.html" />
    <id>tag:iteman.jp,2009:/blog//3.77</id>

    <published>2009-07-27T18:47:27Z</published>
    <updated>2009-08-16T17:55:16Z</updated>

    <summary>まっつんです。前回は、Eclipse の Textual Modeling Framework を 言語ワークベンチ として使って DSL エディタを実装するために、DSL および DSL 処理系のプロセスフローを簡単に説明しました。 今回は Textual Modeling Framework を使って DSL エディタを実装します。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="dsl" label="DSL" scheme="http://www.sixapart.com/ns/types#tag" /><category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="tmf" label="TMF" scheme="http://www.sixapart.com/ns/types#tag" /><category term="xtext" label="Xtext" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ6" label="まっつんチャレンジ 6" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ジェネレーティブプログラミング" label="ジェネレーティブプログラミング" scheme="http://www.sixapart.com/ns/types#tag" /><category term="言語ワークベンチ" label="言語ワークベンチ" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。前回は、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> の <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">Textual Modeling Framework</a> を <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> として使って <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタを実装するために、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> および <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系のプロセスフローを簡単に説明しました。
</p>
<p>
  今回は <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">Textual Modeling Framework</a> を使って <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタを実装します。
</p>]]>
      <![CDATA[<h2>DSL の仕様</h2>
<p>
  最初に <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の仕様を以下のように定めておきます。
</p>
<ul>
  <li>Windows の INI ファイルなどで利用されている name = value 形式のテキストフォーマットであること</li>
  <li>value には文字列または他の name の参照を記述できること</li>
  <li>+ 演算子によって複数の要素を連結できること</li>
</ul>
<p>
  この <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の使用例は以下のようになります。
</p>
<pre class="prettyprint">foo = &quot;AAA&quot;
bar = &quot;BBB&quot;
baz = &quot;CCC&quot;
qux = foo + bar + baz   // &quot;AAABBBCCC&quot;</pre>

<h2>Xtext プロジェクトの作成</h2>
<p>
  それではプロジェクトを作成してみましょう。新規作成ウィザードで <strong>[Xtext Project]</strong> を選択し、作成するプロジェクトの情報を以下のように入力します。
</p>
<table>
  <thead>
    <tr>
      <th>項目</th>
      <th>値</th>
      <th>説明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Main Project name</td><td>jp.iteman.mydsl</td><td>メインプロジェクトの名称</td>
    </tr>
    <tr>
      <td>Language name</td><td>jp.iteman.MyDsl</td><td>作成する言語の名称</td>
    </tr>
    <tr>
      <td>DSL-File extension</td><td>mydsl</td><td><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> ファイルの拡張子</td>
    </tr>
    <tr>
      <td>Create generator project</td><td>オン</td><td>ジェネレータプロジェクトを生成するかどうか</td>
    </tr>
  </tbody>
</table>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/07/tmf2-wizard-417.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/07/tmf2-wizard-417.html','popup','width=700,height=500,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/07/tmf2-wizard-thumb-500x357-417.png" width="500" height="357" alt="tmf2-wizard.png" class="mt-image-none" style="" /></a></span>
<p>
  作成されるプロジェクトと役割は以下のとおりです。
</p>
<table>
  <thead>
    <tr>
      <th>プロジェクト</th>
      <th>役割</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>jp.iteman.mydsl</td><td>グラマーを定義する</td>
    </tr>
    <tr>
      <td>jp.iteman.mydsl.ui</td><td><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタを提供する</td>
    </tr>
    <tr>
      <td>jp.iteman.mydsl.generator</td><td><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> スクリプトをセマンティックモデルに静的に変換する (今回は使用しない) </td>
    </tr>
  </tbody>
</table>

<h2>DSL のグラマーを定義する</h2>
<p>
  続いて <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のグラマー (文法) を定義します。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">Textual Modeling Framework</a> (以下、TMF) はグラマーの定義を起点としてレキサやパーサ、エディタといったさまざまな種類のコードを生成します。
</p>
<p>
  グラマーは <strong>jp.iteman.mydsl/src/jp.iteman/MyDsl.xtext</strong> で定義します。今回の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のグラマーは以下のとおりです。
</p>
<h6>jp.iteman.mydsl/src/jp.iteman/MyDsl.xtext</h6>
<pre class="prettyprint">grammar jp.iteman.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.iteman.jp/MyDsl"

Ini :
    (configurations+=Config)+;

Config :
    name=ID '=' value=Expression;

ConfigRef :
    ref=[Config] | value=STRING;

Expression :
    TerminalExpression ({Operation.left=current} op='+' right=Expression)?;

TerminalExpression returns Expression:
    '(' Expression ')' | {MethodValueLiteral} value=ConfigRef;
</pre>
<blockquote class="note"><strong>ノート</strong>: グラマー言語については「<a href="http://www.eclipse.org/Xtext/documentation/0_7_0/xtext.html" target="_blank">Xtext User Guid</a>」の「<a href="http://www.eclipse.org/Xtext/documentation/0_7_0/xtext.html#grammarLanguage" target="_blank">2. The Grammar Language</a>」をご覧ください。</blockquote>

<h2>DSL エディタを生成する</h2>
<p>
  以上でグラマーの定義が完了し、エディタを生成できるようになりました。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は <a href="http://wiki.eclipse.org/Modeling_Workflow_Engine_(MWE)" target="_blank">Modeling Workflow Engine</a> (MWE) を使用してコード生成を行います。<strong>jp.iteman.mydsl/src/jp.iteman/GenerateMyDsl.mwe</strong> はコード生成のための MWE の定義ファイルです。
</p>
<p>
  <strong>jp.iteman.mydsl/src/jp.iteman/GenerateMyDsl.mwe</strong> を右クリックし、<strong>[Run As] -> [MWE Workflow]</strong> をクリックすることでコード生成が行われます。このときコンソールビューにはコード生成の進行状況が表示されます。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/07/tmf2-console-420.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/07/tmf2-console-420.html','popup','width=1195,height=376,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/07/tmf2-console-thumb-500x157-420.png" width="500" height="157" alt="tmf2-console.png" class="mt-image-none" style="" /></a></span>

<h2>DSL エディタを実行する</h2>
<p>
  それではエディタを動かしてみましょう。最初に <strong>[Run] メニュー -> [Run Configurations...]</strong> をクリックします。次に <strong>Eclipse Application</strong> を作成し、<strong>[Run] ボタン</strong>で実行します。以上の操作で現在開発しているプラグインの実行用 <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> が起動します。
</p>
<p>
  起動した <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> で適当なプロジェクトを作成し、拡張子が <strong>.mydsl</strong> のファイルを作成すると、自動生成されたエディタが起動します。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/07/tmf2-editor-423.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/07/tmf2-editor-423.html','popup','width=987,height=453,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/07/tmf2-editor-thumb-500x229-423.png" width="500" height="229" alt="tmf2-editor.png" class="mt-image-none" style="" /></a></span>
<p>
  スクリーンショットからは、文字列の強調表示、入力の補完、アウトラインビューといったエディタに必要な機能が一通り揃っていることがわかります。もちろん、追加のコードを書くことでエディタの振る舞いを拡張することも可能です。
</p>

<h2>言語ワークベンチとしての TMF</h2>
<p>
  筆者は <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> でテキストエディタを実装したことがありますが、これだけの機能を持つエディタを実装するのは簡単ではありません。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> はグラマーを定義するだけでそれを生成することができます。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は外部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装コストを大幅に下げることができるものである、と言えるでしょう。
</p>
<p>
  では、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> を <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> として評価するとどうでしょうか？
</p>
<p>
  <a href="http://www.martinfowler.com/bliki/" target="_blank">Martin Fowler</a> 氏は記事「<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a>」で <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> の必要条件を以下のようにまとめています。
</p>
<blockquote>
  <ul>
    <li>ユーザが自由に新しい言語を定義できる。言語はそれぞれ完全に統合可能である。</li>
    <li>一次情報ソースは、永続化された抽象形(persistent abstract representation)である。</li>
    <li>言語設計者は、スキーマ、エディタ、ジェネレータの3つの部分に分けてDSLを定義する。</li>
    <li>言語ユーザは、投影エディタ(projectional editor)でDSLを操作する。</li>
    <li>言語ワークベンチは、不完全だったり矛盾だったりする情報を抽象形に永続化できる。</li>
  </ul>
</blockquote>
<p>
  これらのうち <strong>一次情報ソースは、永続化された抽象形(persistent abstract representation)である。</strong> という点を <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は明らかに満たしていません。
</p>
<p>
  <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> の 1 次情報ソースは、テキスト表現の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> スクリプトそのものであり、永続化された抽象形ではありません。<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> のスキーマはこの抽象形に対するグラマーを指しますが、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> のスキーマはテキスト表現の <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> スクリプトに対するグラマーです。
</p>
<blockquote class="note"><strong>ノート</strong>: ここでいう抽象形とは、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の AST あるいはセマンティックモデルを指していると考えられます。なお、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> の抽象形は <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルです。</blockquote>
<blockquote class="note"><strong>ノート</strong>: <a href="http://www.jetbrains.com/index.html" target="_blank">JetBrains</a> の <a href="http://www.jetbrains.com/mps/index.html" target="_blank">Meta Programming System</a> (最近 1.0 がリリースされました！) に関する記事 <a href="http://www.infoq.com/jp/news/2009/01/jetbrains-mps" target="_blank">InfoQ: JetBrains のメタプログラミングシステムは言語指向プログラミングと DSL をサポート</a> で、1 次情報ソースが永続化された抽象形でないことの欠点について、開発チームを率いている Konstantin Solomatov 氏の見解を読むことができます。</blockquote>
<p>
  よって、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> の定義を満たしているとは言えません。これは大きな欠点でしょうか？
</p>
<p>
  幸いにも <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> にはモデリングフレームワーク <a href="http://www.eclipse.org/modeling/emf/" target="_blank">Eclipse Modeling Framework</a> (EMF) と、それを基盤とするグラフィカルなモデリングフレームワーク <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">Eclipse Graphical Modeling Framework</a> (GMF) があります。
</p>
<p>
  <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> は、グラフィカルな <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタを作成するために使うことができますが、ここで中心となるのは <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の抽象形であるセマンティックモデル (ドメインモデル) となります。<a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> でエディタを生成するためのワークフローを見てください。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/07/tmf2-gmf-426.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/07/tmf2-gmf-426.html','popup','width=1013,height=413,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/07/tmf2-gmf-thumb-500x203-426.png" width="500" height="203" alt="tmf2-gmf.png" class="mt-image-none" style="" /></a></span>
<blockquote class="note"><strong>ノート</strong>: <a href="http://piece-framework.com/" target="_blank">Piece Framework</a> のプロダクト <a href="http://redmine.piece-framework.com/projects/show/piece-ide" target="_blank">Piece_IDE</a> にはグラフィカルなエディタでページフローを編集する機能があります。これは <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> ベースの <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実例です。</blockquote>
<p>
  <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> では抽象形および保存形として <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルが使用されます。よって、<a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> の 1 次情報ソースは永続化された抽象形です。そして <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> (Xtext) には <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> のリソース API が実装されており、動的または静的にテキストモデルと <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルを相互変換することができます。
</p>
<p>
  このことは <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> 単体では<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a>を構成できませんが、<a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルを起点にすることで <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> と <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> を統合できる可能性を示しています。
</p>
<p>
  これが可能だとしたら <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> + <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> で<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a>を構成することができるでしょう。例えば、永続化された <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> モデルを <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> ベースのエディタで編集したり、<a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a> ベースのグラフィカルなエディタで編集する、そしてお互いの変更をリアルタイムに反映する、といったことが可能になるでしょう。
</p>
<p>
  アイテマンでは、これらを実現するための具体的なアーキテクチャに関する調査を続けています。何か進展がありましたらブログでお伝えしたいと思います。
</p>

<h2>おわりに</h2>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> はドメインの可変点を表現し、具体的なシステムを発注するための指示書です。<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のための環境である <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a>は、ビジネスの現場で求められる継続的で進化的なプログラミングプラットフォームとして大きな可能性を秘めています。これは、従来のシステム開発のあり方を大きく変えるものになるかもしれません。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> (そして <a href="http://www.eclipse.org/modeling/gmf/" target="_blank">GMF</a>) を使うことで、そのような新しい世界の一端を垣間見ることができるでしょう。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.eclipse.org/" target="_blank">Eclipse</a> (Eclipse Modeling Tools)</th><td>3.5</td>
    </tr>
    <tr>
      <th><a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> (<a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a>)</th><td>0.7.0</td>
    </tr>
    <tr>
      <th><a href="http://www.antlr.org/" target="_blank">ANTLR</a></th><td>3.0.1</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">Martin Fowler's Bliki in Japanese - 言語ワークベンチ</a></li>
  <li><a href="http://www.eclipse.org/Xtext/documentation/0_7_0/xtext.html" target="_blank">Xtext User Guide</a></li>
  <li><a href="http://www.eclipse.org/Xtext/" target="blank">Xtext</a>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 6: 言語ワークベンチによる DSL エディタ の実装 TMF 編 第 1 回</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/07/-6-dsl-tmf-1.html" />
    <id>tag:iteman.jp,2009:/blog//3.75</id>

    <published>2009-07-14T04:15:53Z</published>
    <updated>2009-07-27T18:54:47Z</updated>

    <summary>言語ワークベンチ は ドメイン特化言語 (DSL: Domain Specific Launguage) を中心とするメタプログラミングのための環境であり、実例としては Intentional Software の Intentional Domain Workbench や JetBrains の Meta Programming System, Eclipse の Textual Modeling Framework などが挙げられます。 今回は 言語ワークベンチ として Textual Modeling Framework を使って DSL エディタの実装にチャレンジします。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="dsl" label="DSL" scheme="http://www.sixapart.com/ns/types#tag" /><category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="tmf" label="TMF" scheme="http://www.sixapart.com/ns/types#tag" /><category term="xtext" label="Xtext" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ6" label="まっつんチャレンジ 6" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ジェネレーティブプログラミング" label="ジェネレーティブプログラミング" scheme="http://www.sixapart.com/ns/types#tag" /><category term="言語ワークベンチ" label="言語ワークベンチ" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">ドメイン特化言語</a> (DSL: Domain Specific Launguage) を中心とするメタプログラミングのための環境であり、実例としては <a href="http://www.intentsoft.com/" target="_blank">Intentional Software</a> の <strong>Intentional Domain Workbench</strong> や <a href="http://www.jetbrains.com/" target="_blank">JetBrains</a> の <a href="http://www.jetbrains.com/mps/index.html" target="_blank">Meta Programming System</a>, <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> の <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">Textual Modeling Framework</a> などが挙げられます。
</p>
<p>
 今回は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> として <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">Textual Modeling Framework</a> を使って <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装にチャレンジします。
</p>]]>
      <![CDATA[<h2>外部 DSL と内部 DSL</h2>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> は特定の知識分野 (ドメイン) 向けに設計されたコンピュータ言語であり、日本語では「ドメイン特化言語」あるいは「ドメイン固有言語」と呼ばれています。
</p>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の熱心な支持者である <a href="http://www.martinfowler.com/bliki/" target="_blank">Martin Fowler</a> 氏は記事「<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a>」で、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> を <strong>外部 DSL</strong> と <strong>内部 DSL</strong> に分類しています。
</p>
<p>
  外部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> はアプリケーションを書くためのプログラミング言語 (ホスト言語) とは異なる言語で書かれた <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> です。これに対して、内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> はホスト言語と同じ言語で書かれた <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> です。
</p>
<p>
  同記事に書かれているように、外部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> と内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> には長所と短所があります。筆者なりに以下にまとめてみました。
</p>
<table>
  <thead>
    <tr>
      <th></th>
      <th>外部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a></th>
      <th>内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>表現力 (読みやすさ、理解のしやすさ)</th><td>高い</td><td>低い</td>
    </tr>
    <tr>
      <th><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系の実装コスト</th><td>高い</td><td>低い</td>
    </tr>
    <tr>
      <th>ツールによるサポート</th><td>なし</td><td>あり (ただし限定的) </td>
    </tr>
  </tbody>
</table>
<p>
  内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> はホスト言語の制約を受けるため表現力には限界がありますが、ホスト言語とリンクしており言語設計にホスト言語の機能を活用することができます。これによって <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系の実装を低コストで行うことができます。しかし、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系の実装が不要になるわけではありません。内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> なのでホスト言語および周辺ツールはその <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のことを知りません。よってそのサポートは限定的です。
</p>
<blockquote class="note"><strong>ノート</strong>: <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?FluentInterface" target="_blank">流れるようなインターフェイス</a> はツールによるホスト言語用のサポートを最大限に活用するための内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> といえます。</blockquote>
<p>
  外部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> には表現上の制約がないため、そのドメインに最適な言語を提供できる可能性があります。内部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> と比較すると処理系の実装は高コストです。ツールによるサポートは絶望的であり、この部分の開発は間違いなく高コストになるでしょう。
</p>
<p>
  しかし、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> の登場によりこの状況に変化が生まれています。<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の処理系の大部分を自動生成することができます。同時に <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの自動生成により手厚いツールサポートの提供を可能にします。
</p>
<p>
  今回は <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> の <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">Textual Modeling Framework</a> による <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装を通して、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a> がもたらすものを体験したいと思います。
</p>

<h2>DSL 処理系のプロセスフローを知る</h2>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> エディタの実装に入る前に、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系のプロセスフローを見てみましょう。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/07/tmf1-dsl-408.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/07/tmf1-dsl-408.html','popup','width=646,height=854,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/07/tmf1-dsl-thumb-500x660-408.png" width="500" height="660" alt="tmf1-dsl.png" class="mt-image-none" style="" /></a></span>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> はコンピュータ言語なので、プログラムから利用できる形である <strong>抽象構文木 (AST: Abstract Syntax Tree) </strong> に変換しなければなりません。これは <strong>レキサ (字句解析器)</strong> と <strong>パーサ (構文解析器)</strong> の仕事です。
</p>
<p>
  レキサとパーサによって変換された AST は <strong>ジェネレータ</strong> によって、<strong>セマンティックモデル</strong> のオブジェクトやクラスなどに変換されます。セマンティックモデルは <strong>ドメインモデル</strong> でありそのオブジェクトやクラスはそれぞれ <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の動的および静的な表現です。
</p>
<p>
  <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のグラマー (文法) を読み込んで <strong>パーサ</strong> を生成するのは <strong>パーサジェネレータ</strong> の仕事です。
</p>
<blockquote class="note"><strong>ノート</strong>: パーサジェネレータにはレキサを生成するものがあります。今回使用する <a href="http://www.antlr.org/" target="_blank">ANTLR</a> もそのひとつです。</blockquote>
<p>
  以下は <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系の実装プロセスの例です。
</p>
<ol>
  <li>ホスト言語から使うことができるパーサジェネレータを選定する</li>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> のグラマーを設計する</li>
  <li>パーサジェネレータでパーサ (およびレキサ) を生成する</li>
  <li>ジェネレータ、セマンティックモデルを実装する</li>
</ol>

<h2>TMF</h2>
<p>
  <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は <a href="http://www.eclipse.org/modeling/" target="_blank">Eclipse Modeling Project</a> 傘下のプロジェクトのひとつで、テキストベースのモデリングフレームワークです。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> の根幹となるフレームワークは <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> です。この <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> はもともと <a href="http://www.openarchitectureware.org/" target="_blank">openArchitectureWare</a> で開発されていましたが、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> に寄贈され、現在は <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> のプロジェクトの一環として開発が進められています。
</p>
<p>
</p>
<p>
  ここで、先ほどの図に <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> を加えて、一般的な <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系と <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> を加えた処理系を比較してみましょう。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/07/tmf1-tmf-411.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/07/tmf1-tmf-411.html','popup','width=629,height=837,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/07/tmf1-tmf-thumb-500x665-411.png" width="500" height="665" alt="tmf1-tmf.png" class="mt-image-none" style="" /></a></span>
<p>
  <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> の最大の特徴は <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> ファイルから <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 専用のエディタを生成できることです。また、パーサも自動生成されるため、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系の実装コストは大幅に削減されます。つまり、これらの特徴は外部 <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> の問題を解消します。
</p>
<p>
  <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> ファイルはエディタのための文法ファイルであり、このファイルを起点として、いろいろなプログラムが生成されます。
</p>
<p>
  パーサジェネレータは自由に選択することができますが、実際にはインタフェースが用意されている <a href="http://www.antlr.org/" target="_blank">ANTLR</a> か PackratParser がよいでしょう。<a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> では <a href="http://www.antlr.org/" target="_blank">ANTLR</a> が推奨されています。
</p>
<p>
  また、ジェネレータも生成されます。これは一見すると便利ですが、生成されたコードは <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> や <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> に依存しているため、Java 以外のホスト言語で <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 処理系を構築する場合に応用が難しいという問題があります。
</p>

<h2>TMF のインストール</h2>
<p>
  それでは <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> をインストールしましょう。<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> は Eclipse Modeling Tools に含まれているので、以下のサイトからダウンロードして利用することにします。
</p>
<blockquote class="note"><a href="http://www.eclipse.org/downloads/" target="_blank">http://www.eclipse.org/downloads/</a></blockquote>
<pre class="prettyprint lang-sh">tar xvzf eclipse-modeling-galileo-incubation-linux-gtk.tar.gz</pre>
<p>
  次にパーサジェネレータである <a href="http://www.antlr.org/" target="_blank">ANTLR</a> と、<a href="http://www.antlr.org/" target="_blank">ANTLR</a> を <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> から利用するためのプラグインをインストールします。これらは以下の更新サイトからインストールすることができます。
</p>
<pre class="prettyprint">http://download.itemis.com/updates</pre>

<h2>おわりに</h2>
<p>
  今のところ <a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> はインキュベーションの段階であり、まだまだこれからのプロジェクトです。しかし、グラマーを定義するだけで専用のエディタを生成できることに、筆者は大きな魅力と可能性を感じています。
</p>
<p>
  次回は、<a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> を使って、<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> を定義し、その <a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">DSL</a> 専用のエディタを生成したいと思います。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.eclipse.org/" target="_blank">Eclipse</a> (Eclipse Modeling Tools)</th><td>3.5</td>
    </tr>
    <tr>
      <th><a href="http://www.eclipse.org/modeling/tmf/" target="_blank">TMF</a> (<a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a>)</th><td>0.7.0</td>
    </tr>
    <tr>
      <th><a href="http://www.antlr.org/" target="_blank">ANTLR</a></th><td>3.0.1</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">Martin Fowler's Bliki in Japanese - 言語ワークベンチ</a></li>
  <li><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage" target="_blank">Martin Fowler's Bliki in Japanese - ドメイン特化言語</a></li>
  <li><a href="http://i.loveruby.net/ja/rhg/book/yacc.html" target="_blank">第9章 速習yacc</a></li>
  <li><a href="http://www.eclipse.org/Xtext/documentation/0_7_0/xtext.html" target="_blank">Xtext User Guide</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 5: Spring Roo の謎に迫る</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/06/-5-spring-roo.html" />
    <id>tag:iteman.jp,2009:/blog//3.73</id>

    <published>2009-06-30T06:15:22Z</published>
    <updated>2009-08-01T13:53:04Z</updated>

    <summary>まっつんです。今回のテーマは Spring Roo (以下、Roo) です。Roo とはどんなものなのでしょうか？...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="eclipse" label="Eclipse" scheme="http://www.sixapart.com/ns/types#tag" /><category term="java" label="Java" scheme="http://www.sixapart.com/ns/types#tag" /><category term="maven" label="Maven" scheme="http://www.sixapart.com/ns/types#tag" /><category term="springframework" label="Spring Framework" scheme="http://www.sixapart.com/ns/types#tag" /><category term="springroo" label="Spring Roo" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="シェル" label="シェル" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  まっつんです。今回のテーマは <a href="http://www.springsource.org/roo" target="_blank">Spring Roo</a> (以下、Roo) です。<a href="http://www.springsource.org/roo" target="_blank">Roo</a> とはどんなものなのでしょうか？
</p>]]>
      <![CDATA[<h2>Roo とは？</h2>
<p>
  <a href="http://www.springsource.org/roo" target="_blank">Roo</a> のプロジェクトリード <a href="http://blog.springsource.com/author/bena/" target="_blank">Ben Alex</a> 氏はブログ記事「<a href="http://blog.springsource.com/2009/05/01/roo-part-1/" target="_blank">Jump into Roo for extreme Java productivity</a>」で以下のように説明されています。
</p>
<blockquote>Roo is a sophisticated round-tripping code generator that makes it quicker and easier than you've ever imagined to create and evolve Spring applications. Even if you have reservations about code generation, it will still be worth taking a look at Roo. It contains significant innovation that addresses all major objections to code generation, whilst still delivering best practice Spring applications and remaining useful throughout the application lifecycle.</blockquote>
<p>
  <a href="http://www.springsource.org/roo" target="_blank">Roo</a> は <a href="http://www.springsource.org/" target="_blank">Spring</a> を使用したアプリケーションのコードを生成するツールであり、アプリケーション開発のあらゆる段階でベストプラクティスを提供するツールとのことです。
</p>
<p>
  それでは、具体的にどういった機能を <a href="http://www.springsource.org/roo" target="_blank">Roo</a> は提供しているのでしょうか？
</p>
<p>
  <a href="http://www.springsource.org/roo" target="_blank">Roo のサイト</a> の説明ではわかりにくいので、<a href="http://blog.springsource.com/author/bena/" target="_blank">Ben Alex</a> 氏のブログ記事「<a href="http://blog.springsource.com/2009/06/18/roo-part-3/" target="_blank">Exploring Roo's Architecture</a>」の「Roo Core versus Roo Add-Ons」を参考に、<a href="http://www.springsource.org/roo" target="_blank">Roo</a> のコアが提供する機能を列挙してみましょう。
</p>
<ul>
  <li>a shell</li>
  <li>file system manager</li>
  <li>file system monitor</li>
  <li>file undo capability</li>
  <li>classpath abstraction</li>
  <li>Abstract Syntax Tree (AST) parsing and binding</li>
  <li>project build system interface</li>
  <li>metadata model</li>
  <li>process management</li>
  <li>bootstrap and utility services</li>
</ul>
<p>
  最後に <a href="http://www.springsource.org/roo" target="_blank">Roo</a> のミッションについて見てみましょう。<a href="http://blog.springsource.com/author/bena/" target="_blank">Ben Alex</a> 氏はブログ記事「<a href="http://blog.springsource.com/2009/05/01/roo-part-1/" target="_blank">Jump into Roo for extreme Java productivity</a>」で以下のように書かれています。
</p>
<blockquote>Roo's mission is to fundamentally and sustainably improve Java developer productivity without compromising engineering integrity or flexibility.</blockquote>
<p>
  理論と実装の両方が大事だと考えている筆者にとって、工学的手法を損なうことなく開発者の生産性を改善していこうという <a href="http://www.springsource.org/roo" target="_blank">Roo</a> の姿勢はとても共感できるものです。
</p>

<h2>インストール</h2>
<p>
  <a href="http://www.springsource.org/roo" target="_blank">Roo</a> は以下のサイトからダウンロードできます。
</p>
<blockquote class="note"><a href="http://www.springsource.org/download" target="_blank">http://www.springsource.org/download</a></blockquote>
<p>
  <a href="http://www.springsource.org/roo" target="_blank">Roo</a> の動作環境は以下のとおりです。
</p>
<ul>
  <li><a href="http://maven.apache.org/" target="_blank">Apache Maven</a> 2.0.9 以降</li>
  <li>Java 5 (1.5) 以降</li>
  <li><a href="http://www.eclipse.org/ajdt/" target="_blank">AspectJ Development Tools (AJDT)</a> 1.6.5 以降</li>
  <li>(オプション) <a href="http://www.eclipse.org/" target="_blank">Eclipse</a></li>
  <li>(オプション) <a href="http://www.springsource.com/products/sts" target="_blank">SprintSource Tool Suite (STS)</a> 2.1.0.M1 以降</li>
  <li>(オプション) <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a></li>
</ul>
<p>
  それでは、アーカイブに含まれている readme.txt を参考に <a href="http://www.springsource.org/roo" target="_blank">Roo</a> をインストールしましょう。最初に、Java, <a href="http://maven.apache.org/" target="_blank">Apache Maven</a> をインストールします。
</p>
<pre class="prettyprint lang-sh">sudo aptitude install sun-java6-jdk
sudo aptitude install maven2</pre>
<p>
  次に <a href="http://www.springsource.org/roo" target="_blank">Roo</a> を展開し、コマンドラインシェルへのシンボリックリンクを作成します。
</p>
<pre class="prettyprint lang-sh">unzip spring-roo-1.0.0.M1.zip
sudo ln -s /path/to/roo/bin/roo.sh /usr/bin/roo</pre>
<p>
  続いて、<a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a> をインストールします。<a href="http://www.ubuntulinux.jp/" target="_blank">Ubuntu</a> のパッケージ管理システムからインストールを行うと、設定ファイルと実行ファイルが異なるディレクトリに保存されるため Web Standard Tools が <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a> を認識できず、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> から起動することができません。この問題に対処するために今回は <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat のサイト</a> からダウンロードしたものを使うことにしました。
</p>
<pre class="prettyprint lang-sh">unzip apache-tomcat-6.0.20.zip</pre>
<p>
  次に、開発環境として <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> をインストールします。
</p>
<blockquote class="note"><strong>ノート</strong>: <a href="http://www.springsource.org/roo" target="_blank">Roo</a> はいかなる開発環境にも依存していません。</blockquote>
<p>
  まず、<a href="http://www.eclipse.org/" target="_blank">Eclipse のサイト</a> から Eclipse IDE for Java EE Developers をダウンロードします。次に、以下の更新サイトを利用して AspectJ Development Tools (AJDT) のすべてのフィーチャをインストールします。
</p>
<pre class="prettyprint">http://download.eclipse.org/tools/ajdt/34/dev/update</pre>
<p>
  最後に、<a href="http://www.eclipse.org/" target="_blank">Eclipse</a> のクラスパス変数に <a href="http://maven.apache.org/" target="_blank">Apache Maven</a> のリポジトリのパスを登録します。
</p>
<table>
  <thead>
    <tr>
      <th>Name</th><th>Path</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>M2_REPO</td><td>/path/to/.m2/repository</td>
    </tr>
  </tbody>
</table>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/roo-m2-repo-387.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/roo-m2-repo-387.html','popup','width=751,height=861,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/roo-m2-repo-thumb-500x573-387.png" width="500" height="573" alt="roo-m2-repo.png" class="mt-image-none" style="" /></a></span>
<p>
  以上でインストールは完了です。
</p>

<h2>Roo を使ってみる</h2>
<p>
  では <a href="http://www.springsource.org/roo" target="_blank">Roo</a> を使ってみましょう。readme.txt では clinic.roo スクリプトを使用した例が示されていますが、筆者が試したところいくつかの JSP ファイルが作成されず上手く動作しなかったため、今回は vote.roo スクリプトを使用することにします。
</p>
<p>
  まず、プロジェクトのディレクトリを作成し、<a href="http://www.springsource.org/roo" target="_blank">Roo</a> のコマンドラインシェルを起動します。
</p>
<pre class="prettyprint lang-sh">mkdir vote
cd vote
roo</pre>
<p>bash, zsh などの Unix シェルと同じく、コマンドラインで <strong>タブ</strong> (<strong>TAB</strong>) を押すことで利用可能なコマンドの一覧が表示されます。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/roo-shell-391.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/roo-shell-391.html','popup','width=671,height=413,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/roo-shell-thumb-500x307-391.png" width="500" height="307" alt="roo-shell.png" class="mt-image-none" style="" /></a></span>
<p>
  次に、vote.roo スクリプトを実行し、プロジェクトを作成します。
</p>
<pre class="prettyprint lang-sh">script vote.roo
exit</pre>
<p>
  vote.roo スクリプトの内容を見ると、<a href="http://www.springsource.org/roo" target="_blank">Roo</a> の各種コマンドによってプロジェクトおよびドメインモデル Choice, Vote の作成が行われていることがわかります。
</p>
<h6>spring-roo-1.0.0.M1/samples/vote.roo</h6>
<pre class="prettyprint">create project -topLevelPackage com.springsource.vote

install jpa -provider HIBERNATE -database HYPERSONIC_PERSISTENT

new persistent class jpa -name ~.domain.Choice -testAutomatically
add field string namingChoice -notNull -sizeMin 1 -sizeMax 30
add field string description -sizeMax 80
new controller automatic ~.web.ChoiceController

new persistent class jpa -name Vote -testAutomatically
add field reference jpa choice -type Choice
add field string ip -notNull -sizeMin 7 -sizeMax 15 
add field date jpa registered -type java.util.Date -notNull -past
new controller automatic ~.web.VoteController

new controller manual ~.web.PublicVoteController

configure logging -level DEBUG -package WEB

install security

list finders for -class com.springsource.vote.domain.Vote -depth 2 -filter reg,betw,IpEq</pre>
<p>
  これらのコマンドではディレクトリやファイルが指定されていません。このことは、ディレクトリやファイルが <a href="http://www.springsource.org/roo" target="_blank">Roo</a> によって決定されていることを示唆しています。これは <a href="http://www.springsource.org/roo" target="_blank">Roo</a> によるベストプラクティスの提供方法のひとつといえるでしょう。
</p>
<p>
  次に、作成されたプロジェクトを、<a href="http://maven.apache.org/" target="_blank">Apache Maven</a> を使用して <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> のプロジェクトに変換します。
</p>
<pre class="prettyprint lang-sh">mvn eclipse:eclipse</pre>
<p>
  それでは <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> でプロジェクトをインポートしてみましょう。
</p>
<img src="http://iteman.jp/blog/images/roo-vote-project.png" alt="roo-vote-project.png" class="mt-image-none" style="" />
<p>
  vote.roo スクリプトに記述されているドメインモデル Choice, Vote が作成されています。
</p>
<p>
   <a href="http://www.springsource.org/roo" target="_blank">Roo</a> はプロジェクト作成時にドメインモデルのユニットテストも作成します。プロジェクトを右クリックして、<strong>[Run As...] -> [JUnit Test]</strong> をクリックするとテストを実行することができます。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/roo-junit-390.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/roo-junit-390.html','popup','width=1020,height=473,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/roo-junit-thumb-500x231-390.png" width="500" height="231" alt="roo-junit.png" class="mt-image-none" style="" /></a></span>
<p>
  最後に、<a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a> を起動して vote アプリケーションを実行してみましょう。
</p>
<p>
  プロジェクトを右クリックして、<strong>[Run As...] -> [Run on Server]</strong> をクリックし、<strong>Tomcat v6.0 Server</strong> を起動します。
</p>
<p>
  <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a> が正常に起動したことを確認し、http://localhost:8080/vote/ へアクセスして動作確認を行います。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/roo-vote-web-399.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/roo-vote-web-399.html','popup','width=1020,height=421,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/roo-vote-web-thumb-500x206-399.png" width="500" height="206" alt="roo-vote-web.png" class="mt-image-none" style="" /></a></span>

<h2>Roo によるモデル変更の反映</h2>
<p>
  ここで <a href="http://www.springsource.org/roo" target="_blank">Roo</a> の最大の特徴であるモデル変更の反映について見てみましょう。今回はドメインモデル Choice に投票者の年齢を表す age プロパティを追加することにします。
</p>
<p>
  まず、vote ディレクトリで <a href="http://www.springsource.org/roo" target="_blank">Roo</a> を起動しておきます。
</p>
<pre class="prettyprint lang-sh">cd /path/to/vote
roo</pre>
<p>
  次に、age プロパティを追加します。このとき <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> に依存しないことを確認するため、テキストエディタを使用しましょう。
</p>
<h6>src/main/java/com/springsource/vote/domain/Choice.java</h6>
<pre class="prettyprint lang-java">--- a/src/main/java/com/springsource/vote/domain/Choice.java 2009-06-24 22:07:46.000000000 +0900
+++ b/src/main/java/com/springsource/vote/domain/Choice.java    2009-06-24 21:57:13.000000000 +0900
@@ -19,4 +19,7 @@
 
     @Size(max = 80)
     private String description;
+
+    @NotNull
+    private Integer age;
 }</pre>
<p>
  Choice.java を保存した時点で、<a href="http://www.springsource.org/roo" target="_blank">Roo</a> は変更を検知し、関連するファイルを自動的に変更します。このように <a href="http://www.springsource.org/roo" target="_blank">Roo</a> のモデル変更の反映は <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> やテキストエディタなどの環境に依存していないことがおわかりいただけるでしょう。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/roo-detection-402.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/roo-detection-402.html','popup','width=671,height=413,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/roo-detection-thumb-500x307-402.png" width="500" height="307" alt="roo-detection.png" class="mt-image-none" style="" /></a></span>
<p>
  再び、<a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a> を起動して、http://localhost:8080/vote へアクセスし、<strong>Create New Choice</strong> リンクをクリックすると、新たに追加した age プロパティが Web ページに反映されていることが確認できます。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/roo-add-age-405.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/roo-add-age-405.html','popup','width=980,height=507,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/roo-add-age-thumb-500x258-405.png" width="500" height="258" alt="roo-add-age.png" class="mt-image-none" style="" /></a></span>

<h2>おわりに</h2>
<p>
  <a href="http://www.springsource.org/roo" target="_blank">Roo</a> を評価した当初、筆者はこのソフトウェアをコード生成ツールとして認識しましたが、それは誤りでした。
</p>
<p>
  確かに <a href="http://www.springsource.org/roo" target="_blank">Roo</a> のコード生成部分だけをみれば、<a href="http://rubyonrails.org/" target="_blank">Rails</a> のジェネレータと大きな違いはありません。しかし、今回ご覧いただいたように、<a href="http://www.springsource.org/roo" target="_blank">Roo</a> はユーザが行った変更を検知し、関連するモデル (ここでは .aj および .jsp のファイル) を自動的に変更します。
</p>
<p>
  この機能は <a href="http://www.springsource.org/roo" target="_blank">Roo</a> を単なるコード生成ツールではなく、アプリケーション開発のあらゆる段階で活用できる基盤ツールにしているといえるでしょう。
</p>
<blockquote class="note">あるモデルの変更を自動的に他のモデルに反映する仕組みは <a href="http://martinfowler.com/" target="_blank">Martin Fowler</a> 氏による記事「<a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?LanguageWorkbench" target="_blank">言語ワークベンチ</a>」でも言及されています。</blockquote>
<p>
  このような「コード生成後も面倒をみるツール」には技術的な課題もありますが、筆者が考える最大の課題は「ユーザに受け入れられるかどうか」という点です。
</p>
<p>
  自分が知らない間に勝手にコードが変更されることに嫌悪感を持つ方もおられるでしょう。特に IDE を使う機会が少ない LL (Lightweight Language) のユーザには、そのように感じられる方が多いのではないでしょうか。
</p>
<p>
  「コード生成後も面倒をみるツール」としては <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> の <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> があり、これは徐々に受け入れられつつあります。<a href="http://www.springsource.org/roo" target="_blank">Roo</a> がどのようにユーザに受け入れられるか、非常に興味深いところです。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th><a href="http://www.springsource.org/roo" target="_blank">Spring Roo</a></th><td>1.0.0.M1</td>
    </tr>
    <tr>
      <th><a href="http://maven.apache.org/" target="_blank">Apache Maven</a></th><td>2.0.9</td>
    </tr>
    <tr>
      <th>Java</th><td>1.6.0_13</td>
    </tr>
    <tr>
      <th><a href="http://www.eclipse.org/ajdt/" target="_blank">AspectJ Development Tools (AJDT)</th><td>2.0.0</td>
    </tr>
    <tr>
      <th><a href="http://www.eclipse.org/" target="_blank">Eclipse</a> (Eclipse IDE for Java EE Developers)</th><td>3.4.2</td>
    </tr>
    <tr>
      <th><a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a></th><td>6.0.20</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://www.springsource.org/roo" target="_blank">Welcome to Spring Roo!</a></li>
  <li><a href="http://blog.springsource.com/2009/05/01/roo-part-1/" target="_blank">Jump into Roo for extreme Java productivity</a></li>
  <li><a href="http://blog.springsource.com/2009/05/27/roo-part-2/" target="_blank">Getting Started with Spring Roo</a></li>
  <li><a href="http://blog.springsource.com/2009/06/18/roo-part-3/" target="_blank">Exploring Roo's Architecture</a></li>
  <li><a href="http://www.infoq.com/jp/news/2009/06/spring-roo-1.0-m1-release" target="_blank">Spring Roo 1.0M1 リリース</a></li>
</ul>]]>
    </content>
  </entry>

  <entry>
    <title>Net_UserAgent_Mobile 1.0.0 (stable) をリリースしました</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/06/net-useragent-mobile-100-stabl.html" />
    <id>tag:iteman.jp,2009:/blog//3.74</id>

    <published>2009-06-24T21:52:22Z</published>
    <updated>2009-07-16T13:11:58Z</updated>

    <summary>2003 年 2 月 19 日 の 0.1 リリースから 6 年、2009 年 6 月 23 日に Net_UserAgent_Mobile 1.0.0 をリリースしました。これは Net_UserAgent_Mobile の初めての stable (安定版) リリースとなります。...</summary>
    <author>
      <name>KUBO Atsuhiro</name>
      <uri>http://twitter.com/iteman</uri>
    </author>
    
    <category term="net_useragent_mobile" label="Net_UserAgent_Mobile" scheme="http://www.sixapart.com/ns/types#tag" /><category term="pear" label="PEAR" scheme="http://www.sixapart.com/ns/types#tag" /><category term="php" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  2003 年 2 月 19 日 の 0.1 リリースから 6 年、2009 年 6 月 23 日に <a href="http://pear.php.net/package/Net_UserAgent_Mobile/download/1.0.0" target="_blank">Net_UserAgent_Mobile 1.0.0</a> をリリースしました。これは <a href="http://pear.php.net/package/Net_UserAgent_Mobile" target="_blank">Net_UserAgent_Mobile</a> の初めての stable (安定版) リリースとなります。
</p>]]>
      <![CDATA[<h2>stable (安定版) リリース</h2>
<p>
  パッケージに付与されたバージョン番号や stability (安定性) が実際のパッケージの信頼性をそのまま表現していない場合があります。つまり、世の中には stability が beta であっても安定しているパッケージが存在します。そういう意味では <a href="http://pear.php.net/package/Net_UserAgent_Mobile" target="_blank">Net_UserAgent_Mobile</a> はベータリリースの間も stable な (安定した) パッケージであったといえるでしょう。
</p>
<p>
  とはいえ、<strong>pear</strong> コマンドによるパッケージインストールの際に <strong>-beta</strong> を付け忘れると (おなじみの！) エラーが発生する、ということがなくなったのは開発者にとって利点といえるでしょう。自分で作成したパッケージであるにも関わらず、不注意により筆者自身もこのエラーを何度も見てきました。(筆者は新大阪有数の <strong>pear</strong> パッケージインストールのプロフェッショナルです！)
</p>
<h6>-beta を付け忘れた時のエラー発生の様子</h6>
<pre class="prettyprint lang-sh">$ pear install net_useragent_mobile
Failed to download pear/net_useragent_mobile within preferred state "stable", latest release is version x.x.x, stability "beta", use "channel://pear.php.net/net_useragent_mobile-x.x.x" to install
install failed</pre>
<p>
  加えて、<a href="http://pear.php.net/package/Net_UserAgent_Mobile" target="_blank">Net_UserAgent_Mobile</a> を使いたいと思っているが、stable じゃないためにインストールが禁止されているような環境にいらっしゃる方 (そんな環境があれば不幸なことです) は、これで堂々とインストールを行うことができるようになります。
</p>

<h2>docomo の新機種のサポート</h2>
<p>
  今回のリリースでサポートされた docomo の新機種は下記のとおりです。
</p>
<ol>
  <li>P-10A</li>
  <li>P-08A</li>
  <li>P-09A</li>
  <li>N-09A</li>
  <li>F-08A</li>
  <li>F-09A</li>
  <li>SH-05A</li>
  <li>SH-06A</li>
  <li>SH-07A</li>
</ol>
<p>
  また、<a href="http://pear.php.net/package/Net_UserAgent_Mobile/download/1.0.0RC3" target="_blank">Net_UserAgent_Mobile 1.0.0RC3</a> でサポート済みの i-mode ブラウザ 2.0 搭載機種 (P-07A, N-06A, N-08A ) に対して行われた User-Agent 文字列変更にも対応しています。(例: P07A => P07A3)
</p>

<h2>1.0.0 の不具合修正リリースについて</h2>
<p>
  すでに 1.0.0 以後のリリースを <a href="http://openpear.org/" target="_blank">openpear</a> から行うことを表明していますが、プロジェクト運営環境の準備が整うまでの間に不具合修正が発生した場合は、従来通り <a href="http://pear.php.net/" target="_blank">PEAR</a> からリリースを行う予定です。
</p>

<h2>おわりに</h2>
<p>
  最後になりましたが、<a href="http://pear.php.net/package/Net_UserAgent_Mobile" target="_blank">Net_UserAgent_Mobile</a> のユーザの皆様、<a href="http://pear.php.net/" target="_blank">PEAR</a> コミュニティ、そして <a href="http://pear.php.net/package/Net_UserAgent_Mobile" target="_blank">Net_UserAgent_Mobile</a> の元となった Perl モジュール <a href="http://search.cpan.org/dist/HTTP-MobileAgent/" target="_blank">HTTP::MobileAgent</a> とその作者 <a href="http://bulknews.vox.com/" target="_blank">Tatsuhiko Miyagawa</a> 氏に感謝いたします。
</p>]]>
    </content>
  </entry>

  <entry>
    <title>まっつんチャレンジ 4: Ruby on Rails によるポテトバーガー注文アプリケーションの実装 第 5 回 (最終回)</title>
    <link rel="alternate" type="text/html" href="http://iteman.jp/blog/2009/06/-4-ruby-on-rails-5.html" />
    <id>tag:iteman.jp,2009:/blog//3.72</id>

    <published>2009-06-23T18:41:56Z</published>
    <updated>2009-07-16T13:15:41Z</updated>

    <summary>こんにちは。まっつんです。これまでの記事 では、ポテトバーガー注文アプリケーションを題材にした RESTful な Web アプリケーションを Ruby on Rails (以下、Rails) で実装しました。 ポテトバーガー注文アプリケーションが RESTful であれば、サーバの実装を変更することなくクライアントの実装が行えるはずです。このことを確認するために今回は JavaScript によるクライアントを実装したいと思います。...</summary>
    <author>
      <name>MATSUFUJI Hideharu</name>
      <uri>http://twitter.com/matsu_hide</uri>
    </author>
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" /><category term="rest" label="REST" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ruby" label="Ruby" scheme="http://www.sixapart.com/ns/types#tag" /><category term="rubyonrails" label="Ruby on Rails" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ" label="まっつんチャレンジ" scheme="http://www.sixapart.com/ns/types#tag" /><category term="まっつんチャレンジ4" label="まっつんチャレンジ 4" scheme="http://www.sixapart.com/ns/types#tag" /><category term="ポテトバーガー注文アプリケーション" label="ポテトバーガー注文アプリケーション" scheme="http://www.sixapart.com/ns/types#tag" /><category term="マイクロフォーマット" label="マイクロフォーマット" scheme="http://www.sixapart.com/ns/types#tag" />
    <content type="html" xml:lang="ja" xml:base="http://iteman.jp/blog/">
      <![CDATA[<p>
  こんにちは。まっつんです。<a href="http://mt.iteman.jp/mt-search.cgi?blog_id=3&tag=%E3%81%BE%E3%81%A3%E3%81%A4%E3%82%93%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%204&limit=20&IncludeBlogs=3" target="_blank">これまでの記事</a> では、ポテトバーガー注文アプリケーションを題材にした RESTful な Web アプリケーションを <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> (以下、Rails) で実装しました。
</p>
<p>
  ポテトバーガー注文アプリケーションが RESTful であれば、サーバの実装を変更することなくクライアントの実装が行えるはずです。このことを確認するために今回は JavaScript によるクライアントを実装したいと思います。
</p>]]>
      <![CDATA[<h2>JavaScript クライアントの設計</h2>
<p>
  まず、実装するクライアントの仕様を考えます。1 から実装するのは大変なので、基本的にユーザインタフェースはこれまでに実装したものを流用し、最後の確認を JavaScript の confirm 関数で行うことにします。具体的な仕様は以下のとおりです。
</p>
<ul>
  <li>ユーザインタフェースはポテトバーガー注文アプリケーションの HTML を流用する</li>
  <li>確認は JavaScript の confirm 関数を使用する</li>
  <li>各メニューの表現として <a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> を使用する</li>
  <li>JavaScript のライブラリとして <a href="http://jquery.com/" target="_blank">jQuery</a> を使用する</li>
</ul>
<p>
  ファイル構成は以下のとおりです。
</p>
<table>
  <thead>
    <tr>
      <th>ファイル</th><th>説明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>public/order.html</td><td>ユーザインタフェースとなる HTML ファイル</td>
    </tr>
    <tr>
      <td>public/javascripts/jquery/jquery-1.3.2.js</td><td>JavaScript のライブラリ</td>
    </tr>
    <tr>
      <td>public/javascripts/jquery/jquery.order.js</td><td>ポテトバーガー注文アプリケーションと Ajax による通信を行う <a href="http://jquery.com/" target="_blank">jQuery</a> プラグイン</td>
    </tr>
    <tr>
      <td>public/javascripts/jquery/jquery.hproduct.js</td><td><a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> <a href="http://microformats.org/wiki/hproduct" target="_blank">hProduct</a> を操作するための <a href="http://jquery.com/" target="_blank">jQuery</a> プラグイン</td>
    </tr>
  </tbody>
</table>

<h2>マイクロフォーマット</h2>
<p>
  これまでに実装したビューにはメニューの ID や名称に対して明確なマークアップがなされておらず、このままではクライアントからの操作は困難です。この問題を解決するために <a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> を使うことができます。
</p>
<p>
  <a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> とは人が読んで理解できる情報にマークアップを付加する手段です。<a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> を使用することにより、ドキュメントに埋め込まれたデータに対するソフトウェアからの操作がより簡単になります。
</p>
<p>
  カレンダーや住所など扱う情報の種類毎に <a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> の仕様が策定されています。今回はメインメニューとサイドメニューの商品を表現するために、製品情報用の <a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> である <a href="http://microformats.org/wiki/hproduct" target="_blank">hProduct</a> を採用することにします。
</p>
<p>
  それでは <a href="http://microformats.org/wiki/hproduct" target="_blank">hProduct</a> に従って、メインメニュー、サイドメニュー、確認ページのテンプレートを変更しましょう。
</p>
<h6>app/views/orders/main_menu.html.erb</h6>
<pre class="prettyprint lang-html">&lt;span id=&quot;content&quot;&gt;
  &lt;h3&gt;ご注文は何になさいますか？&lt;/h3&gt;
  &lt;%= error_messages_for :order %&gt;
  &lt;ul class=&quot;hlisting&quot;&gt;
    &lt;li class=&quot;hproduct&quot;&gt;
      &lt;div class=&quot;fn&quot; style=&quot;display: none&quot;&gt;ジャーマンポテトバーガー&lt;/div&gt;
      &lt;div class=&quot;price&quot; style=&quot;display: none&quot;&gt;650&lt;/div&gt;
      &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
        &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;value&quot;&gt;1&lt;/span&gt;
      &lt;/div&gt;
      &lt;%= link_to 'ジャーマンポテトバーガー (650円)', &quot;#{orders_path}/order/side_menu?main=1&quot;, :class =&gt; 'url' %&gt;
    &lt;/li&gt;
    &lt;li class=&quot;hproduct&quot;&gt;
      &lt;div class=&quot;fn&quot; style=&quot;display: none&quot;&gt;ポテトコロッケバーガー&lt;/div&gt;
      &lt;div class=&quot;price&quot; style=&quot;display: none&quot;&gt;600&lt;/div&gt;
      &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
        &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;value&quot;&gt;2&lt;/span&gt;
      &lt;/div&gt;
      &lt;%= link_to 'ポテトコロッケバーガー (600円)', &quot;#{orders_path}/order/side_menu?main=2&quot;, :class =&gt; 'url' %&gt;
    &lt;/li&gt;
    &lt;li class=&quot;hproduct&quot;&gt;
      &lt;div class=&quot;fn&quot; style=&quot;display: none&quot;&gt;肉じゃがバーガー&lt;/div&gt;
      &lt;div class=&quot;price&quot; style=&quot;display: none&quot;&gt;700&lt;/div&gt;
      &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
        &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;value&quot;&gt;3&lt;/span&gt;
      &lt;/div&gt;
      &lt;%= link_to '肉じゃがバーガー (700円)', &quot;#{orders_path}/order/side_menu?main=3&quot;, :class =&gt; 'url' %&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/span&gt;</pre>
<h6>app/views/orders/side_menu.html.erb</h6>
<pre class="prettyprint lang-html">&lt;span id=&quot;content&quot;&gt;
  &lt;h3&gt;サイドメニューは何になさいますか？&lt;/h3&gt;
  &lt;%= error_messages_for :order %&gt;
  &lt;ul class=&quot;hlisting&quot;&gt;
    &lt;li class=&quot;hproduct&quot;&gt;
      &lt;div class=&quot;fn&quot; style=&quot;display: none&quot;&gt;フライドポテト&lt;/div&gt;
      &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
        &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;value&quot;&gt;1&lt;/span&gt;
      &lt;/div&gt;
      &lt;%= link_to 'フライドポテト', &quot;#{orders_path}/order/confirmation?main=#{@order.main}&amp;side=1&quot;, :class =&gt; 'url' %&gt;
    &lt;/li&gt;
    &lt;li class=&quot;hproduct&quot;&gt;
      &lt;div class=&quot;fn&quot; style=&quot;display: none&quot;&gt;ポテトサラダ&lt;/div&gt;
      &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
        &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;value&quot;&gt;2&lt;/span&gt;
      &lt;/div&gt;
      &lt;%= link_to 'ポテトサラダ', &quot;#{orders_path}/order/confirmation?main=#{@order.main}&amp;side=2&quot;, :class =&gt; 'url' %&gt;
    &lt;/li&gt;
    &lt;li class=&quot;hproduct&quot;&gt;
      &lt;div class=&quot;fn&quot; style=&quot;display: none&quot;&gt;スイートポテト&lt;/div&gt;
      &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
        &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;value&quot;&gt;3&lt;/span&gt;
      &lt;/div&gt;
      &lt;%= link_to 'スイートポテト', &quot;#{orders_path}/order/confirmation?main=#{@order.main}&amp;side=3&quot;, :class =&gt; 'url' %&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/span&gt;</pre>
<h6>app/views/orders/confirmation.html.erb</h6>
<pre class="prettyprint lang-html">&lt;h3&gt;注文内容は以上で宜しいですか？&lt;/h3&gt;
&lt;ul class=&quot;hlisting&quot;&gt;
  &lt;li id=&quot;main&quot; class=&quot;hproduct&quot;&gt;
    &lt;div class=&quot;fn&quot;&gt;&lt;%=h @main %&gt;&lt;/div&gt;
    &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
      &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
      &lt;span class=&quot;value&quot;&gt;&lt;%=h @order.main %&gt;&lt;/span&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li id=&quot;side&quot; class=&quot;hproduct&quot;&gt;
    &lt;div class=&quot;fn&quot;&gt;&lt;%=h @side %&gt;&lt;/div&gt;
    &lt;div class=&quot;identifier&quot; style=&quot;display: none&quot;&gt;
      &lt;span class=&quot;type&quot;&gt;model&lt;/span&gt;
      &lt;span class=&quot;value&quot;&gt;&lt;%=h @order.side %&gt;&lt;/span&gt;
    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;小計： &lt;%=h @price %&gt;円&lt;/div&gt;

&lt;% form_for(@order) do |f| %&gt;
  &lt;%= f.hidden_field :main %&gt;
  &lt;%= f.hidden_field :side %&gt;
  &lt;%= link_to_function 'OK', &quot;document.forms[0].submit()&quot; %&gt; 
  &lt;%= link_to '選びなおす', &quot;#{orders_path}/order/main_menu&quot; %&gt;
&lt;% end %&gt;</pre>
<p>
  各 HTML 要素に追加された class 属性によって商品の名称や価格が定義されているのがおわかりいただけると思います。これらのテンプレートに加えられた変更はポテトバーガー注文アプリケーションのビューに何ら影響を与えていないことに注意してください。
</p>

<h2>クライアントの実装</h2>
<p>
  続いて、クライアントを実装しましょう。今回は <strong>public/order.html</strong> に直接実装を行うことにします。
</p>
<h6>public/order.html</h6>
<pre class="prettyprint lang-html">&lt;!DOCTYPE html &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;/&gt;
  &lt;title&gt;ポテトバーガー注文アプリケーション&lt;/title&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;javascripts/jquery/jquery-1.3.2.js&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;javascripts/jquery/jquery.order.js&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;javascripts/jquery/jquery.hproduct.js&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot;&gt;

$(document).ready(function() {
  $.ajaxSetup({
    error: function(xhr) {
      if (xhr.status != '400') {
        alert('予期しないエラーが発生しました');
      }
      show(xhr.responseText);
    }
  });

  $.getMainMenu({
    url: '/orders/order/main_menu',
    success: show
  });
});

function show(html) {
  $('#content').remove();
  $(html).appendTo('body');

  $('.hlisting .hproduct .url').each(function() {
    $(this).click(selectMenu);
  });

  $('a').each(function() {
    $(this).click(function() {
      if (this.href.match(/.+main_menu/)) {
        location.reload();
        return false;
      }
    });
  });
}

function selectMenu() {
  if (this.href.match(/.+side_menu.+/)) {
    $.getSideMenu({
      url: this.href,
      success: show
    });
  } else if (this.href.match(/.+confirmation.+/)) {
    $.isValid({
      url: this.href,
      success: confirmOrder
    });
  }

  return false;
}

function confirmOrder(html) {
  if (confirm(&quot;注文内容は以上で宜しいですか？\n&quot; +
              &quot;メインメニュー : &quot; + $(html).find('#main').getProductName() + &quot;\n&quot; +
              &quot;サイドメニュー : &quot; + $(html).find('#side').getProductName()
              )) {
    $.order({
      authenticityToken: $(html).getAuthenticityToken(),
      main: $(html).find('#main').getProductId(),
      side: $(html).find('#side').getProductId(),
      success: show
    });
  }
}

  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>
  Ajax による通信や <a href="http://microformats.org/wiki/hproduct" target="_blank">hProduct</a> で表現された情報にアクセスする部分は <a href="http://jquery.com/" target="_blank">jQuery</a> のプラグインとして実装しているため、order.html にはページで実行されるコードのみを配置しています。
</p>
<p>
  最初に order.html がロードされると <strong>$(document).ready</strong> が実行されます。ここで Ajax 通信のエラー処理を設定し、メインメニューを取得しています。
</p>
<p>
  <strong>show</strong> 関数はそれぞれのビューを正常に取得できた時に実行されます。取得した HTML を表示し、各商品のリンクがクリックされたときに実行されるイベントをフックします。今回はユーザインタフェースを流用しているので、このような処理を行っていますが、クライアントを 1 から実装する場合には独自のリンクやボタンを用意することになるでしょう。
</p>
<p>
  <strong>selectMenu</strong> 関数はメインメニュー、サイドメニューが選択されたときに実行される関数です。リンクの URI から次に行う処理を判断しています。
</p>
<p>
  <strong>confirmOrder</strong> 関数は confirm 関数による最終確認と注文のリクエストを送信しています。
</p>
<p>
  次に <a href="http://jquery.com/" target="_blank">jQuery</a> を使ったサーバとの通信部分を見てみましょう。この部分は <a href="http://jquery.com/" target="_blank">jQuery</a> のプラグインとして実装しています。
</p>
<h6>public/javascripts/jquery/jquery.order.js</h6>
<pre class="prettyprint lang-js">getHTML = function(config) {
  config = $.extend({
    url: null,
    success: null
  }, config);

  $.ajax({
    url: config.url,
    type: 'GET',
    dataType: 'html',
    success: config.success
  });
}

jQuery.extend({
  getMainMenu: getHTML,
  getSideMenu: getHTML,
  isValid: getHTML,
  order: function(config) {
    config = $.extend({
      authenticityToken: null,
      main: null,
      side: null,
      success: null
    }, config);

    $.ajax({
      url: '/orders',
      type: 'POST',
      data: {
        'authenticity_token' : config.authenticityToken,
        'order[main]': config.main,
        'order[side]': config.side
      },
      dataType: 'html',
      success: config.success
    });
  }
});

jQuery.fn.extend({
  getAuthenticityToken: function() {
    var authenticityToken;
    $(this).find('input').each(function() {
      if (this.name == 'authenticity_token') {
        authenticityToken = this.value;
        return false;
      }
    });
    return authenticityToken;
  }
});</pre>
<p>
  <strong>getMainMenu</strong>, <strong>getSideMenu</strong>, <strong>isValid</strong> メソッドはすべて <strong>getHTML</strong> 関数を呼び出しています。order.html から <strong>getHTML</strong> を直接呼び出しても動作しますが、「何を取得しているのか」という意図を明確にするためにあえてメソッドを用意しました。
</p>
<p>
  最後に <a href="http://microformats.org/wiki/hproduct" target="_blank">hProduct</a> で表現された情報へアクセスする部分を見てみましょう。この部分も <a href="http://jquery.com/" target="_blank">jQuery</a> のプラグインとして実装しています。これらのメソッドは自身を起点に製品の ID または名称をそれぞれ取得します。
</p>
<h6>public/javascripts/jquery/jquery.hproduct.js</h6>
<pre class="prettyprint lang-js">jQuery.fn.extend({
  getProductId: function() {
    return $(this).find('.identifier').find('.value').text();
  },
  getProductName: function() {
    return $(this).find('.fn').text();
  }
});</pre>
<p>
  以上で実装は完了です。http://localhost:3000/order.html にアクセスして、正常に動作することを確認しましょう。また、http://localhost:3000/orders/order/main_menu にアクセスして、これまでの実装も変わりなく動作することも確認しましょう。
</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/rails5-confirmation-381.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/rails5-confirmation-381.html','popup','width=652,height=400,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/rails5-confirmation-thumb-500x306-381.png" width="500" height="306" alt="rails5-confirmation.png" class="mt-image-none" style="" /></a></span>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://iteman.jp/blog/assets_c/2009/06/rails5-main-menu-384.html" onclick="window.open('http://iteman.jp/blog/assets_c/2009/06/rails5-main-menu-384.html','popup','width=655,height=404,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://iteman.jp/blog/assets_c/2009/06/rails5-main-menu-thumb-500x308-384.png" width="500" height="308" alt="rails5-main-menu.png" class="mt-image-none" style="" /></a></span>

<h2>Rails の CSRF 対策</h2>
<p>
  <a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA" target="_blank">CSRF</a> (Cross Site Request Forgeries) は、正規のアカウントを保持するユーザに、仕掛けを埋め込んだ Web ページを閲覧させ、掲示板の書き込みやショッピングサイトでの購入といったユーザが意図しない処理を実行させる攻撃手法です。<a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA" target="_blank">CSRF</a> に対して、<a href="http://rubyonrails.org/" target="_blank">Rails</a> はどのような対策を行っているのでしょうか？
</p>
<p>
  <a href="http://rubyonrails.org/" target="_blank">Rails</a> のドキュメント「<a href="http://guides.rubyonrails.org/security.html" target="_blank">Ruby On Rails Security Guide</a>」の「<a href="http://guides.rubyonrails.org/security.html#csrf-countermeasures" target="_blank">3.1 CSRF Countermeasures</a>」の最初の一文には <a href="http://www.w3.org/" target="_blank">W3C</a> が提案する <a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA" target="_blank">CSRF</a> 対策が書かれています。
</p>
<blockquote>-- First, as is required by the W3C, use GET and POST appropriately. Secondly, a security token in non-GET requests will protect your application from CSRF.</blockquote>
<p>
  これによると、HTTP メソッドの適切に利用し、GET (情報の取得) 以外の処理ではセキュリティトークン (ワンタイムトークン) を利用することが推奨されています。
</p>
<p>
  HTTP メソッドの適切な利用については REST アーキテクチャスタイルに従って実装することで対応できるため、ここではセキュリティトークン (ワンタイムトークン) について考えてみたいと思います。
</p>
<p>
  <a href="http://rubyonrails.org/" target="_blank">Rails</a> は、自動的にセキュリティトークン (ワンタイムトークン) の発行・処理を行います。以下は確認ページのテンプレートのフォームと実際にブラウザで表示されたフォームです。
</p>
<h6>app/views/orders/confirmation.html.erb</h6>
<pre class="prettyprint lang-rb">...
&lt;% form_for(@order) do |f| %&gt;
  &lt;%= f.hidden_field :main %&gt;
  &lt;%= f.hidden_field :side %&gt;
  &lt;%= link_to_function 'OK', &quot;document.forms[0].submit()&quot; %&gt; 
  &lt;%= link_to '選びなおす', &quot;#{orders_path}/order/main_menu&quot; %&gt;
&lt;% end %&gt;</pre>
<h6>ブラウザで表示されたフォーム</h6>
<pre class="prettyprint lang-html">...
&lt;form method=&quot;post&quot; id=&quot;new_order&quot; class=&quot;new_order&quot; action=&quot;/orders&quot;&gt;
  &lt;div style=&quot;margin: 0pt; padding: 0pt;&quot;&gt;
    &lt;input type=&quot;hidden&quot; value=&quot;ppxvv0wTBg0UZXerjs0nm30yeLmMuhObFhbHZImiGMI=&quot; name=&quot;authenticity_token&quot;/&gt;
  &lt;/div&gt;
  &lt;input type=&quot;hidden&quot; value=&quot;2&quot; name=&quot;order[main]&quot; id=&quot;order_main&quot;/&gt;
  &lt;input type=&quot;hidden&quot; value=&quot;3&quot; name=&quot;order[side]&quot; id=&quot;order_side&quot;/&gt;
  &lt;a onclick=&quot;document.forms[0].submit(); return false;&quot; href=&quot;#&quot;&gt;OK&lt;/a&gt; 
  &lt;a href=&quot;/orders/order/main_menu&quot;&gt;選びなおす&lt;/a&gt;
&lt;/form&gt;
...
</pre>
<p>
  <strong>authenticity_token</strong> フィールドがランダムな値で自動的に生成されていることがわかります。他のフィールドといっしょにこの値が POST されなければ、<a href="http://rubyonrails.org/" target="_blank">Rails</a> は以下のエラーを出力します。
</p>
<pre class="prettyprint">ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):</pre>
<p>
  <a href="http://ja.wikipedia.org/wiki/REST" target="_blank">REST</a> の観点から見た場合、このような対策は問題ないでしょうか？
</p>
<p>
  セキュリティトークン (ワンタイムトークン) は複数のリクエストにまたがって管理されなければならないためステートレスな振る舞いとはいえません。<a href="http://rubyonrails.org/" target="_blank">Rails</a> はこの点について、セッションをクッキーに保存することで折り合いを付けているように思えます。リクエストごとにクッキーに保存されたセッションが送信されるため、各リクエストは独立している、つまりステートレスであるというわけです。
</p>
<p>
  セッションの保存先を ActiveRecord にした場合はこの理屈は通らなくなりますが、<a href="http://rubyonrails.org/" target="_blank">Rails</a> のソリューションは <a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA" target="_blank">CSRF</a> 対策と <a href="http://ja.wikipedia.org/wiki/REST" target="_blank">REST</a> との間で適切なものだと思います。
</p>

<h2>Rails を使ってみて</h2>
<p>
  今回はポテトバーガー注文アプリケーションのクライアントを JavaScript で実装しました。ユーザインタフェースを流用したため、テンプレートは変更しましたが、コントローラやモデルは一切変更する必要がありませんでした。従って、ポテトバーガー注文アプリケーションは RESTful な Web アプリケーションとして実装できたのではないかと思います。
</p>
<p>
  最後に <a href="http://rubyonrails.org/" target="_blank">Rails</a> に対する筆者の感想をまとめます。
</p>
<h3>わかりやすい規約</h3>
<p>
  Convention Over Configuration (CoC) による規約は違和感のない非常にわかりやすいものでした。始めて使うフレームワークなので、どういったメソッドを使えば良いかという点ではいろいろ悩みましたが、意図が断絶していてわかりにくい部分はありませんでした。
</p>
<h3>データベースマイグレーションは便利</h3>
<p>
  アプリケーションの開発・運用においてデータベースの変更は避けては通れません。データベースに対して行った履歴を保存することができ、変更をロールバックできるこの機能はプロジェクトに従事する者に心強い味方になるでしょう。
</p>
<h3>Scaffolding は便利</h3>
<p>
  初学者にとって Scaffolding は非常に便利な機能でした。Scaffolding が作成するコードは実際に動作するリファレンスとしても価値があると思います。
</p>
<h3>「設計の可視化」という観点がない</h3>
<p>
  「設計の可視化」は主に IDE がカバーする領域ですが、フレームワーク側にこれを意識した実装があることが前提となります。<a href="http://rubyonrails.org/" target="_blank">Rails</a> の IDE としては <a href="http://www.aptana.com/rails/" target="_blank">RadRails</a> が有名ですが、残念ながら <a href="http://rubyonrails.org/" target="_blank">Rails</a> にも <a href="http://www.aptana.com/rails/" target="_blank">RadRails</a> にも「設計の可視化」には重点がおかれていないようです。
</p>
<p>
  今回で <a href="http://rubyonrails.org/" target="_blank">Rails</a> のチャレンジは終了です。<a href="http://rubyonrails.org/" target="_blank">Rails</a> を中心に <a href="http://ja.wikipedia.org/wiki/REST" target="_blank">REST</a> や <a href="http://microformats.org/" target="_blank">マイクロフォーマット</a> などさまざまな技術を見ることができ、今までのチャレンジの中で一番濃い内容になったのではないかと思います。
</p>

<h2>使用したソフトウェアのバージョン</h2>
<table>
  <tbody>
    <tr>
      <th>Ruby on Rails</th><td>2.3.2</td>
    </tr>
    <tr>
      <th>jQuery</th><td>1.3.2</td>
    </tr>
  </tbody>
</table>

<h2>参考文献</h2>
<ul>
  <li><a href="http://guides.rubyonrails.org/security.html" target="_blank">Ruby On Rails Security Guide</a></li>
  <li><a href="http://microformats.org/wiki/introduction-ja" target="_blank">Microformatsの手引き</a></li>
  <li><a href="http://microformats.org/wiki/hproduct" target="_blank">hProduct · Microformats Wiki</a></li>
  <li><a href="http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA" target="_blank">クロスサイトリクエストフォージェリ</a></li>
</ul>]]>
    </content>
  </entry>

</feed>
