| ## Teeda Extensionにおけるカスタマイズの方法について このドキュメントではTeeda Extensionにおけるカスタマイズ方法について記述します． ビュールートパスのカスタマイズについて Validatorのカスタマイズについて Convererのカスタマイズについて コンポーネントのカスタマイズと新しい規約の導入について XHTMLのパーズについて リダイレクトについて outputTextについて ラベルについて JavaScriptについて ## ビュールートパスのカスタマイズについて Teedaでは動的なHTMLのURLは `<context>/view/aaa/bbb.html` のようになります． この `view` のことを「ビュールートパス」と呼びます． ビュールートパスを変更するには，`convention.dicon` で指定します． 例えばビュールートパスを `hoge` に変更する場合は次のようになります．
      <component class="org.seasar.framework.convention.impl.NamingConventionImpl">
        <property name="viewRootPath">"/hoge"</property>
        <initMethod name="addRootPackageName">
          <arg>"aaa"</arg>
        </initMethod>
      </component>
この場合，HTML を配置するディレクトリも標準の `src/main/webapp/view` から `src/main/webapp/hoge` に変更する必要があります． URL が `<context>/hoge/aaa/bbb.html` の場合，対応する HTML は `src/main/webapp/hoge/aaa/bbb.html` になります． Dolteng を使っている場合は，クラスパスに設定されている `src/main/webapp/view` を `src/main/webapp/hoge` に変更する必要があります． ビュールートパスを無くしたい場合は，`convention.dicon` で次のように指定します．
      <component class="org.seasar.framework.convention.impl.NamingConventionImpl">
        <property name="viewRootPath">"/"</property>
        <initMethod name="addRootPackageName">
          <arg>"aaa"</arg>
        </initMethod>
      </component>
この場合，HTML を配置するディレクトリも標準の `src/main/webapp/view` から `src/main/webapp` 直下に変更する必要があります． URL が `<context>/aaa/bbb.html` の場合，対応する HTML は `src/main/webapp/aaa/bbb.html` になります． Dolteng を使っている場合は，クラスパスに設定されている `src/main/webapp/view` を `src/main/webapp` に変更する必要があります． その際，ビルドパスの設定で `WEB-INF/` を `excluded` に指定してください． ## Validatorのカスタマイズについて TeedaではJSF共通のValidatorのほかにExtension共通のValidatorを準備しています． しかし、実案件ではカスタムでValidatorを作成しなくてはいけない場合があるはずです． このような場合でのカスタムValidatorの作り方を下記に示します． まずは手順を列挙します． 既存Validatorの調査 カスタムValidatorの作成 カスタムValidatorの登録 Tigerアノテーションの作成 Validatorの利用例 ### 1.既存Validatorの調査 まずは何はともあれ、既存Validatorに何があるか調べてみましょう． javax.faces.validator.*, org.seasar.teeda.extension.validator.*に Teedaで搭載しているValidatorはあります．（ドキュメントは少々お待ちください．） ### 2.カスタムValidatorの作成 カスタムのValidatorを作成します．まずは親クラス/インタフェースを決定します． 完全にオリジナルのValidatorを作成する場合は下記のような形になります．StateHolderインタフェースは Validatorが持っているプロパティを維持しなくてはいけないときに必要です．
    package examples.teeda.validator;

    //オリジナルValidatorの実装イメージ
    public class YourOriginalValidator implements Validator, StateHolder {

        public void validate(FacesContext context, UIComponent component,
                Object value) throws ValidatorException {
          //ここにValidtionロジックを記述
        }

        public Object saveState(FacesContext context) {
          //状態維持のためのロジック記述
        }

        public void restoreState(FacesContext context, Object state) {
          //状態復元のためのロジック記述
        }

    }
JSF標準またはTeedaのValidatorを拡張する場合、拡張もとのValidatorを継承して 作成します．例えば、TRequiredValidatorを継承して、MyRequiredValidatorを作成します．
    package examples.teeda.validator;

    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.validator.ValidatorException;

    import org.seasar.teeda.extension.validator.TRequiredValidator;

    public class MyRequiredValidator extends TRequiredValidator {

        public MyRequiredValidator() {
          setMessageId("your.required.validation.message.id");//実際にメッセージファイルで使用するメッセージIDを指定
        }

        public void validate(FacesContext context, UIComponent component,
          Object value) throws ValidatorException {
          //Validationロジックを記述
        }
    }
### 3.カスタムValidatorの登録 Validatorの登録はSMART deploy構成にしたがっているならば、特に必要ありません． 例えばTeeda-html-exampleでは、examples.teeda.validatorの下に、*Validatorのようなクラスです． それ以外の構成で作成する場合は、diconかまたはSeasarのAutoRegister機能を使ってValidatorを登録しなくてはいけません． Validatorのインスタンス属性はprototypeが望ましいです． ### 4.Tigerアノテーションの作成 TeedaではTigerアノテーションでValidatorを使うことが出来ます． その場合はValidatorのアノテーションを作成する必要があります． Validatorのアノテーションは、@ValidatorというTeedaのアノテーションを独自に付与する必要があります．(下記サンプルの[a]参照) @Validatorでは、登録するValidatorをコンポーネント名で登録します．
    package examples.teeda.annotation;

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    import org.seasar.teeda.extension.annotation.validator.Validator;

    @Retention(RetentionPolicy.RUNTIME)
    @Target( { ElementType.FIELD, ElementType.METHOD })
    @Validator("myRequiredValidator")//[a]Teeda独自の指定
    public @interface MyRequired {

        String target() default "";

        String messageId() default "";

    }
