private Object[] calcFields(RowMetaInterface rowMeta, Object[] r) throws KettleValueException { try { Object[] outputRowData = RowDataUtil.createResizedCopy(r, data.outputRowMeta.size()); int tempIndex = rowMeta.size(); // Assign this tempRowData to the formula context // data.context.setRowData(outputRowData); // Initialize parsers etc. Only do it once. // if (data.formulas == null) { // Create a set of LValues to put the parsed results in... data.formulas = new org.pentaho.reporting.libraries.formula.Formula[meta.getFormula().length]; for (int i = 0; i < meta.getFormula().length; i++) { FormulaMetaFunction fn = meta.getFormula()[i]; if (!Const.isEmpty(fn.getFieldName())) { data.formulas[i] = data.createFormula(meta.getFormula()[i].getFormula()); } else { throw new KettleException( "Unable to find field name for formula [" + Const.NVL(fn.getFormula(), "") + "]"); } } } for (int i = 0; i < meta.getFormula().length; i++) { FormulaMetaFunction fn = meta.getFormula()[i]; if (!Const.isEmpty(fn.getFieldName())) { if (data.formulas[i] == null) { data.formulas[i] = data.createFormula(meta.getFormula()[i].getFormula()); } // this is main part of all this step: calculate formula Object formulaResult = data.formulas[i].evaluate(); if (formulaResult instanceof LibFormulaErrorValue) { // inspect why it is happens to get clear error message. throw new KettleException( "Error calculate formula. Formula " + fn.getFormula() + " output field: " + fn.getFieldName() + ", error is: " + formulaResult.toString()); } // Calculate the return type on the first row... // for most cases we can try to convert data on a fly. if (data.returnType[i] < 0) { if (formulaResult instanceof String) { data.returnType[i] = FormulaData.RETURN_TYPE_STRING; fn.setNeedDataConversion(fn.getValueType() != ValueMetaInterface.TYPE_STRING); } else if (formulaResult instanceof Integer) { data.returnType[i] = FormulaData.RETURN_TYPE_INTEGER; fn.setNeedDataConversion(fn.getValueType() != ValueMetaInterface.TYPE_INTEGER); } else if (formulaResult instanceof Long) { data.returnType[i] = FormulaData.RETURN_TYPE_LONG; fn.setNeedDataConversion(fn.getValueType() != ValueMetaInterface.TYPE_INTEGER); } else if (formulaResult instanceof Date) { data.returnType[i] = FormulaData.RETURN_TYPE_DATE; fn.setNeedDataConversion(fn.getValueType() != ValueMetaInterface.TYPE_DATE); } else if (formulaResult instanceof BigDecimal) { data.returnType[i] = FormulaData.RETURN_TYPE_BIGDECIMAL; fn.setNeedDataConversion(fn.getValueType() != ValueMetaInterface.TYPE_BIGNUMBER); } else if (formulaResult instanceof Number) { data.returnType[i] = FormulaData.RETURN_TYPE_NUMBER; fn.setNeedDataConversion(fn.getValueType() != ValueMetaInterface.TYPE_NUMBER); // this types we will not make attempt to auto-convert } else if (formulaResult instanceof byte[]) { data.returnType[i] = FormulaData.RETURN_TYPE_BYTE_ARRAY; if (fn.getValueType() != ValueMetaInterface.TYPE_BINARY) { throw new KettleValueException( "Please specify a Binary type for field [" + fn.getFieldName() + "] as a result of formula [" + fn.getFormula() + "]"); } } else if (formulaResult instanceof Boolean) { data.returnType[i] = FormulaData.RETURN_TYPE_BOOLEAN; if (fn.getValueType() != ValueMetaInterface.TYPE_BOOLEAN) { throw new KettleValueException( "Please specify a Boolean type for field [" + fn.getFieldName() + "] as a result of formula [" + fn.getFormula() + "]"); } } else { data.returnType[i] = FormulaData.RETURN_TYPE_STRING; } } int realIndex = (data.replaceIndex[i] < 0) ? tempIndex++ : data.replaceIndex[i]; outputRowData[realIndex] = getReturnValue(formulaResult, data.returnType[i], realIndex, fn); } } return outputRowData; } catch (Throwable e) { throw new KettleValueException(e); } }