jp.terasoluna.fw.ex.web.taglib
クラス ExtractTag

java.lang.Object
  上位を拡張 javax.servlet.jsp.tagext.TagSupport
      上位を拡張 jp.terasoluna.fw.ex.web.taglib.ExtractTag
すべての実装されたインタフェース:
Serializable, javax.servlet.jsp.tagext.IterationTag, javax.servlet.jsp.tagext.JspTag, javax.servlet.jsp.tagext.Tag

public class ExtractTag
extends javax.servlet.jsp.tagext.TagSupport

動的コードリストから、指定されたキー値を持つオブジェクトを抽出するカスタムタグ。

(動的コードリストとは、ページスコープやリクエストスコープ、セッションスコープ、アクションフォーム内に保存された 同型のオブジェクトの集合を表す(例えば「部署」を表すJavaBeanのListなど)。
通常、セレクトボックスやチェックボックス、ラジオボタン等の限られた選択肢から値を選択する場合に用いる。)

動的コードリストから抽出したオブジェクトは、任意のスコープのbeanとして定義したり、特定のプロパティを表示することができる。
定義するか表示するかは、id属性を設定するか否かで決まる。定義と表示を同時に行うことはない。
・id属性を設定した場合、「定義」として動作する。任意のスコープのbean、および、開始タグ以降で有効なObject型のスクリプティング変数を定義する。
・id属性を設定しなかった場合、「表示」として動作する。このとき、表示したいプロパティをwriteProperty属性で指定しなければならない。

このタグを利用するには、以下の4項目を設定する。
・動的コードリスト (collection属性 / collectionName属性 + collectionProperty属性 + collectionScope属性)
・キープロパティ(抽出時に比較するプロパティ) (keyProperty属性)
・抽出条件(キープロパティと比較される値、あるいは、値のCollectionや配列) (condition属性 / conditionName属性 + conditionProperty属性 + conditionScope属性)
・定義もしくは表示に関する情報 (id属性 + toScope属性 / writeProperty属性 + filter属性)
※上記括弧内の「/」の左右に分けられた属性は、排他的に利用する。

詳細は以下の通り。

「動的コードリスト」の設定方法 以下のA、B、いずれかの方法で設定する。

A. 直接オブジェクトを設定する 使用属性:
・collection (必須)

実行時式(<%=…%>)やEL式(${…})を利用し、collection属性に直接オブジェクトを設定する。

設定例:
collection="${_SampleForm.deptList}"

B. スコープにあるオブジェクトを参照する 使用属性:
・collectionName (必須)
・collectionProperty (任意)
・collectionScope (任意)

参照するスコープを指定する場合は、collectionScope属性にスコープの名前を設定する。
(collectionScope属性を省略した場合、page>request>session>applicationの順に検索する。)
スコープ上の属性名をcollectionName属性に設定する。
collectionName属性が指すオブジェクトが動的コードリストである場合には、 collectionProperty属性は設定しない。
collectionName属性が指すオブジェクト内のプロパティが動的コードリストである場合には、 collectionProperty属性にて、動的コードリストが格納されているプロパティ名を指定する。

設定例:
・collectionName="_SampleForm" collectionProperty="deptList"
・collectionName="deptList" collectionScope="session"

「キープロパティ(抽出時に比較するプロパティ)」の設定方法 使用属性:
・keyProperty (必須)

抽出時に比較するプロパティの名前を、keyProperty属性に設定する。
後述の「抽出条件」と、keyProperty属性で指定されたプロパティの値が一致するJavaBeanが抽出される。
例えば、チェックボックスで選択した項目を抽出したい場合、 チェックボックスの値を提供しているプロパティの名前をkeyProperty属性に設定する。

設定例:
・keyProperty="deptCode"

「抽出条件(キープロパティと比較される値、あるいは、値のCollectionや配列)」の設定方法 以下のA、B、いずれかの方法で設定する。

A. 直接オブジェクトを設定する 使用属性:
・condition (必須)

実行時式(<%=…%>)やEL式(${…})を利用し、condition属性に直接オブジェクトを設定する。

設定例:
condition="${_SampleForm.selectedDeptCode}"

B. スコープにあるオブジェクトを参照する 使用属性:
・conditionName (必須)
・conditionProperty (任意)
・conditionScope (任意)

