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

nablarch.test.support.reader.AggregatingDataReader Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
package nablarch.test.support.reader;

import java.util.ArrayList;
import java.util.List;

import nablarch.fw.DataReader;
import nablarch.fw.ExecutionContext;

/**
 * 既存のデータリーダに対して、複数件データのまとめ読み機能を追加するクラス。
 * 
 * 既存のデータリーダから読み込んだデータを内部的にバッファリングし、
 * 一定の条件が満たされた時点でまとめて返却する。
 * 
* @param 元となるデータリーダのデータ型 * @author Iwauo Tajima */ public abstract class AggregatingDataReader implements DataReader> { /** 元となるデータリーダ */ private DataReader sourceDataReader; /** データを保持するバッファの初期サイズ */ private int bufferSize = 10; /** 同一グループに所属するデータを保持するバッファ */ private List dataBuffer = null; /** * データを保持するバッファの初期サイズを設定する。 * @param bufferSize バッファの初期サイズ * @return このオブジェクト自体 */ public synchronized AggregatingDataReader setBufferSize(int bufferSize) { this.bufferSize = bufferSize; return this; } /** * 元となるデータリーダからデータを読み込み、 * 一定の条件が満たされた時点でまとめて返却する。 * @param ctx {@inheritDoc} * @return 入力データオブジェクトのリスト */ public List read(ExecutionContext ctx) { if (getSourceDataReader() == null) { throw new IllegalArgumentException( "source data reader was not set. source data reader must be set before reading."); } List result = null; D newData = null; synchronized (this) { if (bufferSize < 0) { throw new IllegalArgumentException("buffer size was invalid. buffer size must be bigger than 0."); } while (hasNext(ctx)) { newData = getSourceDataReader().read(ctx); if (newData == null) { // エンドレコードに到達した場合、バッファを結果として返却し、ループを抜ける handleEnd(dataBuffer, ctx); result = dataBuffer; dataBuffer = null; break; } if (dataBuffer == null) { dataBuffer = new ArrayList(bufferSize); } if (dataBuffer.isEmpty() || isInSameGroup(newData, dataBuffer, ctx)) { dataBuffer.add(newData); continue; } else { // 前に読み込んだレコードと、新しく読み込んだレコードが同一グループでない場合、ループを抜ける result = dataBuffer; dataBuffer = new ArrayList(bufferSize); dataBuffer.add(newData); break; } } } return result; } /** * エンドレコードに到達した場合に処理を実行する。 *

* 本クラスの実装では何も処理を行わない。 * 必要に応じてサブクラスでオーバーライドすること。 *

* @param dataBuffer バッファリングしているデータのリスト * @param ctx 実行コンテキスト */ protected void handleEnd(List dataBuffer, ExecutionContext ctx) { // NOP } /** * 元となるデータリーダの次に読み込むデータが存在するかどうかを返却する。 * @param ctx {@inheritDoc} * @return 元となるデータリーダの次に読み込むデータがまだ残っている場合はtrue */ public synchronized boolean hasNext(ExecutionContext ctx) { if (dataBuffer != null && !dataBuffer.isEmpty()) { return true; } return getSourceDataReader().hasNext(ctx); } /** {@inheritDoc} * この実装では、内部的に保持しているリーダを閉じる。 */ public synchronized void close(ExecutionContext ctx) { if (getSourceDataReader() == null) { return; } getSourceDataReader().close(ctx); } /** * 元となるデータリーダを返却する。 * @return 元となるデータリーダ */ public DataReader getSourceDataReader() { return sourceDataReader; } /** * 元となるデータリーダを設定する。 * @param source 元となるデータリーダ * @return このオブジェクト自体 */ @SuppressWarnings({ "unchecked" }) public AggregatingDataReader setSourceDataReader(DataReader source) { sourceDataReader = (DataReader) source; return this; } /** * 新しく読み込んだデータが、バッファリングしているデータのグループに所属するかどうかを返却する。 * * @param newData 新たに読み込んだデータ * @param dataBuffer バッファリングしているデータのリスト * @param ctx 実行コンテキスト * @return 新しく読み込んだデータが、バッファリングしているデータのグループに所属する場合はtrue */ protected abstract boolean isInSameGroup(D newData, List dataBuffer, ExecutionContext ctx); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy