[OLINGO-1028] stricter multiplicity tests in expression parser + clean-up

Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
Klaus Straubinger 2016-09-29 16:25:33 +02:00 committed by Christian Amend
parent b9a71ff88a
commit 72fcaa1a54
13 changed files with 6389 additions and 7218 deletions

View File

@ -180,15 +180,19 @@ public class ExpressionParser {
this.crossjoinEntitySetNames = crossjoinEntitySetNames;
this.aliases = aliases;
return parseExpression();
final Expression expression = parseExpression();
checkNoCollection(expression);
return expression;
}
private Expression parseExpression() throws UriParserException, UriValidationException {
Expression left = parseAnd();
while (tokenizer.next(TokenKind.OrOperator)) {
final Expression right = parseAnd();
checkType(left, EdmPrimitiveTypeKind.Boolean);
checkNoCollection(left);
final Expression right = parseAnd();
checkType(right, EdmPrimitiveTypeKind.Boolean);
checkNoCollection(right);
left = new BinaryImpl(left, BinaryOperatorKind.OR, right,
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean));
}
@ -198,9 +202,11 @@ public class ExpressionParser {
private Expression parseAnd() throws UriParserException, UriValidationException {
Expression left = parseExprEquality();
while (tokenizer.next(TokenKind.AndOperator)) {
final Expression right = parseExprEquality();
checkType(left, EdmPrimitiveTypeKind.Boolean);
checkNoCollection(left);
final Expression right = parseExprEquality();
checkType(right, EdmPrimitiveTypeKind.Boolean);
checkNoCollection(right);
left = new BinaryImpl(left, BinaryOperatorKind.AND, right,
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean));
}
@ -285,8 +291,8 @@ public class ExpressionParser {
TokenKind.MulOperator, TokenKind.DivOperator, TokenKind.ModOperator);
// Null for everything other than MUL or DIV or MOD
while (operatorTokenKind != null) {
final Expression right = parseExprUnary();
checkNumericType(left);
final Expression right = parseExprUnary();
checkNumericType(right);
left = new BinaryImpl(left, tokenToBinaryOperator.get(operatorTokenKind), right,
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Double));
@ -306,6 +312,7 @@ public class ExpressionParser {
} else if (tokenizer.next(TokenKind.NotOperator)) {
final Expression expression = parseExprPrimary();
checkType(expression, EdmPrimitiveTypeKind.Boolean);
checkNoCollection(expression);
return new UnaryImpl(UnaryOperatorKind.NOT, expression, getType(expression));
} else if (tokenizer.next(TokenKind.CastMethod)) {
return parseIsOfOrCastMethod(MethodKind.CAST);
@ -443,6 +450,7 @@ public class ExpressionParser {
case TRIM:
final Expression stringParameter = parseExpression();
checkType(stringParameter, EdmPrimitiveTypeKind.String);
checkNoCollection(stringParameter);
parameters.add(stringParameter);
break;
case YEAR:
@ -450,6 +458,7 @@ public class ExpressionParser {
case DAY:
final Expression dateParameter = parseExpression();
checkType(dateParameter, EdmPrimitiveTypeKind.Date, EdmPrimitiveTypeKind.DateTimeOffset);
checkNoCollection(dateParameter);
parameters.add(dateParameter);
break;
case HOUR:
@ -458,6 +467,7 @@ public class ExpressionParser {
case FRACTIONALSECONDS:
final Expression timeParameter = parseExpression();
checkType(timeParameter, EdmPrimitiveTypeKind.TimeOfDay, EdmPrimitiveTypeKind.DateTimeOffset);
checkNoCollection(timeParameter);
parameters.add(timeParameter);
break;
case DATE:
@ -465,11 +475,13 @@ public class ExpressionParser {
case TOTALOFFSETMINUTES:
final Expression dateTimeParameter = parseExpression();
checkType(dateTimeParameter, EdmPrimitiveTypeKind.DateTimeOffset);
checkNoCollection(dateTimeParameter);
parameters.add(dateTimeParameter);
break;
case TOTALSECONDS:
final Expression durationParameter = parseExpression();
checkType(durationParameter, EdmPrimitiveTypeKind.Duration);
checkNoCollection(durationParameter);
parameters.add(durationParameter);
break;
case ROUND:
@ -478,12 +490,14 @@ public class ExpressionParser {
final Expression decimalParameter = parseExpression();
checkType(decimalParameter,
EdmPrimitiveTypeKind.Decimal, EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double);
checkNoCollection(decimalParameter);
parameters.add(decimalParameter);
break;
case GEOLENGTH:
final Expression geoParameter = parseExpression();
checkType(geoParameter,
EdmPrimitiveTypeKind.GeographyLineString, EdmPrimitiveTypeKind.GeometryLineString);
checkNoCollection(geoParameter);
parameters.add(geoParameter);
break;
@ -495,30 +509,36 @@ public class ExpressionParser {
case CONCAT:
final Expression stringParameter1 = parseExpression();
checkType(stringParameter1, EdmPrimitiveTypeKind.String);
checkNoCollection(stringParameter1);
parameters.add(stringParameter1);
ParserHelper.requireNext(tokenizer, TokenKind.COMMA);
final Expression stringParameter2 = parseExpression();
checkType(stringParameter2, EdmPrimitiveTypeKind.String);
checkNoCollection(stringParameter2);
parameters.add(stringParameter2);
break;
case GEODISTANCE:
final Expression geoParameter1 = parseExpression();
checkType(geoParameter1, EdmPrimitiveTypeKind.GeographyPoint, EdmPrimitiveTypeKind.GeometryPoint);
checkNoCollection(geoParameter1);
parameters.add(geoParameter1);
ParserHelper.requireNext(tokenizer, TokenKind.COMMA);
final Expression geoParameter2 = parseExpression();
checkType(geoParameter2, EdmPrimitiveTypeKind.GeographyPoint, EdmPrimitiveTypeKind.GeometryPoint);
checkNoCollection(geoParameter2);
parameters.add(geoParameter2);
break;
case GEOINTERSECTS:
final Expression geoPointParameter = parseExpression();
checkType(geoPointParameter,
EdmPrimitiveTypeKind.GeographyPoint, EdmPrimitiveTypeKind.GeometryPoint);
checkNoCollection(geoPointParameter);
parameters.add(geoPointParameter);
ParserHelper.requireNext(tokenizer, TokenKind.COMMA);
final Expression geoPolygonParameter = parseExpression();
checkType(geoPolygonParameter,
EdmPrimitiveTypeKind.GeographyPolygon, EdmPrimitiveTypeKind.GeometryPolygon);
checkNoCollection(geoPolygonParameter);
parameters.add(geoPolygonParameter);
break;
@ -526,6 +546,7 @@ public class ExpressionParser {
case SUBSTRING:
final Expression parameterFirst = parseExpression();
checkType(parameterFirst, EdmPrimitiveTypeKind.String);
checkNoCollection(parameterFirst);
parameters.add(parameterFirst);
ParserHelper.requireNext(tokenizer, TokenKind.COMMA);
final Expression parameterSecond = parseExpression();
@ -905,8 +926,9 @@ public class ExpressionParser {
} else if (tokenizer.next(TokenKind.ALL)) {
uriInfo.addResourcePart(parseLambdaRest(TokenKind.ALL, lastResource));
} else if (tokenizer.next(TokenKind.QualifiedName)) {
final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText());
parseBoundFunction(fullQualifiedName, uriInfo, lastResource);
parseBoundFunction(new FullQualifiedName(tokenizer.getText()), uriInfo, lastResource);
} else {
throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX);
}
}
@ -1071,13 +1093,22 @@ public class ExpressionParser {
}
}
private void checkNoCollection(final Expression expression) throws UriParserException {
if (expression instanceof Member && ((Member) expression).isCollection()) {
throw new UriParserSemanticException("Collection not allowed.",
UriParserSemanticException.MessageKeys.COLLECTION_NOT_ALLOWED);
}
}
protected void checkIntegerType(final Expression expression) throws UriParserException {
checkNoCollection(expression);
checkType(expression,
EdmPrimitiveTypeKind.Int64, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int16,
EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte);
}
protected void checkNumericType(final Expression expression) throws UriParserException {
checkNoCollection(expression);
checkType(expression,
EdmPrimitiveTypeKind.Int64, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int16,
EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
@ -1085,6 +1116,9 @@ public class ExpressionParser {
}
private void checkEqualityTypes(final Expression left, final Expression right) throws UriParserException {
checkNoCollection(left);
checkNoCollection(right);
final EdmType leftType = getType(left);
final EdmType rightType = getType(right);
if (leftType == null || rightType == null || leftType.equals(rightType)) {
@ -1141,11 +1175,10 @@ public class ExpressionParser {
}
private void checkRelationTypes(final Expression left, final Expression right) throws UriParserException {
checkNoCollection(left);
checkNoCollection(right);
final EdmType leftType = getType(left);
final EdmType rightType = getType(right);
if (leftType == null || rightType == null) {
return;
}
checkType(left,
EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64,
EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
@ -1160,6 +1193,9 @@ public class ExpressionParser {
EdmPrimitiveTypeKind.Boolean, EdmPrimitiveTypeKind.Guid, EdmPrimitiveTypeKind.String,
EdmPrimitiveTypeKind.Date, EdmPrimitiveTypeKind.TimeOfDay,
EdmPrimitiveTypeKind.DateTimeOffset, EdmPrimitiveTypeKind.Duration);
if (leftType == null || rightType == null) {
return;
}
if (!(((EdmPrimitiveType) leftType).isCompatible((EdmPrimitiveType) rightType)
|| ((EdmPrimitiveType) rightType).isCompatible((EdmPrimitiveType) leftType))) {
throw new UriParserSemanticException("Incompatible types.",
@ -1171,11 +1207,10 @@ public class ExpressionParser {
private EdmType getAddSubTypeAndCheckLeftAndRight(final Expression left, final Expression right, final boolean isSub)
throws UriParserException {
checkNoCollection(left);
checkNoCollection(right);
final EdmType leftType = getType(left);
final EdmType rightType = getType(right);
if (leftType == null || rightType == null) {
return null;
}
if (isType(leftType,
EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64,
EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,

View File

@ -74,7 +74,8 @@ public class UriParserSemanticException extends UriParserException {
/** parameter: expression */
ONLY_FOR_PRIMITIVE_TYPES,
/** parameter: function name */
FUNCTION_MUST_USE_COLLECTIONS;
FUNCTION_MUST_USE_COLLECTIONS,
COLLECTION_NOT_ALLOWED;
@Override
public String getKey() {

View File

@ -21,6 +21,8 @@ package org.apache.olingo.server.core.uri.queryoption.expression;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
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.Member;
@ -85,14 +87,10 @@ public class MemberImpl implements Member {
@Override
public boolean isCollection() {
UriInfoImpl uriInfo = (UriInfoImpl) path;
UriResourceImpl lastResourcePart = (UriResourceImpl) uriInfo.getLastResourcePart();
if (lastResourcePart instanceof UriResourceTypedImpl) {
UriResourceTypedImpl lastTyped = (UriResourceTypedImpl) lastResourcePart;
return lastTyped.isCollection();
} else if (lastResourcePart instanceof UriResourceActionImpl) {
return ((UriResourceActionImpl) lastResourcePart).isCollection();
}
return false;
UriResource lastResourcePart = uriInfo.getLastResourcePart();
return lastResourcePart instanceof UriResourcePartTyped ?
((UriResourcePartTyped) lastResourcePart).isCollection() :
false;
}
@Override

View File

@ -76,6 +76,7 @@ UriParserSemanticException.NOT_A_MEDIA_RESOURCE=The resource '%1$s' is not a med
UriParserSemanticException.IS_PROPERTY=The identifier '%1$s' is already used as a property.
UriParserSemanticException.ONLY_FOR_PRIMITIVE_TYPES='%1$s' is only allowed for primitive-type expressions.
UriParserSemanticException.FUNCTION_MUST_USE_COLLECTIONS=Only bound functions with collections of structural types as binding parameter and as return type are allowed; '%1$s' is not such a function.
UriParserSemanticException.COLLECTION_NOT_ALLOWED=A collection expression is not allowed.
UriValidationException.UNSUPPORTED_QUERY_OPTION=The query option '%1$s' is not supported.
UriValidationException.UNSUPPORTED_URI_KIND=The URI kind '%1$s' is not supported.

View File

@ -0,0 +1,561 @@
/*
* 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.Collections;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException.MessageKeys;
import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
import org.junit.Test;
/** Tests of the parts of the URI parser that parse the sytem query option $expand. */
public class ExpandParserTest {
private static final Edm edm = OData.newInstance().createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
@Test
public void expandStar() throws Exception {
testUri.run("ESKeyNav(1)", "$expand=*")
.isKind(UriInfoKind.resource).goExpand()
.first()
.isSegmentStar();
testUri.run("ESKeyNav(1)", "$expand=*/$ref")
.isKind(UriInfoKind.resource).goExpand()
.first()
.isSegmentStar()
.isSegmentRef();
testUri.run("ESKeyNav(1)", "$expand=*/$ref,NavPropertyETKeyNavMany")
.isKind(UriInfoKind.resource).goExpand()
.first()
.isSegmentStar().isSegmentRef()
.next()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true);
testUri.run("ESKeyNav(1)", "$expand=*($levels=3)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.isSegmentStar()
.isLevelText("3");
testUri.run("ESKeyNav(1)", "$expand=*($levels=max)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.isSegmentStar()
.isLevelText("max");
}
@Test
public void expandNavigationRef() throws Exception {
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef();
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne/$ref")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav, false)
.n().isRef();
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($filter=PropertyInt16 eq 1)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator().goFilter().is("<<PropertyInt16> eq <1>>");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($orderby=PropertyInt16)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.isSortOrder(0, false)
.goOrder(0).goPath().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($skip=1)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.isSkipText("1");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($top=2)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.isTopText("2");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($count=true)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.isInlineCountText("true");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($skip=1;$top=3)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.isSkipText("1")
.isTopText("3");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($skip=1%3b$top=3)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.isSkipText("1")
.isTopText("3");
}
@Test
public void expandNavigationCount() throws Exception {
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$count")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isCount();
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne/$count")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav, false)
.n().isCount();
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$count($filter=PropertyInt16 gt 1)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.n().isCount()
.goUpExpandValidator()
.goFilter().is("<<PropertyInt16> gt <1>>");
}
@Test
public void expandNavigationOptions() throws Exception {
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($filter=PropertyInt16 eq 1)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator().goFilter().is("<<PropertyInt16> eq <1>>");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($orderby=PropertyInt16)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isSortOrder(0, false)
.goOrder(0).goPath().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($skip=1)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isSkipText("1");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($top=2)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isTopText("2");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($count=true)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isInlineCountText("true");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($select=PropertyString)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.goSelectItem(0).isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($expand=NavPropertyETTwoKeyNavOne)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.goExpand()
.goPath().first()
.isNavProperty("NavPropertyETTwoKeyNavOne", EntityTypeProvider.nameETTwoKeyNav, false);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($expand=NavPropertyETKeyNavMany)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.goExpand()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne($levels=5)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav, false)
.goUpExpandValidator()
.isLevelText("5");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($select=PropertyString)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.goSelectItem(0).isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne($levels=max)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav, false)
.goUpExpandValidator()
.isLevelText("max");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($skip=1;$top=2)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isSkipText("1")
.isTopText("2");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($skip=1%3b$top=2)")
.isKind(UriInfoKind.resource).goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isSkipText("1")
.isTopText("2");
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($search=Country AND Western)")
.isKind(UriInfoKind.resource).goExpand()
.first().goPath().first().isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.goUpExpandValidator()
.isSearchSerialized("{'Country' AND 'Western'}");
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='Hugo')", "$expand=NavPropertyETKeyNavMany")
.isKind(UriInfoKind.resource).goPath()
.first()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'Hugo'")
.goUpUriValidator().goExpand()
.first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav, true);
}
@Test
public void expandTypeCasts() throws Exception {
testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETKeyNavMany")
.isKind(UriInfoKind.resource)
.goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='Hugo')",
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETKeyNavMany")
.isKind(UriInfoKind.resource).goPath().first()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'Hugo'")
.goUpUriValidator().goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isType(EntityTypeProvider.nameETKeyNav)
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')",
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany")
.isKind(UriInfoKind.resource).goPath().first()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'2'")
.goUpUriValidator().goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isType(EntityTypeProvider.nameETTwoKeyNav)
.isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')",
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany/olingo.odata.test1.ETTwoBaseTwoKeyNav")
.isKind(UriInfoKind.resource).goPath().first()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'2'")
.goUpUriValidator().goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.isTypeFilterOnCollection(EntityTypeProvider.nameETTwoBaseTwoKeyNav);
testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/NavPropertyETTwoKeyNavOne")
.isKind(UriInfoKind.resource)
.goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false)
.n()
.isNavProperty("NavPropertyETTwoKeyNavOne", EntityTypeProvider.nameETTwoKeyNav, false);
testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/*")
.isKind(UriInfoKind.resource)
.goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.isSegmentStar()
.goPath().first().isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false);
testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav"
+ "/olingo.odata.test1.CTTwoBasePrimCompNav/NavPropertyETTwoKeyNavOne")
.isKind(UriInfoKind.resource)
.goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false)
.isTypeFilter(ComplexTypeProvider.nameCTTwoBasePrimCompNav)
.n()
.isNavProperty("NavPropertyETTwoKeyNavOne", EntityTypeProvider.nameETTwoKeyNav, false);
testUri.run("ESKeyNav", "$expand=NavPropertyETTwoKeyNavMany/Namespace1_Alias.ETBaseTwoKeyNav"
+ "($expand=NavPropertyETBaseTwoKeyNavOne)")
.isKind(UriInfoKind.resource)
.goExpand().goPath().first()
.isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.isType(EntityTypeProvider.nameETTwoKeyNav, true)
.isTypeFilterOnCollection(EntityTypeProvider.nameETBaseTwoKeyNav)
.goUpExpandValidator()
// go to the expand options of the current expand
.goExpand()
.goPath().first()
.isNavProperty("NavPropertyETBaseTwoKeyNavOne", EntityTypeProvider.nameETBaseTwoKeyNav, false);
testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref,NavPropertyETTwoKeyNavMany($skip=2;$top=1)")
.isKind(UriInfoKind.resource)
.goExpand().first()
.goPath()
.first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.n().isRef()
.goUpExpandValidator()
.next()
.goPath()
.first().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.goUpExpandValidator()
.isSkipText("2")
.isTopText("1");
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')", "$expand=olingo.odata.test1.ETBaseTwoKeyNav"
+ "/NavPropertyETTwoKeyNavMany/olingo.odata.test1.ETTwoBaseTwoKeyNav($select=PropertyString)")
.isKind(UriInfoKind.resource).goPath()
.first()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'2'")
.goUpUriValidator().goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
.isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.isType(EntityTypeProvider.nameETTwoKeyNav)
.isTypeFilterOnCollection(EntityTypeProvider.nameETTwoBaseTwoKeyNav)
.goUpExpandValidator()
.goSelectItem(0).isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
testUri.run("ESKeyNav", "$expand=NavPropertyETKeyNavOne($expand=NavPropertyETKeyNavMany("
+ "$expand=NavPropertyETKeyNavOne))")
.isKind(UriInfoKind.resource)
.goExpand().first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav)
.goUpExpandValidator()
.goExpand().first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true)
.isType(EntityTypeProvider.nameETKeyNav)
.goUpExpandValidator()
.goExpand().first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav);
testUri.run("ESKeyNav", "$expand=NavPropertyETKeyNavOne($select=PropertyInt16)")
.isKind(UriInfoKind.resource)
.goExpand().first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav)
.goUpExpandValidator()
.goSelectItem(0).isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.run("ESKeyNav", "$expand=NavPropertyETKeyNavOne($select=PropertyCompNav/PropertyInt16)")
.isKind(UriInfoKind.resource)
.goExpand().first()
.goPath().first()
.isNavProperty("NavPropertyETKeyNavOne", EntityTypeProvider.nameETKeyNav, false)
.isType(EntityTypeProvider.nameETKeyNav)
.goUpExpandValidator()
.goSelectItem(0)
.first().isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTNavFiveProp, false)
.n().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.runEx("ESKeyNav", "$expand=undefined")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESTwoKeyNav", "$expand=PropertyCompNav/undefined")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESTwoKeyNav", "$expand=PropertyCompNav/*+")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
}
@Test
public void duplicatedSystemQueryOptionsInExpand() throws Exception {
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($select=PropertyInt16;$select=PropertyInt16)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($filter=true;$filter=true)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($orderby=PropertyInt16;$orderby=PropertyInt16)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($levels=2;$levels=3)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($expand=*;$expand=*)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($count=true;$count=true)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($top=1;$top=1)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($skip=2;$skip=2)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($search=Test;$search=Test)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
}
@Test
public void simpleKeyInExpandSystemQueryOption() throws Exception {
testUri.runEx("ESAllPrim(0)", "$expand=NavPropertyETTwoPrimMany(-365)($filter=PropertyString eq 'Test String1')")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@Test
public void compoundKeyInExpandSystemQueryOption() throws Exception {
testUri.runEx("ESAllPrim(0)", "$expand=NavPropertyETTwoPrimMany(PropertyInt16=1,PropertyString=2)"
+ "($filter=PropertyString eq 'Test String1')")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@Test
public void keyPredicatesInExpandFilter() throws Exception {
testUri.run("ESKeyNav(0)", "$expand=NavPropertyETTwoKeyNavMany($filter=NavPropertyETTwoKeyNavMany"
+ "(PropertyInt16=1,PropertyString='2')/PropertyInt16 eq 1)").goExpand()
.first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.goUpExpandValidator().goFilter()
.is("<<NavPropertyETTwoKeyNavMany/PropertyInt16> eq <1>>");
}
@Test
public void keyPredicatesInDoubleExpandedFilter() throws Exception {
testUri.run("ESKeyNav(0)", "$expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany"
+ "($filter=NavPropertyETTwoKeyNavMany(PropertyInt16=1,PropertyString='2')/PropertyInt16 eq 1))")
.goExpand()
.first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.goUpExpandValidator().goExpand()
.first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", EntityTypeProvider.nameETTwoKeyNav, true)
.goUpExpandValidator().goFilter()
.is("<<NavPropertyETTwoKeyNavMany/PropertyInt16> eq <1>>");
}
}

View File

@ -0,0 +1,187 @@
/*
* 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.Collections;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.core.uri.parser.search.SearchParserException;
import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Test;
/** Tests of the parts of the URI parser that parse the sytem query option $search. */
public class SearchParserTest {
private static final Edm edm = OData.newInstance().createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
@Test
public void search() throws Exception {
testUri.run("ESTwoKeyNav", "$search=abc");
testUri.run("ESTwoKeyNav", "$search=NOT abc");
testUri.run("ESTwoKeyNav", "$search=abc AND def");
testUri.run("ESTwoKeyNav", "$search=abc OR def");
testUri.run("ESTwoKeyNav", "$search=abc def");
testUri.run("ESTwoKeyNav", "$search=abc AND def AND ghi");
testUri.run("ESTwoKeyNav", "$search=abc AND def OR ghi");
testUri.run("ESTwoKeyNav", "$search=abc AND def ghi");
testUri.run("ESTwoKeyNav", "$search=abc OR def AND ghi");
testUri.run("ESTwoKeyNav", "$search=abc OR def OR ghi");
testUri.run("ESTwoKeyNav", "$search=abc OR def ghi");
testUri.run("ESTwoKeyNav", "$search=abc def AND ghi");
testUri.run("ESTwoKeyNav", "$search=abc def OR ghi");
testUri.run("ESTwoKeyNav", "$search=abc def ghi");
// mixed not
testUri.run("ESTwoKeyNav", "$search= abc def AND ghi");
testUri.run("ESTwoKeyNav", "$search=NOT abc NOT def OR NOT ghi");
testUri.run("ESTwoKeyNav", "$search= abc def NOT ghi");
// parenthesis
testUri.run("ESTwoKeyNav", "$search=(abc)");
testUri.run("ESTwoKeyNav", "$search=(abc AND def)");
testUri.run("ESTwoKeyNav", "$search=(abc AND def) OR ghi ");
testUri.run("ESTwoKeyNav", "$search=(abc AND def) ghi ");
testUri.run("ESTwoKeyNav", "$search=abc AND (def OR ghi)");
testUri.run("ESTwoKeyNav", "$search=abc AND (def ghi)");
// search in function-import return value
testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)", "$search=test");
// percent encoded characters
testUri.run("ESTwoKeyNav", "$search=%41%42%43");
testUri.run("ESTwoKeyNav", "$search=\"100%25\"");
// escaped characters
testUri.run("ESTwoKeyNav", "$search=\"abc\"");
testUri.run("ESTwoKeyNav", "$search=\"a\\\"bc\"");
testUri.run("ESTwoKeyNav", "$search=%22abc%22");
testUri.run("ESTwoKeyNav", "$search=%22a%5C%22bc%22");
testUri.run("ESTwoKeyNav", "$search=%22a%5C%5Cbc%22");
// wrong escaped characters
testUri.runEx("ESTwoKeyNav", "$search=%22a%22bc%22")
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
testUri.runEx("ESTwoKeyNav", "$search=%22a%5Cbc%22")
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
testUri.runEx("ESTwoKeyNav", "$search=not%27allowed")
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
}
@Test
public void searchTree() throws Exception {
testUri.run("ESTwoKeyNav", "$expand=NavPropertyETKeyNavMany($search=(abc AND def) OR NOT ghi)")
.goExpand().isSearchSerialized("{{'abc' AND 'def'} OR {NOT 'ghi'}}");
}
/**
* See <a href=
* "https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-testcases.xml">test
* cases at OASIS</a>.
*/
@Test
public void searchQueryPhraseAbnfTestcases() throws Exception {
// <TestCase Name="5.1.7 Search - simple phrase" Rule="queryOptions">
testUri.run("ESTwoKeyNav", "$search=\"blue%20green\"");
// <TestCase Name="5.1.7 Search - simple phrase" Rule="queryOptions">
testUri.run("ESTwoKeyNav", "$search=\"blue%20green%22");
// <TestCase Name="5.1.7 Search - phrase with escaped double-quote" Rule="queryOptions">
// <Input>$search="blue\"green"</Input>
testUri.run("ESTwoKeyNav", "$search=\"blue\\\"green\"");
// <TestCase Name="5.1.7 Search - phrase with escaped backslash" Rule="queryOptions">
// <Input>$search="blue\\green"</Input>
testUri.run("ESTwoKeyNav", "$search=\"blue\\\\green\"");
// <TestCase Name="5.1.7 Search - phrase with unescaped double-quote" Rule="queryOptions" FailAt="14">
testUri.runEx("ESTwoKeyNav", "$search=\"blue\"green\"")
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
// <TestCase Name="5.1.7 Search - phrase with unescaped double-quote" Rule="queryOptions" FailAt="16">
testUri.runEx("ESTwoKeyNav", "$search=\"blue%22green\"")
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
// <TestCase Name="5.1.7 Search - implicit AND" Rule="queryOptions">
// <Input>$search=blue green</Input>
// SearchassertQuery("\"blue%20green\"").resultsIn();
testUri.run("ESTwoKeyNav", "$search=blue green");
// <TestCase Name="5.1.7 Search - implicit AND, encoced" Rule="queryOptions">
// SearchassertQuery("blue%20green").resultsIn();
testUri.run("ESTwoKeyNav", "$search=blue%20green");
// <TestCase Name="5.1.7 Search - AND" Rule="queryOptions">
// <Input>$search=blue AND green</Input>
testUri.run("ESTwoKeyNav", "$search=blue AND green");
// <TestCase Name="5.1.7 Search - OR" Rule="queryOptions">
// <Input>$search=blue OR green</Input>
testUri.run("ESTwoKeyNav", "$search=blue OR green");
// <TestCase Name="5.1.7 Search - NOT" Rule="queryOptions">
// <Input>$search=blue NOT green</Input>
testUri.run("ESTwoKeyNav", "$search=blue NOT green");
// <TestCase Name="5.1.7 Search - only NOT" Rule="queryOptions">
// <Input>$search=NOT blue</Input>
testUri.run("ESTwoKeyNav", "$search=NOT blue");
// <TestCase Name="5.1.7 Search - multiple" Rule="queryOptions">
// <Input>$search=foo AND bar OR foo AND baz OR that AND bar OR that AND baz</Input>
testUri.run("ESTwoKeyNav", "$search=foo AND bar OR foo AND baz OR that AND bar OR that AND baz");
// <TestCase Name="5.1.7 Search - multiple" Rule="queryOptions">
// <Input>$search=(foo OR that) AND (bar OR baz)</Input>
testUri.run("ESTwoKeyNav", "$search=(foo OR that) AND (bar OR baz)");
// <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
// <Input>$search=foo AND (bar OR baz)</Input>
testUri.run("ESTwoKeyNav", "$search=foo AND (bar OR baz)");
// <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
// <Input>$search=(foo AND bar) OR baz</Input>
testUri.run("ESTwoKeyNav", "$search=(foo AND bar) OR baz");
// <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
// <Input>$search=(NOT foo) OR baz</Input>
testUri.run("ESTwoKeyNav", "$search=(NOT foo) OR baz");
// <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
// <Input>$search=(NOT foo)</Input>
testUri.run("ESTwoKeyNav", "$search=(NOT foo)");
// <TestCase Name="5.1.7 Search - on entity set" Rule="odataUri">
// <Input>http://serviceRoot/Products?$search=blue</Input>
testUri.run("ESTwoKeyNav", "$search=blue");
// <TestCase Name="5.1.7 Search - on entity container" Rule="odataUri">
// <Input>http://serviceRoot/Model.Container/$all?$search=blue</Input>
testUri.run("$all", "$search=blue");
// <TestCase Name="5.1.7 Search - on service" Rule="odataUri">
// <Input>http://serviceRoot/$all?$search=blue</Input>
testUri.run("$all", "$search=blue");
}
}

View File

@ -0,0 +1,177 @@
/*
* 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.Collections;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException.MessageKeys;
import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
import org.apache.olingo.server.tecsvc.provider.ActionProvider;
import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
import org.apache.olingo.server.tecsvc.provider.EnumTypeProvider;
import org.apache.olingo.server.tecsvc.provider.FunctionProvider;
import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
import org.apache.olingo.server.tecsvc.provider.TypeDefinitionProvider;
import org.junit.Test;
/** Tests of the parts of the URI parser that parse the sytem query option $select. */
public class SelectParserTest {
private static final Edm edm = OData.newInstance().createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
@Test
public void select() throws Exception {
testUri.run("ESTwoKeyNav", "$select=*")
.isSelectItemStar(0);
testUri.run("ESTwoKeyNav", "$select=olingo.odata.test1.*")
.isSelectItemAllOp(0, new FullQualifiedName("olingo.odata.test1", "*"));
testUri.run("ESTwoKeyNav", "$select=Namespace1_Alias.*")
.isSelectItemAllOp(0, new FullQualifiedName("Namespace1_Alias", "*"));
testUri.run("ESTwoKeyNav", "$select=PropertyString")
.goSelectItemPath(0).isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
testUri.run("ESTwoKeyNav", "$select=PropertyComp")
.goSelectItemPath(0).isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false);
testUri.run("ESAllPrim", "$select=PropertyTimeOfDay,PropertyDate,NavPropertyETTwoPrimOne")
.isKind(UriInfoKind.resource)
.goSelectItemPath(0).first().isPrimitiveProperty("PropertyTimeOfDay", PropertyProvider.nameTimeOfDay, false)
.goUpUriValidator()
.goSelectItemPath(1).first().isPrimitiveProperty("PropertyDate", PropertyProvider.nameDate, false)
.goUpUriValidator()
.goSelectItemPath(2).first().isNavProperty("NavPropertyETTwoPrimOne", EntityTypeProvider.nameETTwoPrim, false);
testUri.run("ESMixEnumDefCollComp",
"$select=PropertyEnumString,PropertyDefString,CollPropertyEnumString,CollPropertyDefString")
.isKind(UriInfoKind.resource)
.goSelectItemPath(0).isPrimitiveProperty("PropertyEnumString", EnumTypeProvider.nameENString, false)
.goUpUriValidator()
.goSelectItemPath(1).isPrimitiveProperty("PropertyDefString", TypeDefinitionProvider.nameTDString, false)
.goUpUriValidator()
.goSelectItemPath(2).isPrimitiveProperty("CollPropertyEnumString", EnumTypeProvider.nameENString, true)
.goUpUriValidator()
.goSelectItemPath(3).isPrimitiveProperty("CollPropertyDefString", TypeDefinitionProvider.nameTDString, true);
testUri.run("ESTwoKeyNav", "$select=PropertyComp/PropertyInt16")
.goSelectItemPath(0)
.first()
.isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false)
.n()
.isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.run("ESTwoKeyNav", "$select=PropertyComp/PropertyComp")
.goSelectItemPath(0)
.first()
.isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false)
.n()
.isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTAllPrim, false);
testUri.run("ESTwoKeyNav", "$select=olingo.odata.test1.ETBaseTwoKeyNav")
.isSelectStartType(0, EntityTypeProvider.nameETBaseTwoKeyNav);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')",
"$select=olingo.odata.test1.ETBaseTwoKeyNav/PropertyInt16")
.isKind(UriInfoKind.resource).goPath()
.first()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'2'")
.goUpUriValidator()
.isSelectStartType(0, EntityTypeProvider.nameETBaseTwoKeyNav)
.goSelectItemPath(0)
.first()
.isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='1')/PropertyCompNav",
"$select=olingo.odata.test1.CTTwoBasePrimCompNav")
.isSelectStartType(0, ComplexTypeProvider.nameCTTwoBasePrimCompNav);
testUri.run("ESTwoKeyNav", "$select=PropertyCompNav/olingo.odata.test1.CTTwoBasePrimCompNav")
.goSelectItemPath(0)
.first()
.isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false)
.isTypeFilter(ComplexTypeProvider.nameCTTwoBasePrimCompNav);
testUri.run("ESTwoKeyNav", "$select=PropertyCompNav/Namespace1_Alias.CTTwoBasePrimCompNav/PropertyInt16")
.goSelectItemPath(0)
.first()
.isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false)
.isTypeFilter(ComplexTypeProvider.nameCTTwoBasePrimCompNav)
.n()
.isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
testUri.run("ESAllPrim", "$select=olingo.odata.test1.BAESAllPrimRTETAllPrim")
.goSelectItemPath(0)
.first()
.isAction(ActionProvider.nameBAESAllPrimRTETAllPrim.getName());
testUri.run("ESTwoKeyNav", "$select=Namespace1_Alias.BFCESTwoKeyNavRTString")
.goSelectItemPath(0)
.first()
.isFunction(FunctionProvider.nameBFCESTwoKeyNavRTString.getName());
testUri.run("ESTwoKeyNav", "$select=olingo.odata.test1.BFCESTwoKeyNavRTStringParam(ParameterComp)")
.goSelectItemPath(0)
.first()
.isFunction(FunctionProvider.nameBFCESTwoKeyNavRTStringParam.getName());
testUri.runEx("ESMixPrimCollComp", "$select=wrong")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESMixPrimCollComp", "$select=PropertyComp/wrong")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESMixPrimCollComp", "$select=PropertyComp///PropertyInt16")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESMixPrimCollComp", "$select=/PropertyInt16")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESMixPrimCollComp", "$select=PropertyInt16+")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.1")
.isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$select=unknown_namespace.*").isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.ETKeyNav")
.isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/olingo.odata.test1.CTTwoPrim")
.isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/olingo.odata.test1.CTwrong")
.isExSemantic(MessageKeys.UNKNOWN_TYPE);
testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/.")
.isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/olingo.odata.test1.CTTwoBasePrimCompNav/.")
.isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("AIRT", "$select=wrong")
.isExSemantic(MessageKeys.ONLY_FOR_TYPED_PARTS);
testUri.runEx("AIRT", "$select=olingo.odata.test1.BAESAllPrimRT")
.isExSemantic(MessageKeys.ONLY_FOR_TYPED_PARTS);
testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.BFwrong")
.isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.BFCESTwoKeyNavRTStringParam()")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESTwoKeyNav", "$select=Namespace1_Alias.BFCESTwoKeyNavRTStringParam(ParameterComp,...)")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
}

View File

@ -0,0 +1,843 @@
/*
* 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.Arrays;
import java.util.Collections;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException.MessageKeys;
import org.apache.olingo.server.core.uri.testutil.FilterValidator;
import org.apache.olingo.server.core.uri.testutil.ResourceValidator;
import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
import org.apache.olingo.server.core.uri.validator.UriValidationException;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
import org.junit.Test;
/** Tests of the URI parser as a whole - please put more specific tests elsewhere. */
public class UriParserTest {
private static final Edm edm = OData.newInstance().createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
private final ResourceValidator testRes = new ResourceValidator().setEdm(edm);
private final FilterValidator testFilter = new FilterValidator().setEdm(edm);
@Test
public void misc() throws Exception {
testUri.run("")
.isKind(UriInfoKind.service);
testUri.run("/")
.isKind(UriInfoKind.service);
testUri.run("$all")
.isKind(UriInfoKind.all);
testUri.run("$batch")
.isKind(UriInfoKind.batch);
testUri.runEx("//").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$metadata/").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("//$metadata").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("ESKeyNav//$count").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("$metadata/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$batch/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$all/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$entity/olingo.odata.test1.ETKeyNav/$ref")
.isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$wrong").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("", "$wrong").isExSyntax(UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav()").isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
testRes.run("ESTwoKeyNav/olingo.odata.test1.BFC_RTESTwoKeyNav_()")
.isEntitySet("ESTwoKeyNav")
.n().isFunction("BFC_RTESTwoKeyNav_");
testRes.run("ESAllPrim/olingo.odata.test1.BAESAllPrimRTETAllPrim")
.isEntitySet("ESAllPrim")
.n().isAction("BAESAllPrimRTETAllPrim");
testRes.run("ESTwoKeyNav/olingo.odata.test1.BFC_RTESTwoKeyNav_()")
.isEntitySet("ESTwoKeyNav")
.n().isFunction("BFC_RTESTwoKeyNav_");
testRes.run("ESMedia(1)/$value")
.isEntitySet("ESMedia")
.n().isValue();
testRes.run("ESAllPrim/olingo.odata.test1.BAESAllPrimRTETAllPrim")
.isEntitySet("ESAllPrim")
.n().isAction("BAESAllPrimRTETAllPrim");
testRes.run("ESTwoKeyNav/olingo.odata.test1.BFC_RTESTwoKeyNav_()")
.isEntitySet("ESTwoKeyNav")
.n().isFunction("BFC_RTESTwoKeyNav_");
testRes.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/olingo.odata.test1.ETBaseTwoKeyNav")
.isEntitySet("ESTwoKeyNav")
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'2'")
.isType(EntityTypeProvider.nameETTwoKeyNav)
.isTypeFilterOnEntry(EntityTypeProvider.nameETBaseTwoKeyNav);
testRes.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/olingo.odata.test1.ETBaseTwoKeyNav/$ref")
.isEntitySet("ESTwoKeyNav")
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicate(1, "PropertyString", "'2'")
.isType(EntityTypeProvider.nameETTwoKeyNav)
.isTypeFilterOnEntry(EntityTypeProvider.nameETBaseTwoKeyNav)
.n().isRef();
}
@Test
public void enumAndTypeDefAsKey() throws Exception {
testRes
.run("ESMixEnumDefCollComp(PropertyEnumString=olingo.odata.test1.ENString'String1',PropertyDefString='abc')")
.isEntitySet("ESMixEnumDefCollComp")
.isKeyPredicate(0, "PropertyEnumString", "olingo.odata.test1.ENString'String1'")
.isKeyPredicate(1, "PropertyDefString", "'abc'");
testFilter.runOnETMixEnumDefCollComp("PropertyEnumString has Namespace1_Alias.ENString'String1'")
.is("<<PropertyEnumString> has <olingo.odata.test1.ENString<String1>>>");
testRes
.run("ESMixEnumDefCollComp(PropertyEnumString=Namespace1_Alias.ENString'String1',PropertyDefString='abc')")
.isEntitySet("ESMixEnumDefCollComp")
.isKeyPredicate(0, "PropertyEnumString", "Namespace1_Alias.ENString'String1'")
.isKeyPredicate(1, "PropertyDefString", "'abc'");
}
@Test
public void crossjoin() throws Exception {
testUri.run("$crossjoin(ESKeyNav)")
.isKind(UriInfoKind.crossjoin)
.isCrossJoinEntityList(Arrays.asList("ESKeyNav"));
testUri.run("$crossjoin(ESKeyNav,ESTwoKeyNav)")
.isKind(UriInfoKind.crossjoin)
.isCrossJoinEntityList(Arrays.asList("ESKeyNav", "ESTwoKeyNav"));
}
@Test
public void crossjoinFilter() throws Exception {
testUri.run("$crossjoin(ESTwoPrim,ESMixPrimCollComp)",
"$filter=ESTwoPrim/PropertyString eq ESMixPrimCollComp/PropertyComp/PropertyString")
.goFilter()
.isBinary(BinaryOperatorKind.EQ)
.is("<<ESTwoPrim/PropertyString> eq <ESMixPrimCollComp/PropertyComp/PropertyString>>");
}
@Test
public void crossjoinExpand() throws Exception {
testUri.run("$crossjoin(ESTwoPrim,ESAllPrim)",
"$expand=ESTwoPrim")
.goExpand()
.first().goPath().first().isEntitySet("ESTwoPrim");
testUri.run("$crossjoin(ESTwoPrim,ESAllPrim)",
"$expand=ESTwoPrim,ESAllPrim")
.goExpand()
.first().goPath().first().isEntitySet("ESTwoPrim")
.goUpExpandValidator().next().goPath().first().isEntitySet("ESAllPrim");
// TODO: Once crossjoin is implemented these tests should no longer result in errors
// testUri.run("$crossjoin(ESTwoPrim,ESAllPrim)",
// "$expand=ESAllPrim/NavPropertyETTwoPrimOne")
// .goExpand()
// .first().goPath().at(0).isEntitySet("ESAllPrim")
// .at(1).isNavProperty("NavPropertyETTwoPrimOne", EntityTypeProvider.nameETTwoPrim, false);
}
@Test
public void crossjoinError() throws Exception {
testUri.runEx("$crossjoin").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("$crossjoin/error").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$crossjoin()").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("$crossjoin(ESKeyNav, ESTwoKeyNav)/invalid")
.isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
testUri.runEx("$crossjoin(ESKeyNav)/$ref")
.isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
}
@Test
public void entityId() throws Exception {
// simple entity set
testUri.run("$entity", "$id=ESAllPrim(1)").isKind(UriInfoKind.entityId)
.isKind(UriInfoKind.entityId)
.isIdText("ESAllPrim(1)");
// simple entity set; $format before $id
testUri.run("$entity", "$format=xml&$id=ESAllPrim(1)").isKind(UriInfoKind.entityId)
.isFormatText("xml")
.isIdText("ESAllPrim(1)");
testUri.run("$entity", "$format=xml&abc=123&$id=ESAllPrim(1)").isKind(UriInfoKind.entityId)
.isFormatText("xml")
.isCustomParameter(0, "abc", "123")
.isIdText("ESAllPrim(1)");
// simple entity set; $format after $id
testUri.run("$entity", "$id=ESAllPrim(1)&$format=xml").isKind(UriInfoKind.entityId)
.isIdText("ESAllPrim(1)")
.isFormatText("xml");
// simple entity set; $format and custom parameter after $id
testUri.run("$entity", "$id=ESAllPrim(1)&$format=xml&abc=123").isKind(UriInfoKind.entityId)
.isIdText("ESAllPrim(1)")
.isFormatText("xml")
.isCustomParameter(0, "abc", "123");
// simple entity set; $format before $id and custom parameter after $id
testUri.run("$entity", "$format=xml&$id=ESAllPrim(1)&abc=123").isKind(UriInfoKind.entityId)
.isFormatText("xml")
.isIdText("ESAllPrim(1)")
.isCustomParameter(0, "abc", "123");
// simple entity set; with qualifiedentityTypeName
testUri.run("$entity/olingo.odata.test1.ETTwoPrim", "$id=ESBase(111)")
.isEntityType(EntityTypeProvider.nameETTwoPrim)
.isIdText("ESBase(111)");
// simple entity set; with qualifiedentityTypeName;
testUri.run("$entity/olingo.odata.test1.ETBase", "$id=ESTwoPrim(1)")
.isEntityType(EntityTypeProvider.nameETBase)
.isKind(UriInfoKind.entityId)
.isIdText("ESTwoPrim(1)");
// simple entity set; with qualifiedentityTypeName; with format
testUri.run("$entity/olingo.odata.test1.ETBase", "$id=ESTwoPrim(1)&$format=atom")
.isKind(UriInfoKind.entityId)
.isEntityType(EntityTypeProvider.nameETBase)
.isIdText("ESTwoPrim(1)")
.isFormatText("atom");
// simple entity set; with qualifiedentityTypeName; with select
testUri.run("$entity/olingo.odata.test1.ETBase", "$id=ESTwoPrim(1)&$select=*")
.isKind(UriInfoKind.entityId)
.isEntityType(EntityTypeProvider.nameETBase)
.isIdText("ESTwoPrim(1)")
.isSelectItemStar(0);
// simple entity set; with qualifiedentityTypeName; with expand
testUri.run("$entity/olingo.odata.test1.ETBase", "$id=ESTwoPrim(1)&$expand=*")
.isKind(UriInfoKind.entityId)
.isEntityType(EntityTypeProvider.nameETBase)
.isIdText("ESTwoPrim(1)")
.goExpand().first().isSegmentStar();
}
@Test
public void entityIdFailOnValidation() throws Exception {
testUri.runEx("$entity/olingo.odata.test1.ETTwoPrim", "$filter=PropertyInt16 eq 123&$id=ESAllPrim(1)")
.isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
}
@Test
public void resourcePathWithApostrophe() throws Exception {
testUri.runEx("ESAllPrim'").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESAllPrim'InvalidStuff").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testFilter.runOnETKeyNavEx("PropertyInt16' eq 0").isExSemantic(MessageKeys.TYPES_NOT_COMPATIBLE);
testFilter.runOnETKeyNavEx("PropertyInt16 eq' 0").isExSemantic(MessageKeys.TYPES_NOT_COMPATIBLE);
testFilter.runOnETKeyNavEx("PropertyInt16 eq 0'")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testFilter.runOnETKeyNavEx("PropertyInt16 eq 'dsd''")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@Test
public void metaData() throws Exception {
// Parsing the fragment may be used if a uri has to be parsed on the consumer side.
// On the producer side this feature is currently not supported, so the context fragment
// part is only available as text.
testUri.run("$metadata")
.isKind(UriInfoKind.metadata);
testUri.run("$metadata", "$format=atom")
.isKind(UriInfoKind.metadata)
.isFormatText("atom");
// with context (client usage)
testUri.run("$metadata", null, "$ref")
.isKind(UriInfoKind.metadata)
.isFragmentText("$ref");
testUri.run("$metadata", "$format=atom", "$ref")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("$ref");
testUri.run("$metadata", "$format=atom", "Collection($ref)")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("Collection($ref)");
testUri.run("$metadata", "$format=atom", "Collection(Edm.EntityType)")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("Collection(Edm.EntityType)");
testUri.run("$metadata", "$format=atom", "Collection(Edm.ComplexType)")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("Collection(Edm.ComplexType)");
testUri.run("$metadata", "$format=atom", "SINav")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav");
testUri.run("$metadata", "$format=atom", "SINav/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/PropertyInt16");
testUri.run("$metadata", "$format=atom", "SINav/NavPropertyETKeyNavOne")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/NavPropertyETKeyNavOne");
testUri.run("$metadata", "$format=atom", "SINav/NavPropertyETKeyNavMany(1)")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/NavPropertyETKeyNavMany(1)");
testUri.run("$metadata", "$format=atom", "SINav/NavPropertyETKeyNavOne/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/NavPropertyETKeyNavOne/PropertyInt16");
testUri.run("$metadata", "$format=atom", "SINav/NavPropertyETKeyNavMany(1)/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/NavPropertyETKeyNavMany(1)/PropertyInt16");
testUri.run("$metadata", "$format=atom", "SINav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavOne/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavOne/PropertyInt16");
testUri.run("$metadata", "$format=atom",
"SINav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavMany(1)/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("SINav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavMany(1)/PropertyInt16");
testUri.run("$metadata", "$format=atom", "olingo.odata.test1.ETAllKey")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("olingo.odata.test1.ETAllKey");
testUri.run("$metadata", "$format=atom", "ESTwoPrim/$deletedEntity")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESTwoPrim/$deletedEntity");
testUri.run("$metadata", "$format=atom", "ESTwoPrim/$link")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESTwoPrim/$link");
testUri.run("$metadata", "$format=atom", "ESTwoPrim/$deletedLink")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESTwoPrim/$deletedLink");
testUri.run("$metadata", "$format=atom", "ESKeyNav")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav");
testUri.run("$metadata", "$format=atom", "ESKeyNav/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/PropertyInt16");
testUri.run("$metadata", "$format=atom", "ESKeyNav/NavPropertyETKeyNavOne")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/NavPropertyETKeyNavOne");
testUri.run("$metadata", "$format=atom", "ESKeyNav/NavPropertyETKeyNavMany(1)")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/NavPropertyETKeyNavMany(1)");
testUri.run("$metadata", "$format=atom", "ESKeyNav/NavPropertyETKeyNavOne/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/NavPropertyETKeyNavOne/PropertyInt16");
testUri.run("$metadata", "$format=atom", "ESKeyNav/NavPropertyETKeyNavMany(1)/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/NavPropertyETKeyNavMany(1)/PropertyInt16");
testUri.run("$metadata", "$format=atom",
"ESKeyNav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavOne/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavOne/PropertyInt16");
testUri.run(
"$metadata", "$format=atom", "ESKeyNav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavMany(1)/PropertyInt16")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/olingo.odata.test1.ETTwoPrim/NavPropertyETKeyNavMany(1)/PropertyInt16");
testUri.run("$metadata", "$format=atom", "ESKeyNav(PropertyInt16,PropertyString)")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav(PropertyInt16,PropertyString)");
testUri.run("$metadata", "$format=atom", "ESKeyNav/$entity")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/$entity");
testUri.run("$metadata", "$format=atom", "ESKeyNav/$delta")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/$delta");
testUri.run("$metadata", "$format=atom", "ESKeyNav/(PropertyInt16,PropertyString)/$delta")
.isKind(UriInfoKind.metadata)
.isFormatText("atom")
.isFragmentText("ESKeyNav/(PropertyInt16,PropertyString)/$delta");
}
@Test
public void top() throws Exception {
testUri.run("ESKeyNav", "$top=1")
.isKind(UriInfoKind.resource)
.goPath().isEntitySet("ESKeyNav")
.goUpUriValidator().isTopText("1");
testUri.run("ESKeyNav", "$top=0")
.isKind(UriInfoKind.resource)
.goPath().isEntitySet("ESKeyNav")
.goUpUriValidator().isTopText("0");
testUri.runEx("ESKeyNav", "$top=undefined")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$top=")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$top=-3")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
}
@Test
public void format() throws Exception {
testUri.run("ESKeyNav(1)", "$format=atom")
.isKind(UriInfoKind.resource)
.isFormatText("atom");
testUri.run("ESKeyNav(1)", "$format=json")
.isKind(UriInfoKind.resource)
.isFormatText("json");
testUri.run("ESKeyNav(1)", "$format=xml")
.isKind(UriInfoKind.resource)
.isFormatText("xml");
testUri.run("ESKeyNav(1)", "$format=IANA_content_type/must_contain_a_slash")
.isKind(UriInfoKind.resource)
.isFormatText("IANA_content_type/must_contain_a_slash");
testUri.run("ESKeyNav(1)", "$format=Test_all_valid_signsSpecified_for_format_signs%26-._~$@%27/Aa123%26-._~$@%27")
.isKind(UriInfoKind.resource)
.isFormatText("Test_all_valid_signsSpecified_for_format_signs&-._~$@'/Aa123&-._~$@'");
testUri.run("ESKeyNav(1)", "$format=" + ContentType.APPLICATION_ATOM_XML_ENTRY_UTF8)
.isKind(UriInfoKind.resource)
.isFormatText(ContentType.APPLICATION_ATOM_XML_ENTRY_UTF8.toContentTypeString());
testUri.runEx("ESKeyNav(1)", "$format=noSlash")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT);
testUri.runEx("ESKeyNav(1)", "$format=slashAtEnd/")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT);
testUri.runEx("ESKeyNav(1)", "$format=/startsWithSlash")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT);
testUri.runEx("ESKeyNav(1)", "$format=two/Slashes/tooMuch")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT);
testUri.runEx("ESKeyNav(1)", "$format=")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT);
}
@Test
public void count() throws Exception {
testUri.run("ESAllPrim", "$count=true")
.isKind(UriInfoKind.resource)
.isInlineCountText("true");
testUri.run("ESAllPrim", "$count=false")
.isKind(UriInfoKind.resource)
.isInlineCountText("false");
testUri.runEx("ESAllPrim", "$count=undefined")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESAllPrim", "$count=")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
}
@Test
public void skip() throws Exception {
testUri.run("ESAllPrim", "$skip=3")
.isKind(UriInfoKind.resource)
.isSkipText("3");
testUri.run("ESAllPrim", "$skip=0")
.isKind(UriInfoKind.resource)
.isSkipText("0");
testUri.runEx("ESAllPrim", "$skip=F")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESAllPrim", "$skip=")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
testUri.runEx("ESAllPrim", "$skip=-3")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
}
@Test
public void skiptoken() throws Exception {
testUri.run("ESAllPrim", "$skiptoken=foo")
.isKind(UriInfoKind.resource)
.isSkipTokenText("foo");
testUri.runEx("ESAllPrim", "$skiptoken=")
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
}
@Test
public void notExistingSystemQueryOption() throws Exception {
testUri.runEx("ESAllPrim", "$wrong=error")
.isExSyntax(UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION);
}
@Test
public void errors() {
testUri.runEx("FICRTString(wrong1='ABC')/olingo.odata.test1.BFCStringRTESTwoKeyNav()")
.isExSemantic(MessageKeys.FUNCTION_NOT_FOUND);
testUri.runEx("FICRTString(wrong1='ABC',wrong2=1)/olingo.odata.test1.BFCStringRTESTwoKeyNav()")
.isExSemantic(MessageKeys.FUNCTION_NOT_FOUND);
// type filter for entity incompatible
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/olingo.odata.test1.ETBase")
.isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
// type filter for entity double on entry
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')"
+ "/olingo.odata.test1.ETBaseTwoKeyNav/olingo.odata.test1.ETBaseTwoKeyNav")
.isExSemantic(MessageKeys.TYPE_FILTER_NOT_CHAINABLE);
// type filter for entity double on collection
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.ETBaseTwoKeyNav/olingo.odata.test1.ETBaseTwoKeyNav")
.isExSemantic(MessageKeys.TYPE_FILTER_NOT_CHAINABLE);
// type filter for entity double on non key pred
testUri.runEx("SINav/olingo.odata.test1.ETBaseTwoKeyNav/olingo.odata.test1.ETBaseTwoKeyNav")
.isExSemantic(MessageKeys.TYPE_FILTER_NOT_CHAINABLE);
// type filter for complex incompatible
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim"
+ "/olingo.odata.test1.CTCollAllPrim")
.isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
// type filter for complex double on entry
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString='2')"
+ "/olingo.odata.test1.CTBase/olingo.odata.test1.CTBase")
.isExSemantic(MessageKeys.TYPE_FILTER_NOT_CHAINABLE);
// type filter for complex double on collection
testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString='2')"
+ "/olingo.odata.test1.CTBase/olingo.odata.test1.CTBase")
.isExSemantic(MessageKeys.TYPE_FILTER_NOT_CHAINABLE);
// type filter for complex double on non key pred
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim"
+ "/olingo.odata.test1.CTBase/olingo.odata.test1.CTBase")
.isExSemantic(MessageKeys.TYPE_FILTER_NOT_CHAINABLE);
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFC_RTESTwoKeyNav_")
.isExSemantic(MessageKeys.UNKNOWN_TYPE);
// $ref
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim/$ref")
.isExSemantic(MessageKeys.ONLY_FOR_ENTITY_TYPES);
// $count
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim/$count")
.isExSemantic(MessageKeys.ONLY_FOR_COLLECTIONS);
// Actions must not be followed by anything.
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/"
+ "olingo.odata.test1.BA_RTETTwoKeyNav/olingo.odata.test1.ETTwoKeyNav")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BAESTwoKeyNavRTESTwoKeyNav/$count")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
}
@Test
public void doublePercentDecoding() throws Exception {
testUri.runEx("ESAllPrim%252832767%29").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@Test
public void multipleKeysInResourcePath() throws Exception {
// See OLINGO-730
testUri.runEx("ESAllPrim(32767)(1)(2)").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@Test
public void startElementsInsteadOfNavigationProperties() {
testUri.runEx("ESAllPrim(0)/ESAllPrim(0)/ESAllPrim(0)").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESAllPrim(0)/SINav").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESAllPrim(0)/FICRTString()").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESAllPrim(0)/AIRTString").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("SI/ESAllPrim(0)").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("SI/SINav").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("SI/FICRTString()").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("SI/AIRTString").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("FICRTETKeyNav()/ESAllPrim(0)").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("FICRTETKeyNav()/SINav").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("FICRTETKeyNav()/FICRTString()").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("FICRTETKeyNav()/AIRTString").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
testUri.runEx("AIRTESAllPrimParam/ESAllPrim(0)")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
testUri.runEx("AIRTESAllPrimParam/SINav")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
testUri.runEx("AIRTESAllPrimParam/FICRTString()")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
testUri.runEx("AIRTESAllPrimParam/AIRTString")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
}
@Test
public void firstResourcePathWithNamespace() {
testUri.runEx("olingo.odata.test1.ESAllPrim").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
testUri.runEx("olingo.odata.test1.ESAllPrim(0)").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
testUri.runEx("olingo.odata.test1.FINRTInt16()").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
testUri.runEx("olingo.odata.test1.AIRTString").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
testUri.runEx("olingo.odata.test1.SINav").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
}
@Test
public void alias() throws Exception {
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString=@A)", "@A='2'").goPath()
.isKeyPredicate(0, "PropertyInt16", "1")
.isKeyPredicateAlias(1, "PropertyString", "@A")
.goUpUriValidator().isInAliasToValueMap("@A", "'2'");
testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=1").goPath()
.isKeyPredicateAlias(0, "PropertyInt16", "@p1")
.goUpUriValidator().isInAliasToValueMap("@p1", "1");
testUri.run("ESAllPrim(@p1)", "@p1=-2").goPath()
.isKeyPredicateAlias(0, "PropertyInt16", "@p1")
.goUpUriValidator().isInAliasToValueMap("@p1", "-2");
testFilter.runOnETAllPrim("PropertyInt16 gt @alias&@alias=1")
.is("<<PropertyInt16> gt <@alias>>")
.right().isAlias("@alias");
testFilter.runOnETAllPrim("@alias&@alias=@otherAlias&@otherAlias=true")
.isAlias("@alias");
testUri.runEx("ESAllPrim(@p1)")
.isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe'").isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testFilter.runOnETKeyNavEx("PropertyInt16 gt @alias")
.isInAliasToValueMap("@alias", null);
testFilter.runOnETKeyNavEx("PropertyInt16 gt @alias&@alias=@alias")
.isInAliasToValueMap("@alias", "@alias");
testFilter.runOnETKeyNavEx("@alias&@alias=@alias2&@alias2=true or @alias")
.isInAliasToValueMap("@alias", "@alias2");
}
@Test
public void functionImportParameterAlias() throws Exception {
testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)", "@parameterAlias=1");
testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)/$count", "@parameterAlias=1");
testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=@invalidAlias)", "@validAlias=1")
.isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
}
@Test
public void functionsWithComplexParameters() throws Exception {
testUri.run("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1)", "@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}")
.goPath()
.first().isEntitySet("ESTwoKeyNav")
.n().isFunction("BFCESTwoKeyNavRTStringParam").isParameterAlias(0, "ParameterComp", "@p1")
.goUpUriValidator().isInAliasToValueMap("@p1", "{\"PropertyInt16\":1,\"PropertyString\":\"1\"}");
// Test JSON String lexer rule =\"3,Int16=abc},\\\nabc&test%test\b\f\r\t\u0022\\}\\{\\)\\(\\]\\[}
final String stringValueEncoded = "=\\\"3,Int16=abc},\\\\\\nabc%26test%25test\\b\\f\\r\\t\\u0022\\\\}\\\\{\\\\)"
+ "\\\\(\\\\]\\\\[}";
final String stringValueDecoded = "=\\\"3,Int16=abc},\\\\\\nabc&test%test\\b\\f\\r\\t\\u0022\\\\}\\\\{\\\\)"
+ "\\\\(\\\\]\\\\[}";
testUri.run("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1)", "@p1={\"PropertyInt16\":1,\"PropertyString\":\"" + stringValueEncoded + "\"}")
.goPath()
.first().isEntitySet("ESTwoKeyNav")
.n().isFunction("BFCESTwoKeyNavRTStringParam").isParameterAlias(0, "ParameterComp", "@p1")
.goUpUriValidator()
.isInAliasToValueMap("@p1", "{\"PropertyInt16\":1,\"PropertyString\":\"" + stringValueDecoded + "\"}");
testFilter.runOnETTwoKeyNav("olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp={\"PropertyString\":\"Test\",\"PropertyInt16\":1}) eq 'Test'")
.is("<<BFCESTwoKeyNavRTStringParam> eq <'Test'>>")
.isBinary(BinaryOperatorKind.EQ)
.left().isParameterText(0, "{\"PropertyString\":\"Test\",\"PropertyInt16\":1}");
testFilter.runOnETTwoKeyNav("olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp={\"PropertyString\":\"" + stringValueEncoded + "\",\"PropertyInt16\":1}) eq 'Test'")
.is("<<BFCESTwoKeyNavRTStringParam> eq <'Test'>>")
.left().isParameterText(0, "{\"PropertyString\":\"" + stringValueDecoded + "\",\"PropertyInt16\":1}");
testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}");
testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":1,\"PropertyString\":null}")
.goFilter().left().isParameterText(0, null);
testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={}");
testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[1,2,3],\"PropertyString\":\"1\"}");
testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[\"1\",\"2\",\"3\"],\"PropertyString\":\"1\"}");
testUri.run("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[{\"Prop1\":123,\"Prop2\":\"Test\",\"Prop3\":[1,2,3]},"
+ "{\"Prop1\":{\"Prop1\":[\"Prop\\\":{]\"]}}],\"PropertyString\":\"1\"}");
testUri.run("FINRTByteNineParam(ParameterEnum=null,ParameterDef='x',ParameterComp=@c,"
+ "ParameterETTwoPrim=@c,CollParameterByte=@e,CollParameterEnum=@e,CollParameterDef=@e,"
+ "CollParameterComp=@e,CollParameterETTwoPrim=@e)",
"@c={}&@e=[]");
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1)", "@p1={\"PropertyInt16\":1,\"PropertyString\":'1'}")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp={\"PropertyInt16\":1,\"PropertyString\":\"Test\"})")
.isExSemantic(MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH);
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=null)")
.isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)")
.isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null")
.isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
testUri.run("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test='null'");
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test,UnknownParam=1)", "@test='null'")
.isExSemantic(MessageKeys.FUNCTION_NOT_FOUND);
testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test='null'");
testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null");
testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)");
testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=null)");
testUri.runEx("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null&@test='1'")
.isExSyntax(UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS);
testFilter.runOnETKeyNavEx("FINRTInt16() eq 0")
.isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}}")
.isExSemantic(MessageKeys.UNKNOWN_PART);
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[1,2,3]],\"PropertyString\":\"1\"}")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[1,2,3,\"PropertyString\":\"1\"}")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
+ "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[1,2,3},\"PropertyString\":\"1\"}")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
}
@Test
public void allowedSystemQueryOptionsOnAll() throws Exception {
testUri.run("$all", "$count=true&$format=json&$search=abc&$skip=5&$top=5&$skiptoken=abc")
.isKind(UriInfoKind.all)
.isInlineCountText("true")
.isFormatText("json")
.isSearchSerialized("'abc'")
.isSkipText("5")
.isTopText("5")
.isSkipTokenText("abc");
}
@Test
public void allowedSystemQueryOptionsOnCrossjoin() throws Exception {
testUri.run("$crossjoin(ESAllPrim,ESTwoPrim)", "$count=true&$expand=ESAllPrim"
+ "&$filter=ESAllPrim/PropertyInt16 eq 2&$format=json&$orderby=ESAllPrim/PropertyInt16"
+ "&$search=abc&$skip=5&$top=5&$skiptoken=abc")
.isKind(UriInfoKind.crossjoin)
.isInlineCountText("true")
.goExpand().goPath().isEntitySet("ESAllPrim")
.goUpExpandValidator().goUpToUriValidator()
.goFilter().left().goPath().first().isEntitySet("ESAllPrim")
.n().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false)
.goUpFilterValidator().goUpToUriValidator()
.isFormatText("json")
.isSearchSerialized("'abc'")
.isSkipText("5")
.isTopText("5")
.isSkipTokenText("abc");
}
@Test
public void trimQueryOptionsValue() throws Exception {
// OLINGO-846 trim query option value
testUri.run("ESAllPrim", "$filter= PropertyInt16 eq 12 ")
.isKind(UriInfoKind.resource).goPath()
.first().isEntitySet("ESAllPrim");
// OLINGO-846 trim query option value
testUri.run("ESAllPrim", "$filter= PropertyInt16 eq 12 ")
.isKind(UriInfoKind.resource).goFilter().isBinary(BinaryOperatorKind.EQ).is("<<PropertyInt16> eq <12>>");
}
@Test
public void customQueryOption() throws Exception {
testUri.run("ESTwoKeyNav", "custom")
.isCustomParameter(0, "custom", "");
testUri.run("ESTwoKeyNav", "custom=ABC")
.isCustomParameter(0, "custom", "ABC");
}
}