参照するスコープを指定する場合は、conditionScope属性にスコープの名前を設定する。
(conditionScope属性を省略した場合、page>request>session>applicationの順に検索する。)
スコープ上の属性名をconditionName属性に設定する。
conditionName属性が指すオブジェクトが「抽出条件」である場合には、 conditionProperty属性は設定しない。
conditionName属性が指すオブジェクト内のプロパティが「抽出条件」である場合には、 conditionProperty属性にて、「抽出条件」が格納されているプロパティ名を指定する。

設定例:
・conditionName="_SampleForm" conditionProperty="selectedDeptCode"
・conditionName="selectedDeptCode" collectionScope="session"

「定義もしくは表示に関する情報」の設定方法 定義か表示かに応じて、以下の様に設定する。

定義時 使用属性:
・id (必須)
・toScope (任意)

抽出結果をbeanとして定義するときの名前をid属性に設定する。
抽出結果をpageスコープ以外(例えば、sessionスコープ)に格納したい場合は、 toScope属性で、抽出結果を格納するスコープを設定する。
(toScope属性を省略した場合、pageスコープに抽出結果を格納する。)

設定例:
・id="selectedDept"
・id="selectedDept" toScope="session"

表示時 使用属性:
・writeProperty (必須)
・filter (任意)

抽出結果のJavaBeanの、表示したいプロパティの名前をwriteProperty属性に設定する。
表示の際、サニタイズ(「<」→「&lt;」等)を行いたくない場合は、filter属性にfalseを設定する。

設定例:
・writeProperty="deptName"
・writeProperty="deptName" filter="false"

特記事項:

 定義時:
 ・「抽出条件」に特定の値を渡した場合、抽出結果は1つのJavaBeanとなる。
 ・「抽出条件」に値のCollectionや配列を渡した場合、抽出結果はJavaBeanのListとなる。
 
 表示時:
 ・「抽出条件」には、特定の値を渡すことしかできない。(Collectionや配列以外でなければならない。)
 
 動的コードリスト内の各JavaBeanのキープロパティの値について:
 ・型は任意であるが、抽出条件に使用する値と同じ型でなければならない(厳密には、equalsが成立すればよい)。
   なお、アクションフォーム上の、リクエストパラメータの値が入るプロパティは、
   通常Stringやその配列で定義するため、キープロパティの値もString型にした方が相性が良い。
 ・キープロパティの値がnullの場合、キープロパティの値が空文字列(長さ0のString)であるものとして処理する。
   これは、以下の特性を考慮したものである。
   ・null値をhtml:radioやhtml:multiboxで出力すると、空文字列扱いとなる
   ・アクションフォーム上の配列プロパティをリセット機能でリセットした場合、配列要素がnullになる
   ただし、null値を扱う必要が無い限り、null値は使用しないことを推奨する。
 
 動的コードリスト内の各JavaBeanの出力プロパティの値について(writeProperty属性使用時):
 ・型は任意である。toStringの結果が表示される。
 ・出力プロパティの値がnullの場合、非表示(空文字列の出力と同義)となる。
 
 動的コードリストとして使用できる型:
 ・配列
 ・java.util.Collection(java.util.ArrayList等)
 ・java.util.Iterator
 ・java.util.Enumeration
 ・java.util.Map(java.util.LinkedHashMap等)
 ※配列、Collection、Iterator、Enumerationの各要素は、JavaBeanである。
 ※動的コードリストの型がMapの場合、Map.EntryがJavaBeanの代わりとなる。
   よって、keyProperty属性やwriteProperty属性には、"key"や"value"が使用できる。
   なお、Mapのkeyを元にMapのvalueを表示したい場合(keyProperty="key" writeProperty="value"となる場合)は、
   このタグを使用せず、bean:writeタグ等で直接アクセスして表示すればよい。
 

性能を考慮した使用上の注意:

このタグは、動的コードリスト内を順検索してJavaBeanを抽出する。 そのため、使用方法を誤ると、非効率な検索や無駄な検索をしてしまう。
以下が、性能アンチパターンとその解決方法(推奨パターン)である。

