Ejemplo n.º 1
0
  public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException {
    meta = (FormulaMeta) smi;
    data = (FormulaData) sdi;

    Object[] r = getRow(); // get row, set busy!
    if (r == null) { // no more input to be expected...

      setOutputDone();
      return false;
    }

    if (first) {
      first = false;

      data.outputRowMeta = getInputRowMeta().clone();
      meta.getFields(data.outputRowMeta, getStepname(), null, null, this, repository, metaStore);

      // Create the context
      data.context = new RowForumulaContext(data.outputRowMeta);
      data.parser = new FormulaParser();

      // Calculate replace indexes...
      //
      data.replaceIndex = new int[meta.getFormula().length];
      for (int i = 0; i < meta.getFormula().length; i++) {
        FormulaMetaFunction fn = meta.getFormula()[i];
        if (!Const.isEmpty(fn.getReplaceField())) {
          data.replaceIndex[i] = getInputRowMeta().indexOfValue(fn.getReplaceField());
          if (data.replaceIndex[i] < 0) {
            throw new KettleException(
                "Unknown field specified to replace with a formula result: ["
                    + fn.getReplaceField()
                    + "]");
          }
        } else {
          data.replaceIndex[i] = -1;
        }
      }
    }

    if (log.isRowLevel()) {
      logRowlevel("Read row #" + getLinesRead() + " : " + r);
    }

    Object[] outputRowData = calcFields(getInputRowMeta(), r);
    putRow(data.outputRowMeta, outputRowData); // copy row to possible alternate rowset(s).

    if (log.isRowLevel()) {
      logRowlevel("Wrote row #" + getLinesWritten() + " : " + r);
    }
    if (checkFeedback(getLinesRead())) {
      logBasic("Linenr " + getLinesRead());
    }

    return true;
  }
Ejemplo n.º 2
0
  public boolean init(StepMetaInterface smi, StepDataInterface sdi) {
    meta = (FormulaMeta) smi;
    data = (FormulaData) sdi;

    if (super.init(smi, sdi)) {
      // Add init code here.

      // Return data type discovery is expensive, let's discover them one time only.
      //
      data.returnType = new int[meta.getFormula().length];
      for (int i = 0; i < meta.getFormula().length; i++) {
        data.returnType[i] = -1;
      }
      return true;
    }
    return false;
  }
Ejemplo n.º 3
0
  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);
    }
  }