Tapestryとは?

Tapestryは動的で堅牢でとてもスケーラブルなWebアプリケーションを開発するためのJavaオープンソースフレームワークです。 Tapestryは Java Servlet API 上に構築されているため、各種サーブレットコンテナやアプリケーションサーバで動作します。 また、Java Servlet API の補完もします。

Tapestryを用いたWebアプリケーションは複数のページから成り、それぞれのページはコンポーネントによって構成されます。これにより一貫した構造がもたらされ、 URLの解釈やディスパッチ、クライアントサイドまたはサーバサイドにおける永続データの保存、ユーザ入力のバリデーション、ローカライズ/国際化、例外レポートといった 問題をTapestryフレームワークに任せることが可能となります。 Tapestryアプリケーションの開発では、普通のHTMLを用いたテンプレートの作成と、そのテンプレートを少量のJavaコードと結びつける作業を行います。 URLやクエリーパラメータという考え方ではなく、オブジェクトとそのメソッドやプロパティという面から開発します。 Tapestryは真のオブジェクト指向をJavaによるWebアプリケーション開発にもたらします。

アプリケーションを構築する際に独自コンポーネントが必要になることはよくあることなので、 Tapestryは容易に独自コンポーネントを作成できるように配慮した設計となっています。

Tapestryは小さな単一ページのアプリケーションから、大きく多様なチームによって開発された数百ページから成る大規模アプリケーションまで、 さまざまな規模のものに対応できるよう設計されています。Tapestryは、JEEやHiveMind、Spring、Hibernateといった各種バックエンドと 容易に統合できます。

あなたはTapestryを使って多くのことをすることが できます ... それはつまり、あなたが どのように するかということです! Tapstryはとても生産的な環境です。 再デプロイやリスタート無しに Javaコード の変更が即座に反映されるため、TapestryはJava開発者に好まれています。 その上(ファイルの変更があったときでさえ)とても速く動作するのです。Tapestryのテンプレートは普通のHTMLとほとんど変わらず、 JSPにあったようなcruft[TODO:cruft? craft?]や混乱が無いためデザイナにも好まれます。 大きなチームの協調した開発が容易であり、(ローカライズ等の)重要な特徴のためマネージャにも好まれています。 一度Tapestryを使ったらもう戻ることはできません!

Tapestryは Apache Software Licence 2.0 に従ってリリースされています。

サードパーティーライブラリ、チュートリアル、リソース

新型のコンポーネントを提供するライブラリ、他のフレームワークとのより良い統合のためのライブラリなど、多くの人々が Tapestry 5 用のサードパーティーライブラリを開発しています。

NameAuthorDescription
AppFuse for Tapestry 5Serge Eby基本的な認証機能を備え、HibernateとSpringが統合されたアプリケーションテンプレート
equanda-tapestry5Joachim Van der Auweraエンタープライズアプリケーションを構築するのに役立つコンポーネント。Accordion, Tabs, Formtraversal などがあります。これらはマウス無しでも簡単にデータを入力できることに焦点を当てています。
Godcode ComponentsChris Lewisシンプルでかつ時間を節約できる実用的なコンポーネント一式。そして、prototypeとscript.aculo.usをベースにしたよりエキゾチックなコンポーネントもあります。
JumpStartGeoff CallenderTapestryアプリケーションの "生きたチュートリアル" で、これを元にして拡張したりカスタマイズしたりできます。
InterLDAPLinagora / Francois Armand非技術者向けのLDAP管理システム
loom-t5Chris ScheidEclipseプラグイン
Shams Examples, ComponentsMohammad H. ShamsiTapestry 5 初心者向けのサンプル、チュートリアル、コンポーネント及びドキュメント
Tapestry for NonbelieversRenat Zubairov & Igor DrobiazkoTapestryの使い方とコンポーネントの作り方の簡潔な紹介
T5ComponentsSven HomburgPrototypeとScriptaculousベースのAjaxコンポーネント
tacos-seamIgor DrobiazkoJBoss Seamとの統合
tapestry5-acegiRobin HelgelinAcegiセキュリティフレームワークとの統合
tapestry5-treegridGabriel Landaissstreeをベースにした、ツリーナビゲーションとデータグリッドの組み合わせ