### 5.Validatorの利用例 JDK1.4/1.5でのValidatorの利用例を下記に示します． JDK1.4では定数アノテーションでの利用、JDK1.5ではTigerアノテーション(または定数アノテーション)で利用できます．
    //JDK1.4の場合
    public class HogePage {
      public static final String aaa_myRequiredValidator = null;
      private String aaa;
      //以下、getter/setter
    }
    //JDK1.5の場合
    public class HogePage {
      @MyRequired
      private String aaa;
      //以下、getter/setter
    }
## Converterのカスタマイズについて TODO：作成 ## コンポーネントのカスタマイズと新しい規約の導入について TODO：作成 ## XHTMLのパーズについて Teeda 1.0.12以降では，XHTMLテンプレートをパーズする方法をカスタマイズすることが出来ます．カスタマイズするには，以下のインタフェースを実装したクラスを使用します． `org.seasar.teeda.extension.html.impl.TeedaXMLReaderFactory` あらかじめ，4種類の実装クラスを用意しています． DEFAULT (デフォルト) CLASSIC STRICT カスタマイズしない場合はDEFAULTが使用されます． ### DEFAULT DEFAULTは，Teeda Extension標準の方法でXHTMLをパーズします．この方法はTeeda1.0.11以前とは異なります． テンプレートXHTMLの要素内容に記述した`&amp`;等の文字参照や実体参照は，そのままの状態でブラウザに出力されます． テンプレートXHTMLの属性中に記述した`&amp;`等の文字参照や実体参照は，そのままの状態でブラウザに出力されます． 属性中にURLを記述する場合，リクエストパラメータを区切る`&`はそのまま`&`として記述することが出来ます．ただし，正しくは`&amp;`と記述するべきです． Xerces2.6.2でXHTMLをパーズします．Xerces2.6.2を使用できない環境ではSTRICTを使用してください． ### CLASSIC CLASSICは，Teeda 1.0.11以前と互換性のある方法でXHTMLをパーズします． テンプレートXHTMLの要素内容に記述した`&amp`;等の文字参照や実体参照は，`&`等に置換された状態でブラウザに出力されます．このため，ブラウザに対して`&amp;`と出力したい場合，テンプレートXHTMLには`&amp;amp;`と一段階余計にエスケープして記述する必要があります． テンプレートXHTMLの属性中に記述した`&amp;`等の文字参照や実体参照は，そのままの状態でブラウザに出力されます． 属性中にURLを記述する場合，リクエストパラメータを区切る`&`はそのまま`&`として記述することが出来ます．ただし，正しくは`&amp;`と記述するべきです． Xerces2.6.2でXHTMLをパーズします．Xerces2.6.2を使用できない環境ではSTRICTを使用してください． ### STRICT STRICTは，厳密に正しいXMLとしてXHTMLをパーズします． テンプレートXHTMLの要素内容に記述した`&amp`;等の文字参照や実体参照は，そのままの状態でレンダリングされます． テンプレートXHTMLの属性中に記述した`&amp;`等の文字参照や数値参照は，そのままの状態でレンダリングされます． 属性中にURLを記述する場合，リクエストパラメータを区切る`&`は必ず`&amp;`として記述する必要があります．`&`を参照以外で使用するとテンプレートXHTMLのパーズはエラーとなります． XNI (Xerces Native Interface) をサポートした任意のバージョンのXercesでXHTMLをパーズします．Xerces2.6.2を使用することが出来ない環境でも利用することが出来ます． ### 各モードの要約
| 空要素 | 要素内容の`&amp;` | 属性中の`&amp;` | 属性中の`&`(非参照) | XMLパーザ
--- | --- | --- | --- | --- | ---
DEFAULT | `<br/>` | `&amp;` | `&amp;` | `&` | Xerces2.6.2
CLASSIC | `<br/>` | `&` | `&amp;` | `&` | Xerces2.6.2
STRICT | `<br/>` | `&amp;` | `&amp;` | エラー | XNIをサポートした任意の バージョンのXerces
### カスタマイズの方法 XHTMLをパーズする方法をカスタマイズするには，`teedaCustomize.dicon`に`TeedaXMLReaderFactory`の実装クラスを登録します．標準の実装クラスは`TeedaXMLReaderFactory`のネステッドクラスとして用意されているので，次のように記述します．
    <component class="org.seasar.teeda.extension.html.impl.TeedaXMLReaderFactory$CLASSIC"/>
