はじめに †
- AspectJ ログ で作った、おみくじアプリのソースコードに手を加えずに国際化したい
- こんなかんじ
どうするか? †
- Swingアプリの JButton#setText() や JFrame#setTitle() を AspectJ の @Around アドバイス を使って乗っ取ってやればいい
- OmikujiI18N アスペクトを作成する
- 本来 OmikujiUI 内で、?#setText( english ) や ?#setTitle( english ) しているところを乗っ取り、
- english をキーに label_ja.properties から日本語訳(japanese)を取り出し、
- ?#setText( japanese ) 、?#setTitle( japanese ) している。
OmikujiI18Nアスペクト †
package com.snail.exam.aj.omikuji;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class OmikujiI18N {
@Around("call(* *.setText(String)) || call(* *.setTitle(String)))")
public void setText(ProceedingJoinPoint thisJoinPoint) {
// メソッド引数の取得
Object[] args = thisJoinPoint.getArgs();
String srcText = (String) args[0];
try {
// 第一引数を入れ替える
String key = srcText.replaceAll(" ", "_").replaceAll("=", "_");
ResourceBundle resource = PropertyResourceBundle.getBundle("label",
Locale.getDefault(), this.getClass().getClassLoader());
String destText = resource.getString(key);
args[0] = destText;
// メソッド( setText() / setTitle() )の実行。
thisJoinPoint.proceed(args);
} catch (Throwable th) {
// 何らかのエラーが起きたときには、元の引数でメソッドを実行する
// (label_ja.properties に変換するエントリがなかった場合)
// System.out.println(srcText + "は、"
// + Locale.getDefault().getDisplayLanguage() + "化できませんでした。");
try {
thisJoinPoint.proceed();
} catch (Throwable ignoreEx) {
// if RuntimeExceptin occurred, throw it.
if (ignoreEx instanceof RuntimeException) {
throw (RuntimeException) ignoreEx;
}
// Should not happen
ignoreEx = null;
}
}
}
}
Java#AspectJ