選択されたチェックボックスに対応する値を表示するケース(抽出結果を複数表示するケース)
性能アンチパターン:logic:iterateで「抽出条件」を1件ずつ取り出し、このタグで表示する
 <logic:iterate name="_SampleForm" property="selectedDeptCodes" id="selectedDeptCode">
   <logic:present name="selectedDeptCode">
   <tr>
     <td>
       <tl:extract collectionName="_SampleForm" collectionProperty="deptList"
           keyProperty="deptCode"
           conditionName="selectedDeptCode"
           writeProperty="deptName"/>
     </td>
   </tr>
   </logic:present>
 </logic:iterate>
 
「抽出条件」の数だけ、動的コードリストの順検索を行ってしまうため、非効率。
仮に動的コードリスト内のJavaBeanが100個あり、画面で50個選択されたとすると、
少なくとも、1 + 2 + … + 50 = 1275
最悪のケースでは、100 + 99 + … + 51 = 3775
の式で表される通り、抽出だけで、リフレクションAPIを使用したプロパティアクセスが1275〜3775回必要となる。

推奨パターン:「抽出条件」として値のCollectionや配列を渡し、抽出結果(List)をlogic:iterateで1件ずつ取り出し、bean:writeタグで表示する
 <tl:extract collectionName="_SampleForm" collectionProperty="deptList"
     keyProperty="deptCode"
     conditionName="_SampleForm" conditionProperty="selectedDeptCodes"
     id="selectedDeptList"/>
 <logic:iterate name="selectedDeptList" id="selectedDept">
   <tr>
     <td><bean:write name="selectedDept" property="deptName"/></td>
   </tr>
 </logic:iterate>
 
動的コードリスト内部の全JavaBeanに1回ずつアクセスし、「抽出条件」と照合する。
仮に動的コードリスト内のJavaBeanが100個あった場合、画面で選択された個数に関わらず、
抽出時の、リフレクションAPIを使用したプロパティアクセスが100回で済む。
また、「抽出条件」はタグ内部で照合用のHashSetに変換されるため、 画面で選択された個数が多くなっても、照合処理への影響は皆無である。

動的コードリスト内のJavaBeanに、表示したいプロパティが複数あるケース
性能アンチパターン:表示したいプロパティの数だけ、このタグを使用する
 <td>
   <tl:extract collectionName="_SampleForm" collectionProperty="deptList"
       keyProperty="deptCode"
       conditionName="_SampleForm" conditionProperty="selectedDeptCode"
       writeProperty="deptName"/>
 </td>
 <td>
   <tl:extract collectionName="_SampleForm" collectionProperty="deptList"
       keyProperty="deptCode"
       conditionName="_SampleForm" conditionProperty="selectedDeptCode"
       writeProperty="deptShortName"/>
 </td>
 
表示したいプロパティの数だけ、動的コードリストの順検索を行ってしまうため、非効率。

推奨パターン:このタグで抽出結果を定義し、bean:writeタグで表示する
 <tl:extract collectionName="_SampleForm" collectionProperty="deptList"
     keyProperty="deptCode"
     conditionName="_SampleForm" conditionProperty="selectedDeptCode"
     id="selectedDept"/>
 <td><bean:write name="selectedDept" property="deptName" ignore="true"/></td>
 <td><bean:write name="selectedDept" property="deptShortName" ignore="true"/></td>
 
動的コードリストの順検索は1回だけ行う。

関連項目:
TagSupport, 直列化された形式

フィールドの概要
 
クラス javax.servlet.jsp.tagext.TagSupport から継承されたフィールド
pageContext
 
インタフェース javax.servlet.jsp.tagext.IterationTag から継承されたフィールド
EVAL_BODY_AGAIN
 
インタフェース javax.servlet.jsp.tagext.Tag から継承されたフィールド
EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY, SKIP_PAGE
 
コンストラクタの概要
ExtractTag()
           
 
メソッドの概要
 int doStartTag()
          動的コードリストから、指定されたキー値を持つオブジェクトを抽出する。
 Object getCollection()
          動的コードリストオブジェクトを取得する。
 String getCollectionName()
          動的コードリストオブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を取得する。
 String getCollectionProperty()
          動的コードリストオブジェクトが格納されたプロパティを取得する。
 String getCollectionScope()
          動的コードリストを検索するスコープを取得する。
 Object getCondition()
          抽出条件オブジェクトを取得する。
 String getConditionName()
          抽出条件オブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を取得する。
 String getConditionProperty()
          抽出条件オブジェクトが格納されたプロパティを取得する。
 String getConditionScope()
          抽出条件オブジェクトを検索するスコープを取得する。
 String getId()
          抽出結果オブジェクトを定義する際の名前を取得する。