New And Of Note

  • LinkSubmit コンポーネントがついに公式なコンポーネントとなりました。
  • インジェクションの詳細なガイドを追加しました。
  • <script>リンクをページの先頭に移す設定ができるようになりました。
  • Ajaxによるリクエストのイベントハンドラメソッドは、戻り値にページ名やページクラス、ページのインスタンスを返すことで、 そのページへブラウザをリダイレクトさせることができるようになりました。
  • InjectアノテーションとInjectServiceアノテーションが、サービスの実装やIoCコンテナによって生成されるその他のオブジェクトのフィールドに対して使えるようになりました。 これまで、インジェクションはメソッドかコンストラクタのパラメータ経由でのみ可能でした。
  • Tapestry に組み込まれている Prototype のバージョンが 1.6.0.2 になりました。
  • Node に、ノードの移動等の操作を行うメソッドを追加しました。
  • Application State Object は、リクエストの終了時に自動的にセッションに書き戻されるようになりました。 これにより、ASOはクラスタ間で適切に複製されるようになります。
  • @Local アノテーションが新たに追加されました。同じモジュール内のサービスをインジェクトするのがより簡単になります。
  • 多くのドキュメントをtapestry-coreモジュールからプロジェクトの最上位に移動しました。
  • Tapestry Cookbook の作業を開始しました。これは、よくあるシナリオにどのように取り組めばよいかを示します。
  • コンポーネントのメソッドに @Log アノテーションを与えることができるようになりました。 これにより、メソッドの入り口(パラメータを含む)と出口(戻り値や例外を含む)でのデバッグロギングができるようになります。
  • コンポーネントのメソッドに対してアドバイスを与えることができるようになりました。 これにより、Tapestryコンポーネントに対してとても強力なアスペクト指向プログラミングが可能となります。
  • 例外レポートページでTapestryのバージョンを表示するようになりました。 また、システムプロパティ(Javaのクラスパスを含む)の一覧を表示するようになりました。
  • Grid コンポーネントは、 ページングやソートのリンクをクリックした時にAjaxによって内容を更新できるようになりました。
  • Ajaxによる更新をサポートするために、BeanEditForm コンポーネントに zone パラメータを追加しました。
  • メソッドの結果をキャッシュするための@Cachedアノテーションを追加しました。

Tapestry 4 からの変更点は?

Tapestry 5 はJavaによるWebアプリケーション開発の生産性をより高くするために、 ゼロから書かれた全く新しいコードベースとなっています。

この新しいリリースでは Tapestry 4 にあった以下の制限が取り払われています:

  • コンポーネントはペースクラスから派生する必要がなくなりました。
  • コンポーネントを abstract クラスにする必要がなくなりました。 コンポーネントはただの単純なPOJO(plain old Java objects)です。
  • ページSpecificationやコンポーネントSpecificationのXMLファイルはもう必要ありません。 それらのファイルで指定していた情報はJavaアノテーションと命名規約を用いてJavaクラスに直接与えます。
  • コンポーネントテンプレート とクラス の変更は、どのようなリスタートも無しに 直ちに 反映されます。 これは開発中だけでなく 運用時 でさえも適切に働くでしょう。
  • とても速い。新しいコードベースは Tapestry 4 よりもかなり速く動作します。 重要なコード経路は単純化され、リフレクションを使用している箇所はほとんどなくなりました。 Tapestry 4 の速度は同等のServlet/JSPアプリケーションと同程度でしたが、Tapestry 5 は遥かに高速です。

適応型API

Tapestry 5の重要な特徴は 適応型のAPI です。

Tapestry 4も含め、従来のJavaフレームワークはユーザーコードがフレームワークに従うことを前提としています。 フレームワークが提供する基底クラスを拡張したり、フレームワークが提供するインターフェースを実装したりしてクラスを作成します。

あなたがフレームワークの次のリリースにアップグレードするまでは、これでうまくいきます: そのアップグレードの新しい特徴により、後方互換性が損なわれていることをあなたはしばしば経験するでしょう。 インターフェースや基底クラスが変更されると、あなたの既存コードもそれに合わせて修正する必要が生じます。

Tapestry 5では、フレームワークが あなたのコードに適応します。 あなたがメソッドの名前やパラメータや戻り値を支配することができます。 これは、どんな状況であなたのメソッドを実行するのかをTapestryに指示するアノテーションによって実現されます。

例えば、ログインフォームがあって、そのフォームがサブミットされたときに実行するメソッドがあるとします:

public class Login
{
  @Persist
  @Property
  private String userId;

  @Property
  private String password;

  @Component
  private Form form;

  @Inject
  private LoginAuthenticator authenticator;

  void onValidateForm()
  {
    if (! authenticator.isValidLogin(userId, password))
    {
      form.recordError("Invalid user name or password.");
    }
  }

  Object onSuccess()
  {
    return PostLogin.class;
  }

}

