SAStruts + Velocity (2)
SAStruts + Velocity が動くことが確認出来たので、今度はSAStrutsの
チュートリアルに含まれるサンプルをVelocityに移植中です。
そこで、移植にちょっと手間取ったサンプルがありました。
「複数選択リスト」サンプルにて
「複数選択リスト」サンプルのJSPファイルは以下のようになっています。
multiselect.jsp
<html> <head> <title>Multiselect</title> </head> <body> <html:errors/> <s:form action="/multiselect"> <html:select property="select" multiple="true" size="3"> <html:option value="1">One</html:option> <html:option value="2">Two</html:option> <html:option value="3">Three</html:option> </html:select> <br /> ${f:h(select)}<br /> <input type="submit" name="submit" value="サブミット"/> </s:form> </body> </html>
まず、toolbox.xml に ListTool の定義を追加します。
toolbox.xml
<tool> <key>list</key> <scope>application</scope> <class>org.apache.velocity.tools.generic.ListTool</class> </tool>
multiselect.vm
<html> <head> <title>Multiselect</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form name="multiselectActionForm" method="post" action="$link.setRelative("velocity/multiselect/")"> <select name="select" multiple="multiple" size="3"> <option value="1"#if($list.contains($select, "1")) selected="selected" #end>One</option> <option value="2"#if($list.contains($select, "2")) selected="selected" #end>Two</option> <option value="3"#if($list.contains($select, "3")) selected="selected" #end>Three</option> </select> <br /> $!escape.html($!select)<br /> <input type="submit" name="submit" value="サブミット"/> </form> </body> </html>
すると、以下のようなエラーが発生しました。*1
nvocation of method 'contains' in class org.seasar.struts.action.ArrayWrapper threw exception class java.lang.UnsupportedOperationException : contains
何でだろうと思い、ArrayWrapper#contains(Object)の実装を見てみたら、以下のようになっていました。
public boolean contains(Object o) { throw new UnsupportedOperationException("contains"); }
これが原因です。
どうしようかな…、ArrayWrapper#toArray()はサポートされていたので以下のように修正してみました。
修正後の multiselect.vm
<html> <head> <title>Multiselect</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form name="multiselectActionForm" method="post" action="$link.setRelative("velocity/multiselect/")"> <select name="select" multiple="multiple" size="3"> <option value="1"#if($list.contains($select.toArray(), "1")) selected="selected" #end>One</option> <option value="2"#if($list.contains($select.toArray(), "2")) selected="selected" #end>Two</option> <option value="3"#if($list.contains($select.toArray(), "3")) selected="selected" #end>Three</option> </select> <br /> $!escape.html($!select)<br /> <input type="submit" name="submit" value="サブミット"/> </form> </body> </html>
不恰好なコードですが、とりあえず動きました。
もっとスマートな方法は無いのでしょうか?
*1:SAStruts1.0.2-rc3 では、ArrayWrapper#contains(Object) がサポートされる予定になっています