public boolean evaluate()

in core/src/main/java/org/apache/hop/core/Condition.java [317:529]


  public boolean evaluate(IRowMeta rowMeta, Object[] r) {
    boolean evaluation = false;

    // If we have 0 items in the list, evaluate the current condition
    // Otherwise, evaluate all sub-conditions
    //
    try {
      if (isAtomic()) {

        if (function == TRUE) {
          return !negated;
        }

        // Get field index: left value name
        //
        // Check out the field index if we don't have them...
        if (StringUtils.isNotEmpty(leftValueName)) {
          leftFieldIndex = rowMeta.indexOfValue(leftValueName);
        }

        // Get field index: right value name
        //
        if (StringUtils.isNotEmpty(rightValueName)) {
          rightFieldIndex = rowMeta.indexOfValue(rightValueName);

          // We can't have a right value in this case
          rightValue = null;
        }

        // Get field index: left field
        //
        IValueMeta fieldMeta;
        Object field;
        if (leftFieldIndex >= 0) {
          fieldMeta = rowMeta.getValueMeta(leftFieldIndex);
          field = r[leftFieldIndex];
        } else {
          return false; // no fields to evaluate
        }

        // Get field index: right value
        //
        IValueMeta fieldMeta2 = rightValue != null ? rightValue.createValueMeta() : null;
        // Old metadata contains a right value block without name, type and so on.  This means: no
        // value
        // Removed the name check, old fixed values do not contain a name element causing regression
        Object field2 =
            rightValue != null && rightFieldIndex == -2 ? rightValue.createValueData() : null;
        if (field2 == null && rightFieldIndex >= 0) {
          fieldMeta2 = rowMeta.getValueMeta(rightFieldIndex);
          field2 = r[rightFieldIndex];
        }

        // Evaluate
        switch (function) {
          case EQUAL:
            evaluation = (fieldMeta.compare(field, fieldMeta2, field2) == 0);
            break;
          case NOT_EQUAL:
            evaluation = (fieldMeta.compare(field, fieldMeta2, field2) != 0);
            break;
          case SMALLER:
            if (fieldMeta.isNull(field)) {
              evaluation = false;
            } else {
              evaluation = (fieldMeta.compare(field, fieldMeta2, field2) < 0);
            }
            break;
          case SMALLER_EQUAL:
            if (fieldMeta.isNull(field)) {
              evaluation = false;
            } else {
              evaluation = (fieldMeta.compare(field, fieldMeta2, field2) <= 0);
            }
            break;
          case LARGER:
            evaluation = (fieldMeta.compare(field, fieldMeta2, field2) > 0);
            break;
          case LARGER_EQUAL:
            evaluation = (fieldMeta.compare(field, fieldMeta2, field2) >= 0);
            break;
          case REGEXP:
            if (fieldMeta.isNull(field) || field2 == null) {
              evaluation = false;
            } else {
              evaluation =
                  Pattern.matches(
                      fieldMeta2.getCompatibleString(field2), fieldMeta.getCompatibleString(field));
            }
            break;
          case NULL:
            evaluation = (fieldMeta.isNull(field));
            break;
          case NOT_NULL:
            evaluation = (!fieldMeta.isNull(field));
            break;
          case IN_LIST:
            // performance reason: create the array first or again when it is against a field and
            // not a constant
            //
            if (inList == null || rightFieldIndex >= 0) {
              inList = Const.splitString(fieldMeta2.getString(field2), ';', true);
              for (int i = 0; i < inList.length; i++) {
                inList[i] = inList[i] == null ? null : inList[i].replace("\\", "");
              }
              Arrays.sort(inList);
            }
            String searchString = fieldMeta.getCompatibleString(field);
            int inIndex = -1;
            if (searchString != null) {
              inIndex = Arrays.binarySearch(inList, searchString);
            }
            evaluation = inIndex >= 0;
            break;
          case CONTAINS:
            evaluation =
                fieldMeta.getCompatibleString(field) != null
                    && fieldMeta
                        .getCompatibleString(field)
                        .contains(fieldMeta2.getCompatibleString(field2));
            break;
          case STARTS_WITH:
            evaluation =
                fieldMeta.getCompatibleString(field) != null
                    && fieldMeta
                        .getCompatibleString(field)
                        .startsWith(fieldMeta2.getCompatibleString(field2));
            break;
          case ENDS_WITH:
            String string = fieldMeta.getCompatibleString(field);
            if (!Utils.isEmpty(string)) {
              if (rightString == null && field2 != null) {
                rightString = fieldMeta2.getCompatibleString(field2);
              }
              if (rightString != null) {
                evaluation = string.endsWith(fieldMeta2.getCompatibleString(field2));
              } else {
                evaluation = false;
              }
            } else {
              evaluation = false;
            }
            break;
          case LIKE:
            // Converts to a regular expression
            //
            if (fieldMeta.isNull(field) || field2 == null) {
              evaluation = false;
            } else {
              String regex = fieldMeta2.getCompatibleString(field2);
              regex = regex.replace("%", ".*");
              regex = regex.replace("?", ".");
              evaluation = Pattern.matches(regex, fieldMeta.getCompatibleString(field));
            }
            break;
          default:
            break;
        }

        // Only NOT makes sense, the rest doesn't, so ignore!!!!
        // Optionally negate
        //
        if (isNegated()) {
          evaluation = !evaluation;
        }
      } else {
        // Composite : get first
        Condition cb0 = children.get(0);
        evaluation = cb0.evaluate(rowMeta, r);

        // Loop over the conditions listed below.
        //
        for (int i = 1; i < children.size(); i++) {
          // Composite : #i
          // Get right hand condition
          Condition cb = children.get(i);

          // Evaluate the right hand side of the condition cb.evaluate() within
          // the switch statement
          // because the condition may be short-circuited due to the left hand
          // side (evaluation)
          switch (cb.getOperator()) {
            case OR:
              evaluation = evaluation || cb.evaluate(rowMeta, r);
              break;
            case AND:
              evaluation = evaluation && cb.evaluate(rowMeta, r);
              break;
            case OR_NOT:
              evaluation = evaluation || (!cb.evaluate(rowMeta, r));
              break;
            case AND_NOT:
              evaluation = evaluation && (!cb.evaluate(rowMeta, r));
              break;
            case XOR:
              evaluation = evaluation ^ cb.evaluate(rowMeta, r);
              break;
            default:
              break;
          }
        }

        // Composite: optionally negate
        if (isNegated()) {
          evaluation = !evaluation;
        }
      }
    } catch (Exception e) {
      throw new RuntimeException("Unexpected error evaluation condition [" + this + "]", e);
    }

    return evaluation;
  }