View File

@ -23,8 +23,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmType;
@ -38,7 +36,6 @@ import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceAction;
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceKind;
@ -46,8 +43,9 @@ import org.apache.olingo.server.api.uri.UriResourceLambdaAll;
import org.apache.olingo.server.api.uri.UriResourceLambdaAny;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.UriResourceSingleton;
import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.validator.UriValidationException;
@ -57,7 +55,7 @@ public class ResourceValidator implements TestValidator {
private final OData odata = OData.newInstance();
private Edm edm;
private TestValidator invokedBy;
private UriInfo uriInfo = null;
private UriInfoResource uriInfo = null;
private UriResource uriPathInfo = null;
private int uriResourceIndex;
@ -75,10 +73,8 @@ public class ResourceValidator implements TestValidator {
}
public ResourceValidator setUriInfoPath(final UriInfoResource uriInfoPath) {
uriInfo = (UriInfo) uriInfoPath;
if (!uriInfo.getUriResourceParts().isEmpty()) {
last();
}
uriInfo = uriInfoPath;
first();
return this;
}
@ -86,7 +82,6 @@ public class ResourceValidator implements TestValidator {
public ResourceValidator run(final String path) {
UriInfo uriInfoTmp = null;
uriPathInfo = null;
try {
uriInfoTmp = new Parser(edm, odata).parseUri(path, null, null);
} catch (final ODataLibraryException e) {
@ -101,10 +96,10 @@ public class ResourceValidator implements TestValidator {
+ " Message: " + e.getMessage());
}
uriInfo = uriInfoTmp;
isKind(UriInfoKind.resource);
assertEquals("Invalid UriInfoKind: " + uriInfoTmp.getKind().toString(),
UriInfoKind.resource, uriInfoTmp.getKind());
first();
setUriInfoPath(uriInfoTmp.asUriInfoResource());
return this;
}
@ -123,12 +118,10 @@ public class ResourceValidator implements TestValidator {
}
public FilterValidator goParameter(final int index) {
assertEquals(UriResourceKind.function, uriPathInfo.getKind());
UriResourceFunction function = (UriResourceFunction) uriPathInfo;
isUriPathInfoKind(UriResourceKind.function);
return new FilterValidator()
.setEdm(edm)
.setExpression(function.getParameters().get(index).getExpression())
.setExpression(((UriResourceFunction) uriPathInfo).getParameters().get(index).getExpression())
.setValidator(this);
}
@ -148,10 +141,6 @@ public class ResourceValidator implements TestValidator {
return at(0);
}
public ResourceValidator last() {
return at(uriInfo.getUriResourceParts().size() - 1);
}
public ResourceValidator n() {
return at(uriResourceIndex + 1);
}
@ -166,33 +155,21 @@ public class ResourceValidator implements TestValidator {
// --- Validation ---
public ResourceValidator isLambdaVar(final String var) {
String actualVar = null;
if (uriPathInfo.getKind() == UriResourceKind.lambdaAll) {
actualVar = ((UriResourceLambdaAll) uriPathInfo).getLambdaVariable();
} else if (uriPathInfo.getKind() == UriResourceKind.lambdaAny) {
actualVar = ((UriResourceLambdaAny) uriPathInfo).getLambdaVariable();
} else {
fail("invalid resource kind: " + uriPathInfo.getKind().toString());
}
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo.getKind() == UriResourceKind.lambdaAll
|| uriPathInfo.getKind() == UriResourceKind.lambdaAny);
final String actualVar = uriPathInfo.getKind() == UriResourceKind.lambdaAll ?
((UriResourceLambdaAll) uriPathInfo).getLambdaVariable() :
((UriResourceLambdaAny) uriPathInfo).getLambdaVariable();
assertEquals(var, actualVar);
return this;
}
public ResourceValidator isTypeFilter(final FullQualifiedName expectedType) {
if (uriPathInfo.getKind() != UriResourceKind.complexProperty &&
uriPathInfo.getKind() != UriResourceKind.singleton) {
fail("invalid resource kind: " + uriPathInfo.getKind().toString());
}
EdmType actualType = null;
if (uriPathInfo instanceof UriResourceComplexProperty) {
actualType = ((UriResourceComplexProperty) uriPathInfo).getComplexTypeFilter();
} else if (uriPathInfo instanceof UriResourceSingleton) {
actualType = ((UriResourceSingleton) uriPathInfo).getEntityTypeFilter();
}
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo.getKind() == UriResourceKind.complexProperty
|| uriPathInfo.getKind() == UriResourceKind.singleton);
final EdmType actualType = ((UriResourceTypedImpl) uriPathInfo).getTypeFilter();
assertNotNull("type information not set", actualType);
assertEquals(expectedType, actualType.getFullQualifiedName());
return this;
@ -202,9 +179,7 @@ public class ResourceValidator implements TestValidator {
assertTrue("invalid resource kind: "
+ (uriPathInfo.getKind() == null ? "null" : uriPathInfo.getKind().toString()),
uriPathInfo instanceof UriResourcePartTyped);
UriResourcePartTyped uriPathInfoTyped = (UriResourcePartTyped) uriPathInfo;
EdmType actualType = uriPathInfoTyped.getType();
final EdmType actualType = ((UriResourcePartTyped) uriPathInfo).getType();
assertNotNull("type information not set", actualType);
assertEquals(type, actualType.getFullQualifiedName());
return this;
@ -217,141 +192,101 @@ public class ResourceValidator implements TestValidator {
}
public ResourceValidator isTypeFilterOnEntry(final FullQualifiedName type) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceWithKeysImpl);
UriResourceWithKeysImpl uriPathInfoKeyPred = (UriResourceWithKeysImpl) uriPathInfo;
// input parameter type may be null in order to assert that the singleTypeFilter is not set
EdmType actualType = uriPathInfoKeyPred.getTypeFilterOnEntry();
if(actualType == null && type != null){
fail("Expected an entry type filter of type: " + type.getFullQualifiedNameAsString());
}
assertEquals(type, type == null ? actualType : actualType.getFullQualifiedName());
return this;
return isTypeFilter(false, type);
}
public ResourceValidator isTypeFilterOnCollection(final FullQualifiedName expectedType) {
public ResourceValidator isTypeFilterOnCollection(final FullQualifiedName type) {
return isTypeFilter(true, type);
}
private ResourceValidator isTypeFilter(final boolean onCollection, final FullQualifiedName type) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceWithKeysImpl);
UriResourceWithKeysImpl uriPathInfoKeyPred = (UriResourceWithKeysImpl) uriPathInfo;
// input parameter type may be null in order to assert that the collectionTypeFilter is not set
EdmType actualType = uriPathInfoKeyPred.getTypeFilterOnCollection();
if(actualType == null && expectedType != null){
fail("Expected an collection type filter of type: " + expectedType.getFullQualifiedNameAsString());
}
assertEquals(expectedType,
expectedType == null || actualType == null ? actualType : actualType.getFullQualifiedName());
// input parameter type may be null in order to assert that the type filter is not set
final EdmType actualType = onCollection ?
uriPathInfoKeyPred.getTypeFilterOnCollection() :
uriPathInfoKeyPred.getTypeFilterOnEntry();
assertTrue("Expected a type filter of type: " + (type == null ? null : type.getFullQualifiedNameAsString()),
type == null || actualType != null);
assertEquals(type, type == null || actualType == null ? actualType : actualType.getFullQualifiedName());
return this;
}
// other functions
public ResourceValidator isKeyPredicateRef(final int index, final String name, final String referencedProperty) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceWithKeysImpl);
UriResourceWithKeysImpl info = (UriResourceWithKeysImpl) uriPathInfo;
List<UriParameter> keyPredicates = info.getKeyPredicates();
assertEquals(name, keyPredicates.get(index).getName());
assertEquals(referencedProperty, keyPredicates.get(index).getReferencedProperty());
final UriParameter keyPredicate = getKeyPredicate(index);
assertEquals(name, keyPredicate.getName());
assertEquals(referencedProperty, keyPredicate.getReferencedProperty());
return this;
}
public ResourceValidator isKeyPredicateAlias(final int index, final String name, final String alias) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceWithKeysImpl);
UriResourceWithKeysImpl info = (UriResourceWithKeysImpl) uriPathInfo;
List<UriParameter> keyPredicates = info.getKeyPredicates();
assertEquals(name, keyPredicates.get(index).getName());
assertEquals(alias, keyPredicates.get(index).getAlias());
final UriParameter keyPredicate = getKeyPredicate(index);
assertEquals(name, keyPredicate.getName());
assertEquals(alias, keyPredicate.getAlias());
return this;
}
public ResourceValidator isKeyPredicate(final int index, final String name, final String text) {
final UriParameter keyPredicate = getKeyPredicate(index);
assertEquals(name, keyPredicate.getName());
assertEquals(text, keyPredicate.getText());
return this;
}
private UriParameter getKeyPredicate(final int index) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceWithKeysImpl);
UriResourceWithKeysImpl info = (UriResourceWithKeysImpl) uriPathInfo;
List<UriParameter> keyPredicates = info.getKeyPredicates();
assertEquals(name, keyPredicates.get(index).getName());
assertEquals(text, keyPredicates.get(index).getText());
return this;
return ((UriResourceWithKeysImpl) uriPathInfo).getKeyPredicates().get(index);
}
public ResourceValidator isParameter(final int index, final String name, final String text) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceFunction);
UriResourceFunction info = (UriResourceFunction) uriPathInfo;
List<UriParameter> keyPredicates = info.getParameters();
assertEquals(name, keyPredicates.get(index).getName());
assertEquals(text, keyPredicates.get(index).getText());
isUriPathInfoKind(UriResourceKind.function);
final UriParameter parameter = ((UriResourceFunction) uriPathInfo).getParameters().get(index);
assertEquals(name, parameter.getName());
assertEquals(text, parameter.getText());
return this;
}
public ResourceValidator isParameterAlias(final int index, final String name, final String alias) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceFunction);
UriResourceFunction info = (UriResourceFunction) uriPathInfo;
List<UriParameter> keyPredicates = info.getParameters();
assertEquals(name, keyPredicates.get(index).getName());
assertEquals(alias, keyPredicates.get(index).getAlias());
return this;
}
public ResourceValidator isKind(final UriInfoKind kind) {
assertEquals("Invalid UriInfoKind: " + uriInfo.getKind().toString(),
kind, uriInfo.getKind());
isUriPathInfoKind(UriResourceKind.function);
final UriParameter parameter = ((UriResourceFunction) uriPathInfo).getParameters().get(index);
assertEquals(name, parameter.getName());
assertEquals(alias, parameter.getAlias());
return this;
}
public ResourceValidator isPrimitiveProperty(final String name,
final FullQualifiedName type, final boolean isCollection) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourcePrimitiveProperty);
UriResourcePrimitiveProperty uriPathInfoProp = (UriResourcePrimitiveProperty) uriPathInfo;
EdmElement property = uriPathInfoProp.getProperty();
assertEquals(name, property.getName());
assertEquals(type, property.getType().getFullQualifiedName());
assertEquals(isCollection, property.isCollection());
return this;
public ResourceValidator isPrimitiveProperty(final String name, final FullQualifiedName type,
final boolean isCollection) {
return isProperty(UriResourceKind.primitiveProperty, name, type, isCollection);
}
public ResourceValidator isComplexProperty(final String name, final FullQualifiedName type,
final boolean isCollection) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceComplexProperty);
UriResourceComplexProperty uriPathInfoProp = (UriResourceComplexProperty) uriPathInfo;
EdmElement property = uriPathInfoProp.getProperty();
assertEquals(name, property.getName());
assertEquals(type, property.getType().getFullQualifiedName());
assertEquals(isCollection, property.isCollection());
return this;
return isProperty(UriResourceKind.complexProperty, name, type, isCollection);
}
public ResourceValidator isNavProperty(final String name, final FullQualifiedName type, final boolean isCollection) {
assertTrue("invalid resource kind: " + uriPathInfo.getKind().toString(),
uriPathInfo instanceof UriResourceNavigation);
UriResourceNavigation uriPathInfoProp = (UriResourceNavigation) uriPathInfo;
EdmElement property = uriPathInfoProp.getProperty();
return isProperty(UriResourceKind.navigationProperty, name, type, isCollection);
}
private ResourceValidator isProperty(final UriResourceKind kind,
final String name, final FullQualifiedName type, final boolean isCollection) {
isUriPathInfoKind(kind);
final EdmElement property = kind == UriResourceKind.navigationProperty ?
((UriResourceNavigation) uriPathInfo).getProperty() :
((UriResourceProperty) uriPathInfo).getProperty();
assertEquals(name, property.getName());
assertEquals(type, property.getType().getFullQualifiedName());
assertEquals(isCollection, uriPathInfoProp.isCollection());
isType(type, isCollection);
return this;
}
public ResourceValidator isUriPathInfoKind(final UriResourceKind infoType) {
assertNotNull(uriPathInfo);
assertEquals(infoType, uriPathInfo.getKind());
assertEquals("invalid resource kind: " + uriPathInfo.getKind().toString(), infoType, uriPathInfo.getKind());
return this;
}
@ -361,6 +296,12 @@ public class ResourceValidator implements TestValidator {
return this;
}
public ResourceValidator isActionImport(final String name) {
isUriPathInfoKind(UriResourceKind.action);
assertEquals(name, ((UriResourceAction) uriPathInfo).getActionImport().getName());
return this;
}
public ResourceValidator isFunction(final String name) {
isUriPathInfoKind(UriResourceKind.function);
assertEquals(name, ((UriResourceFunction) uriPathInfo).getFunction().getName());
@ -379,12 +320,6 @@ public class ResourceValidator implements TestValidator {
return this;
}
public ResourceValidator isComplex(final String name) {
isUriPathInfoKind(UriResourceKind.complexProperty);
assertEquals(name, ((UriResourceComplexProperty) uriPathInfo).getProperty().getName());
return this;
}
public ResourceValidator isSingleton(final String name) {
isUriPathInfoKind(UriResourceKind.singleton);
assertEquals(name, ((UriResourceSingleton) uriPathInfo).getSingleton().getName());
@ -403,12 +338,6 @@ public class ResourceValidator implements TestValidator {
return isUriPathInfoKind(UriResourceKind.ref);
}
public ResourceValidator isActionImport(final String actionName) {
isUriPathInfoKind(UriResourceKind.action);
assertEquals(actionName, ((UriResourceAction) uriPathInfo).getActionImport().getName());
return this;
}
public ResourceValidator isIt() {
return isUriPathInfoKind(UriResourceKind.it);
}