Tiles Hack だなんて大げさだ。
Struts の Tiles プラグインの挙動を変更したくなった。動的に definition を追加したい。どこから手を付けて良いものか悩んでいたのだけど、DefinitionsFatory を自作のものに変更できることが判明したので、これで対応した。
struts-config.xml で Tiles プラグインを設定している箇所で、definitions-factory-class プロパティに、自作の Factory クラスを指定してあげるだけ。
<plug-in className="org.apache.struts.tiles.TilesPlugin"> <set-property property="definitions-factory-class" value="com.deftrash.struts.OriginalI18nFactorySet" /> <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml"/> <set-property property="moduleAware" value="true"/> </plug-in>
definitions-factory-class を指定しない場合は、デフォルトで、org.apache.struts.tiles.xmlDefinition.I18nFactorySet が使用される。tiles-defs.xml を読み込んで、ComponentDefinition を生成するクラスだ。
動的に definition を追加するために、自作 Factory を、この I18nFactorySet を継承して作成。createDefaultFactory メソッドをオーバーライドして改造することにした。
/* (非 Javadoc) * @see org.apache.struts.tiles.xmlDefinition.I18nFactorySet#createDefaultFactory(javax.servlet.ServletContext) */ protected DefinitionsFactory createDefaultFactory(ServletContext servletContext) throws DefinitionsFactoryException, FileNotFoundException {
DefinitionsFactory factory = super.createDefaultFactory(servletContext);
// TODO 動的にComponentDefinitionを追加する処理をここに
return factory;
たったこれだけで、望むべき動作が得られました。動的に definition を追加する以外のニーズがあっても、ここを起点にいくらでも改造できそうな感じ。まあ、I18nFactorySet クラスで xml を読み出すところが private になっているのが、扱いづらいけど。
すでに struts は枯れて細かいところまで見ずにいたけど、実際に手を入れていこうとすると、改造しやすいように窓口が開いていて、風の通しがすごい良いことに気付く。こういう懐の深いデザインは、見習っていきたいですね。