この短いコード断片は、Tapestryがどのように動作するのかの小さなデモです。 アプリケーション内のサービスが@Injectアノテーションによってインジェクトされています。 Tapestryは onValidateForm() や onSuccess() といったメソッド名によって、そのメソッドをいつ実行するかを識別します。 フォームをサブミットすると、validateFormsuccess というふたつのイベントが発生します; "validateForm" は複数のフィールドにまたがった入力検証を行うためのものです。 "success" は入力検証エラーが無い場合にだけ発生します。 onSuccess() メソッドの戻り値によってTapestryが次に行う動作が決まります: アプリケーションの他のページへジャンプします(ここではページのClassブジェクトで指示していますが、他に多くのオプションがあります)。 入力検証エラーがあった場合は同じページが再表示されます。 (訳注: 原文は When there are exceptions, the page will be redisplayed to the user. この exceptions は「例外」ではなく「入力検証エラー」の意味だろう)

これはまた、Tapestry 4との明確な違いを表しています。 以前のバージョンのTapestryは、Formコンポーネントのlistenerパラメータにメソッド名を指定してメソッドを結びつけていました。 さらに、リスナメソッドはパブリックである必要がありました。 この新しいアプローチは複数のリスナをサポートするだけでなく、 (ページのHTMLテンプレート内にある)ビューにおける関心事とJavaクラス内にあるロジックの関心事をよりうまく分離します。

多くの場合、メソッドにパラメータを追加することでイベントに関する追加の情報を利用できます。 繰り返しますが、あたたがどんな順番でパラメータを定義しようともTapestryはあなたのパラメータに適応するのです。

さらに、Tapestryはあなたの手間を省いてくれます: @Propertyアノテーションによってフィールドを読み出し可/書き込み可として指示することで、 Tapestryが自動的にアクセッサメソッドを提供してくれます。

最後に、Tapestry 5はアクション(何らかの変更を行うリクエスト)とレンダリング(ページを表示するリクエスト)をふたつのリクエストにはっきりと分けています。 リンクをクリックしたりフォームをサブミットするようなアクションの実行後、新しいページへの クライアントサイドリダイレクト を発生させます。 これはしばしば、"Redirect After Post" と呼ばれます。これは、ブラウザに表示されるURL(訳者注:Post直後のURL)がブックマーク可能であることを保証するのに役立ちます ... しかし、(@Persistアノテーションを使って)少しだけ多くの情報をリクエストを跨いでセッションに格納する必要が生じます。

スナップショットとリリースについて

TapestryはMavenを用いてビルドするので、 プロジェクト全体であれひとつのモジュールだけであれソースコードをダウンロードし自分自身でビルドするのはとても簡単です。

もっといいのは、Mavenの中央リポジトリからTapestryモジュールを取り寄せることです。

Mavenを使う事で私たちはプレビューリリースと スナップショット を素早く提供する事ができます。

スナップショットはリリース間の 中間的なバージョン です。これを書いている時点では、最新のプレビューリリースは 5.0.2 でスナップショットは 5.0.3-SNAPSHOT です。 -SNAPSHOTサフィックスは、Mavenの依存関係処理において特別な扱いを受けます。 スナップショットは頻繁に更新されるため、(最低でも1日に1回、おそらくはもっと多く)更新されたバージョンがあるかどうかの確認が行われるでしょう。

Tapestryの継続的統合サーバ上のナイトリービルドでは毎晩、新しいスナップショットを生成しています。

スナップショットはMavenの中央リポジトリに保存される事はありません(中央リポジトリはリリース用のため)。 そのかわり、http://tapestry.formos.com/maven-snapshot-repository のTapestryスナップショットリポジトリに保存されます。

このリポジトリにアクセスするには、Mavenのコマンドラインに -DremoteRepositories=http://tapestry.formos.com/maven-snapshot-repository を加える必要があります。

最も良い方法は、Tapestryプロジェクトの作成に quickstart Maven archetype を使う事です。 これにより、プロジェクトの全ディレクトリが作成されるとともにApacheスナップショットリポジトリへリンクしたPOMも作成されます。

このサイトのドキュメントは通常、最新のスナップショットについて言及しています。つまり、通常は最新のリリースよりも先行しているということです。 時にはスナップショットだけの情報が記載されることもあります。5.0.xのドキュメントに書かれている内容で動作しないことがある場合、5.0.x-SNAPSHOTを試してみてください。

原則 1 -- 静的な構造、動的な振る舞い

Tapestryは様々な面においてとてもスケーラブルになるように設計されています:

  • Tapestryアプリケーションは多数のページと多数のカスタムコンポーネントを含むかもしれません。
  • Tapestryアプリケーションはとても複雑な機能を含むかもしれません。
  • Tapestryアプリケーションは大きく多様なチームによって作成されるかもしれません。
  • Tapestryアプリケーションは同時に多数のユーザーにサービスを提供することができます。

Tapestryコアアーキテクチャのひとつは、上の目標(そして、より説明しにくい他のもの)の多くに役立つということで決定されました。 静的な構造、動的な振る舞いです。

Tapestryではどのページの構造も 静的 です。これには様々な理由がありますが、最も重要なのはTapestryのページは プール されるということです。 ページオブジェクトは他のオブジェクトの大きなツリーのルートに過ぎず、そのツリーにはコンポーネントや様々な構造上のオブジェクト、 テンプートオブジェクト、その他のオブジェクトが含まれているため、Tapestryのページを生成するプロセスは複雑です。 リクエスト毎にページのインスタンスを生成するのは、まったく スケーラブル ではありません。

そのかわり、Tapestryはページを プール します。 一度ページのインスタンスが生成されれば、そのページ用のプールに格納され次のリクエストで再利用されます。 リンクのクリックやフォームのサブミットで発生したリクエストはクラスタ内の いずれかの サーバで処理され、 ページプール内の いずれかの ページインスタンスが使用されるでしょう。 ページインスタンスが静的であれば各サーバのどのインスタンスも同じものとなるため、 Tapestryはどのページインスタンスでも使用することができ、あるいは必要であれば新しいインスタンスを生成することもできます。

TapestryはページインスタンスをHttpSessionに格納する必要が無いのです。 ページインスタンス全体でなく少量の 永続フィールドの値 を格納します。 HttpSessionをあまり使用しないということが、Tapestryの非常に高いスケーラビリティの、特にクラスタ構成での鍵となっています。

TapestryライクなフレームワークのうちFacesやWicketのようないくつかは、 ページ構造がより動的でより大きなコストでより多くのデータをHttpSessionに格納しています。

静的な構造よる制限をあなたは想像するかもしれませんがそのような制限はありません。 条件分岐やループのコンポーネント、「フローを飛び出て」任意の順序でレンダリングすることのできるコンポーネントによって、 Tapestryが融通の利かないものではない...それどころではない! とわかるでしょう。

Public vs. Internal

旧バージョンの Tapestry 4 (とそれ以前)のやっかいな問題のひとつは、プライベートな内部APIとパブリックな外部APIの間の輪郭が不明瞭であったことです。 ベースクラスを継承してはいても、そのベースクラスのメソッドの多くは「立ち入り禁止」であった事がよりいっそう問題を混乱させていました。 これは「Tapestryには学習曲線に障壁がある」と認識される主要因と考えられました。

新たに出直した Tapestry 5 では、内側と外側の区別はとてもはっきりとしています。

まず、org.apache.tapestry5.internal パッケージ内は 内側 です。 そこはTapestryの実装部分です。カーテンの向こうにいる従業員です。 あなたは直接このコードを使用する必要はないはずです。 内部コードは後方互換性を考慮せずに 次のリリースで変更される かもしれないので、内部コードを直接使用するのは 悪い考え です。

後方互換性

Tapestryはメジャーリリース毎に後方互換性の問題に悩まされてきました。 Tapestry 5 は Tapestry 4 に対して後方互換であることを試みてさえいません。 そのかわり、将来における真の後方互換性のために基礎を敷いています。

Tapestry 5 のAPIはそのほとんどが命名規約と アノテーション に基づいています。 コンポーネントは普通のJavaクラスに過ぎず、フィールドアノテーションによりその値の維持やインジェクションの指示をTapestryに与え、 またどういう状況でメソッドが呼び出されるかをメソッド名(またはアノテーション)でTapestryに伝えます。

Tapestryがあなたのクラスに順応するのです。融通の利かない据え付けのインターフェースを実装する代わりに、 メソッドパラメータによって値を渡し、あなたのメソッドを呼ぶでしょう。 アノテーションとシンプルな命名規約によって与えられるヒントによって、Tapestryがあなたのクラスに合わせてくれるのです。

これにより、あなた が書いたどんなアプリケーションコードにも影響を与えることなくTapestryの大きな内部変更をおこなう事が可能となります。 結局は後方互換性のナットにひびは入るだろうけれど、既存のアプリケーションを壊すことなくTapestryの将来のリリースにアップグレードできる大きな保証となります。