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

nablarch.test.core.reader.TestDataParsingTemplate Maven / Gradle / Ivy

The newest version!
package nablarch.test.core.reader;

import nablarch.core.util.StringUtil;
import nablarch.test.NablarchTestUtils;
import nablarch.test.core.util.interpreter.InterpretationContext;
import nablarch.test.core.util.interpreter.TestDataInterpreter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static nablarch.core.util.Builder.concat;


/**
 * テストデータ解析用のテンプレートクラス。
 *
 * @param  解析後の型
 * @author T.Kawasaki
 */
abstract class TestDataParsingTemplate {

    /** 解析に使用するリーダ */
    private final TestDataReader reader;

    /** 委譲先の{@link nablarch.test.core.util.interpreter.TestDataInterpreter} */
    private final List interpreters;

    /** 解析対象のデータ型 */
    private final DataType targetType;

    /** テストデータのキャッシュ */
    private static final Map>> TEST_DATA_CACHE = NablarchTestUtils.createLRUMap(8);

    /** テストデータ */
    private List> testData;

    /** テストデータを読み込む際のインデックス */
    private int index;

    /** ディレクトリ */
    protected String directory;     // SUPPRESS CHECKSTYLE サブクラスに対してカプセル化が不要なため

    /** リソース名 */
    protected String resource;      // SUPPRESS CHECKSTYLE サブクラスに対してカプセル化が不要なため

    /**
     * 行読み込み時に起動されるコールバックメソッド。
     *
     * @param line 読み込まれた行データ
     */
    abstract void onReadLine(List line);

    /**
     * 処理対象のデータ型を発見した場合に起動されるコールバックメソッド。
     *
     * @param line データ型の定義を含む行データ
     */
    abstract void onTargetTypeFound(List line);


    /**
     * 処理対象のデータ型であるかどうか判定する。
     *
     * @param line 読み込み中の行データ
     * @param id ID
     * @return 処理対象のデータ型である場合、真
     */
    abstract boolean isTargetType(List line, String id);

    /**
     * 次の処理対象のデータを発見した場合に処理を停止するか否かを判定する。
     *
     * @return 次の処理対象のデータを発見した場合に処理停止する場合は、真
     */
    abstract boolean shouldStopOnNextOne();

    /**
     * 解析結果を返却する。
     *
     * @return 解析結果
     */
    abstract RET getResult();

    /**
     * コンストラクタ。
     *
     * @param reader       解析に使用するリーダ
     * @param interpreters 解釈クラス
     * @param targetType   解析対象のデータ型
     */
    TestDataParsingTemplate(TestDataReader reader, List interpreters, DataType targetType) {
        this.reader = reader;
        this.interpreters = interpreters;
        this.targetType = targetType;
    }

    /**
     * 解析対象のデータ型を返却する。
     *
     * @return 解析対象のデータ型
     */
    protected final DataType getTargetType() {
        return targetType;
    }

