DynaActionForm: form-beanのインヘリタンス

Adding Spice to Struts[javaboutique.internet.com]をみて、これは便利!と思って早速使ってみることに。
簡単に説明すると、DynaActionFormでインヘリタンスのメカニズムを作ろう、ということなのだ。 例えば、contactFormとcompanyContactFormがあったとする。 contactFormにはname,email,commentのプロパティがあり、companyContactFormにはcontactFormの全て+companyNameとうプロパティがある。 この場合、form-beanを定義する時に同じform-propertyが繰り返されることになる。こんな感じに。


<form-bean name="contactForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="name" type="java.lang.String />
<form-property name="email" type="java.lang.String />
<form-property name="comment" type="java.lang.String />
</form-bean>

<form-bean name="companyContactForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="companyName" type="java.lang.String" />
<form-property name="name" type="java.lang.String />
<form-property name="email" type="java.lang.String />
<form-property name="comment" type="java.lang.String />

</form-bean>

この繰り返された部分を、companyContactFormがcontactFormをインヘリットできる形にして取りのぞこうというのだ。
まずDynaActionFormのサブクラスのCustomDynaFormというクラスを作り、initializeメソッドをオーバーライドする。 DynaActionFormはFormBeanConfigオブジェクトからそれぞれのプロパティ(form-propertyタグで定義される)をとりだして、Mapにいれる。

package package.name;

import org.apache.struts.validator.DynaValidatorForm;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.FormBeanConfig;
import org.apache.struts.config.FormPropertyConfig;

public class CustomDynaForm extends DynaValidatorForm {

public void initialize(ActionMapping mapping) {
super.initialize(mapping);

//form-beanのnameとそのconfigをとりだす。
String name = mapping.getName();
FormBeanConfig config = mapping.getModuleConfig().findFormBeanConfig(name);

//"includes"という名前のform-propertyがあるかどうかチェック。
FormPropertyConfig propertyConfig = config.findFormPropertyConfig("includes");

if(propertyConfig != null) {
String formBeanToInclude = propertyConfig.getInitial();

//includeするform-beanのconfigとそのform-propertyを取り出す。
FormBeanConfig formBeanConfig =
mapping.getModuleConfig().findFormBeanConfig(formBeanToInclude);
FormPropertyConfig properties[] =
formBeanConfig.findFormPropertyConfigs();

for(int i=0; i<properties.length; i++) {
this.getMap().put(properties[i].getName(), properties[i].getInitial());
}

}
}
}

form-propertyに"includes"という名前があれば、そのform-propertyのinitialeのバリューを取り出す。 このバリューがとりこみたいform beanの名前だ。 後は、そのform beanのプロパティを足すだけ。
そしてstruts-configのを定義する際には、上のCustomDynaFormを使用する。

<form-bean name="contactForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="name" type="java.lang.String />
<form-property name="email" type="java.lang.String />
<form-property name="comment" type="java.lang.String />
</form-bean>

<form-bean name="companyContactForm" type="package.name.CustomDynaForm">
<form-property name="companyName" type="java.lang.String" />
<form-property name="includes" type="java.lang.String" initial="contactForm" />
</form-bean>

と、こんな感じになる。 これはいろんな面で便利だ。
と、思うのだが、実際使ってみたら

No getter method for property name of bean org.apache.struts.taglib.html.BEAN' 

なんてエラーが…。 私の場合、実際にはorg.apache.struts.validator.DynaValidatorFormを使っているのだが、それは関係ないと思う。 initialize()が呼び出された段階で、Mapにはちゃんとすべてのプロパティが入っているのも確認済みだ。
誰か暇な人、一度ためしてもらいたい。 (そんな暇人おらんかな…)