MicroNova YUZU JSP タグライブラリ

2006-06-12

MicroNova YUZUは、JSP標準タグライブラリ(JSTL)を補強するべく設計された式言語(EL)に基づくタグライブラリです。 JSTL及びELについてはJSTL仕様を御覧下さい。 YUZUはJSP 1.2及び2.0双方の仕様に対応するように設計されています。 動作はLinux上でApache tomcat(4.x/5.x)とJSTLレファレンス実装を用いて確認されており、BSDライセンスで公開されています。

1 属性値の評価

全てのYUZUタグの属性値は、設定の際に常にELとして評価されます。 例えばJSTLの<c:set>とは異なり、YUZU版の<m:set>では変数名もELとして評価されます:

<%-- 変数"a"に"b"を割当てます --%>

<c:set var="variableName" value="a"/>
<m:set var="${variableName}" value="b"/>

しかしながら、ある種の属性(「EL属性」と呼ばれます)は、後にELとして評価されるべき文字列を値とするため、"${...}"をELとして評価させずに設定を行なうことが必要となります。 JSTLでは、このための一つの方法として"$"の代わりに"${'$'}"を使うことができます。 次の例では変数"x"に文字列"${xyz}"が割当てられます:

<c:set var="x" value="${'$'}{xyz}"/>

プログラムを書きやすくするため、YUZUのEL属性では、特別なパターン"@{"が"${"に変換されます。 次の例では、EL属性である"test"の値が、後にELとして評価される文字列"${!empty param.x}"に設定されます:

<%-- フォーム変数"x"の値が空でなければそのまま、さもなければ"空"を出力します --%>

<m:out value="${param.x}" default="空" test="@{!empty param.x}"/>

"@{"から"${"への変換は、通常通りELとして評価された後に行なわれますので、次の例は前のものと同じです:

<c:set var="PARAMNAME" value="param.x"/>
<m:out value="${param.x}" default="EMPTY" test="@{!empty ${PARAMNAME}}"/>

すべてのYUZUタグに共通なEL属性は以下の通りです: testassignexportprepareCodecimportCodecprocessCodeccodecassignCodecexportCodec、および cleanupCodec.

2 概観

全てのYUZUタグは、各々「タグ値」と呼ばれるオブジェクトに対応しており、常に次の六段階を経て処理されます:

  1. 準備段階(prepare)では、(タグが開かれた際に)タグ値が設定されます
  2. 輸入段階(import)では、(タグが閉じられた際に)準備段階でタグ値が設定されなかった場合に、タグの本文(内部)からタグ値を「輸入」します
  3. 初期値段階(default)では、(タグが閉じられた際に)タグ値の初期値の選択が行なわれます
  4. 処理段階(process)では、(タグが閉じられた際に)タグ値が処理されます
  5. 割当段階(assign)では、(タグがとじられた際に)処理されたタグ値が変数に割り当てられます
  6. 輸出段階(export)では、(タグが閉じられた際に)割り当てが行なわれなかった場合に、タグ値が「輸出(出力)」されます

2.1 準備段階

準備段階では、タグ値は以下の順に設定されます:

準備段階は、タグが開かれた際に本文が処理される前に行なわれ、準備されたタグ値は、タグの本文中で、特別なページ変数である"_"(アンダースコア)を用いて参照することができます。 詳しくは、下の局所変数の項を参照して下さい。

次の例中の<m:out>は、タグ値をそのまま出力するものです:

<%-- "こんにちは"を出力 --%>

<m:out value="こんにちは"/>

<%-- 本日の日付を出力 --%>

<m:out className="java.util.Date"/>

必要があれば、prepareCodec属性を使って、準備されたタグ値に「コーデック」と呼ばれる関数のパイプを適用することができます。 詳しくは、コーデックの項を参照して下さい。

2.2 輸入段階

準備段階でタグ値が設定されなかった場合には、タグ値は、(タグが閉じられる際に)そのタグの本文(内部)をJSPとして処理して得られた出力文字列から「輸入」されます。 通常は得られた文字列がそのままタグ値として用いられますが、必要とあれば、「コーデック」を指定してその文字列に適用することもできます。

例えば:

<%-- "こんにちは"を出力します --%>

<m:out><m:out value="こん"/>に<m:out value="ちは"/></m:out>

<%-- ${message}"の値が空でなければ輸入が行われないため${message}の値を、さもなければ"こんにちは"を輸入して出力します。 --%>

<m:out value="${message}">こんにちは</m:out>

<%-- "String:toLowerCase"コーデックを適用して小文字の"hello world"を出力します --%>

<m:out importCodec="String:toLowerCase">Hello World</m:out>

2.3 初期値段階

必要であれば、default属性を使って、タグ値の初期値を指定することができます。指定された初期値は、通常、初期値段階における(準備段階あるいは輸入段階において設定された)タグ値がnull または空文字列("")であった場合に、タグ値として用いられます:

<%-- 空でないフォーム引数"X"の値あるいは"未設定"を出力します --%>

<m:out value="${param.X}" default="未設定"/>

初期値がどのような条件で用いられるかは、testというEL属性に、論理値(真偽)に評価されるELを割り当てることにより指定することができます。 指定された場合には、初期値はtestの評価値が「偽」であった場合に用いられます:

<%-- フォーム引数"X"の値が"1"であれば"ONE"、さもなければ"NOTONE"を出力します --%>

<m:out test="@{param.X == 1}" value="ONE" default="NOTONE"/>

test属性値の中では、"_"(アンダースコア)を使って現時点でのタグ値を参照することができます:

<%-- ひとつもフォーム引数が与えられていなければ、"引数無し"を出力します --%>

<m:out test="@{!empty _}" default="引数無し"><c:forEach var="p" items="${param}"><m:out value="${p}"/></c:forEach></m:out>

註: 実際にはtest属性値は単なるELではなくコーデックです。 詳しくはコーデックの項を御覧下さい。

2.4 処理段階

処理段階では、タグ値が処理され、必要であれば別のオブジェクトに変換されます。 殆んどのYUZUタグは、この段階でそれぞれ固有の処理を行なっています。

processCodec(別名codec)属性が指定された場合には、割当/輸出段階の前に、処理済のタグ値に指定されたコーデックが適用されます。

2.5 割当段階

処理されたタグ値は、JSTLの<c:set>タグと同様に、以下のように変数に割り当てられます:

property属性が指定されている場合、もしそのタグが別のYUZUタグの本文の中に含まれていれば、target属性を省略することがてきます。 この場合には、最も近い祖先であるYUZUタグのタグ値がtargetとして用いられます。

JSTLと同様に、targetオブジェクトがマップ(java.util.Mapの実装)である場合には、propertyの値がマップのキーとして用いられます:

<%-- "{a=alpha、b=beta}"と初期化されたjava.util.HashMapのインスタンスを変数"map"に割り当てます --%>

<m:set var="map" className="java.util.HashMap">
  <m:set property="a" value="alpha"/>
  <m:set property="b" value="beta"/>
</m:set>

targetオブジェクトがリスト(java.util.Listの実装)である場合には、propertyは次のように要素の位置および動作を示します:

 property  タグ値  動作 
 零または正の整数  何でも  初めから数えた位置(0=最初)にある要素をタグ値で置き換えます 
 負の整数  何でも  終わりから数えた位置(-1=最後)にある要素をタグ値で置き換えます 
 "*"または"**"  nullでない値  タグ値をリストの終わりに追加します 
 "*"  null  最後の要素を取り除きます 
 "*"または"**"に続く正の整数(例えば"*2")  nullでない値  初めから数えた位置にタグ値を挿入します 
 "*"に続く正の整数(例えば"*2")  null  初めから数えた位置にある要素を取り除きます 
 "*"または"**"に続く負の整数(例えば"*-2")  nullでない値  終わりから数えた位置にタグ値を挿入します 
 "*"に続く負の整数(例えば"*-2")  null  終わりから数えた位置にある要素を取り除きます 
 "**"で始まる文字列  null  何も行ないません 

例えば:

<m:set var="list" className="java.util.ArrayList">
  <%-- "a"、"b"、"c"、"d"を追加します --%>
  <m:set property="*" value="a"/>
  <m:set property="*" value="b"/>
  <m:set property="*" value="c"/>
  <m:set property="*" value="d"/>
  <%-- 1の位置の要素("b")を取り除きます --%>
  <m:set property="*1"/>
  <%-- 1の位置に"e"を挿入します --%>
  <m:set property="*1" value="e"/>
  <%-- 最後の二つの要素の前に"f"を挿入します --%>
  <m:set property="*-2" value="f"/>
  <%-- 1の位置の要素を"E"で置き換えます --%>
  <m:set property="1" value="E"/>
  <%-- 最後の要素を取り除きます --%>
  <m:set property="*"/>
</m:set>

<%-- "[a、E、f、c]"が出力されます --%>

<m:out value="${list}"/>

targetオブジェクトが配列である場合には、propertyは、置き換えの位置を、正の整数(初めから数えた位置)または負の整数(終わりから数えた位置)として指定します。

特殊なケースとして、targetの値を文字列"return"とすると、<m:return>タグと同様に、別のJSPから呼出しを受けた場合にタグ値を呼出し側に返すことができます。

通常はタグ値がそのまま割り当てられますが、assignEL属性を使うことで、タグ値を"_"(アンダースコア)で参照しながら、実際に割り当てられる値を指定することができます:

<%-- マップ自体ではなく、"a"の値と"b"の値を繋いだ文字列を、変数"X"に割り当てます --%>

<m:set var="X" className="java.util.HashMap" assign="@{_.a}@{_.b}">
  <m:set property="a" value="alpha"/>
  <m:set property="b" value="beta"/>
</m:set>

<m:out value="${X}"/>

assignCodecコーデックが指定された場合には、assignEL属性の値(またはタグ値)に適用されます。

必要があれば、attribute属性を使って、タグ本文の中で、タグの属性値を設定することもできます(この場合にはtarget属性は指定できません). 例えば、

<m:set var="message">
  <m:set attribute="value">hello</m:set>
</m:set>

は次と同じです:

<m:set var="message" value="hello"/>

2.6 輸出段階

割当段階で割り当てが行なわれなかった場合、タグ値は輸出(文字列として出力)されます。 通常はタグ値がそのまま輸出されますが、必要であれば、export属性を用いて、実際に出力されるオブジェクトを指定することが出来ます。 export属性の値は、タグ値を"_"(アンダースコア)を用いて参照するELで、その評価値が文字列として出力されます。

exportを使った例としては:

<%-- 01/01/1970から現在までの時間を1/1000秒単位で出力します --%>

<m:out className="java.util.Date" export="@{_.time}"/>

exportCodecが指定された場合は、出力の前にexportの評価値に適用されます。 ここで留意していだたきたいのは、JSTLの<c:out>タグと異なり、YUZUのタグは、exportCodecが"XML:encode"のようなものに指定されない限り、タグに使われる特殊文字('<'、'>'等)を変換しないということです。

タグ値がDOMのノード(org.w3c.dom.Nodeの実装)である場合には、(XML宣言を除いた)XMLドキュメントとして出力されます。

通常では、タグ値は割り当てが行なわれなかった場合にのみ輸出されますが、doesExport属性が"always"に設定されれば、割り当ての有無に拘わらず常に輸出されます。

3 コーデック

上の様々な段階において、"URL:encode"、"Base64:decode"等の関数を指定して適用することができます。 このような関数を"コーデック(codec)"と呼びます。 YUZUタグでは以下のようなコーデック属性を用いることが出来ます:

コーデックが適用されるオブジェクトはオペランド("operand")と呼ばれます;例えばimportCodecのオペランドはタグ本文の文字列であり、processCodecのオペランドは処理済のタグ値となります。

例えば:

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれば、"a,b,c"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join"/>

オペランド以外のコーデック引数は":"(コロン)を使って指定されます:

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれば、"a-b-c"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join:-"/>

空文字列は"::"(二つのコロン)を使って指定されます:

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれば、"abc"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join::"/>

コーデックの各引数は、関数が呼ばれる際にELとして評価され、EL属性の場合と同様"@{...}"を用いて割り当ての際の評価を避けることができます:

<m:set var="separator" value=":"/>

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれば、"a:b:c"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join:@{separator}"/>

"|"(バー)を用いることにより、一連のコーデックをパイプとして適用することができます。 二番目のコーデックは、最初のコーデックを適用した結果に適用され、以下同様に適用されていきます:

<m:set var="separator" value=":"/>

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれば、"A:B:C"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join:@{separator}|String:toUpperCase"/>

必要とあれば、"\"を用いて区切り文字を無効にすることができます("\:"および"\|"):

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれば、"|:|:|"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join:\:|String:replaceAll:[abc]:\|"/>

コーデックが適用される際のオペランドは、特別な変数"_operand"を用いて参照することが出来ます:

<%-- フォーム引数として"x=a&x=b&x=c"が与えられれた時にのみ、"abc"の代わりに"MATCH"を出力します --%>

<m:out value="${paramValues.x}" codec="String:join::|Type:ifEqual:abc:MATCH:@{_operand}"/>

コーデックの名前の後に"_"(アンダースコア)を付けると、そのコーデックはオペランドではなく、最初のコーデック引数に適用されます。 次の二つは同じです:

<m:out value="${paramValues.x}" codec="String:join:-"/>

<m:out codec="String:join_:@{paramValues.x}:-"/>

コーデックの中に":"(コロン)が含まれていなければ、それはELとして評価されます:

<%-- もしフォーム引数"x"が二つ以上の"t"を含めば、"true"を出力します --%>

<m:out value="${param.x}" codec="String:replaceAll:[^t]::|String:length|@{_operand > 2}"/>

コーデックは変数に割り当てることができます:

<m:set var="ISAPHONE" value="String:match:^\([0-9]{3}\)[0-9]{3}-[0-9]{4}$"/>

xは米国の電話番号<m:out value="${param.x}" codec="${ISAPHONE}|Type:ifNull:ではありません:です"/>。