protected  Iterator<?> getIterator(Object collection)
          動的コードリストのイテレータを返す。
 String getKeyProperty()
          キープロパティ(抽出条件と比較するプロパティ)を取得する。
 String getToScope()
          抽出結果オブジェクトを定義するスコープを取得する。
 String getWriteProperty()
          出力プロパティを取得する。
 boolean isFilter()
          出力した文字列をHTMLエスケープするか否かを取得する。
 void release()
          すべてのアロケートされた資源を解放する。
 void setCollection(Object collection)
          動的コードリストオブジェクトを設定する。
 void setCollectionName(String collectionName)
          動的コードリストオブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を設定する。
 void setCollectionProperty(String collectionProperty)
          動的コードリストオブジェクトが格納されたプロパティを設定する。
 void setCollectionScope(String collectionScope)
          動的コードリストを検索するスコープを設定する。
 void setCondition(Object condition)
          抽出条件オブジェクトを設定する。
 void setConditionName(String conditionName)
          抽出条件オブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を設定する。
 void setConditionProperty(String conditionProperty)
          抽出条件オブジェクトが格納されたプロパティを設定する。
 void setConditionScope(String conditionScope)
          抽出条件オブジェクトを検索するスコープを設定する。
 void setFilter(boolean filter)
          出力した文字列をHTMLエスケープするか否かを設定する。
 void setId(String id)
          抽出結果オブジェクトを定義する際の名前を設定する。
 void setKeyProperty(String keyProperty)
          キープロパティ(抽出条件と比較するプロパティ)を設定する。
 void setToScope(String toScope)
          抽出結果オブジェクトを定義するスコープを設定する。
 void setWriteProperty(String writeProperty)
          出力プロパティを設定する。
 
クラス javax.servlet.jsp.tagext.TagSupport から継承されたメソッド
doAfterBody, doEndTag, findAncestorWithClass, getParent, getValue, getValues, removeValue, setPageContext, setParent, setValue
 
クラス java.lang.Object から継承されたメソッド
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

コンストラクタの詳細

ExtractTag

public ExtractTag()
メソッドの詳細

getCollection

public Object getCollection()
動的コードリストオブジェクトを取得する。

戻り値:
動的コードリストオブジェクト

setCollection

public void setCollection(Object collection)
動的コードリストオブジェクトを設定する。

パラメータ:
collection - 動的コードリストオブジェクト

getCollectionName

public String getCollectionName()
動的コードリストオブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を取得する。

戻り値:
動的コードリストオブジェクト、またはそれを含むJavaBeanの、スコープ上の名前

setCollectionName

public void setCollectionName(String collectionName)
動的コードリストオブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を設定する。

パラメータ:
collectionName - 動的コードリストオブジェクト、またはそれを含むJavaBeanの、スコープ上の名前

getCollectionProperty

public String getCollectionProperty()
動的コードリストオブジェクトが格納されたプロパティを取得する。

戻り値:
動的コードリストオブジェクトが格納されたプロパティ

setCollectionProperty

public void setCollectionProperty(String collectionProperty)
動的コードリストオブジェクトが格納されたプロパティを設定する。

パラメータ:
collectionProperty - 動的コードリストオブジェクトが格納されたプロパティ

getCollectionScope

public String getCollectionScope()
動的コードリストを検索するスコープを取得する。

戻り値:
動的コードリストを検索するスコープ

setCollectionScope

public void setCollectionScope(String collectionScope)
動的コードリストを検索するスコープを設定する。

パラメータ:
collectionScope - 動的コードリストを検索するスコープ

getKeyProperty

public String getKeyProperty()
キープロパティ(抽出条件と比較するプロパティ)を取得する。

戻り値:
キープロパティ(抽出条件と比較するプロパティ)

setKeyProperty

public void setKeyProperty(String keyProperty)
キープロパティ(抽出条件と比較するプロパティ)を設定する。

パラメータ:
keyProperty - キープロパティ(抽出条件と比較するプロパティ)

getCondition

