-Tapestryサービス(2)

サービスに対するURLもサービスで生成管理します。PageServiceは、IEngineService#getLink()を以下のように実装してします。

public ILink getLink(
    IRequestCycle cycle, IComponent component, Object parameters) {
  if (Tapestry.size(parameters) != 1)
    throw new IllegalArgumentException(
      Tapestry.format("service-single-parameter", Tapestry.PAGE_SERVICE));
  return constructLink(
    cycle, Tapestry.PAGE_SERVICE, new String {(String) parameters[0]}, null, true);
}

このgetLink()メソッドが返す、ILinkは、getURL()メソッドでString型のまさにURL表記文字列を返します。PageService#getLink()中で用いられている、constructLink()は、基底のAbstractServiceクラスにて定義されていて、ILinkの実装を返す機能を持っています。このメソッドの引数は、constructLink(IRequestCycle, String, String, Object, boolean)となっていて、第二引数にサービス名(ここでは「page」)、第三引数にサービスコンテキストを指定すると、望むURLが生成される仕組みです。
この、PageService#getLink()は、PageLinkコンポーネントから呼び出されます。すなわち、HTMLテンプレートに、以下のようなコードで定義します。

<a href="#" jwcid="@PageLink" page="SomePageName">click me</a>

この時、PageLinkコンポーネントレンダリング時に、org.apache.tapestry.link.PageLinkクラスからめぐりめぐってorg.apache.tapestry.link.AbstractLinkComponent#getLink()を呼び出されます。このメソッドの内容は以下のとおりです。

protected ILink getLink(
    IRequestCycle cycle, String serviceName, Object[] serviceParameters) {
  IEngineService service = cycle.getEngine().getService(serviceName);
  return service.getLink(cycle, this, serviceParameters);
}

必要なサービスをエンジンから取得して後に、サービスに実装されているgetLink()を呼んでILinkオブジェクトを生成しています。DirectService-DirectLink、ExternalService-ExternalLink、ActionService-ActionLinkもサービスの内容こそ異なりますが、リンクメカニズムは同様です。
Formはすこし複雑で、状況に応じてDirectServiceかActionServiceどちらかと連携しますが、やはりサービスの生成するURLを用いています。(つづく)