com.moengage.evaluator.ConditionEvaluator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of condition-evaluator Show documentation
Show all versions of condition-evaluator Show documentation
Condition Evaluator for MoEngage Platform
The newest version!
package com.moengage.evaluator;
import com.moengage.enum_models.FilterOperator;
import com.moengage.enum_models.FilterParameter;
import com.moengage.enum_models.FilterType;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.regex.*;
import java.util.TimeZone;
public class ConditionEvaluator {
protected JSONObject filterCondition;
protected JSONObject filters;
protected TimeZone appTimeZone;
/**
* ConditionEvaluator takes conditions and filters and returns whether the filters satisfy the condition or not
*
* @param filterCondition The filter condition object. The sample structure is given below
* condition = {
* filter_operator: "and"
* filters: [
* {
* name: "u_mb",
* operator: "is",
* value: "9898989989",
* data_type: "string",
* "negate": true,
* "case_sensitive": false
* },
* {
* "operator": "lessThan",
* "data_type": "datetime",
* "name": "u_l_a",
* "value": "2015-07-30T00:00:00"
* },
* ]
* }
* @param filters The action attribute filters done by the user or user properties, sample given below
* filters = {
* u_mb: "8887776665",
* u_l_a: "2015-07-30T08:33:54,
* u_n: "moengage",
* u_em: "[email protected]",
* age: 3
* }
* url for reference :
* https://github.com/moengage/commons/blob/master/moengage/commons/attrs/config/config.json
*/
public ConditionEvaluator(JSONObject filterCondition, JSONObject filters, TimeZone appTimeZone) {
this.filterCondition = filterCondition;
this.filters = filters;
this.appTimeZone = appTimeZone;
}
public ConditionEvaluator(JSONObject filterCondition, JSONObject filters) {
this(filterCondition, filters, null);
}
public boolean evaluate() throws JSONException, InvalidFieldValueException, InvalidFilterException {
if (filterCondition == null || filters == null) {
throw new InvalidFilterException("Provided filters are null");
}
String filterOperator = filterCondition.optString(FilterParameter.FILTER_OPERATOR);
Object attributeFilters = filterCondition.opt(FilterParameter.FILTERS);
boolean isFilterSatisfied = false;
if (!(attributeFilters instanceof JSONArray)) return false;
JSONArray attributeFilterList = (JSONArray) attributeFilters;
// If no filters are present, return true
if (attributeFilterList.length() == 0) return true;
// Special case checking whether the passed filters are all user or not
if (isAllUserFilters(attributeFilterList)) return true;
for (int i = 0; i < attributeFilterList.length(); i++) {
JSONObject condition = attributeFilterList.getJSONObject(i);
isFilterSatisfied = false;
if(condition.has("filter_operator")) {
if(condition.has("data_type")) {
String data_type = condition.getString("data_type");
String name = condition.getString("name");
JSONArray values = new JSONArray();
if (filters.keySet().contains(name)) {
if ("object".equals(data_type)) {
JSONObject temp = filters.getJSONObject(name);
values = new JSONArray();
values.put(temp);
} else {
values = filters.getJSONArray(name);
}
}
for(int valueIdx=0; valueIdx < values.length(); valueIdx++) {
JSONObject value = (JSONObject) values.get(valueIdx);
ConditionEvaluator evaluator = new ConditionEvaluator(condition, value, this.appTimeZone);
isFilterSatisfied = evaluator.evaluate();
if(isFilterSatisfied)
break;
}
} else {
ConditionEvaluator evaluator = new ConditionEvaluator(condition, this.filters, this.appTimeZone);
isFilterSatisfied = evaluator.evaluate();
}
} else {
AttributeFilter attributeFilter = new AttributeFilter();
attributeFilter.serializeJson(condition);
Object filterValue = filters.opt(attributeFilter.getName());
boolean isDynamicValue = attributeFilter.getIsDynamicValue();
if(isDynamicValue) {
Pattern pattern = Pattern.compile("\\['(.*?)'\\]");
Object valueList = attributeFilter.getValue();
if (valueList instanceof JSONArray) {
JSONArray value = ((JSONArray) valueList);
for(int j = 0;j < value.length();j++) {
Matcher matcher = pattern.matcher(value.getString(j));
if(matcher.find()) {
value.put(j, filters.opt(matcher.group(1)));
}
}
} else {
Matcher matcher = pattern.matcher(valueList.toString());
if(matcher.find()) {
attributeFilter.setValue(filters.opt(matcher.group(1)));
}
}
}
ValidateFilter validateFilter = new ValidateFilter(attributeFilter, filterValue);
try {
if(validateFilter.isFiltersValid()) {
isFilterSatisfied = doesSatisfyFilter(attributeFilter, filterValue);
}
} catch (InvalidFieldValueException e) {
// InvalidFieldValueException is a happy case when negate is true
isFilterSatisfied = attributeFilter.getNegate();
}
}
if (isFilterSatisfied && filterOperator.equals(FilterOperator.OR)) {
return true;
}
if (!isFilterSatisfied && filterOperator.equals(FilterOperator.AND)) {
return false;
}
}
return isFilterSatisfied;
}
private boolean doesSatisfyFilter(AttributeFilter attributeFilter, Object filterValue) {
FilterConditionEvaluator filterEvaluatorObj = new FilterConditionEvaluator(attributeFilter, appTimeZone);
return filterEvaluatorObj.evaluate(filterValue);
}
private boolean isAllUserFilters(JSONArray attributeFilterList) {
if (attributeFilterList.length() > 1) return false;
// Attribute filter will only contain one condition object when the code reach here.
// No index out of bound exception will be thrown for this.
JSONObject condition = attributeFilterList.getJSONObject(0);
// If the filter type is custom segment and id of the custom segment is moe_all_users return true
return FilterType.CUSTOM_SEGMENTS.equals(condition.optString(FilterParameter.FILTER_TYPE)) &&
"moe_all_users".equals(condition.optString(FilterParameter.ID));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy