Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.sap.gateway.v4.rt.jdbc.hana.HanaExpressionVisitor Maven / Gradle / Ivy
package com.sap.gateway.v4.rt.jdbc.hana;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
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.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.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
import org.apache.olingo.server.api.uri.queryoption.expression.Member;
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HanaExpressionVisitor implements ExpressionVisitor {
final static Logger logger=LoggerFactory.getLogger(HanaExpressionVisitor.class);
public HanaExpressionVisitor() {
// TODO Auto-generated constructor stub
}
@Override
public Object visitBinaryOperator(BinaryOperatorKind operator, Object left, Object right)
throws ExpressionVisitException, ODataApplicationException {
// Binary Operators are split up in three different kinds. Up to the kind of the
// operator it can be applied to different types
// - Arithmetic operations like add, minus, modulo, etc. are allowed on numeric
// types like Edm.Int32
// - Logical operations are allowed on numeric types and also Edm.String
// - Boolean operations like and, or are allowed on Edm.Boolean
// A detailed explanation can be found in OData Version 4.0 Part 2: URL Conventions
String leftString;
if(left instanceof Number || operator==BinaryOperatorKind.AND||operator==BinaryOperatorKind.OR){
leftString=left.toString();
}else{
leftString="\""+left.toString()+"\"";
}
StringBuffer buffer = new StringBuffer(leftString);
switch(operator){
case GT:
buffer.append(' ').append('>').append(' ');
break;
case LT:
buffer.append(' ').append('<').append(' ');
break;
case EQ:
if(buffer.indexOf("LIKE") < 0){
buffer.append(' ').append('=').append(' ');
}
break;
case NE:
buffer.append(' ').append("<>").append(' ');
break;
case LE:
buffer.append(' ').append("<=").append(' ');
break;
case GE:
buffer.append(' ').append(">=").append(' ');
break;
case AND:
buffer.append(' ').append(operator.toString()).append(' ');
break;
case OR:
buffer.append(' ').append(operator.toString()).append(' ');
break;
default:
throw new ODataApplicationException("Operator " + operator + " not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
String rightSide=right.toString();
if ((rightSide.contains("datetimeoffset'")) || (rightSide.contains("datetime'")) || (rightSide.contains("PT") && rightSide.contains("S") && rightSide.contains("H") && rightSide.contains("M"))){
buffer.append(evaluateComparingExpression(rightSide));
}
else {
if(buffer.indexOf("LIKE") < 0 || operator != BinaryOperatorKind.EQ)
buffer.append(right);
else
if(rightSide.equals("false")){
String newBuffer = buffer.toString().replaceFirst(" LIKE ", " NOT LIKE ");
buffer = new StringBuffer(newBuffer);
}
}
//buffer.append(right);
return buffer.toString();
}
@Override
public Object visitUnaryOperator(UnaryOperatorKind operator, Object operand)
throws ExpressionVisitException, ODataApplicationException {
// OData allows two different unary operators. We have to take care, that the type of the
// operand fits to the operand
if(operator == UnaryOperatorKind.NOT && operand instanceof Boolean) {
// 1.) boolean negation
return !(Boolean) operand;
} else if(operator == UnaryOperatorKind.MINUS && operand instanceof Integer){
// 2.) arithmetic minus
return -(Integer) operand;
}
// Operation not processed, throw an exception
throw new ODataApplicationException("Invalid type for unary operator",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitMethodCall(MethodKind methodCall, List parameters)
throws ExpressionVisitException, ODataApplicationException {
// To keep this tutorial small and simple, we implement only one method call
// contains(String, String) -> Boolean
if(methodCall == MethodKind.CONTAINS) {
if(parameters.get(0) instanceof String && parameters.get(1) instanceof String) {
String valueParam1 = (String) parameters.get(0);
String valueParam2 = (String) parameters.get(1);
return valueParam1.contains(valueParam2);
} else {
throw new ODataApplicationException("Contains needs two parametes of type Edm.String",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
} else {
throw new ODataApplicationException("Method call " + methodCall + " not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
@Override
public Object visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)
throws ExpressionVisitException, ODataApplicationException {
// TODO Auto-generated method stub
return null;
}
/*@Override
public Object visitLiteral(String literal) throws ExpressionVisitException, ODataApplicationException {
return literal;
}*/
@Override
public Object visitMember(Member member) throws ExpressionVisitException, ODataApplicationException {
if (member.getResourcePath().getUriResourceParts().size() == 1) {
UriResourcePrimitiveProperty property
= (UriResourcePrimitiveProperty)
member.getResourcePath().getUriResourceParts().get(0);
return property.getProperty().getName();
} else {
List propertyNames = new ArrayList();
for (UriResource property : member.getResourcePath().getUriResourceParts()) {
UriResourceProperty primitiveProperty
= (UriResourceProperty) property;
propertyNames.add(primitiveProperty.getProperty().getName());
}
return propertyNames;
}
}
@Override
public Object visitAlias(String aliasName) throws ExpressionVisitException, ODataApplicationException {
// TODO Auto-generated method stub
return null;
}
@Override
public Object visitTypeLiteral(EdmType type) throws ExpressionVisitException, ODataApplicationException {
// TODO Auto-generated method stub
return null;
}
@Override
public Object visitLambdaReference(String variableName) throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Lambda Expression not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitEnum(EdmEnumType type, List enumValues)
throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Enum Filters not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException {
return literal.getText();
}
public String evaluateComparingExpression(String value) {
if(value.contains("datetime") && !value.contains("datetimeoffset")) {
value = value.substring(9, value.length()-1);
Calendar cal = Calendar.getInstance();
Date date;
date = parseDate(value);
/* long dbTime = date.getTime();
Date originalDate = new Date(dbTime + TimeZone.getDefault().getOffset(dbTime));*/
if(date!=null){
cal.setTime(date);
}
String year = String.format("%04d", cal.get(Calendar.YEAR));
String month = String.format("%02d", cal.get(Calendar.MONTH) + 1);
String day = String.format("%02d", cal.get(Calendar.DAY_OF_MONTH));
String hour = String.format("%02d", cal.get(Calendar.HOUR_OF_DAY));
String min = String.format("%02d", cal.get(Calendar.MINUTE));
String sec = String.format("%02d", cal.get(Calendar.SECOND));
value = "\'" + year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + "\'";
}
else if(value.contains("datetimeoffset")) {
value = value.substring(15, value.length()-1);
Calendar cal = Calendar.getInstance();
Date date;
date = parseDate(value);
/*long dbTime = date.getTime();
Date originalDate = new Date(dbTime + TimeZone.getDefault().getOffset(dbTime));*/
if(date!=null){
cal.setTime(date);
}
String year = String.format("%04d", cal.get(Calendar.YEAR));
String month = String.format("%02d", cal.get(Calendar.MONTH) + 1);
String day = String.format("%02d", cal.get(Calendar.DAY_OF_MONTH));
String hour = String.format("%02d", cal.get(Calendar.HOUR_OF_DAY));
String min = String.format("%02d", cal.get(Calendar.MINUTE));
String sec = String.format("%02d", cal.get(Calendar.SECOND));
String offset = "";
if(value.contains("+")) {
offset = value.substring(value.indexOf('+') , value.length());
} else if(value.contains("-")) {
offset = value.substring(value.lastIndexOf('-') , value.length());
}
value = "\'" + year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + offset + "\'";
}
else {
String hourValue = String.format("%02d", Integer.parseInt(value.substring(7, value.indexOf('H'))));
String minValue = String.format("%02d", Integer.parseInt(value.substring(value.indexOf('H') + 1, value.indexOf('M'))));
String secValue = String.format("%02d", Integer.parseInt(value.substring(value.indexOf('M') + 1, value.indexOf('S'))));
value = "\'" + hourValue + ":" + minValue + ":" + secValue + "\'";
}
return value;
}
public Date parseDate(String dateValue) {
final String[] dateFormats = {
//"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss", //"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
/*"yyyy-MM-dd'T'HH:mm:ss.SSSZ",
"yyyy-MM-dd",
"hh-mm-ss","hh:mm:ss"*/
};
Date date = null;
if (dateValue != null) {
for (String parse : dateFormats) {
SimpleDateFormat sdf = new SimpleDateFormat(parse);
try {
date=sdf.parse(dateValue);
} catch (ParseException e) {
logger.debug("Failed DateFormat ::"+parse,e);
}
}
}
return date;
}
}