Tapestry
Tapestryとは
以下の方針で開発されている。
- 再利用性を向上する。
- 古臭い単純なコーディング作業を減らす。
- アプリケーションの複雑さを隠す。
- 国際化対応を簡単に。
- アプリケーションを堅牢に。
- 統合を簡単に。
特徴
- コンポーネント指向
- イベントドリブン
- ページデザインとロジックを完全に分離することができる。
- ロジックの開発が進んでも、様々なHTMLエディタでレイアウトを編集することができる。
- ロジックの開発が進んでも、様々なブラウザでレイアウトを崩さずに表示することができる。
Spindle
ここではSpindleを利用していないので、適当に検索してください。
さいしょのいっぽ(Quic Start)。TapestryでHelloWorld
階層

図1:HelloWorldプログラムの階層
各ファイルの概要
WEB-INF/lib/ – ライブラリファイル
WEB-INF/Home.html – 表示するHTMLファイル
WEB-INF/Home.page – Home.htmlに対する定義ファイル
WEB-INF/MyTapestryProject.application – アプリケーションの情報定義ファイル
WEB-INF/web.xml – 例のアレ。
各ファイルの内容
Home.html
<span jwcid="$content$"> Hello Tapestry World! </span>
<span jwcid="$content$">〜</span>ブロック内のコンテンツが実行時にサーバーによって解析、表示される。このブロック以外の部分はクライアントに送信されないが、利用方法はいろいろありそう。
Home.page
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<page-specification class="org.apache.tapestry.html.BasePage">
<description><![CDATA[ tapestry sample program ]]></description>
</page-specification>
.pageファイルには、テンプレート(htmlファイル)に対する設定情報を記述する。description要素にはこのファイルの説明文を定義する。
MyTapestryProject.application
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<application name="MyTapestryProject" engine-class="org.apache.tapestry.engine.BaseEngine" >
<description><![CDATA[ tapestry sample program ]]></description>
<page name="Home" specification-path="Home.page"/>
</application>
.applicationファイルに、プロジェクトに対する設定を記述する。description要素にはこのファイルの説明文を定義する。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Tapestryサンプルプログラム</display-name>
<filter>
<filter-name>redirect</filter-name>
<filter-class>org.apache.tapestry.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>redirect</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>MyTapestryProject</servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyTapestryProject</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
</web-app>
web.xmlにTapestryのApplicationServletを定義する。
実行結果
Hello Tapestry World!
成功。
ビュー層からロジック層へデータを渡す。
表記
ここでは以下のような表現で統一する。
ビュー:MVCのV。具体的にTapestryのHTMLを表す。
ロジック:Javaプログラムを指す。
概要
HTMLで入力された値をロジック層で受け取る動作を行うプログラムを作成する。

図3:デザイン層からロジック層へデータを渡す。
階層

図3:プレゼンテーション層ロジック層連携プログラムの階層
src/sample/Home.java – 入力値を受け取るためのクラス
WEB-INF/lib/ – ライブラリファイル
WEB-INF/Home.html – 表示するHTMLファイル
WEB-INF/Home.page – Home.htmlに対する定義ファイル
WEB-INF/MyTapestryProject.application – アプリケーションの情報定義ファイル
WEB-INF/web.xml – いつものアレ。
各ファイルの内容
Home.java
package sample;
import org.apache.tapestry.html.BasePage;
public class Home extends BasePage{
private String name = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void print(){
System.out.println(this.name);
}
}
画面と対応するコンポーネント。プロパティーとそれに対するアクセサメソッドを定義する。
Home.html
<span jwcid="$content$">
<form jwcid="@Form" listener="ognl:listeners.print">
<input jwcid="name" type="text"/>
<input type="submit"></input>
</form>
</span>
この定義により、画面にはテキストボックスとSubmitボタンが表示される。
フォームを利用する際には、<form jwcid="@Form" />を利用することができる。
属性listenerには、OGNL(Object-Graph Navigation Language)を利用したリスナー定義が記述されている。
Home.page
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<page-specification class="sample.Home">
<description><![CDATA[ tapestry sample program ]]></description>
<component id="name" type="TextField">
<binding name="value" expression="name"/>
</component>
</page-specification>
コンポーネントの指定を記述。利用するクラスに加えて、ビューに対応するプロパティのマッピング情報を記述する。
MyTapestryProject.application
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<application name="MyTapestryProject" engine-class="org.apache.tapestry.engine.BaseEngine" >
<description><![CDATA[ tapestry sample program ]]></description>
<page name="Home" specification-path="Home.page"/>
</application>
アプリケーションの情報を記述。画面がひとつしかないので、HelloWorldと同じ。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Tapestryサンプルプログラム</display-name>
<filter>
<filter-name>redirect</filter-name>
<filter-class>org.apache.tapestry.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>redirect</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>MyTapestryProject</servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyTapestryProject</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
</web-app>
web.xmlにTapestryのApplicationServletを定義。HelloWorldと同じ。
フォームに文字列を入力してSubmitボタンを押下すると、値の設定・printメソッドの実行が順に行われ、入力した値がコンソールに表示される。

