[OLINGO-834] clean-up Expression implementations Signed-off-by: Christian Amend <[email protected]>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/208f26c7 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/208f26c7 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/208f26c7 Branch: refs/heads/OLINGO-834_Filter_Parser Commit: 208f26c746263c2d5b9a14e48bae9a7091e1f839 Parents: d7e23bf Author: Klaus Straubinger <[email protected]> Authored: Fri Dec 11 10:10:03 2015 +0100 Committer: Christian Amend <[email protected]> Committed: Fri Dec 11 12:30:10 2015 +0100 ---------------------------------------------------------------------- .../core/uri/UriResourceLambdaAllImpl.java | 11 +- .../core/uri/UriResourceLambdaAnyImpl.java | 11 +- .../core/uri/UriResourceLambdaVarImpl.java | 4 +- .../core/uri/expression/FilterParser.java | 562 ------------------ .../core/uri/parser/ExpressionParser.java | 575 +++++++++++++++++++ .../core/uri/parser/UriParseTreeVisitor.java | 498 ++++++---------- .../core/uri/queryoption/OrderByItemImpl.java | 8 +- .../uri/queryoption/expression/AliasImpl.java | 14 +- .../uri/queryoption/expression/BinaryImpl.java | 34 +- .../queryoption/expression/EnumerationImpl.java | 28 +- .../queryoption/expression/ExpressionImpl.java | 25 - .../queryoption/expression/LambdaRefImpl.java | 14 +- .../uri/queryoption/expression/LiteralImpl.java | 25 +- .../uri/queryoption/expression/MemberImpl.java | 28 +- .../uri/queryoption/expression/MethodImpl.java | 52 +- .../queryoption/expression/TypeLiteralImpl.java | 14 +- .../uri/queryoption/expression/UnaryImpl.java | 23 +- .../core/uri/expression/FilterParserTest.java | 210 ------- .../core/uri/parser/ExpressionParserTest.java | 210 +++++++ .../server/core/uri/UriResourceImplTest.java | 8 +- .../core/uri/queryoption/QueryOptionTest.java | 6 +- .../queryoption/expression/ExpressionTest.java | 103 ++-- 22 files changed, 1095 insertions(+), 1368 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java index b57d12c..d980777 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java @@ -25,15 +25,12 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceLambdaAll; import org.apache.olingo.server.api.uri.queryoption.expression.Expression; -import org.apache.olingo.server.core.uri.queryoption.expression.ExpressionImpl; public class UriResourceLambdaAllImpl extends UriResourceTypedImpl implements UriResourceLambdaAll { protected EdmProperty property; - private String lambdaVariable; - - private ExpressionImpl expression; + private Expression expression; public UriResourceLambdaAllImpl() { super(UriResourceKind.lambdaAll); @@ -64,13 +61,13 @@ public class UriResourceLambdaAllImpl extends UriResourceTypedImpl implements Ur return expression; } - public UriResourceLambdaAllImpl setExpression(final ExpressionImpl expression) { + public UriResourceLambdaAllImpl setExpression(final Expression expression) { this.expression = expression; return this; } - + @Override - public String getSegmentValue(){ + public String getSegmentValue() { return "all"; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java index 49be2fe..fe5dfee 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java @@ -25,15 +25,12 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceLambdaAny; import org.apache.olingo.server.api.uri.queryoption.expression.Expression; -import org.apache.olingo.server.core.uri.queryoption.expression.ExpressionImpl; public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements UriResourceLambdaAny { protected EdmProperty property; - private String lambdaVariable; - - private ExpressionImpl expression; + private Expression expression; public UriResourceLambdaAnyImpl() { super(UriResourceKind.lambdaAny); @@ -64,13 +61,13 @@ public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements Ur return expression; } - public UriResourceLambdaAnyImpl setExpression(final ExpressionImpl expression) { + public UriResourceLambdaAnyImpl setExpression(final Expression expression) { this.expression = expression; return this; } - + @Override - public String getSegmentValue(){ + public String getSegmentValue() { return "any"; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java index f7fa6fc..2eb7607 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java @@ -64,10 +64,10 @@ public class UriResourceLambdaVarImpl extends UriResourceTypedImpl implements Ur } @Override - public String getSegmentValue(){ + public String getSegmentValue() { return variableText; } - + @Override public String toString() { return getSegmentValue(); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/expression/FilterParser.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/expression/FilterParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/expression/FilterParser.java deleted file mode 100644 index 32cbc1a..0000000 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/expression/FilterParser.java +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ -package org.apache.olingo.server.core.uri.expression; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.olingo.commons.api.edm.EdmPrimitiveType; -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; -import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; -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.MethodKind; -import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind; -import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.ExpressionImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.UnaryImpl; - -public class FilterParser { - private Tokenizer tokenizer; - - private static final Map<TokenKind, BinaryOperatorKind> tokenToBinaryOperator; - static { - HashMap<TokenKind, BinaryOperatorKind> temp = new HashMap<FilterParser.TokenKind, BinaryOperatorKind>(); - temp.put(TokenKind.OR_OP, BinaryOperatorKind.OR); - temp.put(TokenKind.AND_OP, BinaryOperatorKind.AND); - - temp.put(TokenKind.EQ_OP, BinaryOperatorKind.EQ); - temp.put(TokenKind.NE_OP, BinaryOperatorKind.NE); - - temp.put(TokenKind.GT_OP, BinaryOperatorKind.GT); - temp.put(TokenKind.GE_OP, BinaryOperatorKind.GE); - temp.put(TokenKind.LT_OP, BinaryOperatorKind.LT); - temp.put(TokenKind.LE_OP, BinaryOperatorKind.LE); - - temp.put(TokenKind.ADD_OP, BinaryOperatorKind.ADD); - temp.put(TokenKind.SUB_OP, BinaryOperatorKind.SUB); - - temp.put(TokenKind.MUL_OP, BinaryOperatorKind.MUL); - temp.put(TokenKind.DIV_OP, BinaryOperatorKind.DIV); - temp.put(TokenKind.MOD_OP, BinaryOperatorKind.MOD); - - tokenToBinaryOperator = Collections.unmodifiableMap(temp); - } - - private static final Map<TokenKind, UnaryOperatorKind> tokenToUnaryOperator; - static { - HashMap<TokenKind, UnaryOperatorKind> temp = new HashMap<FilterParser.TokenKind, UnaryOperatorKind>(); - temp.put(TokenKind.MINUS, UnaryOperatorKind.MINUS); - temp.put(TokenKind.NOT, UnaryOperatorKind.NOT); - tokenToUnaryOperator = Collections.unmodifiableMap(temp); - } - - private static final Map<TokenKind, MethodKind> tokenToMethod; - static { - HashMap<TokenKind, MethodKind> temp = new HashMap<FilterParser.TokenKind, MethodKind>(); - temp.put(TokenKind.Cast, MethodKind.CAST); - temp.put(TokenKind.Ceiling, MethodKind.CEILING); - temp.put(TokenKind.Concat, MethodKind.CONCAT); - temp.put(TokenKind.Contains, MethodKind.CONTAINS); - temp.put(TokenKind.Date, MethodKind.DATE); - temp.put(TokenKind.Day, MethodKind.DAY); - temp.put(TokenKind.Endswith, MethodKind.ENDSWITH); - temp.put(TokenKind.Floor, MethodKind.FLOOR); - temp.put(TokenKind.Fractionalseconds, MethodKind.FRACTIONALSECONDS); - temp.put(TokenKind.GeoDistance, MethodKind.GEODISTANCE); - temp.put(TokenKind.GeoIntersects, MethodKind.GEOINTERSECTS); - temp.put(TokenKind.GeoLength, MethodKind.GEOLENGTH); - temp.put(TokenKind.Hour, MethodKind.HOUR); - temp.put(TokenKind.Indexof, MethodKind.INDEXOF); - temp.put(TokenKind.Isof, MethodKind.ISOF); - temp.put(TokenKind.Length, MethodKind.LENGTH); - temp.put(TokenKind.Maxdatetime, MethodKind.MAXDATETIME); - temp.put(TokenKind.Mindatetime, MethodKind.MINDATETIME); - temp.put(TokenKind.Minute, MethodKind.MINUTE); - temp.put(TokenKind.Month, MethodKind.MONTH); - temp.put(TokenKind.Now, MethodKind.NOW); - temp.put(TokenKind.Round, MethodKind.ROUND); - temp.put(TokenKind.Second, MethodKind.SECOND); - temp.put(TokenKind.Startswith, MethodKind.STARTSWITH); - temp.put(TokenKind.Substring, MethodKind.SUBSTRING); - temp.put(TokenKind.Time, MethodKind.TIME); - temp.put(TokenKind.Tolower, MethodKind.TOLOWER); - temp.put(TokenKind.Totaloffsetminutes, MethodKind.TOTALOFFSETMINUTES); - temp.put(TokenKind.Totalseconds, MethodKind.TOTALSECONDS); - temp.put(TokenKind.Toupper, MethodKind.TOUPPER); - temp.put(TokenKind.Trim, MethodKind.TRIM); - temp.put(TokenKind.Year, MethodKind.YEAR); - - tokenToMethod = Collections.unmodifiableMap(temp); - } - - private static final Map<TokenKind, EdmPrimitiveTypeKind> tokenToPrimitiveType; - static { - /* Enum and null are not present in the map. These have to be handled differently */ - HashMap<TokenKind, EdmPrimitiveTypeKind> temp = new HashMap<FilterParser.TokenKind, EdmPrimitiveTypeKind>(); - temp.put(TokenKind.PrimitiveBooleanValue, EdmPrimitiveTypeKind.Boolean); - temp.put(TokenKind.PrimitiveStringValue, EdmPrimitiveTypeKind.String); - // TODO:Check if int64 is correct here or if it has to be single instead - temp.put(TokenKind.PrimitiveIntegerValue, EdmPrimitiveTypeKind.Int64); - temp.put(TokenKind.PrimitiveGuidValue, EdmPrimitiveTypeKind.Guid); - temp.put(TokenKind.PrimitiveDateValue, EdmPrimitiveTypeKind.Date); - temp.put(TokenKind.PrimitiveDateTimeOffsetValue, EdmPrimitiveTypeKind.DateTimeOffset); - temp.put(TokenKind.PrimitiveTimeOfDayValue, EdmPrimitiveTypeKind.TimeOfDay); - temp.put(TokenKind.PrimitiveDecimalValue, EdmPrimitiveTypeKind.Decimal); - temp.put(TokenKind.PrimitiveDoubleValue, EdmPrimitiveTypeKind.Double); - temp.put(TokenKind.PrimitiveDurationValue, EdmPrimitiveTypeKind.Duration); - temp.put(TokenKind.PrimitiveBinaryValue, EdmPrimitiveTypeKind.Binary); - - tokenToPrimitiveType = Collections.unmodifiableMap(temp); - } - - public Expression parse(Tokenizer tokenizer) { - // Initialize tokenizer - this.tokenizer = tokenizer; - - Expression exp = parseExpression(); - return exp; - } - - private Expression parseExpression() { - Expression left = parseAnd(); - - while (is(TokenKind.OR_OP) != null) { - tokenizer.getText(); - - Expression right = parseAnd(); - left = new BinaryImpl(left, BinaryOperatorKind.OR, right); - } - - return left; - } - - private Expression parseAnd() { - Expression left = parseExprEquality(); - while (is(TokenKind.AND_OP) != null) { - tokenizer.getText(); - - Expression right = parseExprEquality(); - left = new BinaryImpl(left, BinaryOperatorKind.AND, right); - } - return left; - } - - private Expression parseExprEquality() { - Expression left = parseExprRel(); - - TokenKind nextTokenKind = is(TokenKind.EQ_OP, TokenKind.NE_OP); - // Null for everything other than EQ or NE - while (nextTokenKind != null) { - tokenizer.getText(); - - Expression right = parseExprEquality(); - left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); - nextTokenKind = is(TokenKind.EQ_OP, TokenKind.NE_OP); - } - - return left; - } - - private Expression parseExprRel() { - Expression left = parseExprAdd(); - - TokenKind nextTokenKind = is(TokenKind.GT_OP, TokenKind.GE_OP, TokenKind.LT_OP, TokenKind.LE_OP); - // Null for everything other than GT or GE or LT or LE - while (nextTokenKind != null) { - tokenizer.getText(); - - Expression right = parseExprAdd(); - left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); - nextTokenKind = is(TokenKind.GT_OP, TokenKind.GE_OP, TokenKind.LT_OP, TokenKind.LE_OP); - } - - return left; - } - - private Expression parseExprAdd() { - Expression left = parseExprMul(); - - TokenKind nextTokenKind = is(TokenKind.ADD_OP, TokenKind.SUB_OP); - // Null for everything other than ADD or SUB - while (nextTokenKind != null) { - tokenizer.getText(); - - Expression right = parseExprMul(); - left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); - nextTokenKind = is(TokenKind.ADD_OP, TokenKind.SUB_OP); - } - - return left; - } - - private Expression parseExprMul() { - Expression left = parseExprUnary(); - - TokenKind nextTokenKind = is(TokenKind.MUL_OP, TokenKind.DIV_OP, TokenKind.MOD_OP); - // Null for everything other than MUL or DIV or MOD - while (nextTokenKind != null) { - tokenizer.getText(); - - Expression right = parseExprUnary(); - left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); - nextTokenKind = is(TokenKind.MUL_OP, TokenKind.DIV_OP, TokenKind.MOD_OP); - } - - return left; - } - - private Expression parseExprUnary() { - Expression left = null; - TokenKind nextTokenKind = is(TokenKind.MINUS, TokenKind.NOT); - // Null for everything other than - or NOT - while (nextTokenKind != null) { - tokenizer.getText(); - - Expression exp = parseExprValue(); - left = new UnaryImpl(tokenToUnaryOperator.get(nextTokenKind), exp); - nextTokenKind = is(TokenKind.MINUS, TokenKind.NOT); - } - - if (left == null) { - left = parseExprValue(); - } - - return left; - } - - private Expression parseExprValue() { - if (is(TokenKind.OPEN) != null) { - tokenizer.getText(); - Expression exp = parseExpression(); - require(TokenKind.CLOSE); - return exp; - } - - if (is(TokenKind.ParameterAlias) != null) { - return new AliasImpl(tokenizer.getText()); - } - - if (is(TokenKind.RootExpr) != null) { - tokenizer.getText(); - // TODO: ConsumeRootExpression - } - - TokenKind nextPrimitive = isPrimitive(); - if (nextPrimitive != null) { - EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(nextPrimitive); - EdmPrimitiveType type; - if (primitiveTypeKind == null) { - if (nextPrimitive == TokenKind.PrimitiveEnumValue) { - // TODO: Get enum type - type = null; - } else { - // Null handling - type = null; - } - } else { - type = EdmPrimitiveTypeFactory.getInstance(primitiveTypeKind); - } - return new LiteralImpl(tokenizer.getText(), type); - } - - TokenKind nextMethod = isMethod(); - if (nextMethod != null) { - MethodImpl methodImpl = new MethodImpl(tokenToMethod.get(nextMethod)); - // Consume Method - tokenizer.getText(); - if (is(TokenKind.CLOSE) != null) { - // Consume closing bracket - tokenizer.getText(); - } else { - // TODO: Remove Cast - methodImpl.addParameter((ExpressionImpl) parseExpression()); - while (is(TokenKind.COMMA) != null) { - tokenizer.getText(); - methodImpl.addParameter((ExpressionImpl) parseExpression()); - } - require(TokenKind.CLOSE); - } - - validateMethodParameters(methodImpl); - - return methodImpl; - } - - throw new RuntimeException("Unexpected token"); - } - - private void validateMethodParameters(MethodImpl methodImpl) { - // We might validate parameter types in the future - int size = methodImpl.getParameters().size(); - switch (methodImpl.getMethod()) { - // Must have two Parameters - case CONTAINS: - case ENDSWITH: - case STARTSWITH: - case INDEXOF: - case CONCAT: - case GEODISTANCE: - case GEOINTERSECTS: - if (size != 2) { - throw new RuntimeException("The method " + methodImpl.getMethod() + " needs exactly two parameters."); - } - break; - // Must have one parameter - case LENGTH: - case TOLOWER: - case TOUPPER: - case TRIM: - case YEAR: - case MONTH: - case DAY: - case HOUR: - case MINUTE: - case SECOND: - case FRACTIONALSECONDS: - case DATE: - case TIME: - case TOTALOFFSETMINUTES: - case TOTALSECONDS: - case ROUND: - case FLOOR: - case CEILING: - case GEOLENGTH: - if (size != 1) { - throw new RuntimeException("The method: '" + methodImpl.getMethod() + "' needs exactly one parameter."); - } - break; - // Must have no parameter - case NOW: - case MAXDATETIME: - case MINDATETIME: - if (size != 0) { - throw new RuntimeException("The method: '" + methodImpl.getMethod() + "' must have no parameters."); - } - break; - // Variable parameter number - case CAST: - case ISOF: - if (size == 1 || size == 2) { - throw new RuntimeException("The method: '" + methodImpl.getMethod() + "' must have one or two parameters."); - } - break; - case SUBSTRING: - if (size == 2 || size == 3) { - throw new RuntimeException("The method: '" + methodImpl.getMethod() + "' must have two or three parameters."); - } - break; - default: - throw new RuntimeException("Unkown method: '" + methodImpl.getMethod() + "'"); - } - } - - private String require(TokenKind required) { - if (is(required) == null) { - throw new RuntimeException("Requred token: " + required); - } - return tokenizer.getText(); - } - - private TokenKind is(TokenKind... kind) { - for (int i = 0; i < kind.length; i++) { - if (tokenizer.next(kind[i])) { - return kind[i]; - } - } - return null; - } - - private TokenKind isMethod() { - return is(TokenKind.Cast, - TokenKind.Ceiling, - TokenKind.Concat, - TokenKind.Contains, - TokenKind.Date, - TokenKind.Day, - TokenKind.Endswith, - TokenKind.Floor, - TokenKind.Fractionalseconds, - TokenKind.GeoDistance, - TokenKind.GeoIntersects, - TokenKind.GeoLength, - TokenKind.Hour, - TokenKind.Indexof, - TokenKind.Isof, - TokenKind.Length, - TokenKind.Maxdatetime, - TokenKind.Mindatetime, - TokenKind.Minute, - TokenKind.Month, - TokenKind.Now, - TokenKind.Round, - TokenKind.Second, - TokenKind.Startswith, - TokenKind.Substring, - TokenKind.Time, - TokenKind.Tolower, - TokenKind.Totaloffsetminutes, - TokenKind.Totalseconds, - TokenKind.Toupper, - TokenKind.Trim, - TokenKind.Year); - } - - private TokenKind isPrimitive() { - return is(TokenKind.PrimitiveNullValue, - TokenKind.PrimitiveBooleanValue, - TokenKind.PrimitiveStringValue, - - // The order of the next seven expressions is important in order to avoid - // finding partly parsed tokens (counter-intuitive as it may be, even a GUID may start with digits ...). - TokenKind.PrimitiveDoubleValue, - TokenKind.PrimitiveDecimalValue, - TokenKind.PrimitiveGuidValue, - TokenKind.PrimitiveDateTimeOffsetValue, - TokenKind.PrimitiveDateValue, - TokenKind.PrimitiveTimeOfDayValue, - TokenKind.PrimitiveIntegerValue, - TokenKind.PrimitiveDurationValue, - TokenKind.PrimitiveBinaryValue, - TokenKind.PrimitiveEnumValue); - } - - public enum TokenKind { - // BINARY - OR_OP, - AND_OP, - - EQ_OP, - NE_OP, - - GT_OP, - GE_OP, - LT_OP, - LE_OP, - - ADD_OP, - SUB_OP, - - MUL_OP, - DIV_OP, - MOD_OP, - - MINUS, - NOT, - - // Grouping - OPEN, - CLOSE, - - // PrimitiveValues - PrimitiveNullValue, - PrimitiveBooleanValue, - - PrimitiveStringValue, - PrimitiveIntegerValue, - PrimitiveGuidValue, - PrimitiveDateValue, - PrimitiveDateTimeOffsetValue, - PrimitiveTimeOfDayValue, - PrimitiveDecimalValue, - PrimitiveDoubleValue, - PrimitiveDurationValue, - PrimitiveBinaryValue, - PrimitiveEnumValue, - - // ExpressionValues - ParameterAlias, - ArrayOrObject, - RootExpr, - IT, - - // BuiltInMethods - Cast, - Ceiling, - Concat, - Contains, - Date, - Day, - Endswith, - Floor, - Fractionalseconds, - GeoDistance, - GeoIntersects, - GeoLength, - Hour, - Indexof, - Isof, - Length, - Maxdatetime, - Mindatetime, - Minute, - Month, - Now, - Round, - Second, - Startswith, - Substring, - Time, - Tolower, - Totaloffsetminutes, - Totalseconds, - Toupper, - Trim, - Year, - COMMA - } - - public static class Token { - TokenKind kind; - String text; - - public Token(TokenKind kind, String text) { - this.kind = kind; - this.text = text; - } - } - - public static class Tokenizer { - private List<Token> tokens; - int counter = 0; - - public Tokenizer(List<Token> tokens) { - this.tokens = tokens; - } - - public boolean next(TokenKind expectedKind) { - if (counter < tokens.size() && expectedKind == tokens.get(counter).kind) { - return true; - } - return false; - } - - public String getText() { - String text = tokens.get(counter).text; - counter++; - return text; - } - } - -} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java new file mode 100644 index 0000000..854536d --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java @@ -0,0 +1,575 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.olingo.server.core.uri.parser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; +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.Method; +import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind; +import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind; +import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl; +import org.apache.olingo.server.core.uri.queryoption.expression.UnaryImpl; + +public class ExpressionParser { + private Tokenizer tokenizer; + + private static final Map<TokenKind, BinaryOperatorKind> tokenToBinaryOperator; + static { + Map<TokenKind, BinaryOperatorKind> temp = new HashMap<ExpressionParser.TokenKind, BinaryOperatorKind>(); + temp.put(TokenKind.OR_OP, BinaryOperatorKind.OR); + temp.put(TokenKind.AND_OP, BinaryOperatorKind.AND); + + temp.put(TokenKind.EQ_OP, BinaryOperatorKind.EQ); + temp.put(TokenKind.NE_OP, BinaryOperatorKind.NE); + + temp.put(TokenKind.GT_OP, BinaryOperatorKind.GT); + temp.put(TokenKind.GE_OP, BinaryOperatorKind.GE); + temp.put(TokenKind.LT_OP, BinaryOperatorKind.LT); + temp.put(TokenKind.LE_OP, BinaryOperatorKind.LE); + + temp.put(TokenKind.ADD_OP, BinaryOperatorKind.ADD); + temp.put(TokenKind.SUB_OP, BinaryOperatorKind.SUB); + + temp.put(TokenKind.MUL_OP, BinaryOperatorKind.MUL); + temp.put(TokenKind.DIV_OP, BinaryOperatorKind.DIV); + temp.put(TokenKind.MOD_OP, BinaryOperatorKind.MOD); + + tokenToBinaryOperator = Collections.unmodifiableMap(temp); + } + + private static final Map<TokenKind, UnaryOperatorKind> tokenToUnaryOperator; + static { + Map<TokenKind, UnaryOperatorKind> temp = new HashMap<ExpressionParser.TokenKind, UnaryOperatorKind>(); + temp.put(TokenKind.MINUS, UnaryOperatorKind.MINUS); + temp.put(TokenKind.NOT, UnaryOperatorKind.NOT); + tokenToUnaryOperator = Collections.unmodifiableMap(temp); + } + + private static final Map<TokenKind, MethodKind> tokenToMethod; + static { + Map<TokenKind, MethodKind> temp = new HashMap<ExpressionParser.TokenKind, MethodKind>(); + temp.put(TokenKind.Cast, MethodKind.CAST); + temp.put(TokenKind.Ceiling, MethodKind.CEILING); + temp.put(TokenKind.Concat, MethodKind.CONCAT); + temp.put(TokenKind.Contains, MethodKind.CONTAINS); + temp.put(TokenKind.Date, MethodKind.DATE); + temp.put(TokenKind.Day, MethodKind.DAY); + temp.put(TokenKind.Endswith, MethodKind.ENDSWITH); + temp.put(TokenKind.Floor, MethodKind.FLOOR); + temp.put(TokenKind.Fractionalseconds, MethodKind.FRACTIONALSECONDS); + temp.put(TokenKind.GeoDistance, MethodKind.GEODISTANCE); + temp.put(TokenKind.GeoIntersects, MethodKind.GEOINTERSECTS); + temp.put(TokenKind.GeoLength, MethodKind.GEOLENGTH); + temp.put(TokenKind.Hour, MethodKind.HOUR); + temp.put(TokenKind.Indexof, MethodKind.INDEXOF); + temp.put(TokenKind.Isof, MethodKind.ISOF); + temp.put(TokenKind.Length, MethodKind.LENGTH); + temp.put(TokenKind.Maxdatetime, MethodKind.MAXDATETIME); + temp.put(TokenKind.Mindatetime, MethodKind.MINDATETIME); + temp.put(TokenKind.Minute, MethodKind.MINUTE); + temp.put(TokenKind.Month, MethodKind.MONTH); + temp.put(TokenKind.Now, MethodKind.NOW); + temp.put(TokenKind.Round, MethodKind.ROUND); + temp.put(TokenKind.Second, MethodKind.SECOND); + temp.put(TokenKind.Startswith, MethodKind.STARTSWITH); + temp.put(TokenKind.Substring, MethodKind.SUBSTRING); + temp.put(TokenKind.Time, MethodKind.TIME); + temp.put(TokenKind.Tolower, MethodKind.TOLOWER); + temp.put(TokenKind.Totaloffsetminutes, MethodKind.TOTALOFFSETMINUTES); + temp.put(TokenKind.Totalseconds, MethodKind.TOTALSECONDS); + temp.put(TokenKind.Toupper, MethodKind.TOUPPER); + temp.put(TokenKind.Trim, MethodKind.TRIM); + temp.put(TokenKind.Year, MethodKind.YEAR); + + tokenToMethod = Collections.unmodifiableMap(temp); + } + + private static final Map<TokenKind, EdmPrimitiveTypeKind> tokenToPrimitiveType; + static { + /* Enum and null are not present in the map. These have to be handled differently */ + Map<TokenKind, EdmPrimitiveTypeKind> temp = new HashMap<ExpressionParser.TokenKind, EdmPrimitiveTypeKind>(); + temp.put(TokenKind.PrimitiveBooleanValue, EdmPrimitiveTypeKind.Boolean); + temp.put(TokenKind.PrimitiveStringValue, EdmPrimitiveTypeKind.String); + // TODO:Check if int64 is correct here or if it has to be single instead + temp.put(TokenKind.PrimitiveIntegerValue, EdmPrimitiveTypeKind.Int64); + temp.put(TokenKind.PrimitiveGuidValue, EdmPrimitiveTypeKind.Guid); + temp.put(TokenKind.PrimitiveDateValue, EdmPrimitiveTypeKind.Date); + temp.put(TokenKind.PrimitiveDateTimeOffsetValue, EdmPrimitiveTypeKind.DateTimeOffset); + temp.put(TokenKind.PrimitiveTimeOfDayValue, EdmPrimitiveTypeKind.TimeOfDay); + temp.put(TokenKind.PrimitiveDecimalValue, EdmPrimitiveTypeKind.Decimal); + temp.put(TokenKind.PrimitiveDoubleValue, EdmPrimitiveTypeKind.Double); + temp.put(TokenKind.PrimitiveDurationValue, EdmPrimitiveTypeKind.Duration); + temp.put(TokenKind.PrimitiveBinaryValue, EdmPrimitiveTypeKind.Binary); + + tokenToPrimitiveType = Collections.unmodifiableMap(temp); + } + + public Expression parse(Tokenizer tokenizer) throws UriParserException { + // Initialize tokenizer. + this.tokenizer = tokenizer; + + return parseExpression(); + } + + private Expression parseExpression() throws UriParserException { + Expression left = parseAnd(); + + while (is(TokenKind.OR_OP) != null) { + tokenizer.getText(); + + Expression right = parseAnd(); + left = new BinaryImpl(left, BinaryOperatorKind.OR, right); + } + + return left; + } + + private Expression parseAnd() throws UriParserException { + Expression left = parseExprEquality(); + while (is(TokenKind.AND_OP) != null) { + tokenizer.getText(); + + Expression right = parseExprEquality(); + left = new BinaryImpl(left, BinaryOperatorKind.AND, right); + } + return left; + } + + private Expression parseExprEquality() throws UriParserException { + Expression left = parseExprRel(); + + TokenKind nextTokenKind = is(TokenKind.EQ_OP, TokenKind.NE_OP); + // Null for everything other than EQ or NE + while (nextTokenKind != null) { + tokenizer.getText(); + + Expression right = parseExprEquality(); + left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); + nextTokenKind = is(TokenKind.EQ_OP, TokenKind.NE_OP); + } + + return left; + } + + private Expression parseExprRel() throws UriParserException { + Expression left = parseExprAdd(); + + TokenKind nextTokenKind = is(TokenKind.GT_OP, TokenKind.GE_OP, TokenKind.LT_OP, TokenKind.LE_OP); + // Null for everything other than GT or GE or LT or LE + while (nextTokenKind != null) { + tokenizer.getText(); + + Expression right = parseExprAdd(); + left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); + nextTokenKind = is(TokenKind.GT_OP, TokenKind.GE_OP, TokenKind.LT_OP, TokenKind.LE_OP); + } + + return left; + } + + private Expression parseExprAdd() throws UriParserException { + Expression left = parseExprMul(); + + TokenKind nextTokenKind = is(TokenKind.ADD_OP, TokenKind.SUB_OP); + // Null for everything other than ADD or SUB + while (nextTokenKind != null) { + tokenizer.getText(); + + Expression right = parseExprMul(); + left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); + nextTokenKind = is(TokenKind.ADD_OP, TokenKind.SUB_OP); + } + + return left; + } + + private Expression parseExprMul() throws UriParserException { + Expression left = parseExprUnary(); + + TokenKind nextTokenKind = is(TokenKind.MUL_OP, TokenKind.DIV_OP, TokenKind.MOD_OP); + // Null for everything other than MUL or DIV or MOD + while (nextTokenKind != null) { + tokenizer.getText(); + + Expression right = parseExprUnary(); + left = new BinaryImpl(left, tokenToBinaryOperator.get(nextTokenKind), right); + nextTokenKind = is(TokenKind.MUL_OP, TokenKind.DIV_OP, TokenKind.MOD_OP); + } + + return left; + } + + private Expression parseExprUnary() throws UriParserException { + Expression left = null; + TokenKind nextTokenKind = is(TokenKind.MINUS, TokenKind.NOT); + // Null for everything other than - or NOT + while (nextTokenKind != null) { + tokenizer.getText(); + + Expression exp = parseExprValue(); + left = new UnaryImpl(tokenToUnaryOperator.get(nextTokenKind), exp); + nextTokenKind = is(TokenKind.MINUS, TokenKind.NOT); + } + + if (left == null) { + left = parseExprValue(); + } + + return left; + } + + private Expression parseExprValue() throws UriParserException { + if (is(TokenKind.OPEN) != null) { + tokenizer.getText(); + Expression exp = parseExpression(); + require(TokenKind.CLOSE); + return exp; + } + + if (is(TokenKind.ParameterAlias) != null) { + return new AliasImpl(tokenizer.getText()); + } + + if (is(TokenKind.RootExpr) != null) { + tokenizer.getText(); + // TODO: Consume $root Expression. + } + + TokenKind nextPrimitive = isPrimitive(); + if (nextPrimitive != null) { + EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(nextPrimitive); + EdmPrimitiveType type; + if (primitiveTypeKind == null) { + if (nextPrimitive == TokenKind.PrimitiveEnumValue) { + // TODO: Get enum type. + type = null; + } else { + // Null handling + type = null; + } + } else { + type = EdmPrimitiveTypeFactory.getInstance(primitiveTypeKind); + } + return new LiteralImpl(tokenizer.getText(), type); + } + + TokenKind nextMethod = isMethod(); + if (nextMethod != null) { + MethodKind methodKind = tokenToMethod.get(nextMethod); + List<Expression> parameters = new ArrayList<Expression>(); + // Consume Method name. + tokenizer.getText(); + if (is(TokenKind.CLOSE) != null) { + // Consume closing parenthesis. + tokenizer.getText(); + } else { + parameters.add(parseExpression()); + while (is(TokenKind.COMMA) != null) { + tokenizer.getText(); + parameters.add(parseExpression()); + } + require(TokenKind.CLOSE); + } + + MethodImpl methodImpl = new MethodImpl(methodKind, parameters); + validateMethodParameters(methodImpl); + + return methodImpl; + } + + throw new UriParserSyntaxException("Unexpected token", UriParserSyntaxException.MessageKeys.SYNTAX); + } + + private void validateMethodParameters(final Method method) throws UriParserException { + // We might validate parameter types in the future. + int size = method.getParameters().size(); + switch (method.getMethod()) { + // Must have two Parameters. + case CONTAINS: + case ENDSWITH: + case STARTSWITH: + case INDEXOF: + case CONCAT: + case GEODISTANCE: + case GEOINTERSECTS: + if (size != 2) { + throw new UriParserSemanticException( + "The method " + method.getMethod() + " needs exactly two parameters.", + null); // TODO: message key + } + break; + // Must have one parameter. + case LENGTH: + case TOLOWER: + case TOUPPER: + case TRIM: + case YEAR: + case MONTH: + case DAY: + case HOUR: + case MINUTE: + case SECOND: + case FRACTIONALSECONDS: + case DATE: + case TIME: + case TOTALOFFSETMINUTES: + case TOTALSECONDS: + case ROUND: + case FLOOR: + case CEILING: + case GEOLENGTH: + if (size != 1) { + throw new UriParserSemanticException( + "The method '" + method.getMethod() + "' needs exactly one parameter.", + null); // TODO: message key + } + break; + // Must have no parameter. + case NOW: + case MAXDATETIME: + case MINDATETIME: + if (size != 0) { + throw new UriParserSemanticException("The method '" + method.getMethod() + "' must have no parameters.", + null); // TODO: message key + } + break; + // Variable parameter number + case CAST: + case ISOF: + if (size < 1 || size > 2) { + throw new UriParserSemanticException( + "The method '" + method.getMethod() + "' must have one or two parameters.", + null); // TODO: message key + } + break; + case SUBSTRING: + if (size < 2 || size > 3) { + throw new UriParserSemanticException( + "The method '" + method.getMethod() + "' must have two or three parameters.", + null); // TODO: message key + } + break; + default: + throw new UriParserSemanticException( + "Unkown method '" + method.getMethod() + "'", + null); // TODO: message key + } + } + + private String require(TokenKind required) throws UriParserException { + if (is(required) == null) { + throw new UriParserSyntaxException("Required token: " + required, + UriParserSyntaxException.MessageKeys.SYNTAX); + } + return tokenizer.getText(); + } + + private TokenKind is(TokenKind... kind) { + for (int i = 0; i < kind.length; i++) { + if (tokenizer.next(kind[i])) { + return kind[i]; + } + } + return null; + } + + private TokenKind isMethod() { + return is(TokenKind.Cast, + TokenKind.Ceiling, + TokenKind.Concat, + TokenKind.Contains, + TokenKind.Date, + TokenKind.Day, + TokenKind.Endswith, + TokenKind.Floor, + TokenKind.Fractionalseconds, + TokenKind.GeoDistance, + TokenKind.GeoIntersects, + TokenKind.GeoLength, + TokenKind.Hour, + TokenKind.Indexof, + TokenKind.Isof, + TokenKind.Length, + TokenKind.Maxdatetime, + TokenKind.Mindatetime, + TokenKind.Minute, + TokenKind.Month, + TokenKind.Now, + TokenKind.Round, + TokenKind.Second, + TokenKind.Startswith, + TokenKind.Substring, + TokenKind.Time, + TokenKind.Tolower, + TokenKind.Totaloffsetminutes, + TokenKind.Totalseconds, + TokenKind.Toupper, + TokenKind.Trim, + TokenKind.Year); + } + + private TokenKind isPrimitive() { + return is(TokenKind.PrimitiveNullValue, + TokenKind.PrimitiveBooleanValue, + TokenKind.PrimitiveStringValue, + + // The order of the next seven expressions is important in order to avoid + // finding partly parsed tokens (counter-intuitive as it may be, even a GUID may start with digits ...). + TokenKind.PrimitiveDoubleValue, + TokenKind.PrimitiveDecimalValue, + TokenKind.PrimitiveGuidValue, + TokenKind.PrimitiveDateTimeOffsetValue, + TokenKind.PrimitiveDateValue, + TokenKind.PrimitiveTimeOfDayValue, + TokenKind.PrimitiveIntegerValue, + TokenKind.PrimitiveDurationValue, + TokenKind.PrimitiveBinaryValue, + TokenKind.PrimitiveEnumValue); + } + + public enum TokenKind { + // BINARY + OR_OP, + AND_OP, + + EQ_OP, + NE_OP, + + GT_OP, + GE_OP, + LT_OP, + LE_OP, + + ADD_OP, + SUB_OP, + + MUL_OP, + DIV_OP, + MOD_OP, + + MINUS, + NOT, + + // Grouping + OPEN, + CLOSE, + + // PrimitiveValues + PrimitiveNullValue, + PrimitiveBooleanValue, + + PrimitiveStringValue, + PrimitiveIntegerValue, + PrimitiveGuidValue, + PrimitiveDateValue, + PrimitiveDateTimeOffsetValue, + PrimitiveTimeOfDayValue, + PrimitiveDecimalValue, + PrimitiveDoubleValue, + PrimitiveDurationValue, + PrimitiveBinaryValue, + PrimitiveEnumValue, + + // ExpressionValues + ParameterAlias, + ArrayOrObject, + RootExpr, + IT, + + // BuiltInMethods + Cast, + Ceiling, + Concat, + Contains, + Date, + Day, + Endswith, + Floor, + Fractionalseconds, + GeoDistance, + GeoIntersects, + GeoLength, + Hour, + Indexof, + Isof, + Length, + Maxdatetime, + Mindatetime, + Minute, + Month, + Now, + Round, + Second, + Startswith, + Substring, + Time, + Tolower, + Totaloffsetminutes, + Totalseconds, + Toupper, + Trim, + Year, + COMMA + } + + public static class Token { + TokenKind kind; + String text; + + public Token(TokenKind kind, String text) { + this.kind = kind; + this.text = text; + } + } + + public static class Tokenizer { + private List<Token> tokens; + int counter = 0; + + public Tokenizer(List<Token> tokens) { + this.tokens = tokens; + } + + public boolean next(TokenKind expectedKind) { + if (counter < tokens.size() && expectedKind == tokens.get(counter).kind) { + return true; + } + return false; + } + + public String getText() { + String text = tokens.get(counter).text; + counter++; + return text; + } + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java index c58327b..3f7f70c 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java @@ -19,6 +19,7 @@ package org.apache.olingo.server.core.uri.parser; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -59,6 +60,7 @@ import org.apache.olingo.server.api.uri.UriResourcePartTyped; import org.apache.olingo.server.api.uri.UriResourceRoot; import org.apache.olingo.server.api.uri.queryoption.SelectItem; 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.MethodKind; import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind; import org.apache.olingo.server.core.uri.UriInfoImpl; @@ -82,7 +84,9 @@ import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl; import org.apache.olingo.server.core.uri.UriResourceTypedImpl; import org.apache.olingo.server.core.uri.UriResourceValueImpl; import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl; -import org.apache.olingo.server.core.uri.antlr.*; +import org.apache.olingo.server.core.uri.antlr.UriLexer; +import org.apache.olingo.server.core.uri.antlr.UriParserBaseVisitor; +import org.apache.olingo.server.core.uri.antlr.UriParserParser; import org.apache.olingo.server.core.uri.antlr.UriParserParser.AllEOFContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.AllExprContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltAddContext; @@ -96,7 +100,6 @@ import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltMultContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltOrContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.AnyExprContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.ArrayOrObjectContext; -import org.apache.olingo.server.core.uri.antlr.UriParserParser.BatchEOFContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.BinaryLiteralContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.BooleanNonCaseLiteralContext; import org.apache.olingo.server.core.uri.antlr.UriParserParser.CastExprContext; @@ -197,7 +200,6 @@ import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl; import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl; import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl; import org.apache.olingo.server.core.uri.queryoption.expression.EnumerationImpl; -import org.apache.olingo.server.core.uri.queryoption.expression.ExpressionImpl; import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl; import org.apache.olingo.server.core.uri.queryoption.expression.MemberImpl; import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl; @@ -725,26 +727,18 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { all.setLamdaVariable(ctx.vLV.getText()); context.allowedLambdaVariables.push(var); - all.setExpression((ExpressionImpl) ctx.vLE.accept(this)); + all.setExpression((Expression) ctx.vLE.accept(this)); context.allowedLambdaVariables.pop(); return all; } @Override - public ExpressionImpl visitAltAdd(final AltAddContext ctx) { - BinaryImpl binary = new BinaryImpl(); - + public Expression visitAltAdd(final AltAddContext ctx) { int tokenIndex = ctx.vO.getType(); - - if (tokenIndex == UriLexer.ADD) { - binary.setOperator(BinaryOperatorKind.ADD); - } else if (tokenIndex == UriLexer.SUB) { - binary.setOperator(BinaryOperatorKind.SUB); - } - - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - return binary; + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + tokenIndex == UriLexer.ADD ? BinaryOperatorKind.ADD : BinaryOperatorKind.SUB, + (Expression) ctx.vE2.accept(this)); } @Override @@ -756,14 +750,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { EdmType startType = removeUriResourceStartingTypeFilterImpl(uriInfoImplpath); - MemberImpl ret = new MemberImpl(); - - ret.setResourcePath(uriInfoImplpath); - if (startType != null) { - ret.setTypeFilter(startType); - } - - return ret; + return new MemberImpl(uriInfoImplpath, startType); } private EdmType removeUriResourceStartingTypeFilterImpl(final UriInfoImpl uriInfoImplpath) { @@ -794,14 +781,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitAltAnd(final AltAndContext ctx) { - BinaryImpl binary = new BinaryImpl(); - - binary.setOperator(BinaryOperatorKind.AND); - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - - return binary; + public Expression visitAltAnd(final AltAndContext ctx) { + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + BinaryOperatorKind.AND, + (Expression) ctx.vE2.accept(this)); } @Override @@ -812,39 +796,26 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { EdmType startType = removeUriResourceStartingTypeFilterImpl(uriInfoImplpath); - MemberImpl ret = new MemberImpl(); - ret.setResourcePath(uriInfoImplpath); - if (startType != null) { - ret.setTypeFilter(startType); - } - return ret; - } - - @Override - public Object visitBatchEOF(final BatchEOFContext ctx) { - context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.batch); - return null; + return new MemberImpl(uriInfoImplpath, startType); } @Override - public ExpressionImpl visitAltComparism(final AltComparismContext ctx) { - BinaryImpl binary = new BinaryImpl(); - + public Expression visitAltComparism(final AltComparismContext ctx) { int tokenIndex = ctx.vO.getType(); - + BinaryOperatorKind kind = null; if (tokenIndex == UriLexer.GT) { - binary.setOperator(BinaryOperatorKind.GT); + kind = BinaryOperatorKind.GT; } else if (tokenIndex == UriLexer.GE) { - binary.setOperator(BinaryOperatorKind.GE); + kind = BinaryOperatorKind.GE; } else if (tokenIndex == UriLexer.LT) { - binary.setOperator(BinaryOperatorKind.LT); + kind = BinaryOperatorKind.LT; } else if (tokenIndex == UriLexer.LE) { - binary.setOperator(BinaryOperatorKind.LE); + kind = BinaryOperatorKind.LE; } - - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - return binary; + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + kind, + (Expression) ctx.vE2.accept(this)); } @Override @@ -867,31 +838,20 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitAltEquality(final AltEqualityContext ctx) { - BinaryImpl binary = new BinaryImpl(); - + public Expression visitAltEquality(final AltEqualityContext ctx) { int tokenIndex = ctx.vO.getType(); - - if (tokenIndex == UriLexer.EQ_ALPHA) { - binary.setOperator(BinaryOperatorKind.EQ); - } else { - binary.setOperator(BinaryOperatorKind.NE); - } - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - - return binary; + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + tokenIndex == UriLexer.EQ_ALPHA ? BinaryOperatorKind.EQ : BinaryOperatorKind.NE, + (Expression) ctx.vE2.accept(this)); } @Override public Object visitAltHas(final AltHasContext ctx) { - BinaryImpl binary = new BinaryImpl(); - - binary.setOperator(BinaryOperatorKind.HAS); - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - - return binary; + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + BinaryOperatorKind.HAS, + (Expression) ctx.vE2.accept(this)); } @Override @@ -902,33 +862,28 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitAltMult(final AltMultContext ctx) { - BinaryImpl binary = new BinaryImpl(); - + public Expression visitAltMult(final AltMultContext ctx) { int tokenIndex = ctx.vO.getType(); - + BinaryOperatorKind kind; if (tokenIndex == UriLexer.MUL) { - binary.setOperator(BinaryOperatorKind.MUL); + kind = BinaryOperatorKind.MUL; } else if (tokenIndex == UriLexer.DIV) { - binary.setOperator(BinaryOperatorKind.DIV); + kind = BinaryOperatorKind.DIV; } else { - binary.setOperator(BinaryOperatorKind.MOD); + kind = BinaryOperatorKind.MOD; } - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - - return binary; + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + kind, + (Expression) ctx.vE2.accept(this)); } @Override - public ExpressionImpl visitAltOr(final AltOrContext ctx) { - BinaryImpl binary = new BinaryImpl(); - - binary.setOperator(BinaryOperatorKind.OR); - binary.setLeftOperand((ExpressionImpl) ctx.vE1.accept(this)); - binary.setRightOperand((ExpressionImpl) ctx.vE2.accept(this)); - - return binary; + public Expression visitAltOr(final AltOrContext ctx) { + return new BinaryImpl( + (Expression) ctx.vE1.accept(this), + BinaryOperatorKind.OR, + (Expression) ctx.vE2.accept(this)); } @Override @@ -954,7 +909,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { any.setLamdaVariable(ctx.vLV.getText()); context.allowedLambdaVariables.push(var); - any.setExpression((ExpressionImpl) ctx.vLE.accept(this)); + any.setExpression((Expression) ctx.vLE.accept(this)); context.allowedLambdaVariables.pop(); } return any; @@ -963,17 +918,16 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { @Override public Object visitBooleanNonCaseLiteral(final BooleanNonCaseLiteralContext ctx) { final String text = ctx.getText().toLowerCase(); - return new LiteralImpl().setText(text.equals("false") ? "false" : "true") - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)); + return new LiteralImpl(text.equals("false") ? "false" : "true", + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)); } @Override - public ExpressionImpl visitCastExpr(final CastExprContext ctx) { - MethodImpl method = new MethodImpl(); + public Expression visitCastExpr(final CastExprContext ctx) { + List<Expression> parameters = new ArrayList<Expression>(); if (ctx.vE1 != null) { // is optional parameter - ExpressionImpl onExpression = (ExpressionImpl) ctx.vE1.accept(this); - method.addParameter(onExpression); + parameters.add((Expression) ctx.vE1.accept(this)); } String namespace = ctx.vNS.getText(); @@ -981,9 +935,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { FullQualifiedName fullName = new FullQualifiedName(namespace, ctx.vODI.getText()); EdmType type = getType(fullName); - method.setMethod(MethodKind.CAST); - method.addParameter(new TypeLiteralImpl().setType(type)); - return method; + parameters.add(new TypeLiteralImpl(type)); + return new MethodImpl(MethodKind.CAST, parameters); } private EdmType getType(final FullQualifiedName fullName) { @@ -1022,18 +975,15 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitCeilingMethodCallExpr(final CeilingMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.CEILING) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitCeilingMethodCallExpr(final CeilingMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.CEILING, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitConcatMethodCallExpr(final ConcatMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.CONCAT) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitConcatMethodCallExpr(final ConcatMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.CONCAT, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override @@ -1090,47 +1040,38 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitContainsMethodCallExpr(final ContainsMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.CONTAINS) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitContainsMethodCallExpr(final ContainsMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.CONTAINS, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override public Object visitDateMethodCallExpr(final DateMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.DATE) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + return new MethodImpl(MethodKind.DATE, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitDayMethodCallExpr(final DayMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.DAY) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitDayMethodCallExpr(final DayMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.DAY, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitGeoDistanceMethodCallExpr(final GeoDistanceMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.GEODISTANCE) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitGeoDistanceMethodCallExpr(final GeoDistanceMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.GEODISTANCE, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override public Object visitEndsWithMethodCallExpr(final EndsWithMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.ENDSWITH) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + return new MethodImpl(MethodKind.ENDSWITH, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override public Object visitEnumLiteral(final EnumLiteralContext ctx) { - EnumerationImpl enum1 = new EnumerationImpl(); - // get type final String odi = ctx.vODI.getText(); @@ -1141,17 +1082,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { "Enum type '" + fullName.getFullQualifiedNameAsString() + "' not found!", UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, fullName.getFullQualifiedNameAsString())); } - enum1.setType(edmEnumType); String valueString = ctx.vValues.getText(); valueString = valueString.substring(1, valueString.length() - 1); - String[] values = valueString.split(","); - for (String item : values) { - enum1.addValue(item); - } - - return enum1; + return new EnumerationImpl(edmEnumType, Arrays.asList(values)); } @Override @@ -1343,7 +1278,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { @Override public Object visitFilter(final FilterContext ctx) { context.contextReadingQueryPart = true; - final FilterOptionImpl result = new FilterOptionImpl().setExpression((ExpressionImpl) ctx.children.get(2) + final FilterOptionImpl result = new FilterOptionImpl().setExpression((Expression) ctx.children.get(2) .accept(this)); context.contextReadingQueryPart = false; @@ -1353,7 +1288,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { @Override public Object visitFilterExpressionEOF(final FilterExpressionEOFContext ctx) { context.contextReadingQueryPart = true; - final FilterOptionImpl result = new FilterOptionImpl().setExpression((ExpressionImpl) ctx.children.get(0) + final FilterOptionImpl result = new FilterOptionImpl().setExpression((Expression) ctx.children.get(0) .accept(this)); context.contextReadingQueryPart = false; @@ -1361,39 +1296,30 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitFloorMethodCallExpr(final FloorMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.FLOOR) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitFloorMethodCallExpr(final FloorMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.FLOOR, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitFractionalsecondsMethodCallExpr(final FractionalsecondsMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.FRACTIONALSECONDS) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitFractionalsecondsMethodCallExpr(final FractionalsecondsMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.FRACTIONALSECONDS, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitGeoLengthMethodCallExpr(final GeoLengthMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.GEOLENGTH) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitGeoLengthMethodCallExpr(final GeoLengthMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.GEOLENGTH, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitHourMethodCallExpr(final HourMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.HOUR) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitHourMethodCallExpr(final HourMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.HOUR, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitIndexOfMethodCallExpr(final IndexOfMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.INDEXOF) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitIndexOfMethodCallExpr(final IndexOfMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.INDEXOF, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override @@ -1405,19 +1331,17 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitGeoIntersectsMethodCallExpr(final GeoIntersectsMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.GEOINTERSECTS) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitGeoIntersectsMethodCallExpr(final GeoIntersectsMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.GEOINTERSECTS, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override - public ExpressionImpl visitIsofExpr(final IsofExprContext ctx) { - MethodImpl method = new MethodImpl(); + public Expression visitIsofExpr(final IsofExprContext ctx) { + List<Expression> parameters = new ArrayList<Expression>(); if (ctx.vE1 != null) { - ExpressionImpl onExpression = (ExpressionImpl) ctx.vE1.accept(this); - method.addParameter(onExpression); + parameters.add((Expression) ctx.vE1.accept(this)); } String namespace = ctx.vNS.getText(); @@ -1425,17 +1349,14 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { FullQualifiedName fullName = new FullQualifiedName(namespace, ctx.vODI.getText()); EdmType type = getType(fullName); - method.setMethod(MethodKind.ISOF); - method.addParameter(new TypeLiteralImpl().setType(type)); + parameters.add(new TypeLiteralImpl(type)); - return method; + return new MethodImpl(MethodKind.ISOF, parameters); } @Override - public ExpressionImpl visitLengthMethodCallExpr(final LengthMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.LENGTH) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitLengthMethodCallExpr(final LengthMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.LENGTH, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override @@ -1457,9 +1378,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitMaxDateTimeMethodCallExpr(final MaxDateTimeMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.MAXDATETIME); + public Expression visitMaxDateTimeMethodCallExpr(final MaxDateTimeMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.MAXDATETIME, null); } @Override @@ -1501,33 +1421,22 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { EdmType startType = removeUriResourceStartingTypeFilterImpl(uriInfoImplpath); - MemberImpl ret = new MemberImpl(); - ret.setResourcePath(uriInfoImplpath); - if (startType != null) { - ret.setTypeFilter(startType); - } - - return ret; + return new MemberImpl(uriInfoImplpath, startType); } @Override - public ExpressionImpl visitMinDateTimeMethodCallExpr(final MinDateTimeMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.MINDATETIME); + public Expression visitMinDateTimeMethodCallExpr(final MinDateTimeMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.MINDATETIME, null); } @Override - public ExpressionImpl visitMinuteMethodCallExpr(final MinuteMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.MINUTE) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitMinuteMethodCallExpr(final MinuteMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.MINUTE, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitMonthMethodCallExpr(final MonthMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.MONTH) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitMonthMethodCallExpr(final MonthMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.MONTH, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override @@ -1537,9 +1446,9 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { // is single key predicate without a name String valueText = ctx.vVO.getText(); - ExpressionImpl expression = null; + Expression expression = null; try { - expression = (ExpressionImpl) ctx.vVO.accept(this); + expression = (Expression) ctx.vVO.accept(this); } catch (final RuntimeException e) { throw wrap(new UriParserSemanticException("Invalid key value: " + valueText, e, UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, valueText)); @@ -1763,7 +1672,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { if (ctx.vCOM != null) { final String text = ctx.vCOM.getText(); uriParameter.setText("null".equals(text) ? null : text); - uriParameter.setExpression((ExpressionImpl) ctx.vCOM.accept(this)); + uriParameter.setExpression((Expression) ctx.vCOM.accept(this)); } else { uriParameter.setAlias("@" + ctx.vALI.getText()); } @@ -1773,29 +1682,20 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { @Override public Object visitNaninfinityLiteral(final NaninfinityLiteralContext ctx) { - return new LiteralImpl().setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)).setText(ctx - .getText()); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)); } @Override - public ExpressionImpl visitNowMethodCallExpr(final NowMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.NOW); + public Expression visitNowMethodCallExpr(final NowMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.NOW, null); } @Override public Object visitNullruleLiteral(final NullruleLiteralContext ctx) { - return new LiteralImpl().setText("null"); + return new LiteralImpl("null", null); } - /* - * @Override - * public Object visitOdataRelativeUriEOF(final OdataRelativeUriEOFContext ctx) { - * contextUriInfo = null; - * super.visitOdataRelativeUriEOF(ctx); - * return contextUriInfo; - * } - */ @Override public Object visitOrderBy(final OrderByContext ctx) { @@ -1831,7 +1731,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { oItem.setDescending(true); } - oItem.setExpression((ExpressionImpl) ctx.vC.accept(this)); + oItem.setExpression((Expression) ctx.vC.accept(this)); return oItem; } @@ -1906,19 +1806,19 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } // TODO Implement geography types and set a proper type - return new LiteralImpl().setText(ctx.getText()); + return new LiteralImpl(ctx.getText(), null); } @Override public Object visitBinaryLiteral(BinaryLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)); } @Override public Object visitStringLiteral(final StringLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.String)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.String)); } @Override @@ -1928,7 +1828,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { EdmPrimitiveTypeKind.Double : EdmPrimitiveTypeKind.Decimal); - return new LiteralImpl().setText(ctx.getText()).setType(type); + return new LiteralImpl(ctx.getText(), type); } @Override @@ -1948,41 +1848,41 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { typeKind = EdmPrimitiveTypeKind.Int64; } } catch (NumberFormatException e) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)); } - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(typeKind)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(typeKind)); } @Override public Object visitDateLiteral(final DateLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Date)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Date)); } @Override public Object visitDatetimeoffsetLiteral(final DatetimeoffsetLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.DateTimeOffset)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.DateTimeOffset)); } @Override public Object visitDurationLiteral(final DurationLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Duration)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Duration)); } @Override public Object visitGuidLiteral(final GuidLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Guid)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Guid)); } @Override public Object visitTimeofdayLiteral(final TimeofdayLiteralContext ctx) { - return new LiteralImpl().setText(ctx.getText()) - .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.TimeOfDay)); + return new LiteralImpl(ctx.getText(), + EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.TimeOfDay)); } @Override @@ -1996,21 +1896,6 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { return qpList; } - /* - * @Override - * public Object visitResourcePath(final ResourcePathContext ctx) { - * if (ctx.vAll != null) { - * contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.all); - * } else if (ctx.vCJ != null) { - * ctx.vCJ.accept(this); - * } else if (ctx.vlPS != null) { - * UriInfoImpl uriInfoPath = new UriInfoImpl().setKind(UriInfoKind.resource); - * contextUriInfo = uriInfoPath; - * super.visitResourcePath(ctx); // visit all children of ctx - * } - * return contextUriInfo; - * } - */ @Override public Object visitRootExpr(final RootExprContext ctx) { @@ -2042,23 +1927,18 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { context.contextUriInfo = backupUriInfoPath; } - return new MemberImpl() - .setResourcePath(uriInfoImplpath); + return new MemberImpl(uriInfoImplpath, null); } @Override - public ExpressionImpl visitRoundMethodCallExpr(final RoundMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.ROUND) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitRoundMethodCallExpr(final RoundMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.ROUND, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitSecondMethodCallExpr(final SecondMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.SECOND) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitSecondMethodCallExpr(final SecondMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.SECOND, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override @@ -2344,33 +2224,28 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitStartsWithMethodCallExpr(final StartsWithMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.STARTSWITH) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)) - .addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitStartsWithMethodCallExpr(final StartsWithMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.STARTSWITH, Arrays.asList( + (Expression) ctx.vE1.accept(this), + (Expression) ctx.vE2.accept(this))); } @Override - public ExpressionImpl visitSubstringMethodCallExpr(final SubstringMethodCallExprContext ctx) { - MethodImpl ret = new MethodImpl(); - ret.setMethod(MethodKind.SUBSTRING); - ret.addParameter((ExpressionImpl) ctx.vE1.accept(this)); - ret.addParameter((ExpressionImpl) ctx.vE2.accept(this)); + public Expression visitSubstringMethodCallExpr(final SubstringMethodCallExprContext ctx) { + List<Expression> parameters = new ArrayList<Expression>(); + parameters.add((Expression) ctx.vE1.accept(this)); + parameters.add((Expression) ctx.vE2.accept(this)); if (ctx.vE3 != null) { - ret.addParameter((ExpressionImpl) ctx.vE3.accept(this)); + parameters.add((Expression) ctx.vE3.accept(this)); } - return ret; - + return new MethodImpl(MethodKind.SUBSTRING, parameters); } @Override - public ExpressionImpl visitTimeMethodCallExpr(final TimeMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.TIME) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitTimeMethodCallExpr(final TimeMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.TIME, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override @@ -2382,45 +2257,33 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitToLowerMethodCallExpr(final ToLowerMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.TOLOWER) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitToLowerMethodCallExpr(final ToLowerMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.TOLOWER, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitTotalOffsetMinutesMethodCallExpr(final TotalOffsetMinutesMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.TOTALOFFSETMINUTES) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitTotalOffsetMinutesMethodCallExpr(final TotalOffsetMinutesMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.TOTALOFFSETMINUTES, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitTotalsecondsMethodCallExpr(final TotalsecondsMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.TOTALSECONDS) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitTotalsecondsMethodCallExpr(final TotalsecondsMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.TOTALSECONDS, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitToUpperMethodCallExpr(final ToUpperMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.TOUPPER) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitToUpperMethodCallExpr(final ToUpperMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.TOUPPER, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitTrimMethodCallExpr(final TrimMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.TRIM) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitTrimMethodCallExpr(final TrimMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.TRIM, Collections.singletonList((Expression) ctx.vE1.accept(this))); } @Override - public ExpressionImpl visitYearMethodCallExpr(final YearMethodCallExprContext ctx) { - return new MethodImpl() - .setMethod(MethodKind.YEAR) - .addParameter((ExpressionImpl) ctx.vE1.accept(this)); + public Expression visitYearMethodCallExpr(final YearMethodCallExprContext ctx) { + return new MethodImpl(MethodKind.YEAR, Collections.singletonList((Expression) ctx.vE1.accept(this))); } private ParseCancellationException wrap(final UriParserException uriParserException) { @@ -2428,18 +2291,15 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { } @Override - public ExpressionImpl visitAltUnary(@NotNull final UriParserParser.AltUnaryContext ctx) { - UnaryImpl unary = new UnaryImpl(); - unary.setOperator(ctx.unary().NOT() == null ? UnaryOperatorKind.MINUS : UnaryOperatorKind.NOT); - unary.setOperand((ExpressionImpl) ctx.commonExpr().accept(this)); - return unary; + public Expression visitAltUnary(@NotNull final UriParserParser.AltUnaryContext ctx) { + return new UnaryImpl( + ctx.unary().NOT() == null ? UnaryOperatorKind.MINUS : UnaryOperatorKind.NOT, + (Expression) ctx.commonExpr().accept(this)); } @Override - public ExpressionImpl visitAltAlias(@NotNull final UriParserParser.AltAliasContext ctx) { - AliasImpl alias = new AliasImpl(); - alias.setParameter("@" + ctx.odataIdentifier().getChild(0).getText()); - return alias; + public Expression visitAltAlias(@NotNull final UriParserParser.AltAliasContext ctx) { + return new AliasImpl("@" + ctx.odataIdentifier().getChild(0).getText()); } @Override @@ -2455,7 +2315,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> { MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH, ctx.getText())); } - return new LiteralImpl().setText(ctx.getText()).setType(null); + return new LiteralImpl(ctx.getText(), null); } @Override http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java index aac33f0..71c728c 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java @@ -19,11 +19,11 @@ package org.apache.olingo.server.core.uri.queryoption; import org.apache.olingo.server.api.uri.queryoption.OrderByItem; -import org.apache.olingo.server.core.uri.queryoption.expression.ExpressionImpl; +import org.apache.olingo.server.api.uri.queryoption.expression.Expression; public class OrderByItemImpl implements OrderByItem { - private ExpressionImpl expression; + private Expression expression; private boolean descending = false; // default sort order is ascending @Override @@ -37,11 +37,11 @@ public class OrderByItemImpl implements OrderByItem { } @Override - public ExpressionImpl getExpression() { + public Expression getExpression() { return expression; } - public OrderByItem setExpression(final ExpressionImpl expression) { + public OrderByItem setExpression(final Expression expression) { this.expression = expression; return this; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/208f26c7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java index 5309d73..c7d7c20 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java @@ -23,15 +23,11 @@ import org.apache.olingo.server.api.uri.queryoption.expression.Alias; import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException; import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor; -public class AliasImpl extends ExpressionImpl implements Alias { +public class AliasImpl implements Alias { - private String parameterName; + private final String parameterName; - public AliasImpl() { - //TODO: Delete Constructor - } - - public AliasImpl(String parameterName) { + public AliasImpl(final String parameterName) { this.parameterName = parameterName; } @@ -40,10 +36,6 @@ public class AliasImpl extends ExpressionImpl implements Alias { return parameterName; } - public void setParameter(final String ParameterName) { - parameterName = ParameterName; - } - @Override public <T> T accept(final ExpressionVisitor<T> visitor) throws ExpressionVisitException, ODataApplicationException { return visitor.visitAlias(parameterName);