## リダイレクトについて Teeda Extensionは，画面遷移にPRG (Post-Redirect-Get) パターンを使用します． リダイレクトする際のURLは，現在のリクエストのURLに基づいて，同じプロトコル・同じホスト・同じポート番号・同じコンテキストルートで組み立てられます． これをカスタマイズするには，以下のインタフェースを実装したクラスを使用します． `org.seasar.teeda.core.resolver.RedirectUrlResolver` Teedaでは，次の実装クラスを用意しています． `org.seasar.teeda.core.util.DefaultRedirectUrlResolverImpl` `org.seasar.teeda.extension.util.ExtensionRedirectUrlResolverImpl` デフォルトでは，`ExtensionRedirectUrlResolverImpl`が使われます．`teedaCustomize.dicon`に`RedirectUrlResolver`の実装クラスを定義することで，リダイレクトURLをカスタマイズすることが出来ます．`RedirectUrlResolver`の実装クラスを定義するdiconファイルは，teedaExtension.diconよりも先にインクルードされるdiconファイルに定義してください． ### ベースURL `DefaultRedirectUrlResolverImpl`および`ExtensionRedirectUrlResolverImpl`は，リダイレクトURLのベース部分をカスタマイズすることが出来ます． ベースURLは，web.xmlの`<context-param>`で定義することが出来ます．
    <context-param>
        <param-name>teeda.REDIRECT_URL</param-name>
        <param-value>https://127.0.0.1:8443/contest/</param-value>
    </context-param>
### キャッシュ対策 `ExtensionRedirectUrlResolverImpl`は，リダイレクト先のURLがブラウザにキャッシュされることを防ぐために，リクエストパラメータにユニークなパラメータを付加します． この機能は，`ExtensionRedirectUrlResolverImpl`の`addUniqueKeyParameter`プロパティに`false`を設定することで無効にすることが出来ます．
    <component class="org.seasar.teeda.extension.util.ExtensionRedirectUrlResolverImpl">
      <property name="addUniqueKeyParameter">false</property>
    </component>
デフォルトでは，パラメータ名は`te-uniquekey`が使われます．この名前は，`ExtensionRedirectUrlResolverImpl`の`uniqueKeyParameterName`プロパティに`false`を設定することで無効にすることが出来ます．
    <component class="org.seasar.teeda.extension.util.ExtensionRedirectUrlResolverImpl">
      <property name="uniqueKeyParameterName">"requestId"</property>
    </component>
## outputTextについて Teeda 1.0.13以降では，<span>要素の他，<div>および<caption>要素もidが付けられていて対応するプロパティがページクラスにあるか，"xxxLabel"であればoutputTextにマッピングされます． Teeda 1.0.12以前では，outputTextへのマッピングは<span>要素に限定されていました． Teeda 1.0.13以降で，1.0.12以前と同じように，<span>要素の場合のみoutputTextにマッピングされるようにするには`teedaCustomize.dicon`に次の設定を記述します．
    <component class="org.seasar.teeda.extension.util.TeedaExtensionConfiguration">
        <property name="outputTextSpanOnly">true</property>
    </component>
## ラベルについて Teeda 1.0.13以降では，id属性の値が"xxxLabel"となっている<span>要素の内容は"xxx"をキーとするラベルの値に置き換えられます． Teeda 1.0.12以前では，この動作は<a>要素の子要素に限定されていました． Teeda 1.0.13以降で，1.0.12以前と同じように，<a>要素の子要素の場合のみラベルに置き換えるようにするには`teedaCustomize.dicon`に次の設定を記述します．
    <component class="org.seasar.teeda.extension.util.TeedaExtensionConfiguration">
        <property name="outputTextLabelUnderAnchorOnly">true</property>
    </component>
## JavaScriptについて 携帯端末向けなど，一部のページでTeedaが自動的にJavaScriptを出力することを抑止することができます．JavaScriptの出力を抑止するには，`web.xml`に次の設定を記述します．
    <context-param>
      <param-name>teeda.JAVASCRIPT_NOT_PERMITTED_PATH</param-name>
      <param-value>/view/i/</param-value>
    </context-param>
`<param-value>`要素の内容は，JavaScriptを抑止したい画面のコンテキストルートからのパスです．カンマ区切りで複数のパスを指定することができます．指定されたパスから始まるページがリクエストされると，そのページにはJavaScriptが出力されなくなります． ## forEachについて Teeda 1.0.13-sp2以降では，forEachで指定されたxxxItemsが空の場合，id属性にxxxItemsを指定した要素の開始タグおよび終了タグが出力されません． 次の例では，xxxItemsが空の場合，<table>要素の開始タグおよび出力タグを含む全体が出力されません．
    <table id="xxxItems">
        <tr><td>...</td></tr>
    </table>
Teeda 1.0.13-sp1以前では，<table>要素の開始タグおよび出力タグが出力されていました． Teeda 1.0.13-sp2以降で，1.0.13-sp1以前と同じように，xxxItemsが空の場合でも，id属性にxxxItemsを指定した要素の開始タグおよび終了タグが出力されるようにするには，`teedaCustomize.dicon`に次の設定を記述します．
    <component class="org.seasar.teeda.extension.util.TeedaExtensionConfiguration">
        <property name="outputForEachIfEmptyItems">true</property>
    </component>
| Copyright© 2005-2006, The Seasar Foundation and the others. All rights reserved.