    /**
     * 解析を実行する。
     * 

* 読み込んだシートはキャッシュする。 *

* @param directory 読み込み元のディレクトリ * @param resource リソース名称 * @param id ID */ public final void parse(String directory, String resource, String id) { parse(directory, resource, id, true); } /** * 解析を実行する。 * @param directory 読み込み元のディレクトリ * @param resource リソース名称 * @param id ID * @param saveCache 読み込んだファイルのデータをキャッシュに保存するか */ public final void parse(String directory, String resource, String id, boolean saveCache) { this.directory = directory; this.resource = resource; String dataCacheKey = directory + '/' + resource; if (!TEST_DATA_CACHE.containsKey(dataCacheKey)) { // テストデータがキャッシュ上に存在しない場合は、テストデータをロードしキャッシュする。 if (reader instanceof PoiXlsReader) { ((PoiXlsReader) reader).setUseCache(saveCache); } reader.open(directory, resource); try { testData = readTestData(); if (saveCache) { TEST_DATA_CACHE.put(dataCacheKey, testData); } } finally { reader.close(); } } else { testData = TEST_DATA_CACHE.get(dataCacheKey); } try { index = 0; parse(id); } catch (RuntimeException e) { String msg = concat("can't get data. ", "directory=[", directory, "] resource=[", resource, "] id=[", id, "]"); throw new IllegalStateException(msg, e); } } /** * テストデータを読み込む。 * * @return 読み込んだテストデータ */ private List> readTestData() { List> lines = new ArrayList>(1024); while (true) { List line = reader.readLine(); if (line == null) { break; } if (isCommentRow(line)) { continue; } line = cutComment(line); if (isBlankLine(line)) { continue; } List interpret = interpret(line); // キャッシュするので、他の箇所で書き換えられないようにする。 List unmodifiable = Collections.unmodifiableList(interpret); lines.add(unmodifiable); } // キャッシュするので、他の箇所で書き換えられないようにする。 return Collections.unmodifiableList(lines); } /** * 解析を実行する。 * * @param id ID */ void parse(String id) { boolean nowReading = false; // データ行読み込み中か List line; while ((line = readLine()) != null) { // テーブル名の行 String firstCol = line.get(0); DataType dataType = getDataType(firstCol); // データタイプとグループIDが一致するか if (isTargetType(line, id)) { if (nowReading && shouldStopOnNextOne()) { break; } nowReading = true; onTargetTypeFound(line); } else if (dataType.equals(DataType.DEFAULT)) { // データ行読み込み中か? if (nowReading) { onReadLine(line); } } else { // データ行読み込み中なら処理終了 if (nowReading) { break; } } } } /** データタイプのリスト */ private static final DataType[] DATA_TYPES = DataType.values(); /** * データタイプを返却する。
* * @param dataTypeCell データタイプが記載されたセル * @return データタイプ */ protected final DataType getDataType(String dataTypeCell) { if (dataTypeCell == null) { return DataType.DEFAULT; } for (DataType type : DATA_TYPES) { if (dataTypeCell.startsWith(type.getName())) { return type; } } return DataType.DEFAULT; } /** * テストデータタイプのバリュー値を取得する。 * * @param dataTypeRow 1行分のデータ * @return バリュー値 */ protected final String getTypeValue(List dataTypeRow) { String str = dataTypeRow.get(0); return str.substring(str.indexOf('=') + 1); } /** * テストデータから1行文のデータを読み込む。
* テストデータをすべて読み込んだ場合は、nullを返却する。 * * @return 1行データ */ protected final List readLine() { if (index < testData.size()) { return testData.get(index++); } return null; } /** コメントを表す文字列 */ private static final String COMMENT_EXPRESSION = "//"; /** * コメント行であるか判定する。
* 先頭が//始まりの場合はコメント行とみなす。 * * @param line 行データ * @return 判定結果 */ boolean isCommentRow(List line) { String first = line.get(0); return isComment(first); } /** * コメントセルであるかどうか判定する。 * * @param cell セルの値 * @return そのセルの値が//からスタートしている場合、真 */ private boolean isComment(String cell) { return cell != null && cell.startsWith(COMMENT_EXPRESSION); } /** * 1行を表すデータからコメントを削除する。
* コメント部は、「//」以降の要素 * * @param src 1行を表すテストデータ * @return コメント部を取り除いた1行データ */ private List cutComment(List src) { List result = new ArrayList(src.size()); for (String s : src) { if (isComment(s)) { break; } result.add(s); } return result; } /** * 全要素が空かどうか判定 * * @param line 1行分のデータ * @return 配列の全要素が空であればtrue、空でなければfalse */ private boolean isBlankLine(List line) { return StringUtil.isNullOrEmpty(line); } /** * テストデータ記法を解釈する。 * * @param originalLine 元のデータ行 * @return 解釈後のデータ行 */ private List interpret(List originalLine) { List result = new ArrayList(originalLine.size()); for (String e : originalLine) { InterpretationContext context = new InterpretationContext(e, interpreters); String interpreted = context.invokeNext(); result.add(interpreted); } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy