/*******************************************************************************
* Copyright 2017 Capital One Services, LLC and Bitwise, 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 hydrograph.engine.cascading.utilities;
import cascading.tuple.Fields;
import cascading.tuple.Tuple;
import cascading.tuple.TupleEntry;
import hydrograph.engine.transformation.userfunctions.base.ReusableRow;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Map;
/**
* @author Ganesh
*
*/
public class ReusableRowHelper {
@SuppressWarnings("rawtypes")
public static ReusableRow extractFromTuple(int[] tuplePos,
Tuple sourceTuple, ReusableRow target) {
if (tuplePos == null || sourceTuple == null || target == null) {
return target;
}
int counter = -1;
for (int position : tuplePos) {
counter = counter + 1;
target.setField(counter,
(Comparable) sourceTuple.getObject(position));
}
return target;
}
@SuppressWarnings("rawtypes")
public static ReusableRow extractFromTuple(Tuple sourceTuple,
ReusableRow target) {
if (sourceTuple == null || target == null) {
return target;
}
int counter = 0;
while (counter < sourceTuple.size()) {
target.setField(counter,
(Comparable) sourceTuple.getObject(counter));
counter = counter + 1;
}
return target;
}
public static ArrayList<String> getListFromFields(Fields fields) {
ArrayList<String> result = new ArrayList<String>();
for (int i = 0; i < fields.size(); i++) {
result.add(fields.get(i).toString());
}
return result;
}
public static LinkedHashSet<String> getLinkedSetFromFields(Fields fields) {
LinkedHashSet<String> result = new LinkedHashSet<String>();
for (int i = 0; i < fields.size(); i++) {
result.add(fields.get(i).toString());
}
return result;
}
/**
* Sets the values in {@link TupleEntry} object {@code target} from the
* {@link ReusableRow} object {@code row}
*
* @param target
* the {@link TupleEntry} object in which the values need to be
* set
* @param row
* the {@link ReusableRow} object from which the values need to
* be copied over
* @return the updated {@link TupleEntry} object
*/
public static TupleEntry setTupleEntryFromResuableRowAndReset(
TupleEntry target, ReusableRow row) {
if (row == null) {
return target;
}
for (String fieldName : row.getFieldNames()) {
target.setRaw(fieldName, row.getField(fieldName));
}
row.reset();
return target;
}
public static TupleEntry setTupleEntryFromResuableRowAndReset(
TupleEntry target, ReusableRow row, int[] fieldPositions) {
if (row == null) {
return target;
}
int counter = 0;
for (Object value : row.getFields()) {
if (counter <= fieldPositions.length - 1) {
if (fieldPositions[counter] != -1) {
target.setRaw(fieldPositions[counter], value);
counter++;
}
}
}
row.reset();
return target;
}
/**
* Sets the values in {@link TupleEntry} object {@code target} from the
* {@link ReusableRow} object {@code row}
*
* @param target
* the {@link TupleEntry} object in which the values need to be
* set
* @param row
* the {@link ReusableRow} object from which the values need to
* be copied over
* @return the updated {@link TupleEntry} object
*/
public static TupleEntry setTupleEntryFromResuableRow(TupleEntry target,
ReusableRow row) {
if (row == null) {
return target;
}
for (String fieldName : row.getFieldNames()) {
target.setRaw(fieldName, row.getField(fieldName));
}
return target;
}
/**
* Sets the values in {@link TupleEntry} object {@code target} from the
* {@link ReusableRow} object {@code row}. The field names can be changed
* from source to target by specifying the {@code fieldMapping} object of
* type {@link Map}<{@link String}, {@link String}>. The
* {@code fieldMapping} object should specify the field mapping as
* Map<SourceFieldName, TargetFieldName>
*
* @param target
* the {@link TupleEntry} object in which the values need to be
* set
* @param row
* the {@link ReusableRow} object from which the values need to
* be copied over
* @param fieldMapping
* the map object specifying the field mapping as
* Map<SourceFieldName, TargetFieldName>
* @return the updated {@link TupleEntry} object
*/
public static TupleEntry setTupleEntryFromResuableRowWithNewFieldNames(
TupleEntry target, ReusableRow row, Map<String, String> fieldMapping) {
if (row == null) {
return target;
}
if (fieldMapping == null) {
return setTupleEntryFromResuableRowAndReset(target, row);
}
// The object row will only contain the values for map fields. Iterate
// over the map and fetch values from row using the key field, which
// corresponds to the SourceFieldName. Set the value in target, i.e.
// TupleEntry using the value field from the map which corresponds to
// the TargetFieldName
for (String key : fieldMapping.keySet()) {
target.setRaw(fieldMapping.get(key), row.getField(key));
}
return target;
}
/**
* Sets the values in {@link TupleEntry} object {@code target} from the
* ArrayList of {@link ReusableRow} object {@code row}
*
* @param target
* the {@link TupleEntry} object in which the values need to be
* set
* @param row
* the ArrayList of {@link ReusableRow} object from which the
* values need to be copied over
* @return the updated {@link TupleEntry} object
*/
public static TupleEntry setTupleEntryFromResuableRowsAndReset(
TupleEntry target, ArrayList<ReusableRow> rows) {
for (ReusableRow row : rows) {
setTupleEntryFromResuableRowAndReset(target, row);
}
return target;
}
public static TupleEntry setTupleEntryFromResuableRowsAndReset(
TupleEntry target, ArrayList<ReusableRow> rows,
ArrayList<int[]> fieldPositions) {
int counter = 0;
for (ReusableRow row : rows) {
setTupleEntryFromResuableRowAndReset(target, row,
fieldPositions.get(counter));
counter++;
}
return target;
}
/**
* Sets the values in Operation Row of type {@link ReusableRow} from Output
* Rows of type {@link ArrayList<ReusableRow>} on which operations is
* performed.
*
* @param allOutputRow
* @param operationRow
*/
public static void extractOperationRowFromAllOutputRow(
ArrayList<ReusableRow> allOutputRow, ReusableRow operationRow) {
for (String operationRowFieldName : operationRow.getFieldNames()) {
getValueFromFieldName(allOutputRow, operationRowFieldName,
operationRow);
}
}
private static void getValueFromFieldName(
ArrayList<ReusableRow> allOutputRow, String operationRowFieldName,
ReusableRow operationRow) {
for (ReusableRow eachReusableRow : allOutputRow) {
if (eachReusableRow.getFieldNames().contains(operationRowFieldName)) {
operationRow.setField(operationRowFieldName,
eachReusableRow.getField(operationRowFieldName));
}
}
}
public static ReusableRow setOperationRowFromPassThroughAndMapRow(
Map<String, String> mapFields, ReusableRow mapRow,
ReusableRow passThroughRow, ReusableRow operationRow) {
if (operationRow == null) {
return null;
}
for (String fieldName : mapRow.getFieldNames()) {
operationRow.setField(mapFields.get(fieldName),
mapRow.getField(fieldName));
}
for (String fieldName : passThroughRow.getFieldNames()) {
operationRow
.setField(fieldName, passThroughRow.getField(fieldName));
}
return operationRow;
}
}