package test.generic;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import test.AbstractAnotationDataSet;
import logger.TraceLogger;
public class LoggingHandler<T> implements InvocationHandler {
final T target;
public LoggingHandler(T target) {
this.target = target;
}
/**
* <pre>
* 動的Profileを利用したロギング処理
* </pre>
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
boolean logging = isLogging();
if (logging) startTrace(method, args);
Object ret = method.invoke(target, args);
if (logging) endTrace(method, ret);
return ret;
}
/**
* <pre>
* アノテーションの判定処理
* 強制的にTrueを返す事で、抽象クラスをimplementsして実装したメソッドはすべてロギングする
* </pre>
*
* @return true:ログ出力実施、false:ログ出力しない
*/
private boolean isLogging() {
TraceLogger logger = target.getClass().getAnnotation(TraceLogger.class);
return logger != null && logger.values();
}
/**
* <pre>
* 引数用ロギング処理
* </pre>
*
* @param method 実行されたメソッド
* @param args 実行メソッドの引数
*/
private void startTrace(Method method, Object[] args) {
StringBuilder stb = new StringBuilder();
// beforログ
stb.append("ENTER:");
// クラス名の取得
stb.append(target.getClass().getName());
// メソッド名の取得
stb.append("#").append(method.getName());
// パラメータの取得
stb.append("(");
// パラメータの設定
if (args != null) {
Iterator<Object> it = Arrays.asList(args).iterator();
while(it.hasNext()) {
Object arg = it.next();
if (arg instanceof AbstractAnotationDataSet) {
stb.append(getDataSet(arg));
} else if (arg == null) {
stb.append("null");
} else {
stb.append(arg.toString());
}
if (it.hasNext()) stb.append(",");
}
}
stb.append(")");
// 戻り値の型を取得
stb.append(" ");
stb.append(method.getReturnType());
// ログ出力
System.out.println(stb.toString());
}
/**
* <pre>
* DataSetオブジェクトを解析、ログ出力する
* </pre>
*
* @param obj DataSetオブジェクト
* @return 解析したDataSetオブジェクトの文字列
*/
private String getDataSet(Object obj) {
StringBuilder stb = new StringBuilder();
// DataSetクラスの名称を取得
stb.append(obj.getClass().getName());
stb.append("{");
// DataSetクラスに存在する全フィールドオブジェクトの取得
Field[] fields = obj.getClass().getDeclaredFields();
Iterator<Field> it = Arrays.asList(fields).iterator();
try {
while (it.hasNext()) {
Field field = it.next();
// privateオブジェクトに対するアクセス権限の付与
field.setAccessible(true);
Class clazz = field.getType();
// クラス名の取得
stb.append(clazz.getName());
stb.append(" ");
// 生成されたオブジェクト名称の取得
stb.append(field.getName());
stb.append("=");
// オブジェクトに格納されている値の取得
stb.append(field.get(obj));
if (it.hasNext()) stb.append(",");
}
} catch (IllegalAccessException e) {
e.printStackTrace();
System.out.println(e.getStackTrace());
}
stb.append("}");
return stb.toString();
}
/**
* <pre>
* 返り値用ロギング処理
* </pre>
*
* @param method 実行されたメソッド
* @param obj 実行メソッドの返り値
*/
private void endTrace(Method method, Object obj) {
StringBuilder stb = new StringBuilder();
// beforログ
stb.append("RETURN:");
// クラス名の取得
stb.append(target.getClass().getName());
// メソッド名の取得
stb.append("#").append(method.getName());
// パラメータの取得
stb.append("() ");
// パラメータの設定
if (obj instanceof AbstractAnotationDataSet) {
stb.append(getDataSet(obj));
} else if (obj == null) {
stb.append("null");
} else {
stb.append(obj.toString());
}
// ログ出力
System.out.println(stb.toString());
}
}
最終更新:2012年07月27日 15:05