package com.ifsworld.projection;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
import org.apache.olingo.server.api.uri.queryoption.expression.*;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
public class AirportFilterVisitor implements ExpressionVisitor<Object> {
@Override
public Object visitBinaryOperator(BinaryOperatorKind operator, Object left, Object right) throws ExpressionVisitException, ODataApplicationException {
if (operator == BinaryOperatorKind.EQ
|| operator == BinaryOperatorKind.NE
|| operator == BinaryOperatorKind.GE
|| operator == BinaryOperatorKind.GT
|| operator == BinaryOperatorKind.LE
|| operator == BinaryOperatorKind.LT) {
return evaluateComparisonOperation(operator, left, right);
} else if (operator == BinaryOperatorKind.AND
|| operator == BinaryOperatorKind.OR) {
return evaluateBooleanOperation(operator, left, right);
} else {
throw new ODataApplicationException("Binary operation " + operator.name() + " is not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
@Override
public Object visitUnaryOperator(UnaryOperatorKind unaryOperatorKind, Object o) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitMethodCall(MethodKind methodKind, List<Object> list) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitLambdaExpression(String s, String s1, Expression expression) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException {
String literalAsString = literal.getText();
if(literal.getType() instanceof EdmString) {
String stringLiteral = "";
if(literal.getText().length() > 2) {
stringLiteral = literalAsString.substring(1, literalAsString.length() - 1);
}
return stringLiteral;
} else {
try {
return Integer.parseInt(literalAsString);
} catch(NumberFormatException e) {
throw new ODataApplicationException("Only Edm.Int32 and Edm.String literals are implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
}
@Override
public Object visitMember(final Member member) throws ExpressionVisitException, ODataApplicationException {
HashMap<String,String> propertyMap = new HashMap<>();
propertyMap.put("Icao","icao");
propertyMap.put("Iata","iata");
propertyMap.put("Name","name");
propertyMap.put("City","city");
propertyMap.put("Region","region");
propertyMap.put("Country","country");
propertyMap.put("Timezone","timezone");
final List<UriResource> uriResourceParts = member.getResourcePath().getUriResourceParts();
if(uriResourceParts.size() == 1 && uriResourceParts.get(0) instanceof UriResourcePrimitiveProperty) {
UriResourcePrimitiveProperty uriResourceProperty = (UriResourcePrimitiveProperty) uriResourceParts.get(0);
return propertyMap.get(uriResourceProperty.getProperty().getName());
} else {
throw new ODataApplicationException("Only primitive properties are implemented in filter expressions",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
@Override
public Object visitAlias(String s) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitTypeLiteral(EdmType edmType) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitLambdaReference(String s) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitEnum(EdmEnumType edmEnumType, List<String> list) throws ExpressionVisitException, ODataApplicationException {
return null;
}
@Override
public Object visitBinaryOperator(BinaryOperatorKind binaryOperatorKind, Object o, List<Object> list) throws ExpressionVisitException, ODataApplicationException {
return null;
}
private Object evaluateComparisonOperation(BinaryOperatorKind operator, Object left, Object right)
throws ODataApplicationException {
// All types in our tutorial supports all logical operations, but we have to make sure that the types are equals
if(left.getClass().equals(right.getClass()) && left instanceof Comparable) {
if (operator == BinaryOperatorKind.EQ) {
return left + "=" + right;
} else if (operator == BinaryOperatorKind.NE) {
return left + "!=" + right;
} else if (operator == BinaryOperatorKind.GE) {
return left + ">=" + right;
} else if (operator == BinaryOperatorKind.GT) {
return left + ">" + right;
} else if (operator == BinaryOperatorKind.LE) {
return left + "<=" + right;
} else {
return null;
}
} else {
throw new ODataApplicationException("Comparision needs two equal types",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
}
private Object evaluateBooleanOperation(BinaryOperatorKind operator, Object left, Object right)
throws ODataApplicationException {
if(operator == BinaryOperatorKind.AND) {
return left + "&" + right;
} else {
return left + "or" + right;
}
}
}