以下のコーデックは組込み済です("[:xxx]"は省略できる引数を意味します):

 XML:encode[:PATTERN]  文字列としてのオペランドに含まれる特殊文字 (>、<、&、"、'、{ (&#123;)、および } (&125;))を「無害化」します。 PATTERN引数としてこれらの内で変換されるべき文字を正規表現の記法で指定することができます(例えば"[<>]"を与えれば"<"と">"のみが無害化されます)。 もしPATTERNとして"~"(ティルダ)を与えれば、"[&<>]"が与えられたものと見なされます。 
 XML:decode  文字列としてのオペランド内の無害化された特殊文字 (>、<、&、"、'、{ (&#123;)、および } (&#125;))を逆変換します 
 XML:parse[:CONTROLMAP]  オペランドをXML文書として、CONTROLMAP(マップまたはフォーム型式で符号化された文字列)による指定に沿って、DOMオブジェクトに構文解析します。 CONTROLMAPは次の属性を指定します: "namespaceAware"、"ignoringComments"、"ignoringElementContentWhitespace"、"expandEntityReferences"、"coalescing"、および"validating"。 特に指定されなければ、"validating"以外は全て"true"と見なされます。 
 XML:output[:CONTROLMAP]  オペランドをDOMオブジェクトとして、CONTROLMAP (マップまたはフォーム型式で符号化された文字列)による指定に沿って、XML文書に変換します。 CONTROLMAPは標準的なXSLT出力属性を指定します("method"、"version"、"encoding"、"omit-xml-declaration"、"standalone"、"doctype-public"、"doctype-system"、"cdata-section-elements"、"indent"、および"media-type")。 特に指定がなれけば、"omit-xml-declaration=yes"が与えられたものと見なされます。 
 XMLMap:encode[:CONTROLMAP]  多層マップとしてのオペランドをCONTROLMAP (マップまたはフォーム型式で符号化された文字列)による指定に沿って、XML文書に変換します。詳しくはXMLMapをご覧下さい。 
 XMLMap:decode[:CONTROLMAP]  XML文書としてのオペランドをCONTROLMAP (マップまたはフォーム型式で符号化された文字列)による指定に沿って、多層マップに変換します。詳しくはXMLMapをご覧下さい。 
 URL:encode[:ENCODING]  オペランドを文字列として、ENCODING(指定されなければ"utf-8")を用いて、URL符号化します。 
 URL:decode[:ENCODING]  オペランドをURL符号化された文字列として、ENCODING(指定されなければ"utf-8")を用いて、復号化します。 
 URL:streamType  バイト配列としてのオペランドの内容型を推定します。 
 URL:nameType  URL文字列としてのオペランドの内容型を推定します。 
 URL:normalize  オペランドをURIとして正規化します。 
 URL:relativize:BASE  オペランドをURIとしてBASEに対して相対化します。 
 URL:resolve:BASE  オペランドをURIとしてBASEに対して解決します。 
 Backslash:encode  文字列としてのオペランド中の、改行やタブ等の特殊文字を、バックスラッシュ("\\")を用いた表現に変換します。 現在以下の特殊文字が変換されます:\n、 \r、 \t、 \b、 及び \\. 
 Backslash:decode  文字列としてのオペランド中の、バックスラッシュを用いて表現された特殊文字、を本来の文字に復元します。 但し、"\\"の後に続く改行は無視されます。 
 Bean:encode  オペランドをビーンとしてXML文書に直列化します。 
 Bean:decode  XML文書として直列化されたオペランド文字列をビーンに復元します。 
 Bean:get:PROPERTY  オペランドの、PROPERTYと名付けられたビーンとしてのプロパティの値を求めます。 もしオペランドがマップあるいはリストであれば、PROPERTYに対応した要素を求めます。 
 Bean:getProperty:PROPERTY  オペランドの、PROPERTYと名付けられたビーンとしてのプロパティの値を求めます。 もしオペランドがマップあるいはリストであっても特殊な処理は行われません。 
 Bean:set:PROPERTY:PROPERTYVALUE  オペランドの、PROPERTYと名付けられたビーンとしてのプロパティの値を、PROPERTYVALUEに設定します。 もしオペランドがマップあるいはリストであれば、PROPERTYに対応した要素が、PROPERTYVALUEに設定されます。 
 Bean:setProperty:PROPERTY:PROPERTYVALUE  オペランドの、PROPERTYと名付けられたビーンとしてのプロパティの値を、PROPERTYVALUEに設定します。 もしオペランドがマップあるいはリストであっても特殊な処理は行われません。 
 Base64:encode[:ENCODING]  文字列としてのオペランドに、ENCODING(指定がなければ"utf-8")を用いて、Base64符号化を行ないます。 
 Base64:decode[:ENCODING]  Base64符号化された文字列としてのオペランドに、ENCODING(指定がなければ"utf-8")を用いて、Base64復号化を行ないます。 
 GZIP:encode or GZIP:compress  文字列としてのオペランドを、GZIP型式で圧縮します。 
 GZIP:decode or GZIP:decompress  GZIP型式で圧縮された文字列としてのオペランドを解凍します。 
 Zip:encode or Zip:compress  文字列としてのオペランドを、Zip型式で圧縮します。 
 Zip:decode or Zip:decompress  Zip型式で圧縮された文字列としてのオペランドを解凍します。 
 Hex:encode  バイト配列としてのオペランドを、16進法表記の文字列に変換します。 
 Hex:decode  16進法表記の文字列としてのオペランドを、バイト配列に復元します。 
 Mime:decode  "x/y;a=1 b=2;..."の型のMIME文字列としてのオペランドを、"{type=x、 subtype=y、 parameter={a=1、 b=2、 ...}}"の型のマップに変換します。 
 Mime:encode  "{type=x、 subtype=y、 parameter={a=1、 b=2、 ...}}"の型のマップとしてのオペランドを、"x/y;a=1;b=2;..."の型のMIME文字列に変換します。 "subtype"の値はnullでも構いません。 
 String:replaceAll:PATTERN:WITH  文字列としてのオペランドの中の、正規表現PATTERNに適合する全ての部分を、WITHで置き換えます。 
 String:replaceFirst:PATTERN:WITH  文字列としてのオペランドの中の、正規表現PATTERNに適合する最初の部分を、WITHで置き換えます。 
 String:split[:PATTERN]  文字列としてのオペランドを、与えられた正規表現PATTERN(指定されなければ",")に適合する部分で、リストに分割します。 
 String:match:PATTERN[:GROUP]  文字列としてのオペランドの中で、正規表現PATTERNのGROUP群に適合する最初の部分列あるいはnullを返します。GROUPは指定されなければ0(すなわちPATTERNの全体)とみなされます。 
 String:matchAll:PATTERN[:GROUP]  文字列としてのオペランドの中に含まれた正規表現PATTERNのGROUP群に適合する全ての部分列をリストとして返します。GROUPは指定されなければ0(則ちPATTERNの全体)とみなされます。 
 String:matchingGroups:PATTERN  文字列としてのオペランドに適合する正規表現PATTERNの全ての群をリストとして返します(最初の要素は正規表現の全体に適合する部分文字列、次の要素は最初の群に適合する部分、等)。 オペランドがPATTERNと適合しない場合には、空のリストを返します。 
 String:decompose:PATTERN[:GROUP]  文字列としてのオペランドを、与えられた正規表現PATTERNで分解し、適合しない部分と適合する部分のGROUP群の交替するリストとして返します(すなわち"split"と"matchAll"の混合されたものです)。 GROUPは指定されなければ0(則ちPATTERNの全体)とみなされます。 最初と最後の要素は(空文字列であるかもしれませんが)常に適合しない部分列です。 
 String:trim  文字列としてのオペランドの初めと終わりから空白を取り除きます。 
 String:toUpperCase  文字列としてのオペランドの全ての文字を大文字に変換します。 
 String:toLowerCase  文字列としてのオペランドの全ての文字を小文字に変換します。 
 String:capitalize  文字列としてのオペランドの最初の文字を大文字に変換します。 
 String:reverse  文字列としてのオペランドを逆転します。 
 String:multiply:COUNT  文字列としてのオペランドをCOUNT回繰り返します。 
 String:append:STRING  文字列としてSTRINGをオペランドに後に追加します。 
 String:prepend:STRING  文字列としてSTRINGをオペランドの前に追加します。 
 String:indexOf:SUBSTRING  文字列としてのオペランドに含まれる部分列SUBSTRINGが含まれればその最初のインデックスを、さもなければ-1を返します。  
 String:lastIndexOf:SUBSTRING  文字列としてのオペランドに含まれる部分列SUBSTRINGが含まれればその最後のインデックスを、さもなければ-1を返します。  
 String:substring:STARTINDEX[:ENDINDEX]  文字列としてのオペランドの、STARTINDEX位置を含んで始まり(与えられた場合にはENDINDEX位置を含まずに終る)部分文字列を返します。 もしSTARTINDEXあるいはENDINDEXが負であれば、位置は文字列の終りから数えられます(例えば、"String:substring:-2"は、最後の二文字を意味します)。 
 String:join[:GLUE]  リストあるいは配列としてのオペランドの要素を、GLUEを用いて文字列に結合します。 指定されなければ、GLUEは","と見なされます。 
 String:toCharacterList  文字列としてのオペランドを、各Characterを要素とするリストに変換します。 
 String:fromCharacterList  Characterのリストとしてのオペランドを、文字列に変換します。 
 String:toByteArray:ENCODING  ENCODINGに従い、文字列としてのオペランドを、バイト配列に変換します。 
 String:fromByteArray:ENCODING  ENCODINGに従い、バイト配列としてのオペランドを、文字列に変換します。 
 String:countWords[:PATTERN]  文字列としてのオペランドを、与えられた正規表現PATTERN(指定されなければ"[ ]+")で「単語」に分解し、その出現頻度を示すマップに変換します。 例えば、"a b b a b"は、"{a=2、 b=3}"に変換されます。 
 Type:isDouble  可能であれば、オペランドをjava.lang.Double型に変換します。 もし不可能なら、nullを返します。 
 Type:isFloat  可能であれば、オペランドをjava.lang.Float型に変換します。 もし不可能なら、nullを返します。 
 Type:isCharacter  可能であれば、オペランドをjava.lang.Character型に変換します。 もし不可能なら、nullを返します。 
 Type:isLong  可能であれば、オペランドをjava.lang.Long型に変換します。 もし不可能なら、nullを返します。 
 Type:isShort  可能であれば、オペランドをjava.lang.Short型に変換します。 もし不可能なら、nullを返します。 
 Type:isByte  可能であれば、オペランドをjava.lang.Byte型に変換します。 もし不可能なら、nullを返します。 
 Type:isString  オペランドを文字列に変換します。 
 Type:isBoolean  可能であれば、オペランドをjava.lang.Boolean型に変換します。 もし不可能なら、nullを返します。 
 Type:isList  可能であれば、オペランドをjava.util.List型に変換します。 もし不可能なら、nullを返します。 
 Type:isArray  可能であれば、オペランドを配列に変換します。 もし不可能なら、nullを返します。 
 Type:isStringArray  可能であれば、オペランドを文字列の配列に変換します。 もし不可能なら、nullを返します。 
 Type:isLocale  可能であれば、オペランドをjava.util.Locale型に変換します。 もし不可能なら、nullを返します。 オペランドは"language"、"country"、及び "variant"のプロパティを指定するマップまたはフォーム形式で符号化された文字列でも構いません。 
 Type:isTimezone  可能であれば、オペランドをjava.util.TimeZonee型に変換します。 もし不可能なら、nullを返します。 オペランドは"id"のプロパティを指定するマップまたはフォーム形式で符号化された文字列でも構いません。 
 Type:isDate[:PATTERN:LOCALE]  可能であれば、オペランドを(必要であれば与えられたPATTERNとLOCALEに基づいて)java.util.Date型に変換します。 もし不可能なら、nullを返します。 PATTERNは、java.util.SimpleDateFormatで用いられるパターン文字列です。 LOCALEとしてはjava.util.Localeのインスタンスあるいは"language"、"country"、及び"variant"を指定するマップを用いることが出来ます。 
 Type:isCalendar[:PATTERN:LOCALE]  Type:isDateと同様に、可能であれば、オペランドをjava.util.Calendarのインスタンスに変換します。不可能であれば、nullを返します。 
 Type:isNumber[:PATTERN:LOCALE]  可能であれば、オペランドを(必要であれば与えられたPATTERNとLOCALEに基づいて)java.lang.Number型に変換します。 もし不可能なら、nullを返します。 PATTERNは、java.util.NumberFormatで用いられるパターン文字列です。 LOCALEとしてはjava.util.Localeのインスタンスあるいは"language"、"country"、及び"variant"を指定するマップを用いることが出来ます。 
 Type:isSQLDate[:PATTERN:LOCALE]  Type:isDateと同様に、可能であれば、オペランドをjava.sql.Date型に変換します。 もし不可能なら、nullを返します。 
 Type:isSQLTime[:PATTERN:LOCALE]  Type:isDateと同様に、可能であれば、オペランドをjava.sql.Time型に変換します。 もし不可能なら、nullを返します。 
 Type:isSQLTimestamp[:PATTERN:LOCALE]  Type:isDateと同様に、可能であれば、オペランドをjava.sql.Timestamp型に変換します。 もし不可能なら、nullを返します。 
 Type:isURI  可能であれば、オペランドをjava.net.URI型に変換します。 もし不可能なら、nullを返します。 
 Type:isURL[:CONTEXT]  可能であれば、オペランドを、(もし与えられれば、CONTEXT URLの中で)java.net.URL型に変換します。 もし不可能なら、nullを返します。 
 Type:isFile[:PARENTFILE]  可能であれば、ファイル名あるいはURIとしてのオペランドを、(もし与えられれば、PARENTFILEの子として)java.io.File型に変換します。 もし不可能なら、nullを返します。 
 Type:isInternetAddress  可能であれば、オペランドを、正しいインターネットメールアドレス(javax.mail.internet.InternetAddress型)に変換します。 もし不可能なら、nullを返します。 
 Type:numericValueOf  文字としてのオペランドが正の整数を表す場合はその数を返します。 
 Type:unicodeBlockOf  文字としてオペランドのユニコードのブロックを返します。 
 Type:charAsNumber  文字としてのオペランドに対応した数値コードを返します。 
 Type:numberAsChar  整数としてのオペランドの数値コードに対応した文字を返します。 
 Type:ifEqual:TARGET:IFOBJECT[:ELSEOBJECT]  もしオペランドがTARGETに等しければIFOBJECTを、さもなければELSEOBJECT(指定されなければオペランド)を返します。 
 Type:isEqual:TARGET  もしオペランドがTARGETに等しければ「真」の論理値(java.lang.Boolean.TRUE)を、さもなければnullを返します。 
 Type:isNotEqual:TARGET  もしオペランドがTARGETに等しくなければ「真」の論理値(java.lang.Boolean.TRUE)を、さもなければnullを返します。 
 Type:ifNotEqual:TARGET:IFOBJECT  もしオペランドがTARGETに等しくなければIFOBJECTを、さもなければオペランドを返します。 
 Type:ifEmpty:IFOBJECT[:ELSEOBJECT]  もしオペランドが空であればIFOBJECTを、さもなければELSEOBJECT(指定されなければオペランド)を返します。 
 Type:ifNotEmpty:IFOBJECT  もしオペランドが空でなければIFOBJECTを、さもなければオペランドを返します。 
 Type:isEmpty  もしオペランドが空であれば「真」の論理値(java.lang.Boolean.TRUE)を、さもなければnullを返します。 
 Type:isNotEmpty  もしオペランドが空でなければ「真」の論理値(java.lang.Boolean.TRUE)を、さもなければnullを返します。 
 Type:length  もし可能であれば、オペランドの(コレクションや配列としての)長さを、さもなければ-1を返します。 
 Type:clear  コレクションとしてのオペランドを空にして返します。 
 Type:add:OBJECT  可能であれば、コレクションとしてのオペランドに、OBJECTを要素として追加します。 
 Type:addAll:OBJECT  可能であれば、コレクションとしてのオペランドに、コレクションまたは配列としてのOBJECTの全ての要素を追加します。 
 Type:remove:OBJECT  コレクションとしてのオペランドから、OBJECTを取り除きます。 
 Type:removeAll:OBJECT  可能であれば、コレクションとしてのオペランドから、コレクションまたは配列としてのOBJECTの全ての要素を取り除きます。 
 Type:retainAll:OBJECT  コレクションとしてのオペランドの要素の内、OBJECT(配列またはコレクション)に属さない全ての要素を取り除きます。 
 Type:ifContains:OBJECT:ELSEOBJECT  コレクションとしてのオペランドにOBJECTが含まれていればオペランドを、さもなければELSEOBJECT(指定されなければnull)を返します。 
 Type:ifContainsAll:OBJECT  コレクションをしてのオペランドにOBJECT(配列またはコレクション)の全ての要素が含まれていればオペランドを、さもなければnullを返します。 
 Type:ifNull:IFOBJECT[:ELSEOBJECT]  もしオペランドがnullであればIFOBJECTを、さもなければELSEOBJECT(指定されなければnull)を返します。 
 Type:ifNotNull:IFOBJECT  オペランドがnullでなれけばIFOBJECTを、さもなければnullを返します。 
 Type:isNull  オペランドがnullであればBoolean.TRUEを、さもなければnullを返します。 
 Type:isNotNull  オペランドがnullでなければBoolean.TRUEを、さもなければnullを返します。 
 Type:isClass:CLASS  もし可能であれば、オペランドを与えられたCLASSのインスタンスとして、さもなければnullを返します。 CLASSとしては、クラスオブジェクトあるいはクラス名を使うことができます。 もしCLASSが"java.lang.Integer"等の原始型を包むものであれば、オペランドは、可能であればそのクラスのインスタンスに変換されますが、さもなければ、オペランドは、それが与えられたクラスのインスタンスであるときに限って返されます。 
 Type:forName  可能であれば、文字列としてのオペランドを名前に持つクラスオブジェクトを返します。 
 Type:indexOfSubList:SUBLIST  リストとしてのオペランドに部分列としてSUBLISTが含まれればその最初のインデックスを、さもなければ-1を返します。 
 Type:lastIndexOfSubList:SUBLIST  リストとしてのオペランドに部分列としてSUBLISTが含まれればその最後のインデックスを、さもなければ-1を返します。 
 Type:subList:START[:END]  リストとしてのオペランドのSTARTインデックスを含んで始まり、もし与えられればENDインデックスを含まずに終わる部分列を返します。START及びENDは終わりからのインデックスとして負の整数でも構いません。 
 Type:makeSynchronized  Collectionとしてのオペランドを同期化したものを返します。  
 Type:makeUnmodifiable  Collectionとしてのオペランドを不変化したものを返します。  
 Format:date[:PATTERN:LOCALE]  日付としてのオペランドを、指定されたPATTERNとLOCALEに従ってフォーマットします。 PATTERNはjava.util.SimpleDateFormatで用いられる書式です。 LOCALEとしては、java.util.Localeのインスタンスあるいは"language"、"country"及び"variant"の値を指定したマップを用いることができます。 
 Format:number[:PATTERN:LOCALE]  数値としてのオペランドを、指定されたPATTERNとLOCALEに従ってフォーマットします。 PATTERNはjava.util.NumberFormatで用いられる書式です。 LOCALEとしては、java.util.Localeのインスタンスあるいは"language"、"country"及び"variant"の値を指定したマップを用いることができます。 
 System:sleep  実行中のスレッドを、1/1000秒単位で与えられたオペランドの時間休止します。 
 System:yield_  実行中のスレッドの実行権を他のスレッドに譲ります。 
 System:invoke  動的にjavaのメソッドを呼び出します。 オペランドは次のプロパティをもつ多層マップです: "object" (メソッドを呼び出す対象となるオブジェクト)、 "class" (静的なメソッドの場合それを持つクラス)、 "method" (メソッドの名前; "*"はコンストラクタを意味し、"."(ドット)で始まる文字列はフィールド名を意味します)、 "_" (引数のリスト; 各要素は{type=xxx、 value=xxx}の形のマップあるいは引数型と同じ型を持つオブジェクト). 引数の型としては、完全なクラス名、"String"等の"java.lang."を省略したクラス名、"int"、"float"等の原始型名、またはそれ等の配列として"String[]"等を用いることができます。 詳しくは下の動的なメソッドの呼び出しを御覧下さい。 
 System:uniqueId_  (どのスレッドからでも)呼ばれる度に新しい整数を返します。 
 System:setProperties  マップまたはフォーム形式で符号化された文字列としてのオペランドのキーと値の組からシステムプロパティを設定します。 
 System:getProperties_  現在のシステムプロパティをマップとして返します。 
 System:currentTimeMillis_  現在のシステム時間を1000分の1秒単位の整数として返します。 
 System:currentTime_  現在のシステム時間をjava.util.Dateとして返します。 
 System:createCache  マップまたはフォーム形式で符号化された文字列としてのオペランドの指定に従ってキャッシュ(java.util.LinkedHashMapの実装)を作成します。現在次のプロパティがサポートされています: "initialCapacity" (指定されなければ16), "loadFactor" (指定されなければ0.75), "maxSize" (指定されなければ16), "type" (指定されなければ"LRU"、または"FIFO")。 もし更に"lifespan"が1000分の1秒単位で指定されれば、指定されたlifespanより長い時間キャッシュされているデータはヒットした際に自動的に無効化され取り除かれます。 
 Security:digest:ALGORITHM  与えられたALGORITHM("MD5"、"SHA"等)に従って、文字列としてのオペランドのダイジェストを返します。 
 Security:secureRandom:ALGORITHM  与えられたALGORITHM("SHA1PRNG"等)に従って、与えられた整数としてのオペランドと同じバイト長を持つ乱数を返します。 もしオペランドが整数でない文字列の場合には、その文字列と同じ長さの乱数を返します。 
 Security:generateSecretKey_:ALGORITHM  与えられたALGORITHM("AES"、"DES"、"DESede"、"Blowfish"等)に従った暗号鍵を作成し返します。 
 Security:encrypt:KEY:ALGORITHM  文字列としてのオペランドを、与えられたKEYとALGORITHMに従って暗号化します。 ALGORITHMに対応する長さであればどのようなKEYでも使うことが出来ます。 
 Security:decrypt:KEY:ALGORITHM  与えられたKEYとALGORITHMに従って、文字列としてのオペランドを復号化します。 
 Thread:sleep  System:sleepと同義です。 
 Thread:yield_  System:yieldと同義です。 
 Thread:currentThread_  現在実行されているスレッドを返します。 
 Thread:join:WAIT  スレッドとしてのオペランドが停止するまで1000分の1秒単位でWAITの間待機します。 
 Thread:interrupt  スレッドとしてのオペランドに割り込みます。 
 Thread:maxPriority_  スレッドの最大優先度を返します。 
 Thread:minPriority_  スレッドの最小優先度を返します。 
 Thread:normPriority_  スレッドの通常優先度を返します。 
 Thread:stop  スレッドとしてのオペランドを停止します(推奨されません)。 
 Thread:suspend  スレッドとしてのオペランドを中断します(推奨されません)。 
 Thread:resume  スレッドとしてのオペランドを再開します(推奨されません)。 
 Number:toHexString[:FILLER]  数値としてのオペランドを、十六進文字列に変換します。 FILLERが指定されれば、 桁の左側を補填するのに用いられます(FILLERが"0000"であれば、"caf"は"0caf"に補填されます)。 
 Number:fromHexString  十六進文字列としてのオペランドを、Longに変換します。 
 Number:toBinaryString[:FILLER]  数値としてのオペランドを、二進文字列に変換します。FILLERが指定されれば、桁の左側を補填するの用いられます。 
 Number:fromBinaryString  二進文字列としてのオペランドを、Longに変換します。 
 Number:toOctalString[:FILLER]  数値としてのオペランドを、八進文字列に変換します。FILLERが指定されれば、桁の左側を補填するの用いられます。 
 Number:fromOctalString  八進文字列としてのオペランドを、Longに変換します。 
 Number:e_  定数"e"(自然対数基底)を返します。 
 Number:pi_  定数"pi"(三角比)を返します。 
 Number:abs  Doubleとしてのオペランドの絶対値を返します。 
 Number:max_:X:Y  XとYのDoubleとしての最大値を返します。 
 Number:min_:X:Y  XとYのDoubleとしての最小値を返します。 
 Number:ceil  Doubleとしてのオペランドの天井整数をLongとして返します。 
 Number:floor  Doubleとしてのオペランドの床整数をLongとして返します。 
 Number:round  Doubleとしてのオペランドに最も近い整数をLongとして返します。 
 Number:exp  Doubleとしてのオペランドの指数関数値を返します。 
 Number:log  Doubleとしてのオペランドの対数関数値を返します。 
 Number:sqrt  Doubleとしてのオペランドの平方根を返します。 
 Number:pow_:X:Y  XをYで累乗した値を返します。 
 Number:sin  Doubleとしてのオペランドの正弦関数値を返します。 
 Number:cos  Doubleとしてのオペランドの余弦関数値を返します。 
 Number:tan  Doubleとしてのオペランドの正接関数値を返します。 
 Number:asin  Doubleとしてのオペランドの逆正弦関数値を返します。 
 Number:acos  Doubleとしてのオペランドの逆余弦関数値を返します。 
 Number:atan  Doubleとしてのオペランドの逆正接関数値を返します。 
 Number:toDegrees  ラジアンとしてのオペランドを度に変換します。 
 Number:toRadians  度としてのオペランドをラジアンに変換します。 
 Calendar:get:PROPERTY  java.util.Calendarとしてのオペランドの、与えられたPROPERTYの値を返します(例えば"DAY_OF_WEEK"は週の曜日を返します)。 
 Calendar:set:PROPERTY:VALUE  java.util.Calendarとしてのオペランドの、与えられたPROPERTYの値をVALUEに設定し、もし成功すればオペランドを、さもなければnullを返します。 
 Calendar:add:PROPERTY:VALUE  java.util.Calendarとしてのオペランドの、与えられたPROPERTYの値にVALUEを加え、もし成功すればオペランドを、さもなければnullを返します。 
 Calendar:roll:PROPERTY:VALUE  java.util.Calendarとしてのオペランドの、与えられたPROPERTYの値をVALUE分「回し」(より大きな単位を変えずに加え)、もし成功すればオペランドを、さもなければnullを返します。 
 Calendar:monthly  java.util.Dateあるいはjava.util.Calendarとしてのオペランドの日付を今日とした、その月のカレンダーを、多層マップ構造として返します。 以下のプロパティが設定されます: "numberOfWeeks" (週の数)、 "week._" (各週のマップ; 例えば"week._[0]"は第一週)、 "week._[n]._" (第n週の曜日のリスト)、 "week._[n].dayIndexStart" (その月の第n週の最初の曜日の包含的インデックス; 最初の週以外では0)、 "week._[n].dayIndexEnd" (その月の第n週の最後の曜日の包含的インデックス; 最後の週以外では6)、 "week._[n].dayIndexToday" (第n週に於ける今日のインデックス; もし今日が第n週でなければ空)、 "today.date" (今日の日付)、 "today.weekIndex" (今日の属する週のインデックス)、 "today.dayIndex" (今日の属する週での今日のインデックス)、 "lastDayOfMonth.date" (その月の最後の日の日付)、 "lastDayOfMonth.dayIndex" (その月の最後の日のその月の最後の週におけるインデックス)、 "firstDayOfMonth.date" (その月の最初の日の日付)、 "firstDayOfMonth.dayIndex" (その月の最初の日のその月の最初の週に於けるインデックス)、 "nextMonth" (一ヶ月後の今日の日付)、 "lastMonth" (一ヶ月前の今日の日付)、 "nextYear" (一年後の今日の日付)、 "lastYear" (一年前の今日の日付)、 "thisWeek" (今日を含む週)。 
 Random:pick  文字列としてのオペランドから、ランダムに文字を選びます。 同じ文字を重複して用いることで分布を調整することが出来ます(例えば、もしオペランドが"0000000001"であれば、"0"の返される確率は"1"の九倍となります。) 
 Random:number  数値としてのオペランドよりも小さな正の乱数を、Doubleとして返します。 
 _JSP:eval[:CONTROLMAP]  CONTROLMAP(マップまたは符号化された文字列)の指定に従って、オペランドをELとして評価します。 [[#eval][<m:eval>]と同じように、CONTROLMAPは以下のような属性を指定します: "pattern"、 "recursive"、 "evalCodec"、 "allowGroup"、 "environment"。 
 _JSP:applyCodec:CODEC  オペランドにCODECを、コーデックとして適用します。 
 _JSP:applyFilter:CONTROLMAP  <m:filter>のように、オペランドにフィルタをかけます。 CONTROLMAPは以下の属性を指定します: "include"、 "break"、 "apply"、 "applyCodec" 
 _JSP:dynamicMap  マップとしてのオペランドから、"get"及び"put"操作に際してそれぞれ"getCodec"及び"putCodec"で指定されたコーデックを適用する動的マップを作成します。 指定されたコーデックは、get/put操作のkey"及び"value"の値を持ったオペランドマップに適用されます。 コーデックが適用される際には、"_"(アンダースコア)変数の値がオペランドマップに割り当てられます。 詳しくは動的マップを御覧下さい。 
 _JSP:dynamicIterator  マップとしてのオペランドから、"hasNext"及び"next"操作に際してそれぞれ"hasNextCodec"及び"nextCodec"で指定されたコーデックを適用する動的反復子を作成します。 指定されたコーデックは動的反復子自身に適用されます。 以下の属性を設定することが出来ます: "collection" (反復を行なうコレクション)、 "next" (次のオブジェクト;"collection"や"nextCodec"より優先されます)、 "hasNext" (次のオブジェクトの存在を示す真理値;"collection"や"hasNextCodec"より優先されます)、 "index" (反復する毎に加算される、0から始まるインデクス)。 詳しくは下の動的反復子を御覧下さい。 
 _JSP:encodeURL  必要であれば、URLとしてのオペランドに、セッションIDを付加します。 
 _JSP:encodeRedirectURL  必要であれば、転送URLとしてのオペランドに、セッションIDを付加します。 
 _JSP:getRealPath  URLとしてのオペランドに対応したファイルシステムのパスを返します。 
 _JSP:getMimeType  ファイル名としてのオペランドに対応したmime型を返します。 
 _JSP:getResource  パスとしてオペランドに対応したリソースURLを返します。 
 _JSP:getMessageMap_[:]  リソースよりMessageMapを作成します。必要であればオペランドとして次のプロパティを持つマップまたはフォーム形式で符号化された文字列を指定することが出来ます: "basename" (リソースのbase名), "defaultValue" (メッセージが定義されていない場合に返されるべき文字列)。 詳しくは下のMessageMapをご覧下さい。 
 _JSP:sort[:CONTROLMAP]  リストとしてのオペランドを次のようなCONTROLMAPの指定に従って整列します: "codec" (比較の前に各要素に適用されるコーデック), "equal" (二つの要素"${_operand.x}"と"${_operand.y}"が「等しい」と見なされる時trueを返すコーデック), "more" (要素"${_operand.x}"が"${_operand.y}"より「大きい」とみなされる時trueを返すコーデック)。 
 _JSP:max[:CONTROLMAP]  Collectionとしてのオペランドの中の「最大値」を次のようなCONTROLMAPの指定に従って求めます: "codec" (比較の前に各要素に適用されるコーデック), "equal" (二つの要素"${_operand.x}"と"${_operand.y}"が「等しい」と見なされる時trueを返すコーデック), "more" (要素"${_operand.x}"が"${_operand.y}"より「大きい」とみなされる時trueを返すコーデック)。 
 _JSP:min[:CONTROLMAP]  Collectionとしてのオペランドの中の「最小値」を次のようなCONTROLMAPの指定に従って求めます: "codec" (比較の前に各要素に適用されるコーデック), "equal" (二つの要素"${_operand.x}"と"${_operand.y}"が「等しい」と見なされる時trueを返すコーデック), "more" (要素"${_operand.x}"が"${_operand.y}"より「大きい」とみなされる時trueを返すコーデック)。 
 File:list  ファイルディレクトリとしてのオペランド内のファイル名を、文字列のリストとして返します。 オペランドとしては、ディレクトリ名あるいはjava.io.Fileのインスタンスを用いることが出来ます。 
 File:listFiles  ファイルディレクトリとしてのオペランド内のファイルを、ファイル(java.io.File)のリストとして返します。 オペランドとしては、ディレクトリ名あるいはjava.io.Fileのインスタンスを用いることが出来ます。 
 File:delete  ファイルとしてのオペランドを削除します。 オペランドとしては、ファイル名またはjava.io.Fileオブジェクトを用いることが出来ます。 成功すればBoolean.TRUEを、さもなければnullを返します。 
 File:rename:NEWNAME  ファイルとしてのオペランドの名前を、NEWNAMEに変更します。 オペランドとしては、ファイル名またはjava.io.Fileオブジェクトを用いることが出来ます。 成功すればファイルとしてのオペランドを、さもなければnullを返します。 
 File:read[:ENCODING]  ファイルとしてのオペランドの内容を、ENCODING(指定されなければ"iso-8859-1")に従って、文字列として読みこみます。 
 File:write:OUTFILE[:ENCODING]  文字列としてのオペランドを、ENCODING(指定されなければ"iso-8859-1")を従って、OUTFILEで指定されたファイルに書き込みます。 成功すればオペランドを、さもなければnullを返します。 
 File:append:OUTFILE[:ENCODING]  文字列としてのオペランドを、ENCODING(指定されなければ"iso-8859-1")に従って、OUTFILEで指定されたファイルに追加します。 成功すればオペランドを、さもなければnullを返します。 
 File:mkdir[:CREATEPARENTS]  オペランドで指定されたディレクトリを作成します。 成功すればオペランドを、さもなければnullを返します。 nullでないCREATEPARENTSが指定されれば、必要な親ディレクトリも作成されます。 
 File:mkdirs  "File:mkdir:true"と同義です。 
 File:type  ファイルとしてのオペランドのmime型を返します。 オペランドとしては、ファイル名またはjava.io.Fileオブジェクトを用いることが出来ます。 
 File:tempfile  テンプレートとしてのオペランドを用いて、一時的なファイルを作成します。 オペランドは"prefix*suffix"の形の文字列です; 例えば、"TEMP*.dat"は"TEMP"で始まり".dat"で終るファイル名を持つ一時的なファイルを作成します。 もし"prefix"が"/"を含めば、初めから最後の"/"に至る部分はディレクトリ名として扱われます(例えば"/tmp/TEMP*.dat")。 もしオペランドがnullであれば、"temp*"がテンプレートとして用いられます。 

Javaの用語を使えば、コーデックとは、一つ以上のオブジェクト引数を持つ公開された関数(静的メソッド)です。すなわち、次のような型を持つものです:

public static Object codec(Object operand, Object opt1, Object opt2, ...)

組込み済のコーデックは、"com.micronova.util.codec"パッケージの中でクラス名の前に"Codec"を付けて定義されています。 例えば"URL:encode"は"com.micronova.util.codec.CodecURL"で定義された関数"encode"に対応しています。

"."(ドット)を含む完全なクラス名を使えば、組みこまれていないコーデックを呼び出すことができます。例えば"com.yourcompany.codec"パッケージの中の"abc"という名のコーデックは、"com.yourcompany.codec:abc"として指定できます。

必要とあれば、明示的でない("implicit"な)引数を持つ次のような型のコーデックを呼び出すことも出来ます:

public static Object codec(Object implicit1, Object implicit2, ..., Object operand, Object opt1, Object opt2, ...)

明示的でない引数は、次のように指定することが出来ます:

CODECCLASS:CODECNAME;implicit1;implicit2;...:opt1:opt2:...

もしコーデックの名前の前に"_"(アンダースコア)が付けられれば、現在のpageContextの値が、明示的でない引数として用いられます。例えば、"_JSP:eval"は"JSP:eval;@{pageContext}"と同じです。

4 局所変数

全てのYUZUタグは本文を持つことが出来ます。 本文中で一時的に値を割り当てる変数が必要な場合には、local属性を用いて「局所変数」として扱われるべきページ変数の名前をコンマで区切られたリストとして指定することが出来ます。 「局所変数」として指定された変数の値は、タグ本文が処理される前に保存され、処理後に復元されます。

次の例はまず"a=AAA, b=BBB"を、続いて"a=A, b=B"を出力します:

<m:set var="a" value="A"/>

<m:set var="b" value="B"/>

<m:out local="a,b">
  <m:set var="a" value="AAA"/>
  <m:set var="b" value="${a}"/>
  <m:out value="a=${a}, b=${b}"/>
</m:out>

<m:out value="a=${a}, b=${b}"/>

特殊な局所変数として、"_"(アンダースコア)変数には準備段階で設定されたタグ値が割り当てられます。 例えば:

<m:set var="map" className="java.util.HashMap">
  <m:set property="a" value="A"/>
  <m:set property="b" value="B"/>
  <m:set property="c" value="${_.a}${_.b}"/>
</m:set>

<m:out value="${map.c}"/>

は"AB"を出力します。

attribute属性を用いてタグ値が変更されれば、 "_"変数の値も変更されます。 例えば:

<%-- "a-a/a-a"を出力します。 --%>

<m:out value="a">

  <%-- タグ値を"a-a"に変更します。 --%>

  <m:set attribute="value" value="${_}-${_}"/>

  <%-- タグ値を"a-a/a-a"に変更します。 --%>

  <m:set attribute="value" value="${_}/${_}"/>

</m:out>

5 共通の属性

全てのYUZUタグは通常以下の属性をサポートします("EL"型の属性では文字列中の"@{"が"${"に変換されます。):

 名前  型  説明  初期値 
 value  オブジェクト  設定されるタグ値  null 
 className  文字列  タグ値がインスタンスとして設定されるクラス名  null 
 var  文字列  タグ値が割り当てられる変数名  null 
 scope  文字列  var変数の有効範囲("page"、"request"、"session"、または"application")  page 
 target  オブジェクト  割り当てられるpropertyを持つビーン  null 
 property  文字列  割り当てられるtargetのプロパティ名  null 
 attribute  文字列  設定されるタグ属性の名前  null 
 default  オブジェクト  タグ値が空(あるいはtestELの評価値がfalse)である場合に用いられる初期値  null 
 test  EL  評価値がfalseであればdefaultが用いられるEL  null 
 prepareCodec  EL  本文処理の前に、準備されたタグ値に適用されるコーデック  null 
 importCodec  EL  輸入の際に、本文を処理して得られる文字列に適用されるコーデック  null 
 processCodec  EL  処理後のタグ値に適用されるコーデック  null 
 codec  EL  processCodecの別名  null 
 assignCodec  EL  割り当ての際にassignELの評価値あるいはタグ値に適用されるコーデック  null 
 exportCodec  EL  輸出の際にexportELの評価値あるいはタグ値に適用されるコーデック  null 
 cleanupCodec  EL  タグ処理終了の際に、準備されたタグ値に適用されるコーデック;もし例外が生じても無視されます  null 
 assign  EL  タグ値を"_"(アンダースコア)を用いて参照した、割り当てられる値を示すEL  ${_} (タグ値) 
 export  EL  タグ値を"_"(アンダースコア)を用いて参照した、輸出される値を示すEL  ${_} (タグ値) 
 doesExport  文字列  "always"に設定されると、常に輸出が行なわれます  default 
 local  文字列  コンマで区切られた局所変数名のリスト  null 

6 Tags

YUZUは以下のタグから成っています:

 名前  要約 
 set  変数の値の設定。 
 out  変数の値のを出力 
 map  多層マップ構造の操作 
 eval  ELの評価 
 param  構造化されたフォーム引数の操作 
 call  JSPの呼び出し 
 return  呼び出しの際の返し値の設定 
 value  親タグのタグ値の変更 
 include  HTTPクライアント 
 log  ログ出力 
 postData  POSTされたHTTPデータの操作 
 throw  例外の放出 
 synchronized  タグ本文処理の同期化 
 query  ELを埋めこんだSQL検索文 
 update  ELを埋めこんだSQL実行文 
 response  HTTPの応答の制御 
 system  外部処理 
 filter  要素の選別 
 parseHtml  HTML文書の解析 
 mail  メールの送付 
 mailFolder  メールの受信 

6.1 set

<m:set>はJSTLの<c:set>の拡張です。 YUZUの共通属性の全てを持ち、他のYUZUタグの基本型となっています(処理段階では何も行ないません)。

6.2 out

<m:out>は基本的には<m:set>と同じですが、以下の属性を持ちません: varscopetargetpropertyattributeassignassignCodec

6.3 map

<m:map>は準備段階においてマップ(キーと値の対)をタグ値として設定します。 与えられたキーに対する値は、そのキーをプロパティとして用いて参照または設定をすることができます。 例えば:

<%-- マップを初期化します。 --%>

<m:map var="x"/>

<m:set target="${x}" property="a" value="alpha"/>

<m:out value="aの値は${x.a}"/>

は次の様に出力を行ないます。:

aの値はalpha

マップは、次の様に入れ子状に「多層化」することが出来ます:

<%-- 多層マップを設定します。 --%>

<m:map var="account">
  <m:set property="balance" value="100"/>
  <m:map property="customer">
    <m:set property="lastName" value="山田"/>
    <m:set property="firstName" value="太郎"/>
  </m:map>
</m:map>

すると:

<m:out value="${account.customer.lastName}${account.customer.firstName}"/>さんの口座残高は<m:out value="${account.balance}"/>円です。

は次のように出力します:

山田太郎さんの口座残高は100円です。

上の例で、"firstName"を変更するには、次のような二通りの方法があります:

<%-- "account.customer"をtargetとして --%>

<m:set target="${account.customer}" property="firstName" value="次郎"/>

<%-- または、"account"をtargetとし、"@"で始まる多層化されたプロパティ名を用いて --%>

<m:set target="${account}" property="@customer.firstName" value="次郎"/>

プロパティ名が"@"で始まる場合、残りの文字列は、ドット(".")記法を用いた多層マップのプロパティとして扱われます。 もし"@"が省かれた場合は、ドットを含む文字列の全てが単層のプロパティ名として扱われます(必要であれば、プロパティ名の前に"#"を付けることで、残りの文字列が例え"@"で始まっていても、強制的に単層のプロパティ名として扱わせることが出来ます)。

多層プロパティ名が用いられた場合、中間に位置するマップは、未設定であれば自動的に作成されます。たとえば、上の例のマップは、次の様にして作成することも出来ます:

<%-- 多層プロパティ名を用いた初期化 --%>

<m:map var="account">
  <m:set property="@balance" value="100"/>
  <m:set property="@customer.lastName" value="山田"/>
  <m:set property="@customer.firstName" value="太郎"/>
</m:map>
この場合、中間のマップである"${account.customer}"は自動的に作成され、"{firstName=John, lastName=Doe}"の様に初期化されます。

特別なプロパティとして"__encoded"(二つのアンダースコア)を使うと、多層化マップを、フォーム型式("x=a&y=b&...")に符号化された文字列に変換することが出来ます。 次のコード:

<m:out value="${account.__encoded}"/>

の出力は以下の通りです:

balance=100&customer.lastName=Doe&customer.firstName=John

"__encoded"の代わりに"__encodedSorted"を使えば、符号化の際にキーの名前を整列することができます。

逆にフォーム型式で符号化された文字列から次のようにマップを初期化することも出来ます:

<m:map var="account">
  <m:set property="__encoded">
    balance=100&customer.lastName=Doe&customer.firstName=John
  </m:set>
</m:map>

各々のマップには特殊な要素として"_" (アンダースコア)という「疎」なリストが備わっています(「疎」というのは、任意のインデックスの要素を任意の順に設定できるという意味です)。 "_"リストの要素は"@_.property"という形の多層プロパティを用いて設定できます。ここで"property"の部分は整数、"*", または"*"に続く整数で、割り当て段階と同様にリストのインデックスを表します。例えば:

<m:map var="map">
  <m:set property="@_.5" value="五番目"/>
  <m:set property="@_.2" value="二番目"/>
  <m:set property="@_.*" value="最後"/>
</m:map>

<c:forEach var="element" items="${map._}" varStatus="status">
  <m:out value="${status.index}:${element}"/>
</c:forEach>

は次のように出力します:

0: 1: 2:二番目 3: 4: 5:五番目 6:最後

"_"リストの要素は、"_.index=xxx"、または要素がマップの場合には"_.index.key=value"の形で符号化されます。 例えば:

<m:map export="@{_.__encodedSorted}">
  <m:set property="@_.*" value="名前"/>
  <m:map property="@_.*">
    <m:set property="lastName" value="山田"/>
    <m:set property="firstName" value="太郎"/>
  </m:map>
  <m:map property="@_.*">
    <m:set property="lastName" value="山田"/>
    <m:set property="firstName" value="花子"/>
  </m:map>
</m:map>

は次のように出力します:

_.0=名前&_.1.firstName=太郎&_.1.lastName=山田&_.2.firstName=花子&_.2.lastName=山田

"_"以外の"_"で始まる名前を持つプロパティはキーのリストには現れず、source属性やプロパティを用いても複製されません。

source属性を用いると、<m:map>タグを、他のマップ、フォーム型式に符号化された文字列、またはマップまたはフォーム型式に符号化された文字列を要素にもつリストから、初期化することが出来ます(sourceがリストの場合は、"_"リストが初期化されます)。例えば:

<%-- 符号化された文字列からマップを初期化します --%>

<m:map var="x" source="a=alpha&b=beta"/>

<%-- "x"を複製します --%>

<m:map source="${x}"/>

<%-- "_"リストを初期化します。"{_=[{a=1}, {b=2}, {c=3}, {d=4}, {e=5}]}"が出力されます。 --%>

<m:set var="list" value="a=1,b=2,c=3,d=4,e=5" codec="String:split:,"/>

<m:map source="${list}"/>

また、attribute属性(または"__source"プロパティ)を用いて、タグの本文中でsourceを設定することも出来ます。 この場合、既に存在するキーの値は上書きされます:

<%-- "a=A&b=beta&c=C"を出力します --%>

<m:map source="a=alpha&b=beta" export="@{_.__encodedSorted}">
  <m:set attribute="source" value="a=A&c=C"/>
  <%-- または <m:set property="__source" value="a=A&c=C"/> --%>
</m:map>

"source"は"浅い"複製しか行ないませんので、ご注意下さい。

特別なプロパティ名は以下の通りです(全て二つのアンダースコアで始まります; "参照/設定"はそのプロパティ名が値を参照または設定する際のどちらに使用出来るかを示します):

 名前  説明  型  参照/設定 
 __keyList  キーのリスト  リスト  参照 
 __valueList  値のリスト  リスト  参照 
 __entryList  キーと値の対のリスト  リスト  参照 
 __encoded  フォーム型式に符号化された文字列  文字列  参照/設定 
 __param  フォーム型式に符号化されたキーと値の対から成るマップ  マップ  参照/設定 
 __keyListSorted  整列されたキーのリスト  リスト  参照 
 __entryListSorted  整列されたキーと値の対のリスト  リスト  参照 
 __encodedSorted  キーで整列された__encoded  文字列  参照 
 __listSize  "_"リストの長さ  整数  参照 
 __listActualSize  「疎」なリストとしての"_"に実際に含まれている要素の数  整数  参照 
 __source  マップ、リスト、またはフォーム型式に符号化された文字列から複製  マップ/リスト/文字列  設定 

<m:map>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 source  オブジェクト  マップの複製元  null 
 bodyProperty  文字列  もしnullでなければ、タグの本文を処理して得られた文字列がこのプロパティに割り当てられます  null 

6.4 eval

<m:eval>はタグ値を、任意のパターン(特に設定されなければ"@{...}")を"${...}"に代用してELとして評価します。 例えば、次のコード:

<m:set var="a" value="3"/>
<m:set var="b" value="5"/>

<m:eval>
  aは@{a}、bは@{b}、そしてa + bは@{a + b}
</m:eval>

は次のように出力します:

aは3、bは5、そしてa + bは8

"${...}"に代用される正則表現パターンはpattern属性を用いて指定することが出来ます(正則表現については例えばSun tutorialを御覧下さい)。 pattern属性の値の正則表現の最初のグループ(括弧で囲まれた部分)に適合する文字列がELの"${...}"の内部として用いられます。 特に設定されなければ、patternの値は"[@]\{([^}]*)\}"に設定されています。 次の二つは同等となります:

<%-- 初期値パターンを用いた場合 --%>

<m:eval>
  aは@{a}、bは@{b}
</m:eval>

<%-- "[[XXX]]"パターンを用いた場合 --%>

<m:eval pattern="\[\[([^\]]*)\]\]">
  aは[[a]]、bは[[b]]
</m:eval>

もしpattern属性の値に"("(括弧)が含まれていなければ、その値は"{...}"に先行する文字列と見なされ、"\{([^}]*)\}"が自動的に付加されます。 例えば、次の例では、"!{...}"が用いられます:

<%-- "!{....}"パターンを用いた場合 --%>

<m:eval pattern="[!]">
  aは!{a}、bは!{b}
</m:eval>

evalCodec属性を用いて埋め込まれた各ELパターンの評価値にコーデックを適用することができます:

<%-- "XML:encode"を適用 --%>

<m:set var="text" value="<B>太字</B>"/>

<m:eval evalCodec="XML:encode">
これは@{text}.
</m:eval>

は文字どおりには次のような出力を行ないます:

This is &lt;B&gt;太字&lt;/B&gt;.

environment属性を用いると、EL中で使われる"_"(アンダースコア)変数の値を設定することが出来ます:

<%-- 評価されるEL --%>

<m:set var="expr">
  aは@{_.a}、bは@{_.b}
</m:set>

<%-- 環境1の設定 --%>

<m:map var="env1">
  <m:set property="a" value="AAA1"/>
  <m:set property="b" value="BBB1"/>
</m:map>

<%-- 環境2の設定 --%>

<m:map var="env2">
  <m:set property="a" value="AAA2"/>
  <m:set property="b" value="BBB2"/>
</m:map>

<%-- "expr"を環境1に応じて評価 --%>

<m:eval environment="${env1}" value="${expr}"/>

<%-- "expr"を環境2に応じて評価" --%>

<m:eval environment="${env2}" value="${expr}"/>

必要であればrecursive属性の値を"true"とすることで、再帰的なELの評価を行なうことも出来ます。 次のコード:

<m:set var="welcomeMessage" value="@{userName}さん、こんにちは"/>
<m:set var="userName" value="太郎"/>
<m:eval recursive="true">@{welcomeMessage}</m:eval>

は以下のように出力します:

太郎さん、こんにちは

<m:eval>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 pattern  文字列  ELとして扱われるパターン  [@]\\{([^}]*)\\} 
 recursive  真理値  もし真であれば再帰的評価を行ないます  false 
 evalCodec  EL  埋め込まれた各ELの評価値に適用されるコーデック  null 
 allowGroup  真理値  ELの値の中で正規表現のグループ指定("$1"等)の使用を許す  false 
 environment  オブジェクト  "_"変数の値を設定  null 

必要があれば、タグの代わりに"_JSP:eval"コーデックを使用することも出来ます。 例えば:

<%-- 以下の二つは同じとなります --%>

<m:eval value="x is @{param.x}" evalCodec="XML:encode"/>

<m:out value="x is @{param.x}" codec="_JSP:eval:evalCodec=XML\:encode"/>

6.5 param

<m:param><m:map>の特殊化されたもので、処理段階に於いて、フォーム引数の文字列を(あたかも"__encoded"プロパティとして与えられたかのように)タグ値である多層マップに複製します。 例えば、次のJSPページ:

<m:param var="in"/>

<m:out value="${in.user}"/>

は、もし"user.first=太郎&user.last=山田"というフォーム引数が与えられた場合には、"${in.user}"を以下のように初期化されたマップとして出力します:

{first=太郎, last=山田}

フォーム引数からの複製は処理段階に於いて(タグ本文を処理した後に)行なわれますので、次のようにして省略可能な引数の初期値を設定することが出来ます:

<%-- フォーム引数"x"の値か、もし与えられていなければ"DEFAULT"を出力します。 --%>

<m:param var="in">
  <m:set property="x" value="DEFAULT"/>
</m:param>

<m:out value="${in.x}"/>

現在のサーブレットリクエスト(javax.servlet.http.HttpServletRequestのインスタンス)は特別なプロパティ"request"に割り当てられます。 例えば、<m:param>の値が${in}にあれば、現在のリクエストのURIは"${in._request.requestURI}"として得られます。

必要な場合にはparameterMap属性を用いて実際のフォーム引数の代わりに使われるフォーム型式に符号化されて文字列乃至はマップを指定することも出来ます。 例えば次のようにHTMLの"SUBMIT"ボタンに符号化した値を用いることができます:

<%-- 押されたボタンを「点灯」します。 --%>

<m:param var="in">
  <m:set property="maxRows" value="3"/>
  <m:set property="maxColumns" value="3"/>
</m:param>

<m:param target="${in}" property="__source">
  <m:set attribute="parameterMap" value="${in.SUBMIT.__keyList}" codec="String:join"/>
</m:param>

<HTML>
  <BODY>
    <FORM METHOD="POST">
      <TABLE CELLPADDING="4">
        <c:forEach var="row" begin="1" end="${in.maxRows}">
          <TR>
            <c:forEach var="column" begin="1" end="${in.maxColumns}">
              <m:map var="submit" assign="@{_.__encoded}">
                <m:set property="row" value="${row}"/>
                <m:set property="column" value="${column}"/>
              </m:map>
              <m:set var="cellAttribute" test="${row == in.row && column == in.column}">BGCOLOR="#000000"</m:set>
              <m:eval>
                <TD @{cellAttribute}>
                  <INPUT TYPE="SUBMIT" NAME="SUBMIT.@{submit}" VALUE="Click Here">
                </TD>
              </m:eval>
            </c:forEach>
          </TR>
        </c:forEach>
      </TABLE>
    </FORM>
  </BODY>
</HTML>

control属性を用いて、様々な制御属性の設定を一度に行なうことが出来ます。 controlの値としては、フォーム型式に符号化された文字列またはマップを用いることが出来ます。

encoding属性はURLの復号化の際に用いられる文字のエンコーディングを指定します(初期値はnull)。 もしencodingの値が"*"に設定されれば、リクエストのエンコーディングを優先し、もしなければ"utf-8"或いはサーバ設定の"com.micronova.jsp.tag.ParamTag.defaultEncoding"の値が用いられます。

maxContentLength属性を用いれば受け付けられるHTTPリクエストの内容の最大長を設定することができます。 もしmaxContentLengthが正の整数であれば、与えられたmaxContentLengthよりも長い内容を持つHTTPリクエストは黙殺されます。 もしmaxContentLengthが負の整数であれば、その絶対値よりも長い内容を持つHTTPリクエストは"max content length exceeded"というメッセージを持つ例外を放出します。 サーバ設定に"com.micronova.jsp.tag.ParamTag.maxContentLength"という名前を持つ値を置けば、maxContentLengthの初期値を設定することも出来ます。

各々のフォーム引数が多層マップに複製される際に、その引数の名前と値に対しそれぞれ適用されるコーデックをnameCodec属性とvalueCodec属性を用いて指定することが出来ます。 nameCodecは各引数名に適用されます(未指定の場合には各引数名から__ (アンダースコア二つ)を削除します)。 valueCodec各引数値に適用されます(未指定の場合はXSS(cross-site-scripting)に対処するための一助として"XML:encode"を適用します)。

<m:param>はある種の引数名を特別なものとして扱います。 もし引数名がselectPattern属性で与えられる正規表現に適合すれば、 それはドロップダウンリストの値を示すものとして扱われ、その引数値に対応したプロパティが"SELECTED"の値に設定されます; 例えば、もしselectPatternの値が"select_.*"であり、"select_x=a"が引数として与えられれば、それはあたかも"select_x.a=SELECTED"が与えられたかのように扱われます。 同じように、もし引数名がradioPattern属性で与えられる正規表現に適合すれば、 それはチェックボックスの値を示すものとして扱われ、その引数値に対応したプロパティが"CHECKED"に設定されます; 例えば、 もしradioPatternの値が"radio_.*"であり、"radio_x=a"が引数として与えられれば、それはあたかも"check_x.a=CHECKED"が与えられたかのように扱われます。 通常はこれらの引数は単一の値を持つ(則ち、同じ名前を持つ引数の内最後の一つの値のみが意味を持つ)ものとして扱われますが、もし引数名が更にmultiPattern属性で与えられる正規表現に適合すれば、複数の値を持つものとして扱われます。 例えば:

<m:set var="in">
  <m:param attribute="value" control="multiPattern=m_.*&selectPattern=.*s_.*&radioPattern=.*r_.*"/>
  <c:if test="${empty _.submit}">
    <m:set property="@m_s_x.USA" value="SELECTED"/>
    <m:set property="@m_r_x.INCLUDE" value="CHECKED"/>
  </c:if>
</m:set>

<m:eval>
  <FORM>
    <TABLE>
      <TR>
        <TD>単一選択</TD>
        <TD>
          <SELECT NAME="s_x">
            <OPTION VALUE="USA" @{in.s_x.USA}>米国</OPTION>
            <OPTION VALUE="EU" @{in.s_x.EU}>欧州</OPTION>
            <OPTION VALUE="JPN" @{in.s_x.JPN}>日本</OPTION>
          </SELECT>
        </TD>
      </TR>

      <TR>
        <TD>複数選択</TD>
        <TD>
          <SELECT NAME="m_s_x" MULTIPLE>
            <OPTION VALUE="USA" @{in.m_s_x.USA}>米国</OPTION>
            <OPTION VALUE="EU" @{in.m_s_x.EU}>欧州</OPTION>
            <OPTION VALUE="JPN" @{in.m_s_x.JPN}>日本</OPTION>
          </SELECT>
        </TD>
      </TR>

      <TR>
        <TD>ラジオボタン</TD>
        <TD>
          <INPUT TYPE="RADIO" NAME="r_x" VALUE="INCLUDE" @{in.r_x.INCLUDE}>含む</INPUT>
          <INPUT TYPE="RADIO" NAME="r_x" VALUE="EXCLUDE" @{in.r_x.EXCLUDE}>除く</INPUT>
        </TD>
      </TR>

      <TR>
        <TD>チェックボックス</TD>
        <TD>
          <INPUT TYPE="CHECKBOX" NAME="m_r_x" VALUE="INCLUDE" @{in.m_r_x.INCLUDE}>含む</INPUT>
          <INPUT TYPE="CHECKBOX" NAME="m_r_x" VALUE="EXCLUDE" @{in.m_r_x.EXCLUDE}>除く</INPUT>
        </TD>
      </TR>
      
      <TR>
        <TD>&nbsp;</TD>
        <TD>
          <INPUT TYPE="SUBMIT" NAME="submit" VALUE="submit">
        </TD>
      </TR>
    </TABLE>
  </FORM>
</m:eval>

もし通常の引数名がmultiPatternに適合すれば、それはあたかも変数名に"._.*"が付加されたかのように扱われます; 例えば、 もし"multi_x=a&multi_x=b"が引数として与えられれば、それはあたかも"multi_x._.*=a&multi_x._.*=b"が与えられたかのように扱われ、"multi_x._"はリスト"[a,b]"に設定されます。

<m:param>はまた"multipart/form-data"(ファイルアップロード)にも対応しています。 アップロードされた引数の値は文字列ではなく入力ストリーム(java.io.InputStreamのインスタンス)に設定され、"File:write"コーデックを用いてファイルに書きこんだり、または更なる処理のために"File:read"コーデックを用いて文字列に変換したりすることが出来ます。 アップロードの詳細(例えば、ヘッダ、ファイル型、長さ、等)は特別なプロパティであるmultipart<m:mailFolder>タグと同様の形で保存されています。 例えば、アップロードされた引数名"xxx"のファイルの長さはmultipart.partName.xxx.fileSizeとして得られます。 なお通常の(ファイルで無い)引数はENCTYPEに拘わらず常に同じように扱われます。 例えば:

<m:set var="MAXFILESIZE" value="1000000"/>

<m:param var="in"/>

<c:if test="${!empty in.submit}">

  <m:set var="fileDetail" value="${in.multipart.partName.file_upload}"/>

  <m:set var="result" value="ファイルの長さは${MAXFILESIZE}バイトまでです"/>

  <c:if test="${fileDetail.size < MAXFILESIZE}">
    <m:set var="tempFile" codec="File:tempfile"/>

    <m:set var="result" value="${in.file_upload}" codec="File:write:@{tempFile}|Type:ifNull:失敗しました:@{tempFile}に書きこまれました"/>
  </c:if>

</c:if>

<m:eval>
  <FORM METHOD="POST" ENCTYPE="multipart/form-data">
    <TABLE>
      <c:if test="${!empty result}">
        <TR><TD>結果</TD><TD>@{result}</TD></TR>
      </c:if>
      <TR><TD>ファイル(最大@{MAXFILESIZE}バイト)</TD><TD><INPUT TYPE="FILE" NAME="file_upload"></TD></TR>
      <TR><TD>メモ</TD><TD><INPUT TYPE="TEXT" NAME="memo" VALUE="@{in.memo}"></TD></TR>
      <TR><TD>&nbsp;</TD><TD><INPUT TYPE="SUBMIT" NAME="submit" VALUE="アップロード"></TD></TR>
    </TABLE>
  </FORM>
</m:eval>

valueCodecは文字列の値を持つ引数にのみ適用されますが、ブラウザによってはテキストファイルの内容をバイナリでなく文字列としてアップロードするものもあります。 filePattern属性を用いれば、ファイル名として扱われるべき引数名の正規表現を指定することが出来、 valueCodecが適用されるのを防ぐことが出来ます。 特に指定されなければ、".*[Ff]ile.*"が用いられます(則ち"file"あるいは"File"を名前に含む引数はファイルとして扱われます)。

control属性を用いれば、これらの属性及び<m:mailFolder>で用いられるコントロールプロパティをマップまたはフォーム型式で符号化された文字列として設定することが出来ます。

<m:param><m:map>の特殊化であり、その全ての属性を用いることが出来ます。 <m:param>に固有の属性は次の通りです:

 名前  型  説明  初期値 
 parameterMap  オブジェクト  実際のフォーム引数の代わりに用いられるマップ。 この値としては、マップまたはフォーム型式で符号化された文字列を使用することが出来ます。  null 
 nameCodec  String  各フォーム引数の名前に適用されるコーデック  String:replaceAll:__:: 
 valueCodec  文字列  各フォーム引数の値に適用されるコーデック  XML:encode 
 encoding  文字列  フォーム引数の文字表記の指定  null 
 maxContentLength  文字列  リクエストの内容の長さの最大値  0(無制限) 
 multiPattern  文字列  複数の値をとるフォーム引数名の適合すべき正規表現  null 
 selectPattern  文字列  "select"の値を持つフォーム引数名の適合すべき正規表現  null 
 radioPattern  文字列  "radio"の値を持つフォーム引数の適合すべき正規表現  null 
 filePattern  文字列  ファイルの値を持つフォーム引数の適合すべき正規表現  .*[Ff]ile.* 
 control  オブジェクト  次の属性を指定するマップまたはフォーム型式に符号化された文字列: "nameCodec"、 "valueCodec"、 "encoding"、 "maxContentLength"、 "filePattern"、 "multiPattern"、 "selectPattern"、 "radioPattern"、 及び<m:mailFolder>で用いられる制御属性  null 

6.6 call

<m:call><m:map>の特殊化で、処理段階に於いて同一のコンテクスト内の別のJSPをサブルーティンとして呼び出します。 例えば、次のように、与えられたフォーム引数"parameter"の値を灰色の箱で囲んで表示するJSPがあるとします:

<m:param var="in"/>

<TABLE BGCOLOR="DDDDDD" CELLPADDING="6">
  <TR><TD><PRE><m:out value="${in.parameter}"/></PRE></TD></TR>
</TABLE>

すると、次のコードはあたかも"/Box.jsp?parameter=テスト"を呼び出したかのように動作します:

<m:call path="/Box.jsp">
  <m:set property="parameter" value="テスト"/>
</m:call>

そして次のように出力します:

<TABLE BGCOLOR="DDDDDD" CELLPADDING="6">
  <TR><TD><PRE>テスト</PRE></TD></TR>
</TABLE>

<m:call>のプロパティ"x"は、呼び出されたJSP側では、<m:param>の値が変数"in"に割り当てられていれば、"${in.x}"として現れます。 プロパティの値は整列化されずにそのまま呼び出された側のJSPに渡され、そのためもしプロパティの値がサブマップであれば、その内容は呼び出す側と呼び出された側の双方に共有されます。

通常は<m:call>のタグ値は呼び出された側のJSPの出力に設定されますが、呼び出された側のJSPは<m:return>タグを使用するかまたはtarget属性として"return"を用いることで、呼び出し側に返される値を明示的に設定することが出来ます。 次のコードは上の"/Box.jsp"と同じように動作します:

<m:param var="in"/>

<m:return>
<TABLE BGCOLOR="DDDDDD" CELLPADDING="6">
  <TR><TD><PRE><m:out value="${in.parameter}"/></PRE></TD></TR>
</TABLE>
</m:return>
この部分の出力は無視されます

呼び出し側にはどのようなオブジェクトでも返すことが出来ます。 例えば、次のような簡単な"MVC"スタイルのコントローラを書くことが出来ます:

<m:param var="in">
  <m:set property="action" value="login"/>
</m:param>

<m:call var="view" path="control/${in.action}.jsp" source="${in}"/>

<m:call path="view/${view.path}" source="${view.param}" doesForward="true"/>

ここで、"control/login.jsp"等は表示されるべきJSPのパスと引数を次のように返します:

<%-- パスと引数をマップを用いて返します --%>

<m:map target="return">
  <m:set property="path" value="パス"/>
  <m:map property="param">
    <m:set property="引数1" value="引数1の値"/>
    <m:set property="引数2" value="引数2の値"/>
  ...
  </m:map>
</m:map>

必要であれば、再帰的な呼び出しを行なうことも出来ます。 例えば、次のコードは"file=xxx"で与えられたファイルディレクトリの内容をHTMLの"UL"タグを用いて簡単な樹として出力します:

<m:param var="in"/>
 
<m:set var="file" value="${in.file}" codec="Type:isFile"/>
 
<LI><c:out value="${file.name}"/></LI>
 
<c:if test="${file.directory == true}">
  <m:set var="subfiles" value="${file}" codec="File:listFiles"/>
  <UL>
    <c:forEach var="subfile" items="${subfiles}">
      <%-- このJSPを再帰的に呼び出します --%>
      <m:call path="${in._request.servletPath}">
        <m:set property="file" value="${subfile}"/>
      </m:call>
    </c:forEach>
  </UL>
</c:if>

また次の例では、前もって計算された値を共有された"cache"に保存しつつ、与えられた引数"x"に対するfibonacci数を計算します:

<m:param var="in">
  <m:set property="x" value="1"/>
</m:param>

<c:if test="${empty in.cache}">
  <m:map target="${in}" property="cache" source="1=1&2=1"/>
</c:if>

<m:set var="cached" value="${in.cache[in.x]}"/>

<c:if test="${empty cached}">
  <m:call var="a" path="${in._request.servletPath}">
    <m:set property="x" value="${in.x - 2}"/>
    <m:set property="cache" value="${in.cache}"/>
  </m:call>

  <m:call var="b" path="${in._request.servletPath}">
    <m:set property="x" value="${in.x - 1}"/>
    <m:set property="cache" value="${in.cache}"/>
  </m:call>

  <m:set var="cached" target="${in.cache}" property="${in.x}" value="${a + b}"/>
</c:if>

<m:return value="${cached}"/>

もし必要であれば、doesForward属性を"true"とすることで、呼び出されるJSPに処理を移行させることが出来ます。

<m:call>タグの本文は通常"parameter"という名前のプロパティに割り当てられます(bodyParameter属性を用いて別の名前に割り当てることが出来ます)。 次のコードは先の呼出側のコードと同じです:

<m:call path="/Box.jsp">テスト</m:call>

あるJSPが別のJSPに呼び出された場合には、<m:param>タグの"_caller"という特別なプロパティに呼出側のHTTPリクエスト("javax.servlet.http.HttpServletRequest"のインスタンス)が割り当てられますので、例えば呼出側のJSPのパスは"_caller.servletPath"として得られます。

必要であれば、contextPath属性を指定することで、別のコンテクスト内のJSPを呼び出すことも出来ます。 コンテクストの境界を越えるためには、渡されるオブジェクトは同一のクラスローダに属するものでなければなりません(例えば、JSTL及びYUZUのjarファイルを個別のアプリケーションの"WEB-INF/lib"ではなく"common/lib"に置く等)。

<m:call>では<m:map>の全ての属性を使用することが出来ます。 <m:call>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 contextPath  文字列  コンテクストを越える場合呼び出されるJSPのコンテクスト  null 
 bodyProperty  文字列  タグ本文の値が割り当てられるプロパティ  parameter 
 body  オブジェクト  bodyPropertyの値  null 
 doesForward  真理値  もしtrueであれば、処理は呼び出されたJSPに移行します  false 

6.7 return

<m:return>はJSPが呼び出された場合に、呼び出し側のJSPに値を返します。 JSPの呼び出しについては<m:call>を御覧下さい。 呼び出されていないJSPの中で使われた場合には、このタグは常にタグ値を輸出します。 これにより直接呼び出すことで返される値を見ることが出来ますので、呼び出される側のJSPをデバッグする際に便利です。もしタグ値がnullであれば、""(空文字列)が呼出側に返されます。

またどのYUZUタグの場合でもtarget属性の値を"return"とすることで、呼び出し側にそのタグ値を返すことが出来ます。 例えば次のコード:

<m:return>
  <m:map attribute="value">
    <m:set property="name" value="test"/>
  </m:map>
</m:return>

は次のコードと同じです:

<m:map target="return">
  <m:set property="name" value="test"/>
</m:map>

タグの性質上、<m:return>では以下の属性は使用出来ません:vartargetpropertyattributescopeassignCodecassign

6.8 value

<m:value>attribute 属性が"value"に設定されたかのように、親のYUZUタグのタグ値を設定します。 次の二つは同じです:

<m:out>
  <m:set attribute="value" codec="String:toUpperCase">これはテストです</m:value>
</m:out>

<m:out>
  <m:value codec="String:toUpperCase">これはテストです</m:value>
</m:out>

<m:value>タグのdefault属性の値は、特にnullでない値に指定されなければ、("${_}"のように)最も近い親タグのタグ値に設定されます。 例えば:

<%-- マップは"a=alpha&b=beta"に初期化されます --%>

<m:map>
  <m:set attribute="value" default="${_}" codec="Bean:set:a:alpha"/>
  <m:set attribute="value" default="${_}" codec="Bean:set:b:beta"/>
</m:map>

<%-- これは上と同じです --%>

<m:map>
  <m:value codec="Bean:set:a:alpha"/>
  <m:value codec="Bean:set:b:beta"/>
</m:map>

タグの性質上 <m:value>ではattribute属性は使用出来ません。

6.9 include

<m:include><m:map>の特殊化として、処理段階に置いてHTTP/HTTPSリクエストを行ないます。 以下のプロパティを用いることが出来ます:

 名前  説明 
 url  呼び出すURL 
 method  HTTPの要求メソッド; "get"または"post"が使えます。 指定されなければ、"post"が使われます。 
 throwsException  もし"true"に設定されれば、HTTPエラー(200以外のコードが返された場合)例外が放出されます。 特に指定されなければ、"true"が用いられます。 もしfalseであれば、response.status及びresponse.messageが設定されます。下を御覧下さい。 
 followsRedirects   もし"true"であれば、自動的にHTTPのリダイレクト先へ移動します。 未設定であれば、"true"見なされます。 
 usesTrustManager  もし"true"であれば、HTTPS接続に際し証明書の認証を行なうTrustManagerを使用します。 未設定であれば、"true"と見なされます。 
 allowsFile  もし"true"であれば、"file://*"の形のURLを受け付けます。 未設定であれば、"false"と見なされます。 
 usesHostnameVerifier  もし"true"であれば、HTTPS接続に際してホスト名の検証を行ないます。 未設定であれば、"true"と見なされます。 
 request  多層マップとしての要求構造 
 request.content  要求内容の文字列 
 request.parameter  要求引数のマップ。 もしrequest.contentが与えられていなければ、このマップがフォーム型式に符号化されてrequest.contentとして用いられます。 
 request.encoding  request.parameterを符号化する際に用いられる文字エンコーディング 
 request.header  要求ヘッダの名前と値のマップ。 値としては、文字列乃至は文字列の配列またはリストを使うことが出来ます。 
 request.authorization  もし"basic"であれば、request.userrequest.passwordからHTTPの基本認証ヘッダが作成されます。 
 request.user  HTTPの基本認証に用いられるユーザ名。 request.authorizationが"basic"である場合に使用されます。 
 request.password  HTTPの基本認証に用いられるパスワード。 request.authorizationが"basic"である場合に使用されます。 
 response  多層マップとしての応答構造 
 response.status  応答コード。 request.throwsExceptionがfalseである場合に設定されます。 
 response.message  応答メッセージ。 request.throwsExceptionがfalseである場合に設定されます。 
 response.header  応答ヘッダの名前と値のマップ 
 response.type  応答内容のmime型を解析して得られるマップ 
 response.type.type  応答内容のmime主型; 例えば、もし"content-type"が"text/html; charset=utf-8"であれば、"text" 
 response.type.subtype  応答内容のmime副型; 例えば, もし"content-type"が"text/html; charset=utf-8"であれば、"html" 
 response.type.parameter  応答内容のmime引数のマップ; 例えば, もし"content-type"が"text/html; charset=utf-8"であれば{charset=utf-8} 
 response.content  文字列としての応答内容; 通常この値が輸出されます。 

URLの輸入を簡単にするため、<m:include>export属性は"${_.response.content}"に初期設定されています。 assign属性は"${_}"ですので、変数に割り当てることで、応答の詳しい内容を見ることが出来ます。

これは簡単な"get"の例です:

<m:include>
  <m:set property="url" value="http://www.micronova.com/"/>
</m:include>

これは"get"メソッドを用いて引数を送ります:

<m:include>
  <m:set property="url" value="http://www.micronova.com/"/>
  <m:set property="method" value="get"/>
  <m:map property="request">
    <m:map property="parameter">
      <m:set property="page" value="yuzu"/>
    </m:map>
  </m:map>
</m:include>

もしasynchronous属性が"true"に設定されれば、HTTP要求は非同期的に行なわれます。 ⌒の場合タグ値は要求を行なうスレッドとなります。

<m:include>では<m:map>の全ての属性を使用することが出来ます。 <m:include>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 url  文字列  urlプロパティを設定  null 
 allowsFile  真理値  "file://*"URLを使用可能にします  false 
 asynchronous  真理値  もし設定されれば、非同期的にHTTP要求を行ないます  false 

6.10 postData

<m:postData>はHTTPでpostされた内容を返します。 例えば、次のようにしてpostされた内容をXMLとして構文解析することが出来ます:

<x:parse var="x"><m:postData/></x:parse>

contentTypePrefixを設定すれば、要求内容の型の文字列が与えられたcontentTypePrefixで始まる場合にのみpostされた内容を返します。 例えば、次のコードは要求内容の型が"text/xml*"であるときのみpostされた内容を出力します:

<m:postData contentTypePrefix="text/xml"/>

通常postされた内容は文字列として返されますが、実際には<m:postData>は、もし要求内容の型がcontentTypePrefixで始まれば、ます準備段階に於いてタグ値を現在のサーブレットリクエストオブジェクトに設定し、本文を処理した後もしタグ値に変更がなければ、初期値段階に於いて文字列への変換を行ないます。 このため、必要であれば、次のようにタグ本文の中でpostされた内容を処理することも出来ます:

<m:postData var="parsed" contentTypePrefix="text/xml">
  <m:set attribute="value" value="${_.reader}" codec="XML:parse"/>
</m:postData>

<m:postData><m:call>を用いて呼び出されたJSPの中では、何も行ないません。

<m:postData>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 contentTypePrefix  文字列  もし与えられば、要求内容の型がこの文字列で始まる場合に限ってpostされた内容を返します  null (どのような要求内容の型も受け付けます) 

6.11 throw

<m:throw>は処理段階においてもしタグ値がnullでなければ、それをメッセージと仕手持つ例外を放出します。 放出された例外はJSTLの<c:catch>を用いて受け取ることが出来ます。 次の例はフォーム変数"x"の値が"bad"であるとき"例外:不正入力"と出力します:

<m:param var="in"/>

<c:catch var="exception">
  <m:throw test="${in.x == 'bad'}" value="不正入力"/>
</c:catch>

<m:out value="例外:${exception.message}" test="${!empty exception}"/>

もし必要であれば<m:throw>を用いてJSTLの<c:forEach>__等の反復子から抜け出すことも出来ます:

<m:param var="in"/>

<c:catch var="exception">
  <c:forEach var="p" items="${in}">
    <m:throw test="${p.key == '針'}" value="発見"/>
  </c:forEach>
</c:catch>

<c:if test="${exception.message == '発見'}">
  フォーム変数に「針」を発見しました
</c:if>

タグの性質上、<m:throw>では以下の属性は使用できません: vartargetpropertyattributescopeexportCodecassignCodecassignexportdoesExportprocessCodeccodec

6.12 synchronized

<m:synchronized>はタグ本文の処理が唯一つのスレッドのみによって実行されるように同期化します。 例えば:

<m:synchronized>
  <m:set target="${applicationScope.data}" property="${name}" value="${value}"/>
</m:synchronized>

は"applicationScope.data"の値を同期的に変更します。

必要であれば、waitTime属性を用いて、同期の際の最大待ち時間を1/1000秒単位で設定することが出来ます(特に指定されなければ、「無制限」を意味する0が用いられます)。 もし待ち時間内に同期出来ない場合には"thread lock timeout"というメッセージを持つ例外が放出されます。

またlockId属性を用いて同期に用いられるロックオブジェクトの名前を指定することも出来ます(特に指定がなければ""(空文字列)が使われます)。 lockIdが"X"である<m:synchronized>タグの本文は、他のスレッドが同じlockIdを持つ<m:synchronized>タグの本文を実行中でない時に限って処理されます。 例えば:

<%-- ${content}を${fileName}に書き込むスレッドは常に一つだけです --%>

<m:synchronized lockId="${fileName}">
  <m:set var="result" value="${content}" codec="File:write:@{fileName}"/>
</m:synchronized>

<m:synchronized>では次の属性を使用することが出来ます:

 名前  型  説明  初期値 
 waitTime  Long  1/1000秒単位の最大同期待ち時間  0 (無制限) 
 lockId  オブジェクト  同期ロックの名前  "" (空文字列) 

6.13 query

<m:query>はJSTLの<sql:query>の簡略化されたもので、SQL検索文の中に特定のパターン (特に指定されなければ"%{x}")を用いてELを埋め込むことができます。 例えば、次のJSTLコード:

<sql:query>
  select * from Test where Age = ? and Name = ?
  <sql:param value="${age}"/>
  <sql:param value="${name}"/>
</sql:query>

<m:query>を用いると次のようになります:

<m:query>
  select * from Test where Age = %{age} and Name = %{name}
</m:query>

JSTLと同様、<m:query>のタグ値はjavax.servlet.jsp.jstl.sql.Resultのインスタンスに設定され、assignまたはexport属性を用いることで、次のように特定の行または列の値を取り出すことができます:

<%-- 表"Test"が主キー"id"と項目"name"を持つとして、あたえられた変数"id"の値に対応した項目"name"の値があれば変数"name"に割り当てます。 --%>

<m:query var="name" assign="@{_.rows[0].name}">
  select name from Test where id = %{id}
</m:query>

次のようにしてリストの値を埋め込むことも出来ます:

<%-- 変数"names"にリスト["a","b","c","d","e"]を割り当てます。 --%>

<m:set var="names" value="a,b,c,d,e" codec="String:split"/>

<%-- 次の文は"select id from Test where name in ('a','b','c','d','e')"と同義です。 --%>

<m:query>
  select id from Test where name in (%{names})
</m:query>

<m:query><m:eval>の特殊化であり、その全ての属性を用いることが出来ます。 <m:query>にのみ使われる属性は以下の通りです:

 名前  型  説明  初期値 
 dataSource  文字列  SQLデータソース(jdbc URLまたはリソース名)  サーバ設定"javax.servlet.jsp.jstl.sql.dataSource"の値 
 startRow  整数  最初に返される行の番号  0 
 maxRows  整数  返される行数の最大値  -1(無制限) 

6.14 update

<m:update>はJSTLの<sql:update>の簡略化されたもので、SQL実行文の中に特定のパターン(特に指定されなければ"%{x}")を用いてELを埋め込むことができます。 例えば、次のJSTLコード:

<sql:update>
  update table Test set age = ? where name = ?
  <sql:param value="${age}"/>
  <sql:param value="${name}"/>
</sql:update>

<m:update>を用いると次のようになります:

<m:update>
  update table Test set age = %{age} where name = %{name}
</m:update>

JSTLと同様、<m:update>のタグ値は変更された行の数に設定されます。

<m:update><m:eval>の特殊化であり、その全ての属性を用いることが出来ます。 <m:update>にのみ使われる属性は以下の通りです:

 名前  型  説明  初期値 
 dataSource  文字列  SQLデータソース(jdbc URLまたはリソース名)  サーバ設定"javax.servlet.jsp.jstl.sql.dataSource"の値 

6.15 response

<m:response><m:map>の特殊化で、現在処理中のHTTP要求に対する応答を変更します。 以下のプロパティを用いることが出来ます:

 名前  説明 
 header  応答ヘッダの名前と値から成るマップ。 値としては、文字列乃至は文字列のリストを使うことが出来ます 
 error  応答エラーコード 
 errorMessage  応答エラーメッセージ 
 redirect  転送URL 
 cookie  cookieの名前と値から成るマップ。. 値としては、javax.servlet.http.Cookieのインスタンスまたはそのプロパティ名(comment, domain, maxAge, path, secure, value, version)と値から成るマップを使用することが出来ます。 

次のコードはブラウザを転送します:

<m:response>
  <m:set property="redirect" value="http://www.micronova.com/"/>
</m:response>

次のコードは内容の型を設定します:

<m:response>
  <m:set property="@header.content-type" value="text/xml; charset=utf-8"/>
</m:response>

次のコードは応答エラーを"500: Something happened"に設定します:

<m:response>
  <m:set property="error" value="500"/>
  <m:set property="errorMessage" value="Something happened"/> 
</m:response>

次のコードは"secure cookie"を設定します:

<m:response>
  <m:map property="@cookie.test">
    <m:set property="value" value="test cookie"/>
    <m:set property="secure" value="true"/>
  </m:map>
</m:response>

6.16 system

<m:system><m:map>の特殊化で、外部関数を呼び出します。 次のプロパティを用いることが出来ます:

 名前  説明 
 command  実行される外部関数の名前 
 stdin  外部関数への標準入力 
 stdout  外部関数からの標準出力 
 stderr  外部関数からのエラー出力 
 rc  外部関数の実行結果コード 

標準出力の値を埋め込みやすくするため、export属性は"${_.stdout}"に設定されています。 次のコードはダウンロード用にtarファイルを作成します:

<m:system command="sh">
  <m:set property="stdin">
    cd mydirectory
    tar cz *
  </m:set>
  <m:response>
    <m:map property="header">
      <m:set property="content-type" value="application/binary"/>
      <m:set property="content-disposition" value="filename=myfile.tar.gz"/>
    </m:map>
  </m:response>
  <%-- "</m:system>"の後には何の文字も無いようにして下さい。 --%>
</m:system>

<m:system>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 command  文字列  実行される外部関数の名前  null 
 stdin  文字列  外部関数に送られる標準入力  null 
 export  文字列  輸出されるオブジェクト  ${_.stdout} 

6.17 filter

<m:filter>は、タグ値のリストの各要素を「フィルタ」に通し、その結果から成る新しいリストを作成します。 タグ値のリストの各要素を「フィルタ」を通す際に、まず次のページ変数の値が設定されます:

そして各要素は、与えられたEL属性includeapplyapplyCodec、及びbreakの値に従って次のように処理されます:

特に設定されなければ、全ての要素が処理され(includeは"true"であり、またbreakはfalse)、それぞれそのまま新しいリストに複製されます(applyは"${_element}"であり、またapplyCodecはnull)。

次のコードは、最初の負の数より前にある奇数番目の数を平方します:

<%-- [1, 9, 25]を出力します --%>

<m:set var="list" value="1,2,3,4,5,-1,6,7,8,9" codec="String:split"/>

<m:filter value="${list}" include="@{(_element % 2 > 0) && (_element > 0)}" apply="@{_element * _element}" break="@{_element < 0}"/>

またタグ値として、文字列あるいはマップを用いることも出来ます。 タグ値が文字列の場合には、各文字が _element として用いられ、「フィルタ」を通した結果から、再び文字列が作成されます:

<%-- 各文字を4桁の16進数に変換します --%>

<m:filter value="Hello World" applyCodec="Type:charAsNumber|Number:toHexString:0000"/>

タグ値がマップである場合には、キーと値の対(java.util.Map.Entryのインスタンス)の各々が _element として用いられ、, フィルタを通した結果が、新しいマップでのそのキーの値として設定されます:

<m:map var="map">
  <m:set property="a" value="alpha"/>
  <m:set property="b" value="beta"/>
  <m:set property="c" value="gamma"/>
</m:map>

<%-- 値を"key:value"に変換します --%>

<m:filter value="${map}" apply="@{_element.key}:@{_element.value}"/>

もし必要であれば、タグの代わりに"_JSP:applyFilter"コーデックを使用することが出来ます。 例えば:

<%-- 次の二つは同じです --%>

<m:filter value="Hello World" applyCodec="Type:charAsNumber|Number:toHexString:0000"/>

<m:out value="Hello World" codec="_JSP:applyFilter:applyCodec=Type\:charAsNumber\|Number\:toHexString\:0000"/>

<m:filter>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 include  EL  このELの評価値がtrueであれば、要素の処理が行なわれます  true 
 break  EL  このELの評価値がfalseであれば、以後の要素の処理は行なわれません  false 
 apply  EL  このELの評価値が「フィルタ」を通した値として扱われます  ${_element} 
 applyCodec  EL  もしnullでなければ、applyの評価値にコーデックとして適用されます  null 

6.18 parseHtml

<m:parseHtml>はタグ値をHTML文書として(JSTLのXMLタグが適用できるように)DOM構造に構文解析します。 例えば、次のコードはMicroNovaのホームページ上の全てのリンクを出力します:

<m:parseHtml var="html"><m:include url="http://www.micronova.com/"/></m:parseHtml>

<x:forEach var="link" select="$html//a/@href">
  リンク: <x:out select="$link"/>
</x:forEach>

<m:parseHtml>に固有の属性は以下の通りです:

 名前  説明  初期値 
 include  構文解析の際に含まれるべきHTMLタグの名前をコンマで区切られたリストとして指定します(指定されなければ"全て"を意味するnullが用いられます)。 次のような特殊な要素名を用いることも出来ます: "text"(本文)、 "comment"(コメント)、 "script" (<script>タグ)、 "style" (<style>タグ)、 "sgml" (コメント以外の<!...>)、 及び"pi" (<?...>)。  null (全てを含む) 
 exclude  構文解析の際に除外されるべきHTMLタグの名前をコンマで区切られたリストとして指定します(指定されなければ"無"を意味するnullが用いられます)。 上と同じく特殊な要素名を用いることも出来ます。  null (除外無し) 
 strategy  タグが閉じられていない場合に採用すべき方策("single"、 "data"、 または"none")を指定します。 詳しくは下を御覧下さい。  single 
 rootName  XML文書の最上位要素として使われる名前  root 

strategyは、タグが閉じられていない場合の動作を設定します。 "single"方策では、閉じられていないタグは単一タグ("<x/>")と見なされます。 "data"方策の場合は、閉じられていないタグはそれに続くテクストを囲むものと見なされます。 "none"方策の場合は、閉じられていないタグはそれに続く全てのテクストとタグを囲むものと見なされます。 たとえば、次のような文書:

<a>
<b>
text1
<c>
text1
<d>
text2
</a>

は、strategyが"single"である場合は次のように:

<a>
  <b/>
  text1
  <c/>
  text1
  <d/>
  text2
</a>

またstrategyが"data"であれば:

<a>
  <b>text1</b>
  <c>text1</c>
  <d>text2</d>
</a>

最後にstrategyが"none"であれば:

<a>
  <b>
    text1
    <c>
      text1
      <d>
        text2
      </d>
    </c>
  </b>
</a>

というXML文書となります。

6.19 mail

<m:mail><m:map>の特殊化で、処理段階においてマルチパートメイルを送信します。 最も簡単な形として、次のコードは通常文書のみのメールを送信します:

<m:mail url="smtp://your-smtp-server">
  <m:set property="to">somebody@someaddress</m:set>
  <m:set property="from">somebody@someaddress</m:set>
  <m:set property="subject">テストメール</m:set>
  <m:set property="type">text/plain; charset=utf-8</m:set>
  <m:set property="content">こんにちは、これはテストです</m:set>
</m:mail>

"_" (アンダースコア)リストが空でなければ、"type"プロパティの値を副型として、それぞれ内容やヘッダを持つ各要素"_.0"、 "_.1"、 ...から再帰的にマルチパートメールが作成されます。 次のコードは代用可能な通常文書と画像を持つHTML文書から成るメールを送信します:

<m:mail url="smtp://your-smtp-server">
  <m:set property="to">[email protected]</m:set>
  <m:set property="from">[email protected]</m:set>
  <m:set property="subject">テスト</m:set>
  <m:set property="type" value="alternative"/>

  <%-- 代用可能な通常文書の部分 --%>

  <m:map property="@_.*">
    <m:set property="type" value="text/plain; charset=utf-8"/>
    <m:set property="content">これは通常文書です</m:set>
  </m:map>

  <%-- 代用可能なHTML文書と画像の部分 --%>

  <m:map property="@_.*">
    <m:set property="type" value="related"/>

    <%-- 関連したHTML部分 --%>
 
    <m:map property="@_.*">
      <m:set property="type" value="text/html; charset=utf-8"/>
      <m:set property="content">
        <HTML>
          <BODY>画像です:<IMG SRC="cid:image1"></BODY>
        </HTML>
      </m:set>
    </m:map>

    <%-- 関連した画像"cid:image1" --%>
    
    <m:map property="@_.*">
      <m:set property="dataSource" value="file:///somedirectory/image.png"/>
      <m:set property="@header.Content-ID" value="<image1>"/>
      <m:set property="@header.Content-Transfer-Encoding" value="base64"/>
    </m:map>

  </m:map>
</m:mail>

次のプロパティを使用することが出来ます:

 名前  説明 
 to  "to"アドレス。 値としては、コンマで区切られたメールアドレスの文字列、またはメールアドレスの文字列乃至は"yyy <xxx>"というメールアドレスを示す{address=xxx, personal=yyy, charset=zzz}の形のマップ("personal"及び"charset"は省略可能です)から成るリスト(java.util.Listのインスタンス)を用いることができます 
 cc  "cc"アドレス。 "to"と同じ値をとります 
 bcc  "bcc"アドレス。 "to"と同じ値をとります 
 from  "from"アドレス。 "to"と同じ値をとります 
 replyTo  "replyTo"アドレス。 "to"と同じ値をとります 
 subject  メールの題名 
 type  内容の型。 指定されなければ、"text/plain; charset=ISO-8859-1"が用いられます。 マルチパートの場合には、これは副型("related"、"alternative"、 "mixed")を指定します 
 content  メッセージ内容 
 header  ヘッダマップ。 名前と値の対か、あるいは順序が重要である場合には"_"(アンダースコア)に{name=xxx, value=yyy}の形のマップあるいは"Content-type: text/plain"のような文字列を与えます。 
 fileName  内容のファイル名 
 dataSource  内容の元であるURL 

通常はメールサーバとの接続は<m:mail>タグが閉じられる度に閉じられますが、 もしurl属性が与えられていなければ、<m:mail>は最も近い祖先の<m:mail>タグでurl属性を持つものの接続を共有します。 例えば:

<m:set var="addresses" importCodec="String:split">a1,a2,a3</m:set>

<m:mail url="smtp://your-smtp-server">
  <c:forEach var="address" items="${addresses}">
    <m:mail>
      <m:set property="to" value="${address}"/>
      <m:set property="from">somebody@someaddress</m:set>
      <m:set property="subject">テストメール</m:set>
      <m:set property="type">text/plain; charset=utf-8</m:set>
      <m:set property="content">こんにちは、テストです</m:set>
    </m:mail>
  </c:forEach>
</m:mail>

は、外側の<m:mail>タグのサーバ接続を用いて、"a1"、 "a2"、 "a3"にメールを送信します。メールサーバとの接続は外側の<m:mail>が閉じられた時に閉じられます。

<m:mail>では<m:map>の全ての属性を使用することが出来ます。 <m:mail>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 url  文字列  メールサーバのURL  null 
 properties  オブジェクト  javax.mail.Sessionの属性を指定するマップまたはフォーム形式に符号化された文字列  null 

6.20 mailFolder

<m:mailFolder>は処理段階に於いてメールボックス(フォルダ)からのメッセージの読みこみまたは削除を行ないます。 例えば、

<%-- 全てのメッセージを読みます --%>

<m:mailFolder url="pop3://your-username:your-password@your-popserver/INBOX" operation="read" messages="*"/>

<%-- メッセージ番号123と126を読みます --%>

<m:mailFolder url="pop3://your-username:your-password@your-popserver/INBOX" operation="read" messagesNumbers="123,126"/>

<%-- メッセージ番号123、124、125、126を削除します --%>

<m:mailFolder url="pop3://your-username:your-password@your-popserver/INBOX" operation="delete" messages="123-126"/>

messages属性は読みこみまたは削除されるメッセージの番号を指定します。 値としては、コンマで区切られたメッセージ番号またはメッセージ番号の範囲("m-n"は"m、m+1、...、n"を、"m-*"は"m以上の全て", "*-n"は"n以下の全て", また"*"は"全て"を意味します)、またはメッセージ番号乃至は"javax.mail.Message"のインスタンスから成るリストを使うことができます。

<m:mailFolder>のタグ値は次のようなプロパティを持つ多層マップです:

 名前  説明 
 name  フォルダの名前 
 fullName  フォルダのフルネーム 
 urlName  フォルダのURL名 
 messageCount  フォルダ内のメッセージの総数 
  _folder   javax.mail.Folderのインスタンス 
  _   読みこみの場合、読みこまれたメッセージのリスト 

各メッセージ及びその部分は、次のようなプロパティを持つ多層マップとして読みこまれます:

 名前  説明 
  to._   "to"アドレス。 {address=xxx, personal=yyy}の形のマップから成るリスト 
  cc._   "cc"アドレス。 {address=xxx, personal=yyy}の形のマップから成るリスト 
  bcc._   "bcc"アドレス。 {address=xxx, personal=yyy}の形のマップから成るリスト 
  from._   "from"アドレス。 {address=xxx, personal=yyy}の形のマップから成るリスト 
  replyTo._   "replyTo"アドレス。 {address=xxx, personal=yyy}の形のマップから成るリスト 
 subject  メッセージの題名 
 sentDate  送信時刻 
 receivedDate  受信時刻 
 type  構文解析された内容のmime型; 例えば"text/html; charset=utf-8"というmime型は{type=text, subtype=html, parameter={charset=utf-8}}というマップに対応します。 もしマルチパートであれば、<m:mail>と同様に"_"(アンダースコア)リストに各部分が収められます。 
 content  メッセージまたは部分の内容 
 header  ヘッダマップ。 "_"(アンダースコア)リストに各ヘッダが{name=xxx, value=yyy}の形のマップとして与えられた順序のままに収められます。 
 description  もしあれば、"description"ヘッダの値 
 lineCount  もしあれば、"line count"ヘッダの値 
 fileName  もしあれば、"file name"ヘッダの値 
 size  もしあれば、"size"ヘッダの値 
 disposition  もしあれば、typeと同様に構文解析された"disposition"ヘッダの値 
 partName  "disposition"名から部分へのマップ;例えば、もしある部分の"disposition"が"name=xxx"を含めば、それは"partName.xxx"として参照できます。 
  _   各部分のリスト 
  _part   javax.mail.Partのインスタンス 

例えば:

<%-- 全てのメッセージの題名/送信時刻/送信者を表示します --%>

<m:mailFolder var="folder" url="pop3://your-username:your-password@your-popserver/INBOX" operation="read" messages="*" control="content=false&header=false"/>

<TABLE>
  <TR>
    <TH>subject</TH>
    <TH>sent date</TH>
    <TH>from</TH>
  </TR>

  <c:forEach var="message" items="${folder._}">
    <m:set target="${message}" property="fromList" value="${message.from._}" codec="String:join"/>
    <m:eval evalCodec="XML:encode">
      <TR>
        <TD>@{message.subject}</TD>
        <TD>@{message.sentDate}</TD>
        <TD>@{message.fromList}</TD>
      </TR>
    </m:eval>
  </c:forEach>
</TABLE>

control属性を用いれば、様々な制御用のプロパティを設定することが出来ます。 controlの値としては、マップまたはフォーム型式で符号化された文字列を使用することが出来ます。 次のような制御用のプロパティを設定することが出来ます:

 名前  説明  初期値 
 content  もし"false"であれば、メッセージの内容は読みこまれません  true 
 header  もし"false"であれば、メッセージのヘッダは読みこまれません  true 
 headerMap  もし"true"であれば、"header"マップにおいて各ヘッダの値がその名前に対応します  false 
 maxContentSize  部分の内容の長さの最大値を指定します。 これより長い内容を持つ部分は無視されます。  0 (無制限) 
 maxPartSize  マルチパートを含めて、部分の長さの最大値を指定します。 これより長い部分は無視されます。  0 (無制限) 

通常メールボックスへの接続は、<m:mailFolder>タグが閉じられる度に閉じられますが、もしutl属性が与えられていなければ、<m:mailFolder>タグは最も近い祖先の<m:mailFolder>タグのurl属性を持つものの接続を共有します。 例えば:

<m:mailFolder url="pop3://your-username:your-password@your-popserver/INBOX">

  <%-- 123-130番のメッセージを読みこみます --%>

  <m:mailFolder operation="read" messagesNumbers="123-130"/>

  <%-- 更に150-180番のメッセージを読みこみます --%>

  <m:mailFolder operation="read" messagesNumbers="150-180"/>

</m:mailFolder>

<m:mailFolder>では<m:map>の全ての属性を使用することが出来ます。 <m:mailFolder>に固有の属性は以下の通りです:

 名前  型  説明  初期値 
 url  文字列  メールボックスのURL  null 
 operation  文字列  実行される操作; "read"(読みこみ)または"delete"(削除)  read 
 messages  オブジェクト  読みこみまたは削除されるメッセージ番号の指定;値としては、コンマで区切られたメッセージ番号あるいはその範囲、またはメッセージ番号あるいはjavax.mail.Messageのインスタンスから成るリストを使用することができます;"*"は"全て"を意味します  null 
 control  オブジェクト  制御用のプロパティを設定;値としては、マップまたはフォーム型式に符号化された文字列を使用することが出来ます。  null 

7 その他

7.1 動的なメソッドの呼び出し

必要であれば、"System:invoke"を用いてjavaのメソッドを動的に呼びだすことが出来ます。 "System:invoke"は次のようなプロパティを持つ多層マップをオペランドとします:

 名前  説明 
 object  インスタンスメソッドを呼び出す対象となるオブジェクト 
 class  静的メソッドを持つクラスオブジェクト。 この値としては、java.lang.Classのインスタンスか、または型を表す文字列 ("String"、 "int[]"、 "java.lang.security.MessageDigest"、 等)を使うことが出来ます。 もしクラス名に"."(ドット)が含まれていなければ、"java.lang."に続くものとして扱われます。 
 method  呼び出されるメソッドの名前。 もしこの値が"*"(アステリスク)であれば、与えられた classのコンストラクタが呼び出されます。 もしこの値が"."(ドット)で始まる文字列であれば、メソッド名としてではなくフィールド名として扱われ、メソッド呼び出しの代わりにそのフィールドの値が返されます。 
  _   メソッドの引数のリスト。 リストの要素としては、type及びvalueのプロパティを持つマップか、もし型が引数の型と適合していれば、引数オブジェクトをそのまま用いることが出来ます。 typeの値としてはjava.lang.Classのインスタンスまたは"java.lang.Integer"のような型を示す文字列を使うことが出来ます。 

例えば:

<%-- "This is a Test".substring(3)を実行します。 --%>

<m:map codec="System:invoke">
  <m:set property="object" value="This is a Test"/>
  <m:set property="method" value="substring"/>
  <m:map property="@_.*">
    <m:set property="type" value="int"/>
    <m:set property="value" value="3"/>
  </m:map>
</m:map>

<%-- {'a', 'b', 'c', 'd'}に初期化された長さ4のchar[]を作成します。 --%>

<m:set var="c">
  <m:map attribute="value" codec="System:invoke">
    <m:set property="class" value="java.lang.reflect.Array"/>
    <m:set property="method" value="newInstance"/>
    <m:map property="@_.*">
      <m:set property="type" value="java.lang.Class"/>
      <m:set property="value" codec="Type:forName" value="char"/>
    </m:map>
    <m:map property="@_.*">
      <m:set property="type" value="int"/>
      <m:set property="value" value="4"/>
    </m:map>
  </m:map>

  <%-- char[]を{'a','b','c','d'}に初期化します。 --%>

  <m:set property="0" codec="Type:isCharacter" value="a"/>
  <m:set property="1" codec="Type:isCharacter" value="b"/>
  <m:set property="2" codec="Type:isCharacter" value="c"/>
  <m:set property="3" codec="Type:isCharacter" value="d"/>
</m:set>

<%-- char[]である"c"から文字列"abcd"を作成します。 --%>

<m:map codec="System:invoke">
  <m:set property="class" value="String"/>
  <m:set property="method" value="*"/>
  <m:map property="@_.*">
    <m:set property="type" value="char[]"/>
    <m:set property="value" value="${c}"/>
  </m:map>
</m:map>

<%-- javax.xml.transform.OutputKeys.MEDIA_TYPE"の値を求めます。 --%>

<m:map codec="System:invoke">
  <m:set property="class" value="javax.xml.transform.OutputKeys"/>
  <m:set property="method" value=".MEDIA_TYPE"/>
</m:map>

7.2 動的マップ

「動的マップ」とは参照及び設定操作の際に特定のコーデックを呼び出す特殊なマップです。 このようなマップは"_JSP:dynamicMap"コーデックを用いて、"getCodec"及び"putCodec"というプロパティを持つたオペランドマップから作成することが出来ます。 作成された動的マップに対して行なわれるキー"XXX"を参照する("get")操作に際し、先ず元のオペランドマップの"key"プロパティとして"XXX"が割り当てられ、それをオペランドとして"getCodec"で指定されたコーデックが適用されます。 またキー"XXX"の値を"YYYに設定する("put")操作に際し、先ず元のオペランドマップの"key"プロパティとして"XXX"、"value"プロパティとして"YYY"が割り当てられ、それをオペランドとして"putCodec"で指定されたコーデックが適用されます。何れの場合もコーデック中では元のオペランドマップは"_"(アンダースコア)変数を用いても参照出来ます。 例えば:

<%-- キーの長さを返す動的マップを定義します。 --%>

<m:map var="lengthMap" codec="_JSP:createDynamicMap">
  <m:set property="getCodec" value="Bean:get:key|Type:length"/>
  <%-- 或いは
  <m:set property="getCodec" value="Type:length_:@{_.key}"/>
  --%>
</m:map>

<%-- これは10を出力します。 --%>

<m:out value="${lengthMap['something']}"/>

元のオペランドマップのプロパティで、"getCodec"、"putCodec"、"key"、"value"以外のものは、自由に使用できます。 例えば:

<%-- 大文字小文字の区別をしない動的マップ --%>

<m:map var="ignoreCaseMap" codec="_JSP:dynamicMap">
  <m:map property="storage"/>
  <m:map property="getCodec" value="String:toUpperCase_:@{_.key}|Bean:get_:@{_.storage}:@{_operand}"/>
  <m:map property="putCodec" value="String:toUpperCase_:@{_.key}|Bean:set_:@{_.storage}:@{_operand}:@{_.value}"/>
</m:map>

<m:set target="${ignoreCaseMap}" property="this" value="something"/>
<m:out value="${ignoreCaseMap['This']}"/>
<m:out value="${ignoreCaseMap['THIS']}"/>

"System:invoke"と組み合わせて、javaのメソッドを呼び出す動的マップも作成出来ます:

<m:map var="SYSTEMPROPERTY" codec="_JSP:dynamicMap">
  <m:map property="getMethod">
    <m:set property="class" value="java.lang.System"/>
    <m:set property="method" value="getProperty"/>
    <m:map property="@_.*">
      <m:set property="type" value="String"/>
    </m:map>
  </m:map>
  <m:map property="putMethod">
    <m:set property="class" value="java.lang.System"/>
    <m:set property="method" value="setProperty"/>
    <m:map property="@_.*">
      <m:set property="type" value="String"/>
    </m:map>
    <m:map property="@_.*">
      <m:set property="type" value="String"/>
    </m:map>
  </m:map>
  <m:set property="getCodec" value="Bean:set_:@{_.getMethod}:@_.0.value:@{_.key}|System:invoke_:@{_.getMethod}"/>
  <m:set property="putCodec" value="Bean:set_:@{_.putMethod}:@_.0.value:@{_.key}|Bean:set_:@{_.putMethod}:@_.1.value:@{_.value}|System:invoke_:@{_.putMethod}"/>
</m:map>

<m:out value="${SYSTEMPROPERTY['os.name']}"/>

<m:set target="${SYSTEMPROPERTY}" property="unknown" value="UNKNOWNPROPERTY"/>

<m:out value="${SYSTEMPROPERTY['unknown']}"/>

7.3 動的反復子

「動的反復子」は動的に制御し得る反復子です。 与えられたコレクション上の動的反復子は"_JSP:dynamicIterator"を用いて次の様に作成することが出来ます:

<%-- "words"は["this", "is", "a", "test"]というリストです。 --%>

<m:set var="words" value="this is a test" codec="String:split: :"/>

<%-- "words"上の通常の反復 --%>

<c:forEach var="word" items="${words}">
  <m:out value="${word}"/>
</c:forEach>

<%-- "words"上の動的反復子の作成 --%>

<m:map var="wordIterator" codec="_JSP:dynamicIterator">
  <m:set property="collection" value="${words}"/>
</m:map>

<%-- 動的反復子を用いた上と同じ反復 --%>

<c:forEach var="word" items="${wordIterator}">
  <m:out value="${word}"/>
</c:forEach>

動的反復子は動的に変更することが出来ます; 例えば、次のようにすれば、"a"を見つけた後に反復を中止することが出来ます:

<%-- 動的反復子を用いて、"a"を見つけた後反復を中止 --%>

<c:forEach var="word" items="${wordIterator}">
  <m:out value="${word}"/>
  <c:if test="${word == 'a'}">
    <%-- 次の反復の際に"wordIterator"が"hasNext"操作に際して"false"を返すようにします。 --%>
    <m:set target="${wordIterator}" property="hasNext" value="false"/>
  </c:if>
</c:forEach>

"while"反復は次のようにして行なえます:

<%-- "01"がある間は削除し続けます。 --%>

<m:map var="whileLoop" codec="_JSP:dynamicIterator">
  <m:set property="hasNext" value="true"/>
</m:map>

<m:set var="x" value="10001010111001101"/>

<c:forEach items="${whileLoop}">
  <m:set var="before" value="${x}"/>
  <m:set var="x" value="${x}" codec="String:replaceAll:10::"/>
  <m:out value="[[${before}:${x}]]"/>
  <m:set target="${whileLoop}" property="hasNext" value="${x != before}"/>
</c:forEach>

<m:out value="${x}"/>

また"for"反復は次のようにして行なえます:

<%-- i = 0, 1, 2, 3, 4 --%>

<m:map var="forLoop" codec="_JSP:dynamicIterator">
  <m:set property="hasNextCodec" value="@{_.index < 5}"/>
  <m:set property="nextCodec" value="Bean:get:index"/>
</m:map>

<c:forEach var="i" items="${forLoop}">
  <m:out value="${i}"/>
</c:forEach>

動的反復子では以下のプロパティを使用することができます:

 名前  説明 
 collection  反復を行なうコレクション 
 hasNext  この反復子にまだ訪ねるべき要素があるかどうかを示す真理値。 もし"hasNextCodec"が設定されていなければ、 この値が実際の"collection"よりも優先されます。 
 hasNextCodec  各"hasNext"操作に際して反復子自体に適用されるコーデック。 これは、もしまだ訪ねるべき要素があるば真を、なければ偽を返すものです。 もし設定されれば、"hasNext"及び"collection"より優先されます。 
 next  次に訪ねられるオブジェクト。 もし"nextCodec"が設定されていなければ、この値が"collection"よりも優先されます。 
 nextCodec  各"next"操作に際して反復子自体に適用されるコーデック。 これは、次に訪ねられるオブジェクトを返すものです。もし設定されれば、"next"及び"collection"より優先されます。 
 index  0から始まり、反復の度に一つ加算されるインデックス 

7.4 XMLMap

XMLMap:encode及びXMLMap:decodeを用いると多層マップとXMLとの変換を簡単に行うことが出来ます。 特に指定が無ければ、変換は次の規則に従って行われます:

  1. XML文書の最上位要素の名前は"root";
  2. それぞれのキー名とキー値の対は「<キー名>[キー値]</キー名>」の形のXMLに変換されます。ここで[キー値]の部分は文字列かあるいは再帰的に変換されたキー値のXML表現になります;
  3. 多層マップの"_"リストは「<_><item index="0">[value0]</item><item index="1">[value1]</item>....</_>」の形に変換されます。ここで [value0]は"${_[0]}"のXML表現、[value1]は"${_[1]}"のXML表現等となります。

例えば次のコード:

<m:map exportCodec="XMLMap:encode">
  <m:set property="a">p</m:set>
  <m:map property="b">
    <m:set property="c">q</m:set>
    <m:set property="d">r</m:set>
  </m:map>
</m:map>

出力は:

<root>
  <a>p</a>
  <b>
    <c>q</c>
    <d>r</d>
  </b>
</root>

また次のコード:

<m:map exportCodec="XMLMap:encode">
  <m:map property="@_.*">
    <m:set property="a">p0</m:set>
    <m:set property="b">q0</m:set>
  </m:map>
  <m:map property="@_.*">
    <m:set property="a">p1</m:set>
    <m:set property="b">q1</m:set>
  </m:map>
  <m:map property="@_.*">
    <m:set property="a">p2</m:set>
    <m:set property="b">q2</m:set>
  </m:map>
</m:map>

の出力は:

<root>
  <_>
    <item index="0">
      <a>p0</a>
      <b>q0</b>
    </item>
    <item index="1">
      <a>p1</a>
      <b>q1</b>
    </item>
    <item index="2">
      <a>p2</a>
      <b>q2</b>
    </item>
  </_>
</root>

となります。

生成されたXMLはXMLMap:decodeを用いて多層マップに変換することが出来ます:


<%-- "{_=[{a=p0, b=q0}, {a=p1, b=q1}, {a=p2, b=q2}]}"を出力します --%>

<m:out codec="XML:parse|XMLMap:decode|Bean:get:root">
  <m:map exportCodec="XMLMap:encode">
    <m:map property="@_.*">
      <m:set property="a">p0</m:set>
      <m:set property="b">q0</m:set>
    </m:map>
    <m:map property="@_.*">
      <m:set property="a">p1</m:set>
      <m:set property="b">q1</m:set>
    </m:map>
    <m:map property="@_.*">
      <m:set property="a">p2</m:set>
      <m:set property="b">q2</m:set>
    </m:map>
  </m:map>
</m:out>

マップまたはフォーム形式で符号化された"controlMap"変数を使えばデフォルトの設定を変更することができます。 例えば最上位の要素の名前はcontrolMapとして"rootName=xxx"を指定すれば変更することが出来ます。例えば:

<m:map exportCodec="XMLMap:encode:rootName=response">
  <m:set property="a">p</m:set>
  <m:map property="b">
    <m:set property="c">q</m:set>
    <m:set property="d">r</m:set>
  </m:map>
</m:map>

は次のように出力します:

<response>
  <a>p</a>
  <b>
    <c>q</c>
    <d>r</d>
  </b>
</response>

XMLMap:decodeを使用する際にはcontrolMapの"nameMap"という属性を指定することで簡単なXML要素名の変換を行うことが出来ます;例えば、与えられたXMLが次のように重複する要素を持つ場合:

<list>
  <item>a</item>
  <item>b</item>
  <item>c</item>
</list>

次のようにしてXMLMap:decodeを適用することが出来ます:


<%-- {list={_=[a,b,c]}}を出力します --%>

<m:out codec="XML:parse|XMLMap:decode:nameMap.item=@_.*">
  <list>
    <item>a</item>
    <item>b</item>
    <item>c</item>
  </list>
</m:out>

もしcontrolMapに"nameMap.xxx"という属性が定義されていれば、XMLMapが"xxx"という名前のXML要素を処理する場合、その値が通常の"xxx"の代わりにマップに値を割り当てる際のキーとして使用されます。

7.5 MessageMap

_JSP:getMessageMapはメッセージリソースにアクセスするためにJSTLの<fmt:message>の代用となるマップを作成します。MessageMapは次のようにして作成出来ます:

<m:set var="message" codec="_JSP:getMessageMap_"/>

すると以下の二つは同じになります:

${message['x']}

<fmt:message key="x"/>

メッセージが変数を持つ場合にはコーデックと同様に':'を用いて指定することが出来ます。以下の二つは同じです:

${message['x:@{a}:b']}

<fmt:message key="x">
  <fmt:param value="${a}"/>
  <fmt:param value="b"/>
</fmt:message>

<fmt:message>とは異なり、未定義のメッセージに対しては空文字列が返されます:

${message['undefined']}は空ですが
<fmt:message key="undefined"/>は空ではありません。

You can set your own default value by setting the "defaultValue" property of the message map:

<m:set target="${message}" property="defaultValue" value="MISSING"/>
This is "MISSING":${message['undefined']}

To make the message map return the same default value as <fmt:message>, set the "defaultValue" property to "*". If necessary, you can also set the base name of the message resource by setting "basename" property. You can apply "_JSP:getMessageMap" to a map that defines these properties:

<%-- creates a message map that behaves like <fmt:message> --%>
<m:map var="message" codec="_JSP:getMessageMap">
  <m:set property="defaultValue" value="*"/>
</m:map>

8 カスタマイズ

この章は、JSPカスタムタグの作成の経験をお持ちの方を対象とします。 JSTLや他ののサーブレット|JSPに関連したjarファイルと共に"yuzu.jar"をあなたのCLASSPATHに登録しておいて下さい。

8.1 カスタム属性を持たないタグ

カスタム属性を持たないカスタムなYUZUタグを作成するには、

例えば、次にコードはタグ値を文字列として、小文字に変換するタグを作成します:

package com.mycompany.jsp.tag;

import com.micronova.jsp.tag.*;

public class LowerCaseTag extends YuzuTag
{
    protected Object processValue(Object tagValue) throws Exception
    {
        if (tagValue != null)
        {
            tagValue = tagValue.toString().toLowerCase();
        }

        return tagValue;
    }
}

それから、次のような宣言をTLDファイルに追加して、タグを公開して下さい:

<tag>
 <name>lowerCase</name>
 <tagclass>com.mycompany.jsp.tag.LowerCaseTag</tagclass>
 <bodycontent>JSP</bodycontent>

 <attribute><name>var</name><required>false</required></attribute>
 <attribute><name>target</name><required>false</required></attribute>
 <attribute><name>property</name><required>false</required></attribute>
 <attribute><name>attribute</name><required>false</required></attribute>
 <attribute><name>scope</name><required>false</required></attribute>
 <attribute><name>value</name><required>false</required></attribute>
 <attribute><name>default</name><required>false</required></attribute>
 <attribute><name>className</name><required>false</required></attribute>
 <attribute><name>exportCodec</name><required>false</required></attribute>
 <attribute><name>importCodec</name><required>false</required></attribute>
 <attribute><name>processCodec</name><required>false</required></attribute>
 <attribute><name>codec</name><required>false</required></attribute>
 <attribute><name>assignCodec</name><required>false</required></attribute>
 <attribute><name>test</name><required>false</required></attribute>
 <attribute><name>local</name><required>false</required></attribute>
 <attribute><name>assign</name><required>false</required></attribute>
 <attribute><name>export</name><required>false</required></attribute>
 <attribute><name>doesExport</name><required>false</required></attribute>
</tag>

JSP2.0の場合は各"attribute"文に"<rtexprvalue>true</rtexprvalue>"を追加して下さい。

新しく作成された"lowerCase"タグではYUZUの全ての属性を用いることが出来ます。 例えば、次のコード:

<m:map>
  <m:lowerCase property="lower" value="UpperCase"/>
</m:map>

は次のように出力します:

lower=uppercase

8.2 カスタム属性を持つタグ

カスタム属性を持つYUZUタグを作成するには、さらに以下の段階が必要です:

例えば、次のコードは、タグ値を文字列として与えられた回数複製するタグを作成します。 カスタム属性として、整数"count"を持ちます:

package com.mycompany.jsp.tag;

import com.micronova.jsp.tag.*;

public class MultiplyTag extends YuzuTag
{
    /** "count"属性の値 */

    int _count;

    /** 初期化。 必ずsuper.init()を最初に呼んで下さい。 */

    protected void init()
    {
        super.init();

        /** countの初期値を2に設定 */

        _count = 2;
    }

    /** タグ値の処理 */

    protected Object processValue(Object tagValue) throws Exception
    {
        if (tagValue != null)
        {
            String tagValueString = tagValue.toString();
            StringBuffer buffer = new StringBuffer();

            for (int i = _count; --i >= 0;)
            {
                buffer.append(tagValueString);
            }

            tagValue = buffer.toString();
        }

        return tagValue;
    }

    /** 属性"count"の設定 */

    public void setCount(Object expression) throws Exception
    {
        _count = ((Integer)evaluateAttribute("count", expression, Integer.class)).intValue();
    }
}

"evaluateAttribute()"メソッドは、属性の名前(エラーの際に用いられます)、EL表現、及びEL表現の評価値の型のクラスを引数として持ちます。 なお、EL表現用の引数"expression"は、attribute属性を処理する都合で、オブジェクトとして定義されており、文字列ではないことにご注意下さい("evaluateAttribute()"はもしタグ本文の処理中に呼ばれると"expression"オブジェクトそのまま返します)。

TLDファイル内での宣言は次のようになります:

<tag>
 <name>multiply</name>
 <tagclass>com.mycompany.jsp.tag.MultiplyTag</tagclass>
 <bodycontent>JSP</bodycontent>

 <attribute><name>var</name><required>false</required></attribute>
 <attribute><name>target</name><required>false</required></attribute>
 <attribute><name>property</name><required>false</required></attribute>
 <attribute><name>attribute</name><required>false</required></attribute>
 <attribute><name>scope</name><required>false</required></attribute>
 <attribute><name>value</name><required>false</required></attribute>
 <attribute><name>default</name><required>false</required></attribute>
 <attribute><name>className</name><required>false</required></attribute>
 <attribute><name>exportCodec</name><required>false</required></attribute>
 <attribute><name>importCodec</name><required>false</required></attribute>
 <attribute><name>processCodec</name><required>false</required></attribute>
 <attribute><name>codec</name><required>false</required></attribute>
 <attribute><name>assignCodec</name><required>false</required></attribute>
 <attribute><name>test</name><required>false</required></attribute>
 <attribute><name>local</name><required>false</required></attribute>
 <attribute><name>assign</name><required>false</required></attribute>
 <attribute><name>export</name><required>false</required></attribute>
 <attribute><name>doesExport</name><required>false</required></attribute>

 <attribute><name>count</name><required>false</required></attribute>
</tag>

JSP2.0の場合は各"attribute"文に"<rtexprvalue>true</rtexprvalue>"を追加して下さい。

9 JSP2.0関数

この章はJSP2.0版のYUZUにのみ当て嵌まります。

JSP 2.0よりEL関数が導入されましたが、残念ながらまだ引数型を多数持つ関数を使用することが出来ないため、YUZUのコーデック関数は暫定的に次のような命名法を用いて"m.tld"ファイルの中にEL関数として宣言されています:

m:コーデック部類名_コーデック関数名[_引数の数](...)

"_引数の数"の部分が省略されたものは、最小の引数の数を持つ(必須引数のみを持つ)ものを意味します。 例えば、 "m:URL_encode"は"m:URL_encode_1"と同義であり、省略可能なENCODING引数を持つ"m:URL_encode_2"とは異ります。 なおEL関数として宣言されたコーデックでは最初の引数がオペランドとして用いられます。 例えば、次の二つは同義です:

<m:out value="こんにちは" exportCodec="URL:encode:utf-8|Hex:encode"/>

<m:out value="${m:Hex_encode(m:URL_encode_2('こんにちは', 'utf-8'))}"/>

もう一つの問題はEL関数はまだ動的なELの評価によく対応していないことです(例えば、EL関数の宣言に用いられる接頭辞は動的な評価においては参照できません)。 このためYUZUでは、"@{...}"や"%{...}"の内部等でELが動的に評価される際に、接頭辞"fn"はJSTL標準関数を示すものとして、また接頭辞"m"はYUZUのコーデック関数を示すものとして固定的に扱います。

動的なEL評価においては、コーデックの様に"URL:encode"または"com.yourcompany.codec.Codec:method"といった名前をそのままEL関数として用いることができます。 引数の数が異る場合には、名前の後にアンダースコアに続けて引数の数を付加したり(例えば"String:join_2")、また、最大の引数を持つものを意味する"_max"または最小の引数を持つものを意味する"_min"を付加することが出来ます(何も指定されなければ"_min"が用いられます)。 例えば"URL:encode_max"は"URL:encode_2"と同義であり、"URL:encode"は"URL:encode_min"または"URL:encode_1"と同義です。

JSP2.0のEL関数では明示的でない引数はまだ使用することができませんので、全ての引数は明示的に与えられなくてはなりません。 例えば、次の二つは同じとなります:

<m:out value="index.jsp" codec="_JSP:encodeURL"/>

<m:out value="${m:JSP_encodeURL(pageContext, 'index.jsp')}"/>