in nuget-feed/src/jetbrains/buildServer/nuget/feed/server/olingo/processor/ExpressionEvaluator.java [30:206]
public <T> String evaluateExpression(final T data, final CommonExpression expression) throws ODataException {
switch (expression.getKind()) {
case UNARY:
final UnaryExpression unaryExpression = (UnaryExpression) expression;
final String operand = evaluateExpression(data, unaryExpression.getOperand());
switch (unaryExpression.getOperator()) {
case NOT:
return Boolean.toString(!Boolean.parseBoolean(operand));
case MINUS:
return operand.startsWith("-") ? operand.substring(1) : "-" + operand;
default:
throw new ODataNotImplementedException();
}
case BINARY:
final BinaryExpression binaryExpression = (BinaryExpression) expression;
CommonExpression leftOperand = binaryExpression.getLeftOperand();
final String left = evaluateExpression(data, leftOperand);
final String right = evaluateExpression(data, binaryExpression.getRightOperand());
switch (binaryExpression.getOperator()) {
case ADD:
if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
return Double.toString(Double.valueOf(left) + Double.valueOf(right));
} else {
return Long.toString(Long.valueOf(left) + Long.valueOf(right));
}
case SUB:
if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
return Double.toString(Double.valueOf(left) - Double.valueOf(right));
} else {
return Long.toString(Long.valueOf(left) - Long.valueOf(right));
}
case MUL:
if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
return Double.toString(Double.valueOf(left) * Double.valueOf(right));
} else {
return Long.toString(Long.valueOf(left) * Long.valueOf(right));
}
case DIV:
final String number = Double.toString(Double.valueOf(left) / Double.valueOf(right));
return number.endsWith(".0") ? number.replace(".0", "") : number;
case MODULO:
if (binaryExpression.getEdmType() == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()
|| binaryExpression.getEdmType() == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
return Double.toString(Double.valueOf(left) % Double.valueOf(right));
} else {
return Long.toString(Long.valueOf(left) % Long.valueOf(right));
}
case AND:
return Boolean.toString(left.equals("true") && right.equals("true"));
case OR:
return Boolean.toString(left.equals("true") || right.equals("true"));
case EQ:
return Boolean.toString(compare(leftOperand, left, right) == 0);
case NE:
return Boolean.toString(compare(leftOperand, left, right) != 0);
case LT:
return Boolean.toString(compare(leftOperand, left, right) < 0);
case LE:
return Boolean.toString(compare(leftOperand, left, right) <= 0);
case GT:
return Boolean.toString(compare(leftOperand, left, right) > 0);
case GE:
return Boolean.toString(compare(leftOperand, left, right) >= 0);
case PROPERTY_ACCESS:
throw new ODataNotImplementedException();
default:
throw new ODataNotImplementedException();
}
case PROPERTY:
final EdmProperty property = (EdmProperty) ((PropertyExpression) expression).getEdmProperty();
final EdmSimpleType propertyType = (EdmSimpleType) property.getType();
return propertyType.valueToString(valueAccess.getPropertyValue(data, property),
EdmLiteralKind.DEFAULT, property.getFacets());
case MEMBER:
final MemberExpression memberExpression = (MemberExpression) expression;
final PropertyExpression propertyExpression = (PropertyExpression) memberExpression.getProperty();
final EdmProperty memberProperty = (EdmProperty) propertyExpression.getEdmProperty();
final EdmSimpleType memberType = (EdmSimpleType) memberExpression.getEdmType();
final List<EdmProperty> propertyPath = new ArrayList<>();
CommonExpression currentExpression = memberExpression;
while (currentExpression != null) {
final PropertyExpression currentPropertyExpression =
(PropertyExpression) (currentExpression.getKind() == ExpressionKind.MEMBER ?
((MemberExpression) currentExpression).getProperty() : currentExpression);
final EdmTyped currentProperty = currentPropertyExpression.getEdmProperty();
final EdmTypeKind kind = currentProperty.getType().getKind();
if (kind == EdmTypeKind.SIMPLE || kind == EdmTypeKind.COMPLEX) {
propertyPath.add(0, (EdmProperty) currentProperty);
} else {
throw new ODataNotImplementedException();
}
currentExpression = currentExpression.getKind() == ExpressionKind.MEMBER
? ((MemberExpression) currentExpression).getPath()
: null;
}
final Object memberValue = valueAccess.getPropertyValue(data, propertyPath);
return memberType.valueToString(memberValue, EdmLiteralKind.DEFAULT, memberProperty.getFacets());
case LITERAL:
final LiteralExpression literal = (LiteralExpression) expression;
final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType();
final Object literalValue = literalType.valueOfString(literal.getUriLiteral(),
EdmLiteralKind.URI, null, literalType.getDefaultType());
return literalType.valueToString(literalValue, EdmLiteralKind.DEFAULT, null);
case METHOD:
final MethodExpression methodExpression = (MethodExpression) expression;
final String first = evaluateExpression(data, methodExpression.getParameters().get(0));
final String second = methodExpression.getParameterCount() > 1 ?
evaluateExpression(data, methodExpression.getParameters().get(1)) : "";
final String third = methodExpression.getParameterCount() > 2 ?
evaluateExpression(data, methodExpression.getParameters().get(2)) : "";
switch (methodExpression.getMethod()) {
case ENDSWITH:
return Boolean.toString(first != null && first.endsWith(second));
case INDEXOF:
return Integer.toString(first == null ? -1 : first.indexOf(second));
case STARTSWITH:
return Boolean.toString(first != null && first.startsWith(second));
case TOLOWER:
return first == null ? null : first.toLowerCase(Locale.ROOT);
case TOUPPER:
return first == null ? null : first.toUpperCase(Locale.ROOT);
case TRIM:
return first == null ? null : first.trim();
case SUBSTRING:
final int offset = second == null || second.length() == 0 ? 0 : Integer.parseInt(second);
final int length = third == null || third.length() == 0 ? 0 : Integer.parseInt(third);
return first.substring(offset, offset + length);
case SUBSTRINGOF:
return Boolean.toString(second != null && second.contains(first));
case CONCAT:
return first + second;
case LENGTH:
return Integer.toString(first.length());
case YEAR:
return String.valueOf(Integer.parseInt(first.substring(0, 4)));
case MONTH:
return String.valueOf(Integer.parseInt(first.substring(5, 7)));
case DAY:
return String.valueOf(Integer.parseInt(first.substring(8, 10)));
case HOUR:
return String.valueOf(Integer.parseInt(first.substring(11, 13)));
case MINUTE:
return String.valueOf(Integer.parseInt(first.substring(14, 16)));
case SECOND:
return String.valueOf(Integer.parseInt(first.substring(17, 19)));
case ROUND:
return Long.toString(Math.round(Double.valueOf(first)));
case FLOOR:
return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
case CEILING:
return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
default:
throw new ODataNotImplementedException();
}
default:
throw new ODataNotImplementedException();
}
}