All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nablarch.fw.handler.DispatchHandler Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package nablarch.fw.handler;

import nablarch.core.log.Logger;
import nablarch.core.log.LoggerManager;
import nablarch.fw.ExecutionContext;
import nablarch.fw.Handler;
import nablarch.fw.Result;

/**
 * ハンドラキューの委譲チェインとは独立したルールに従って、
 * ハンドラのディスパッチを行うハンドラ(ディスパッチャ)
 * 
 * @param    ハンドラに対する入力オブジェクトの型
 * @param  ハンドラの処理結果オブジェクトの型
 * @param    具象ハンドラの型
 *
 * @author Iwauo Tajima
 */
public abstract class DispatchHandler>
implements Handler {
    /** ロガー */
    private static final Logger LOGGER = LoggerManager.get(DispatchHandler.class);

    /** デリゲートファクトリ */
    private DelegateFactory delegateFactory = new DefaultDelegateFactory();

    /**
     * 処理を委譲するハンドラの型を決定する。
     * 
     * @param  input 入力データ
     * @param  context 実行コンテキスト
     * @return 処理を委譲するハンドラ
     * @throws ClassNotFoundException 指定されたクラスが存在しなかった場合。
     */
    protected abstract Class getHandlerClass(TData input, ExecutionContext context)
    throws ClassNotFoundException;
    
    /**
     * {@inheritDoc}
     * 
     * このクラスの実装では、 #getHandlerClass() で指定されるクラスのインスタンスを生成し、
     * ハンドラキューに追加した後、後続のハンドラに処理を委譲する。
     * 
     * ハンドラの追加位置は{@link #immediate}の値に従って以下のように変化する。
     * 
     *   immediate = true : ハンドラキューの先頭に追加。(即時に実行される。)
     *   immediate = false: ハンドラキューの末尾に追加。 
     * 
*/ @SuppressWarnings("unchecked") public TResult handle(TData req, ExecutionContext ctx) { Handler handler = null; Object delegate = null; String fqn = null; Class clazz = null; try { clazz = getHandlerClass(req, ctx); fqn = clazz.getName(); // 委譲先クラスのインスタンスを生成する delegate = delegateFactory.create(clazz); handler = createHandlerFor(delegate, ctx); } catch (ClassNotFoundException e) { // クラス名が存在しない場合は404エラーにする。 String message = "Couldn't find handler.: " + fqn; LOGGER.logInfo(message, e); throw new Result.NotFound(message, e); } catch (InstantiationException e) { // Couldn't create an instance because the class was // abstract or interface. throw new RuntimeException(e); } catch (IllegalAccessException e) { // Couldn't create an instance because access to // its constructor was not permitted. throw new RuntimeException(e); } if (handler == null) { String message = "Couldn't instantiate handler.: " + fqn; LOGGER.logInfo(message); throw new Result.NotFound(message); } if (immediate) { // ハンドラキューの先頭に追加。(直後に実行される。) ctx.addHandler(0, handler); } else { // ハンドラキューの最後尾に追加。 ctx.addHandler(handler); } return (TResult) ctx.handleNext(req); } /** * 渡されたインスタンスからハンドラインスタンスを作成して返す。 * * 指定されたクラスがHandlerインターフェースを実装している場合は * そのインスタンスをキャストして返す。 * 対象のクラスがハンドラインターフェースを実装していない場合でも、 * MethodBinderが実行コンテキストに設定されていれば、それを使用して * Handlerインターフェースのラッパーを作成して返す。 * MethodBinderも存在しない場合はnullを返す。 * @param delegate インスタンス * @param ctx 実行コンテキスト * @return ハンドラインスタンス */ @SuppressWarnings({ "rawtypes", "unchecked" }) protected Handler createHandlerFor(Object delegate, ExecutionContext ctx) { if (delegate instanceof Handler) { return (Handler) delegate; } if (ctx.getMethodBinder() != null) { return (Handler) ctx.getMethodBinder().bind(delegate); } return null; } /** ディスパッチされたハンドラの実行タイミング。 */ private boolean immediate = true; /** * ディスパッチされたハンドラの実行タイミングを指定する。 * * @param immediate * trueの場合は、ディスパッチされたハンドラをハンドラキューの先端に追加する。 * falseの場合は、ディスパッチされたハンドラをハンドラキューの最後尾に追加する。 * * @return このオブジェクト自体 */ @SuppressWarnings("unchecked") public TSelf setImmediate(boolean immediate) { this.immediate = immediate; return (TSelf) this; } /** * アクセスログにディスパッチ先クラスを出力する。 * * デフォルトでは何もしない。 * 必要に応じてオーバーライドすること。 * * @param data 入力データオブジェクト * @param context 実行コンテキスト * @param fqn ディスパッチ先クラスの完全修飾クラス名 */ protected void writeDispatchingClassLog(TData data, ExecutionContext context, String fqn) { //nop } /** * ハンドラファクトリを設定する。 * 明示的に設定されない場合、デフォルト実装として{@link DefaultDelegateFactory}を使用する。 * @param delegateFactory ハンドラファクトリ */ public void setDelegateFactory(DelegateFactory delegateFactory) { this.delegateFactory = delegateFactory; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy