/*
 * Copyright (c) 2011 NTT DATA Corporation
 */

package jp.terasoluna.batch.functionsample.b005;


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * ログを出力するためのインタセプタの基底クラス。
 * 
 * <p>
 * コンテナ内のBeanの相互参照を避けるため、 操作ログ出力クラスを直接設定(DI)しない。
 * 一回目の実行時に、ApplicationContextから取得を行う。
 * </p>
 * 
 * 
 */
public abstract class LoggingInterceptor implements MethodInterceptor,
        ApplicationContextAware {
    /**
     * Log。
     */
    private static Log logger = LogFactory.getLog(LoggingInterceptor.class);

    /**
     * 操作ログ。
     */
    private OperationLogger operationLogger = null;

    /**
     * 操作ログのBean名称。
     */
    private String operationLoggerBeanName = null;

    /**
     * アプリケーションコンテキスト。
     */
    private ApplicationContext applicationContext = null;

    /**
     * 操作ログのBean名称を設定する。
     * 
     * @param operationLoggerBeanName 操作ログのBean名称。
     */
    public void setOperationLoggerBeanName(String operationLoggerBeanName) {
        this.operationLoggerBeanName = operationLoggerBeanName;
    }

    /**
     * アプリケーションコンテキストを設定する。
     * 
     * @param applicationContext アプリケーションコンテキスト
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /**
     * MethodInvocationの情報を一部文字列化する。
     * 
     * @param invocation MethodInvocation
     * @return MethodInvocationの情報を一部文字列化したもの
     */
    protected String getInvocationDescription(MethodInvocation invocation) {
        return "method '" + invocation.getMethod().getName() + "' of class ["
                + invocation.getThis().getClass().getName() + "]";
    }

    /**
     * 操作ログ出力クラスを取得する。
     * 
     * @return 操作ログ出力クラス
     */
    protected OperationLogger getOperationLogger() {
        if (this.operationLogger == null) {
            try {
                this.operationLogger = (OperationLogger) applicationContext
                        .getBean(operationLoggerBeanName, OperationLogger.class);
            } catch (Exception e) {
                logger.error("logger bean not found.", e);
            }
        }
        return this.operationLogger;
    }

}
