MessageオブジェクトをTapestryで表示する(その3)

では、その1で示したモデル図に従って、MessageComponentを内包したTestPageを作ってみたいと思います。

まずは、MessageComponentです。
このコンポーネントはMessageオブジェクトを一つもっている必要があります。

MessageComponent.javaTapestry

/**
 * メッセージを表示するコンポーネント
 * 
 * @author toolkit
 * @version $Revision$
 */
public abstract class MessageComponent extends BaseComponent {
	public abstract Message getMessage();
	public abstract void setMessage(Message message);
	public void resAction(IRequestCycle rc) {
		//TODO
	}
}

抽象クラスになっている事に注目して下さい。
実際にMessageComponentはMessageオブジェクトを持っていませんが、getterとsetterが用意されています。
バインドされるMessageオブジェクトはTapestryに管理させるやり方が正当です。
また、今回はまだ実装しませんが、返信機能としてresActionというメソッドを付け加えています。
「返信」のリンクがクリックされた時にこのメソッドが呼ばれる想定です。

WebObjectsならこうなるでしょう。

MessageComponent.java(WOF)

/**
 * メッセージを表示するコンポーネント
 * 
 * @author toolkit
 * @version $Revision$
 */
public class MessageComponent extends WOComponent {
	private Message message;
	
	public Message getMessage();
	public void setMessage(Message message);
	
	public WOComponent resAction() {
		//TODO
		return null;
	}

}

次に、HTMLを用意します。
こんなやつを作ってみしました。

MessageComponent.html

<table width="400" border="0" cellspacing="0" cellpadding="2">
	<tr>
		<td bgcolor="#999999">
			<table width="100%" border="0" cellspacing="0" cellpadding="4">
				<tr>
					<td bgcolor="#FFFFFF">
						<table width="100%" border="0" cellspacing="0" cellpadding="0">
							<tr valign="top">
								<td><span class="message">■</span> 
								<span jwcid="subject" class="subject">サブジェクト</span> / <span jwcid="userName" class="subject">ユーザ名</span> 
								<img src="images/mail.gif"/> <img src="images/home.gif"/></td>
								<td align="right" nowrap>
									<span jwcid="resActionLink">返信</span>
								</td>
							</tr>
						</table>
						<br>
						<table border="0" cellspacing="0" cellpadding="4">
							<tr>
								<td><span jwcid="content" class="message">ダミーのコメントずらずら </span></td>
							</tr>
						</table>
						<br>
						<div align="right">
							2004/09/01(Wed) 12:00</div>
					</td>
				</tr>
			</table>
		</td>
	</tr>
</table>

いたってシンプルなHTMLです。フォームの類いも普通に<input>タグなんかを使っています。
したがって、HTMLエディタでもちゃんと表示されます。
StrutsWebObjectsではそうはいきませんねー。)

ただし、Tapestryバインディングを認識するためにjwcidという属性が入っています。
このjwcidとJavaクラスを関連づけるファイルが.jwcになります。

MessageComponent.jwc

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE component-specification PUBLIC
  "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">

<component-specification class="bbs.view.MessageComponent"
    allow-body="no"
    allow-informal-parameters="yes">
    
	<!-- Message -->
	<parameter name="message" type="bbs.data.Message" direction="in" required="yes"/>
		
	<component id="subject" type="Insert">
		<binding name="value" expression="message.subject"/>
	</component>
	<component id="userName" type="Insert">
		<binding name="value" expression="message.userName"/>
	</component>
	<component id="mail" type="Insert">
		<binding name="value" expression="message.mail"/>
	</component>
	<component id="url" type="Insert">
		<binding name="value" expression="message.url"/>
	</component>
	<component id="content" type="InsertText">
		<binding name="value" expression="message.content"/>
	</component>
	<component id="resActionLink" type="ActionLink">
		<binding name="listener" expression="listeners.resAction"/>
		<binding name="stateful" expression="no"/>
	</component>
</component-specification>

htmlのjwcidがsubjectのところは、コンポーネントタイプがInsertで、MessageComponentの持っているMessageオブジェクトのgetSubjectメソッドを呼び出したものがvalueとなる・・・と言う事です。
Insertコンポーネントとは、Tapestryが標準で持っているコンポーネントで、このコンポーネントvalueに文字列をバインドすると、htmlにその文字を表示してくれると言うシンプルなものです。
WebObjectsでいうところのWOStringコンポーネントになります。
同様にjwcid="content"はInsertTextコンポーネントを使用しています。
このコンポーネントは改行コードが含まれいるテキストを表示する事が出来ます。つまり、<br>タグを自動挿入してくれます。

タグは、外部に公開されるバインドすべき値となります。属性のrequiredが"true"になっていますので、このコンポーネントを使う時は、必ずmessageにMessageオブジェクトをバインドさせなければなりません。

type="ActionLink"というコンポーネントも一番最後に定義されています。
これはWebObjectsで言う所のWOHyperLinkです。
listener要素にMessageComponentのresActionメソッドをバインディングします。
この場合、実装するresActionメソッドの引数にはIRequestCycleオブジェクトをとる必要があります。
WebObjectsならWOComponentを返し、引数なしのメソッドを実装しなければならないのと同じような決まりですね。