2015年6月21日日曜日

[業務ロジック][機能単位][実装][サービス]ServiceInputParameter

 サービス入力パラメータクラス。バッチ実行を考慮し、ログファイルから入力パラメータを作成するメソッドを持っている。これまでに紹介しているサービス呼び出しの仕組みは、画面操作からでも、バッチからでも同じサービスを呼び出すため、ログにサービス入力内容、サービス出力内容を記録しておけば、問題が起きた状況をいつでも再現できることになる。
 ログの内容からサービス入力パラメータを作成する仕組みを実装することにより、問題状況をバッチで簡単に再現することができるようになる。

package service.param;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import util.SvFile;
import exception.ApplicationInternalException;

/**
 * サービス入力パラメータ<br>
 * 本クラスは固有の属性を持ちませんが、サービス入力パラメータは<br>
 * 全て本クラスを継承させて作るため、プレースホルダとしての意味を持っています。
 */
public abstract class ServiceInputParameter extends ServiceParameter {

    /**
     * コンストラクタ
     *
     * @param parameterName
     *            パラメータ名
     */
    public ServiceInputParameter(String parameterName) {
        super(parameterName);
    }

    /**
     * CSVファイルパスで示されるCSVファイルを開き、パラメータユニットの 設定に従ってサービス入力パラメータを設定します。
     *
     * @param filePath
     *            CSVファイルパス
     * @param skipFirstLine
     *            最初の行を読み飛ばす場合はtrue、そうでなければfalse
     */
    public void importCsvFile(String filePath, boolean skipFirstLine) {

        try {
            // CSVファイルを開き、内容をロードする
            SvFile svFile = new SvFile();
            svFile.loadFile(filePath, ",", skipFirstLine);

            // パラメータユニット設定に従い、全ての入力パラメータをCSVファイルから取得する
            importSvFile(svFile, 0);

        } catch (IOException e) {
            throw new ApplicationInternalException(e);
        }
    }

    /**
     * CSVファイルパスで示されるCSVファイルを開き、パラメータユニットの 設定に従ってサービス入力パラメータを設定します。
     * CSVファイルパスのみを指定した場合、CSVファイルの最初の1行はヘッダ行として読み飛ばされます。
     *
     * @param filePath
     *            CSVファイルパス
     */
    public void importCsvFile(String filePath) {

        // デフォルトでは最初の1行をヘッダ行とみなす
        importCsvFile(filePath, true);
    }

    /**
     * TSVファイルパスで示されるCSVファイルを開き、パラメータユニットの 設定に従ってサービス入力パラメータを設定します。
     *
     * @param filePath
     *            TSVファイルパス
     * @param skipFirstLine
     *            最初の行を読み飛ばす場合はtrue、そうでなければfalse
     */
    public void importTsvFile(String filePath, boolean skipFirstLine) {

        try {
            // TSVファイルを開き、内容をロードする
            SvFile svFile = new SvFile();
            svFile.loadFile(filePath, "\t", skipFirstLine);

            // パラメータユニット設定に従い、全ての入力パラメータをCSVファイルから取得する
            importSvFile(svFile, 0);

        } catch (IOException e) {
            throw new ApplicationInternalException(e);
        }
    }

    /**
     * TSVファイルパスで示されるCSVファイルを開き、パラメータユニットの 設定に従ってサービス入力パラメータを設定します。
     * TSVファイルパスのみを指定した場合、TSVファイルの最初の1行はヘッダ行として読み飛ばされます。
     *
     * @param filePath
     *            TSVファイルパス
     */
    public void importTsvFile(String filePath) {

        // デフォルトでは最初の1行をヘッダ行とみなす
        importTsvFile(filePath, true);
    }

    /**
     * SVファイル(CSV or TSV)から入力パラメータを取得します。
     *
     * @param svFile
     *            SVファイル
     * @param lineIndex
     *            行インデックス(先頭行を読み飛ばさない場合は1行目が0、先頭行を読み飛ばす設定の場合は2行目が0となる)
     */
    public void importSvFile(SvFile svFile, int lineIndex) {

        // SVファイルの内容を取得する
        List<List<String>> svLineList = svFile.getSvLineList();

        // パラメータユニット設定に従い、全ての入力パラメータをTSVファイルから取得する
        for (int i = 0; i < getParameterUnitList().size(); i++) {

            // パラメータユニットの列とSVカラムの並びは同じであると仮定する
            ParameterUnit parameterUnit = getParameterUnitList().get(i);
            List<String> svLine = svLineList.get(lineIndex);

            // 型に応じた入力値設定を行う
            if ("String".equalsIgnoreCase(parameterUnit.getType())) {
                String value = svLine.get(i);
                setString(parameterUnit.getPhysicalName(), value);
            }
            if ("int".equalsIgnoreCase(parameterUnit.getType())
                    || "Integer".equalsIgnoreCase(parameterUnit.getType())) {
                Integer value = Integer.valueOf(svLine.get(i));
                setInt(parameterUnit.getPhysicalName(), value);
            }
            if ("long".equalsIgnoreCase(parameterUnit.getType())
                    || "Long".equalsIgnoreCase(parameterUnit.getType())) {
                Long value = Long.valueOf(svLine.get(i));
                setLong(parameterUnit.getPhysicalName(), value);
            }
            if ("Double".equalsIgnoreCase(parameterUnit.getType())) {
                Double value = Double.valueOf(svLine.get(i));
                setDouble(parameterUnit.getPhysicalName(), value);
            }
            if ("Date".equalsIgnoreCase(parameterUnit.getType())) {
                Date value = getDateByDateString(svLine.get(i));
                setDate(parameterUnit.getPhysicalName(), value);
            }
        }
    }

    /**
     * 日付文字列を解釈して、Date型に変換します。 許容する書式は次の通りです。<br>
     * 1. yyyy/MM/dd HH:mm:ss<br>
     * 2. yyyy/MM/dd<br>
     * 3. yy-MM-dd HH:mm:ss<br>
     * 4. yy-mm-dd<br>
     *
     * @param dateString
     *            日付文字列
     * @return 日付
     */
    private Date getDateByDateString(String dateString) {

        try {
            // 許容する日付書式を列挙する
            String[] formats = new String[] { "yyyy/MM/dd HH:mm:ss",
                    "yyyy/MM/dd", "yy-MM-dd HH:mm:ss", "yy-mm-dd" };

            // 許容する日付書式で日付と解釈できるかどうか試す
            Date date = null;
            ParseException lastException = null;
            for (int i = 0; i < formats.length; i++) {

                try {
                    // 日付と解釈できる文字列であればreturnする
                    SimpleDateFormat sdf = new SimpleDateFormat(formats[i]);
                    date = sdf.parse(dateString);
                    return date;

                    // 最後の例外を記憶しておく
                } catch (ParseException e) {
                    lastException = e;
                }
            }

            // ここまでreturnできていなければ最後の例外をスローする
            throw lastException;

        } catch (ParseException e) {
            throw new ApplicationInternalException(e);
        }
    }
}

0 件のコメント:

コメントを投稿