/**
* AnalyzerBeans
* Copyright (C) 2014 Neopost - Customer Information Management
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.eobjects.analyzer.job.runner;
import java.util.ArrayList;
import java.util.List;
import org.eobjects.analyzer.data.InputRow;
/**
* Delegate execution object for {@link ConsumeRowHandler}. Contains state
* particular to processing of a single consumer in the chain, and also handles
* recursive logic coming from {@link RowProcessingChain} callbacks.
*/
final class ConsumeRowHandlerDelegate implements RowProcessingChain {
private final List<RowProcessingConsumer> _consumers;
private final InputRow _row;
private final int _consumerIndex;
private final FilterOutcomes _outcomes;
private final List<InputRow> _resultRecords;
private final List<FilterOutcomes> _resultOutcomes;
public ConsumeRowHandlerDelegate(final List<RowProcessingConsumer> consumers, final InputRow row,
final int consumerIndex, final FilterOutcomes outcomes) {
this(consumers, row, consumerIndex, outcomes, new ArrayList<InputRow>(1), new ArrayList<FilterOutcomes>(1));
}
private ConsumeRowHandlerDelegate(final List<RowProcessingConsumer> consumers, final InputRow row,
final int consumerIndex, final FilterOutcomes outcomes, final List<InputRow> resultRecords,
final List<FilterOutcomes> resultOutcomes) {
_consumers = consumers;
_row = row;
_consumerIndex = consumerIndex;
_outcomes = outcomes;
_resultRecords = resultRecords;
_resultOutcomes = resultOutcomes;
}
public ConsumeRowResult consume() {
final RowProcessingConsumer consumer = _consumers.get(_consumerIndex);
final boolean process = consumer.satisfiedForConsume(_outcomes, _row);
if (process) {
if (consumer.isConcurrent()) {
consumer.consume(_row, 1, _outcomes, this);
} else {
synchronized (consumer) {
consumer.consume(_row, 1, _outcomes, this);
}
}
} else {
// jump to the next step
processNext(_row, 1, _outcomes);
}
return new ConsumeRowResult(_resultRecords, _resultOutcomes);
}
@Override
public void processNext(final InputRow row, final int distinctCount, final FilterOutcomes outcomes) {
final int nextIndex = _consumerIndex + 1;
if (nextIndex >= _consumers.size()) {
// finished!
_resultRecords.add(row);
_resultOutcomes.add(outcomes);
return;
}
final ConsumeRowHandlerDelegate subDelegate = new ConsumeRowHandlerDelegate(_consumers, row, nextIndex,
outcomes, _resultRecords, _resultOutcomes);
subDelegate.consume();
}
}