Strutsの画面レイアウトの為の機能でTilesという概念がありますが、こちらもstruts-config.xmlと同様に設定ファイルが大変な事になります。実際の開発では画面単位できめ細かい設定を行うわけではなく、使用するレイアウトを継承して中身1画面の定義で完了するケースが殆どでしょう。そのために設定ファイルを書くのは非常に馬鹿らしいです。
そこで、基本の設定ファイルを活かしつつ、設定にない部分を動的に補完する方法を説明します。
まず、StrutsがTilesの定義を取得する際のフローを説明すると、TilesRequestProcessorというクラスの中でフィールドとして保持しているDefinitionFactoryというクラスのインスタンスを使用して、Tilesの設定ファイルの内容を元にタイル定義を取得します。ですので、TilesRequestProcessorのDefinitionFactoryを独自のインスタンスに差し替える事が出来れば、後は独自の方法で色々と拡張可能になります。
具体的には以下のようなコードで差し替えが可能になります。オーバーライドする対象のクラスはorg.apache.struts.tiles.TilesRequestProcessorです。もちろん、そのサブクラスでも構いません。
/**
* @see org.apache.struts.tiles.TilesRequestProcessor#initDefinitionsMapping()
*/
@Override
protected void initDefinitionsMapping() throws ServletException {
super.initDefinitionsMapping();
final DefinitionsFactory original = this.definitionsFactory;
definitionsFactory = new DefinitionsFactory() {
private static final long serialVersionUID = -8325761699308319074L;
public void destroy() {
original.destroy();
}
public DefinitionsFactoryConfig getConfig() {
return original.getConfig();
}
public ComponentDefinition getDefinition(String name,
ServletRequest request, ServletContext context)
throws NoSuchDefinitionException,
DefinitionsFactoryException {
//ここで差し替え処理を行う!
return null;
}
public void init(DefinitionsFactoryConfig config,
ServletContext context) throws DefinitionsFactoryException {
original.init(config, context);
}
public void setConfig(DefinitionsFactoryConfig config,
ServletContext context) throws DefinitionsFactoryException {
original.setConfig(config, context);
}
};
}
差し替え部分で元のインスタンスに委譲しつつ、値が取得できない場合はリクエストの情報を元に独自のComponentDefinitionのインスタンスを生成して返すのが一番楽なパターンだと思います。私の場合は無設定化Struts用の注釈にTiles定義の注釈を埋め込めるようにして、Tilesの設定をアクションのフィールドから行えるようにしました。