/*
 * Copyright (c) 2007 NTT DATA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.terasoluna.rich.functionsample.common;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import jp.terasoluna.fw.exception.SystemException;

/**
 * リクエストヘッダに特定値がある場合に例外を発生するフィルタークラス
 *
 */
public class ExceptionHandlerFilter implements Filter {
    
    /**
     * 例外生成時発生する例外のエラーコード
     */
    public static final String ERROR_CODE = "8004C029";
    
    /**
     * フィルタの初期化を行う。
     * なにもしない。
     * 
     * @param config フィルタ設定
     * @throws ServletException サーブレット例外
     */
    public void init(FilterConfig config) throws ServletException {
    }

    /**
     * リクエストのヘッダに例外値がある場合に例外を発生する。
     *
     * @param req HTTPリクエスト
     * @param res HTTPレスポンス
     * @param chain チェインされたフィルタ
     * @throws IOException 入出力例外
     * @throws ServletException サーブレット例外
     */
    public void doFilter
    (ServletRequest req, ServletResponse res, FilterChain chain) 
    throws IOException, ServletException {
        // リクエストヘッダに設定されているreigai値取得
        String className =
            ((HttpServletRequest) req).getHeader("exceptionhandler");
        
        // 例外情報がある場合例外を発生        
        if (className == null) {
            chain.doFilter(req, res);            
        } else {
            try {
                Class clazz = Class.forName(className);
                Object exception = clazz.newInstance();
                if (exception instanceof IOException) {
                    throw (IOException) exception;
                } else if (exception instanceof ServletException) {
                    throw (ServletException) exception;
                } else if (exception instanceof RuntimeException) {
                    throw (RuntimeException) exception;
                } else {
                    throw new SystemException(
                            (Exception) exception, ERROR_CODE);
                }
            } catch (ClassNotFoundException e) {
                throw new SystemException(e, ERROR_CODE);
            } catch (IllegalAccessException e) {
                throw new SystemException(e, ERROR_CODE);
            } catch (InstantiationException e) {
                throw new SystemException(e, ERROR_CODE);
            } catch (ClassCastException e) {
                throw new SystemException(e, ERROR_CODE);
            }
        }
    }

    /**
     * フィルタの破棄処理を行う。
     * なにもしない。
     */
    public void destroy() {
    }

}