図4:実行結果
メソッド呼び出し
Home.java
package sample;
import org.apache.tapestry.html.BasePage;
public class Home extends BasePage{
private String name = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
プロパティとアクセサを持っている。
Home.page
<page-specification class="sample.Home">
<component id="getName" type="Insert">
<binding name="value" expression="getName()"/>
</component>
</page-specification>
Conponent定義にInsertを指定して、expressionにメソッドを指定する。上記の場合、sample.HomeクラスのgetName()メソッドを実行する。
Home.html
<span jwcid="$content$"> <form jwcid="@Form" listener="ognl:listeners.print"> <input jwcid="name" type="text"/> <input type="submit"></input> </form> your name is <span jwcid="getName">NAME</span>. </span>
これがTapestryのスゴイところ。HTMLをTapestryの実行エンジン上ではなく、ブラウザで表示した場合でもレイアウトが崩れない。(your name is NAME.と表示される)
実行すると、テキストボックスに入力された値が画面に表示される。

図5:メソッド呼び出し実行結果
Visitの利用
階層

図5:Visit利用プログラムの階層
src/sample/Home.java – BasePage継承クラス
src/visit/PageViewCount.java – アクセス数を保持するvisitクラス
WEB-INF/Home.html – 表示HTML
WEB-INF/Home.page – ページ仕様
WEB-INF/MyTapestrySample.application – アプリケーション仕様
WEB-INF/web.xml – J2EEのアレ
各ファイルの内容
Home.java
package sample;
import org.apache.tapestry.html.BasePage;
import visit.PageViewCount;
public class Home extends BasePage{
public int getCount(){
PageViewCount visit = (PageViewCount)getVisit();
return visit.getCount();
}
}
PageViewCount.java
package visit;
import java.io.Serializable;
public class PageViewCount implements Serializable{
private int count;
public int getCount(){
this.count = this.count + 1;
return count;
}
}
Home.html
<span jwcid="$content$">
<span jwcid="getCount">10</span>.
</span>
Home.page
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<page-specification class="sample.Home">
<component id="getCount" type="Insert">
<binding name="value" expression="getCount()"/>
</component>
</page-specification>
MyTapestrySample.application
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application
PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<application name="MyTapestryProject" engine-class="org.apache.tapestry.engine.BaseEngine" >
<property name="org.apache.tapestry.visit-class">visit.PageViewCount</property>
<page name="Home" specification-path="Home.page"/>
</application>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>MyTapestryProject</display-name>
<filter>
<filter-name>redirect</filter-name>
<filter-class>org.apache.tapestry.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>redirect</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>MyTapestryProject</servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyTapestryProject</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
</web-app>
web.xmlにTapestryのApplicationServletを定義。HelloWorldと同じ。
ページにアクセスするたびに、画面に表示されるカウントが1ずつUPする。セッションが保持されているかぎり、値も保持される。

