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;
}