/*
* Copyright 2011 jmarsden.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* under the License.
*/
package jsonij.json.jpath;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import jsonij.json.Value;
import jsonij.json.jpath.functions.FunctionArgument;
import jsonij.json.jpath.functions.RegexFunction;
/**
* Complex Predicate Implementation.
*
* @author J.W.Marsden
*/
public class ExpressionPredicate extends PredicateComponent {
String expression;
ArrayList<ExpressionPredicateCondition> conditions;
static {
}
public ExpressionPredicate() {
this.expression = null;
this.conditions = new ArrayList<ExpressionPredicateCondition>();
}
public ArrayList<ExpressionPredicateCondition> getConditions() {
return conditions;
}
public void setConditions(ArrayList<ExpressionPredicateCondition> conditions) {
this.conditions = conditions;
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public ArrayList<ExpressionPredicateCondition> conditions() {
return conditions;
}
@Override
public String toString() {
StringBuilder conditionString = new StringBuilder();
for (ExpressionPredicateCondition epc : conditions()) {
conditionString.append(epc);
conditionString.append(" ");
}
String output = String.format("ExpressionPredicate (\"%s\" -> %s)", getExpression(), conditionString);
return output;
}
@Override
public List<Value> evaluate(List<Value> values, List<Value> results) {
for (Value value : values) {
if (value.getValueType() == Value.TYPE.ARRAY) {
for (int j = 0; j < value.size(); j++) {
Value checkElement = value.get(j);
if (checkElement.getValueType() == Value.TYPE.OBJECT) {
boolean expressionValid = true;
for (ExpressionPredicateCondition condition : conditions) {
if (condition instanceof OperatorExpressionPredicateCondition) {
OperatorExpressionPredicateCondition operatorCondition = (OperatorExpressionPredicateCondition) condition;
Value checkValue = checkElement.get(operatorCondition.getAttribute());
if (checkValue == null) {
expressionValid = false;
break;
}
ExpressionPredicateOperator expressionConditionOperator = operatorCondition.getOperator();
if (expressionConditionOperator.equals(ExpressionPredicateOperator.NOT_NULL)) {
if (checkValue.isNull()) {
expressionValid = false;
break;
}
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.EQUAL)) {
if (!checkValue.equals(operatorCondition.value)) {
expressionValid = false;
break;
}
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.LESS)) {
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.GREATER)) {
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.LESS_EQUAL)) {
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.GREATER_EQUAL)) {
}
} else if (condition instanceof FunctionExpressionPredicateCondition) {
FunctionExpressionPredicateCondition functionCondition = (FunctionExpressionPredicateCondition) condition;
String functionName = functionCondition.getFunctionName();
FunctionArgument[] funtionArguments = functionCondition.getArguments();
if(functionName.equals("regex")) {
RegexFunction regexFunction = new RegexFunction();
Value result = regexFunction.evaluate(funtionArguments, checkElement);
if(result == null) {
expressionValid = false;
break;
}
}
}
}
if (expressionValid) {
results.add(checkElement);
}
}
}
} else {
if(value.getValueType() == Value.TYPE.OBJECT) {
boolean expressionValid = true;
for (ExpressionPredicateCondition condition : conditions) {
if (condition instanceof OperatorExpressionPredicateCondition) {
OperatorExpressionPredicateCondition operatorCondition = (OperatorExpressionPredicateCondition) condition;
Value checkValue = value.get(operatorCondition.getAttribute());
if (checkValue == null) {
expressionValid = false;
break;
}
ExpressionPredicateOperator expressionConditionOperator = operatorCondition.getOperator();
if (expressionConditionOperator.equals(ExpressionPredicateOperator.NOT_NULL)) {
if (checkValue.isNull()) {
expressionValid = false;
break;
}
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.EQUAL)) {
if (!checkValue.equals(operatorCondition.value)) {
expressionValid = false;
break;
}
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.LESS)) {
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.GREATER)) {
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.LESS_EQUAL)) {
} else if (expressionConditionOperator.equals(ExpressionPredicateOperator.GREATER_EQUAL)) {
}
} else if (condition instanceof FunctionExpressionPredicateCondition) {
FunctionExpressionPredicateCondition functionCondition = (FunctionExpressionPredicateCondition) condition;
String functionName = functionCondition.getFunctionName();
FunctionArgument[] funtionArguments = functionCondition.getArguments();
if(functionName.equals("regex")) {
RegexFunction regexFunction = new RegexFunction();
Value result = regexFunction.evaluate(funtionArguments, value);
if(result != null) {
results.add(value);
}
}
}
}
if (expressionValid) {
results.add(value);
}
}
}
}
return results;
}
public enum ExpressionPredicateOperator {
NOT_NULL,
EQUAL,
LESS,
GREATER,
LESS_EQUAL,
GREATER_EQUAL
}
public enum ExpressionPredicateCombineOperator {
AND,
OR,}
public static class ExpressionPredicateCondition {
}
/**
* Complex Predicate Implementation.
*
* @author J.W.Marsden
*/
public static class OperatorExpressionPredicateCondition extends ExpressionPredicateCondition {
ExpressionPredicateCombineOperator combine;
String attribute;
ExpressionPredicateOperator operator;
Value value;
public OperatorExpressionPredicateCondition() {
super();
combine = null;
attribute = null;
operator = null;
value = null;
}
public OperatorExpressionPredicateCondition(String attribute, ExpressionPredicateOperator operator) {
super();
this.attribute = attribute;
this.operator = operator;
value = null;
}
public OperatorExpressionPredicateCondition(String attribute, ExpressionPredicateOperator operator, Value value) {
super();
this.attribute = attribute;
this.operator = operator;
this.value = value;
}
public OperatorExpressionPredicateCondition(ExpressionPredicateCombineOperator combine, String attribute, ExpressionPredicateOperator operator, Value value) {
super();
this.combine = combine;
this.attribute = attribute;
this.operator = operator;
this.value = value;
}
public ExpressionPredicateCombineOperator getCombine() {
return combine;
}
public void setCombine(ExpressionPredicateCombineOperator combine) {
this.combine = combine;
}
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
public ExpressionPredicateOperator getOperator() {
return operator;
}
public void setOperator(ExpressionPredicateOperator operator) {
this.operator = operator;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
@Override
public String toString() {
return String.format("OperatorExpressionPredicateCondition (%s%s %s %s)", ( ( combine != null ) ? String.format("%s ", combine) : "" ), attribute, operator, value.toJSON());
}
}
public static class FunctionExpressionPredicateCondition extends ExpressionPredicateCondition {
String functionName;
FunctionArgument[] arguments;
public FunctionExpressionPredicateCondition(String functionName, FunctionArgument[] arguments) {
this.functionName = functionName;
this.arguments = arguments;
}
public FunctionArgument[] getArguments() {
return arguments;
}
public void setArguments(FunctionArgument[] arguments) {
this.arguments = arguments;
}
public String getFunctionName() {
return functionName;
}
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
@Override
public String toString() {
StringBuilder argumentStringBuilder = new StringBuilder();
Object argValue = null;
int argCount;
if (( argCount = Array.getLength(arguments) ) > 0) {
for (int i = 0; i < argCount - 1; i++) {
argValue = arguments[i];
if (argValue != null) {
argumentStringBuilder.append(argValue.toString()).append(',');
} else {
argumentStringBuilder.append("null").append(',');
}
}
argValue = arguments[argCount - 1];
if (argValue != null) {
argumentStringBuilder.append(argValue.toString());
} else {
argumentStringBuilder.append("null");
}
}
return String.format("FunctionExpressionPredicateCondition (%s[%s])", functionName, argumentStringBuilder.toString());
}
}
}