/**
* Copyright 2010 TransPac Software, Inc.
*
* 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 com.scaleunlimited.cascading;
import java.security.InvalidParameterException;
import cascading.flow.FlowProcess;
import cascading.operation.BaseOperation;
import cascading.operation.Filter;
import cascading.operation.FilterCall;
import cascading.operation.OperationCall;
import cascading.pipe.Each;
import cascading.pipe.Pipe;
import cascading.pipe.SubAssembly;
@SuppressWarnings("serial")
public class SplitterAssembly extends SubAssembly {
private static final String LHS_SUFFIX = "-lhs";
private static final String RHS_SUFFIX = "-rhs";
private String _baseName;
private enum SplitterCounters {
LHS,
RHS,
}
@SuppressWarnings("unchecked")
private static class SplitterFilter extends BaseOperation<NullContext> implements Filter<NullContext> {
private BaseSplitter _splitter;
private boolean _wantLHS;
private Enum _counter;
private transient LoggingFlowProcess _flowProcess;
public SplitterFilter(BaseSplitter splitter, boolean wantLHS, Enum counter) {
_splitter = splitter;
_wantLHS = wantLHS;
_counter = counter;
}
@Override
public void prepare(FlowProcess flowProcess,
OperationCall<NullContext> operationCall) {
super.prepare(flowProcess, operationCall);
_flowProcess = new LoggingFlowProcess(flowProcess);
_flowProcess.addReporter(new LoggingFlowReporter());
}
@Override
public boolean isRemove(FlowProcess flowProcess, FilterCall<NullContext> filterCall) {
boolean result = _splitter.isLHS(filterCall.getArguments()) != _wantLHS;
if (!result) {
_flowProcess.increment(_counter, 1);
}
return result;
}
@Override
public void cleanup(FlowProcess flowProcess,
OperationCall<NullContext> operationCall) {
_flowProcess.dumpCounters();
super.cleanup(flowProcess, operationCall);
}
}
public SplitterAssembly(Pipe inputPipe, BaseSplitter splitter) {
this(inputPipe, splitter, SplitterCounters.LHS, SplitterCounters.RHS);
}
@SuppressWarnings("unchecked")
public SplitterAssembly(Pipe inputPipe,
BaseSplitter splitter,
Enum lhsCounter,
Enum rhsCounter) {
super(inputPipe);
_baseName = inputPipe.getName();
Pipe lhsPipe = new Pipe(_baseName + LHS_SUFFIX, inputPipe);
lhsPipe = new Each(lhsPipe, new SplitterFilter(splitter, true, lhsCounter));
Pipe rhsPipe = new Pipe(_baseName + RHS_SUFFIX, inputPipe);
rhsPipe = new Each(rhsPipe, new SplitterFilter(splitter, false, rhsCounter));
setTails(lhsPipe, rhsPipe);
}
public Pipe getLHSPipe() {
return getTailPipe(_baseName + LHS_SUFFIX);
}
public Pipe getRHSPipe() {
return getTailPipe(_baseName + RHS_SUFFIX);
}
private Pipe getTailPipe(String pipeName) {
String[] pipeNames = getTailNames();
for (int i = 0; i < pipeNames.length; i++) {
if (pipeName.equals(pipeNames[i])) {
return getTails()[i];
}
}
throw new InvalidParameterException("Invalid pipe name: " + pipeName);
}
}