S2Mai のテンプレートパスを少し指定できるように
S2Mai は手軽にメール送信メソッドを作れる、という印象。だけれども、テンプレートのパスがパッケージ込みクラス+メソッド名で固定になっているので、「運用者がテンプレートを書き換えたい」場合にはちょっとわかりづらい。
そこで、クラスパス上という制限だけはそのままに、ファイル名をメソッド単位で指定できるようにしてみた。具体的にはメソッドにアノテーションを付け、そこでファイル名(拡張子除く)を指定する形。
前提として MaiMetaDataFactory の実装および MaiMetaData の実装を作成し、s2mai.dicon および s2mai-core.dicon を別名で定義してそっちを使うようにする。ここは詳細略。MaiMetaDataFactory の方も MaiMetaData の実装インスタンスを変えるだけなので略。
作成したアノテーション。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MailTemplatePath { /** * テンプレートファイルパスの部分文字列。 * <p> * クラスパスのルートから、この文字列 + "." + 拡張子を探す。 * 先頭は "/" 無し、拡張子を除いたファイル名を指定する。 * {@see ClassLoader#getResource(java.lang.String)} * </p> * @return テンプレートファイルパスの部分文字列。 */ String value(); }
MaiMetaData の実装。org.seasar.mai.meta.impl.MaiMetaDataImpl を extends して、getTemplatePath を override。あと ext が private なので別に保持するように変更。
org.seasar.mai.meta.impl.MaiMetaDataImpl の拡張 public synchronized String getTemplatePath(Method method) { String path = templatePathCache.get(method); if (path != null) { return path; } MailTemplatePath annotation = method.getAnnotation(MailTemplatePath.class); if (annotation == null) { Class<?> maiClass = method.getDeclaringClass(); path = maiClass.getName().replaceAll("\\.", "/") + "_" + method.getName() + "." + ext; } else { path = annotation.value() + "." + ext; } templatePathCache.put(method, path); return path; }
あとは XxxMai のメソッドに @MailTemplatePath("foo/bar") と書けば、クラスパスルートから foo/bar.ftl というファイルを探してテンプレートとして使用される。