/*******************************************************************************
* 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.expression.userfunctions;
import hydrograph.engine.expression.utils.ExpressionWrapper;
import hydrograph.engine.transformation.schema.DataType;
import hydrograph.engine.transformation.schema.Field;
import hydrograph.engine.transformation.schema.Schema;
import hydrograph.engine.transformation.userfunctions.base.GroupCombineTransformBase;
import hydrograph.engine.transformation.userfunctions.base.ReusableRow;
/**
* The Class GroupCombineForExpression.
*
* @author Bitwise
*/
@SuppressWarnings("rawtypes")
public class GroupCombineForExpression implements GroupCombineTransformBase {
private ExpressionWrapper expressionWrapperForUpdate;
private ExpressionWrapper expressionWrapperForMerge;
private String bufferFieldType;
private String bufferFieldFormat;
private int bufferFieldScale;
private int bufferFieldPrecision;
private Comparable accumulatorInitialValue;
public GroupCombineForExpression() {
}
public void setValidationAPIForUpateExpression(ExpressionWrapper expressionWrapper) {
this.expressionWrapperForUpdate = expressionWrapper;
}
public void setValidationAPIForMergeExpression(ExpressionWrapper expressionWrapper) {
this.expressionWrapperForMerge = expressionWrapper;
}
public void init(String bufferFieldType, String bufferFieldFormat, int bufferFieldScale, int bufferFieldPrecision) {
this.bufferFieldType = bufferFieldType.split("\\.")[bufferFieldType.split("\\.").length - 1];
this.bufferFieldFormat = bufferFieldFormat;
this.bufferFieldScale = bufferFieldScale;
this.bufferFieldPrecision = bufferFieldPrecision;
try {
expressionWrapperForUpdate.getValidationAPI().init(expressionWrapperForUpdate.getIntialValueExpression());
accumulatorInitialValue = (Comparable) (valueOf(bufferFieldType,expressionWrapperForUpdate.getValidationAPI().exec(new Object[]{})));
} catch (Exception e) {
throw new RuntimeException(
"Exception in aggregate initial value expression: "
+ expressionWrapperForUpdate.getIntialValueExpression() + ".", e);
}
}
private Object valueOf(String className,Object value){
try {
Class clazz = Class.forName(className);
return clazz.cast(value);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public void callPrepare(String[] inputFieldNames, String[] inputFieldTypes) {
String fieldNames[] = new String[inputFieldNames.length + 1];
String fieldTypes[] = new String[inputFieldTypes.length + 1];
for (int i = 0; i < inputFieldNames.length; i++) {
fieldNames[i] = inputFieldNames[i];
fieldTypes[i] = inputFieldTypes[i];
}
fieldNames[inputFieldNames.length] = "_accumulator";
fieldTypes[inputFieldNames.length] = bufferFieldType;
expressionWrapperForUpdate.getValidationAPI().init(fieldNames, fieldTypes);
expressionWrapperForMerge.getValidationAPI().init(new String[]{"_accumulator1", "_accumulator2"}, new String[]{bufferFieldType, bufferFieldType});
}
@Override
public Schema initBufferSchema(Schema inputSchema, Schema outputSchema) {
Field _accumulator = new Field.Builder("_accumulator", DataType.valueOf(bufferFieldType))
.addFormat(bufferFieldFormat).addPrecision(bufferFieldPrecision).addScale(bufferFieldScale).build();
Schema schema = new Schema();
schema.addField( _accumulator);
return schema;
}
@Override
public void initialize(ReusableRow bufferRow) {
bufferRow.setField(0, accumulatorInitialValue);
}
@Override
public void update(ReusableRow bufferRow, ReusableRow inputRow) {
Comparable tuples[] = new Comparable[inputRow.getFieldNames().size() + 1];
int i = 0;
for (; i < inputRow.getFieldNames().size(); i++) {
tuples[i] = inputRow.getField(i);
}
tuples[i] = bufferRow.getField(0);
try {
bufferRow.setField(0, (Comparable) expressionWrapperForUpdate.getValidationAPI().exec(tuples));
} catch (Exception e) {
throw new RuntimeException("Exception in aggregate expression: "
+ expressionWrapperForUpdate.getValidationAPI().getExpr() + ".\nRow being processed: "
+ inputRow.toString(), e);
}
}
@Override
public void merge(ReusableRow bufferRow1, ReusableRow bufferRow2) {
Comparable tuples[] = new Comparable[2];
tuples[0] = bufferRow1.getField(0);
tuples[1] = bufferRow2.getField(0);
try {
bufferRow1.setField(0, (Comparable) expressionWrapperForMerge.getValidationAPI().exec(tuples));
} catch (Exception e) {
throw new RuntimeException("Exception in merge expression: "
+ expressionWrapperForMerge.getValidationAPI().getExpr() + ".\nRow being processed: "
+ bufferRow2.toString(), e);
}
}
@Override
public void evaluate(ReusableRow bufferRow, ReusableRow outRow) {
outRow.setField(0, bufferRow.getField(0));
}
}