いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Tapestry奮闘記-0017 (独自コンポーネントの作成-01)

Tapestryでは、ユーザが独自のコンポーネントを作成できます。
作成した独自コンポーネントは、他のビルドインコンポーネント
同じく使用できるようになります。

コンポーネントの作成には、大きく分けて2種類の作成方法が
あります。

AbstractComponentを継承して作成するのと、BaseComponentを継承して
作成するのでは、以下の違いがあります。

  1. AbstractComponentの場合は、テンプレートを使用せず直接レンダリング
  2. BaseComponentの場合は、テンプレートを使用してレンダリング

今回は、AbstractComponentを使用した場合のサンプルを作成します。
(もっとも、ほんまに基本の部分しかわかってないのでサンプルもヘボイですが・・w)

独自コンポーネントを作成する場合、最低以下のものが必要になります。

  • 該当コンポーネントクラス
  • コンポーネント定義ファイル(jwcファイル)
  • ライブラリ定義ファイル(オプション。applicationファイルに直接定義することもできます.)

今回は、上記3つの全てを作成します。

まずは、該当コンポーネントクラス。
このコンポーネントは指定された値を単に大文字にするだけのものです。

[コンポーネントクラス]

// vim:set ts=4 sw=4 et ws is nowrap ft=java fenc=cp932 ff=dos:
package gsf.samples.tapestry.components;

import org.apache.tapestry.*;

/**
 * 指定された値を単に大文字に変換して出力するコンポーネント.<br/>
 *
 * <br/>
 *
 * AbstractComponentを継承して、コンポーネントを作成する場合は
 * テンプレートを用いず、renderComponentメソッド内で直接タグを
 * 含めたレンダリング処理を行います.<br/>
 * <br/>
 * <p>
 * この形式の場合に必要なファイルは、javaクラスとjwcファイルの
 * 2つとなります.<br/>
 * <br/>
 * </p>
 *
 * @author gsf_zero1
 *
 */
public abstract class UpperCaseInsert extends AbstractComponent{

    /**
     * 値を返す.<br/>
     *
     * @return 値
     *
     */
    public abstract Object getValue();

    /**
     * このコンポーネントレンダリングを行う.<br/>
     *
     * @param writer マークアップライターオブジェクト
     * @param cycle  リクエストサイクル
     *
     * @see org.apache.tapestry.AbstractComponent#renderComponent(IMarkupWriter, IRequestCycle)
     *
     */
    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle){

        writer.print(this.getValue().toString().toUpperCase(), false);

    }

}

つぎは、コンポーネント定義ファイル(jwc).

[コンポーネント定義ファイル]

<?xml version="1.0" encoding="Windows-31J"?>
<!-- vim:set ts=4 sw=4 et ws is nowrap ft=xml fenc=cp932 ff=dos: -->
<!DOCTYPE component-specification PUBLIC 
  "-//Apache Software Foundation//Tapestry Specification 4.0//EN" 
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">

<!--
    コンポーネント定義を行う設定ファイル.

    ルート要素はcomponent-specification.

    • >
<component-specification class="gsf.samples.tapestry.components.UpperCaseInsert" allow-body="false" allow-infomal-parameters="false"> <!-- パラメータ定義. このコンポーネントがpageファイルもしくは、htmlファイル内で 指定された際に、必要とするパラメータを記述する. required属性をtrueまたはyesに設定した場合、その属性は 必須となる. --> <parameter name="value" required="true"/> </component-specification>

次は、ライブラリ定義ファイル.(library)

[ライブラリ定義ファイル]

<?xml version="1.0" encoding="Windows-31J"?>
<!-- vim:set ts=4 sw=4 et ws is nowrap ft=xml fenc=cp932 ff=dos: -->
<!DOCTYPE library-specification
    PUBLIC "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
    "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">

<!--
    ライブラリ定義を行う設定ファイル.

    ルート要素は, library-specification.


    日本語が表示されるコンポーネントを作成している場合は

        <meta key="org.apache.tapestry.template-encoding" value="Windows-31J"/>

    を指定しておくこと。


    このファイル内で別のライブラリ定義を読み込むこともできる。(Include)

    例)
    <library id="contrib" specification-path="classpath:/org/apache/tapestry/contrib/Contrib.library"/>


    各コンポーネント定義は、component-type要素を用いて定義する。

    例)
    <component-type type="UpperCaseInsert"      specification-path="classpath:/gsf/samples/tapestry/components/UpperCaseInsert.jwc"/>

    • >
<library-specification> <!-- 使用するテンプレートのエンコーディングを指定. --> <meta key="org.apache.tapestry.template-encoding" value="Windows-31J"/> <!-- 別のライブラリファイルの読み込み. --> <library id="contrib" specification-path="classpath:/org/apache/tapestry/contrib/Contrib.library"/> <!-- 各コンポーネント定義. --> <component-type type="UpperCaseInsert" specification-path="classpath:/gsf/samples/tapestry/components/UpperCaseInsert.jwc"/> </library-specification>

ここまで、できたらコンポーネントの定義は終わりです。
最後にアプリケーションから今回定義したコンポーネントが呼べるように
ライブラリ定義ファイルをアプリケーション定義ファイルに定義します。

[アプリケーション定義ファイル]

    <!--
        カスタムコンポーネントの定義

        カスタムコンポーネントは、ここで指定したIDを接頭辞として指定すれば
        使用できるようになる。たとえば、Tapestryの追加コンポーネントである
        ControlledCheckboxを使用する場合は、以下のようになる。

            jwcid="@contrib:ControlledCheckbox"

    -->
    <library id="contrib" specification-path="classpath:/org/apache/tapestry/contrib/Contrib.library"/>
    <library id="my"      specification-path="classpath:/gsf/samples/tapestry/components/MyComponent.library"/>

以上で定義終了。今度からは、MyComponent.libraryに定義を追加していけば
アプリケーション内でmy接頭辞を使用してコンポーネントを使用できるようになります。

使用方法は、以下のような感じです。

                    <!--
                    
                        独自コンポーネントを使用する。
                        (UpperCaseInsertコンポーネントを使用。)

                    -->
                    <br/>
                    <hr/>
                    <div id="original_component_001" align="center">
                        <b>
                            独自コンポーネントを使用(1)<br/>
                            <br/>
                            UpperCaseInsertコンポーネントを使用。<br/>
                        </b>
                        <br/>
                        出力: <span jwcid="@my:UpperCaseInsert" value="hoge">aaaaaaa</span><br/>
                        <br/>
                    </div>
                    <hr/>
                    <br/>

UpperCaseInsertのコンポーネント定義において、allow-body属性をfalseにしている(タグのボディを許さない)
ので、実行した後のソースをみるとaaaaaaaaとなっている部分が削除されているのがわかります。