public Object getCondition()
抽出条件オブジェクトを取得する。

戻り値:
抽出条件オブジェクト

setCondition

public void setCondition(Object condition)
抽出条件オブジェクトを設定する。

パラメータ:
condition - 抽出条件オブジェクト

getConditionName

public String getConditionName()
抽出条件オブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を取得する。

戻り値:
抽出条件オブジェクト、またはそれを含むJavaBeanの、スコープ上の名前

setConditionName

public void setConditionName(String conditionName)
抽出条件オブジェクト、またはそれを含むJavaBeanの、スコープ上の名前を設定する。

パラメータ:
conditionName - 抽出条件オブジェクト、またはそれを含むJavaBeanの、スコープ上の名前

getConditionProperty

public String getConditionProperty()
抽出条件オブジェクトが格納されたプロパティを取得する。

戻り値:
抽出条件オブジェクトが格納されたプロパティ

setConditionProperty

public void setConditionProperty(String conditionProperty)
抽出条件オブジェクトが格納されたプロパティを設定する。

パラメータ:
conditionProperty - 抽出条件オブジェクトが格納されたプロパティ

getConditionScope

public String getConditionScope()
抽出条件オブジェクトを検索するスコープを取得する。

戻り値:
抽出条件オブジェクトを検索するスコープ

setConditionScope

public void setConditionScope(String conditionScope)
抽出条件オブジェクトを検索するスコープを設定する。

パラメータ:
conditionScope - 抽出条件オブジェクトを検索するスコープ

getId

public String getId()
抽出結果オブジェクトを定義する際の名前を取得する。

オーバーライド:
クラス javax.servlet.jsp.tagext.TagSupport 内の getId
戻り値:
抽出結果オブジェクトを定義する際の名前

setId

public void setId(String id)
抽出結果オブジェクトを定義する際の名前を設定する。

オーバーライド:
クラス javax.servlet.jsp.tagext.TagSupport 内の setId
パラメータ:
id - 抽出結果オブジェクトを定義する際の名前

getToScope

public String getToScope()
抽出結果オブジェクトを定義するスコープを取得する。

戻り値:
抽出結果オブジェクトを定義するスコープ

setToScope

public void setToScope(String toScope)
抽出結果オブジェクトを定義するスコープを設定する。

パラメータ:
toScope - 抽出結果オブジェクトを定義するスコープ

getWriteProperty

public String getWriteProperty()
出力プロパティを取得する。

戻り値:
出力プロパティ

setWriteProperty

public void setWriteProperty(String writeProperty)
出力プロパティを設定する。

パラメータ:
writeProperty - 出力プロパティ

isFilter

public boolean isFilter()
出力した文字列をHTMLエスケープするか否かを取得する。

戻り値:
出力した文字列をHTMLエスケープするか否か

setFilter

public void setFilter(boolean filter)
出力した文字列をHTMLエスケープするか否かを設定する。

パラメータ:
filter - 出力した文字列をHTMLエスケープするか否か

doStartTag

public int doStartTag()
               throws javax.servlet.jsp.JspException
動的コードリストから、指定されたキー値を持つオブジェクトを抽出する。

id属性が設定されていれば、結果のオブジェクトをbeanとして定義し、 id属性が設定されていなければ、結果のオブジェクトの、writePropertyで指定されたプロパティを表示する。

定義:
インタフェース javax.servlet.jsp.tagext.Tag 内の doStartTag
オーバーライド:
クラス javax.servlet.jsp.tagext.TagSupport 内の doStartTag
戻り値:
処理制御指示。常に SKIP_BODY
例外:
javax.servlet.jsp.JspException - JSP例外
関連項目:
TagSupport.doStartTag()

getIterator

protected Iterator<?> getIterator(Object collection)
                           throws javax.servlet.jsp.JspException
動的コードリストのイテレータを返す。

パラメータ:
collection - 動的コードリスト
例外:
javax.servlet.jsp.JspException - 動的コードリストの型に対応するイテレータが取得できない場合

release

public void release()

すべてのアロケートされた資源を解放する。

定義:
インタフェース javax.servlet.jsp.tagext.Tag 内の release
オーバーライド:
クラス javax.servlet.jsp.tagext.TagSupport 内の release


Copyright © 2012. All Rights Reserved.