[OLINGO-834] URI parser shall not ignore empty path segments
Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
parent
b0866014df
commit
3295bcc062
|
@ -114,7 +114,7 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIEEE754ParameterContentNegotiation() throws Exception {
|
public void testIEEE754ParameterContentNegotiation() throws Exception {
|
||||||
final URL url = new URL(SERVICE_URI + "/ESAllPrim(32767)?$format=application/json;IEEE754Compatible=true");
|
final URL url = new URL(SERVICE_URI + "ESAllPrim(32767)?$format=application/json;IEEE754Compatible=true");
|
||||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setRequestMethod(HttpMethod.GET.name());
|
connection.setRequestMethod(HttpMethod.GET.name());
|
||||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;IEEE754Compatible=false");
|
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;IEEE754Compatible=false");
|
||||||
|
@ -131,7 +131,7 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIEEE754ParameterViaAcceptHeader() throws Exception {
|
public void testIEEE754ParameterViaAcceptHeader() throws Exception {
|
||||||
final URL url = new URL(SERVICE_URI + "/ESAllPrim(32767)");
|
final URL url = new URL(SERVICE_URI + "ESAllPrim(32767)");
|
||||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setRequestMethod(HttpMethod.GET.name());
|
connection.setRequestMethod(HttpMethod.GET.name());
|
||||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;IEEE754Compatible=true");
|
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;IEEE754Compatible=true");
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.olingo.server.core.uri.parser;
|
package org.apache.olingo.server.core.uri.parser;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ public class Parser {
|
||||||
private static final String ATOM = "atom";
|
private static final String ATOM = "atom";
|
||||||
private static final String JSON = "json";
|
private static final String JSON = "json";
|
||||||
private static final String XML = "xml";
|
private static final String XML = "xml";
|
||||||
|
private static final String DOLLAR = "$";
|
||||||
private static final String AT = "@";
|
private static final String AT = "@";
|
||||||
private static final String NULL = "null";
|
private static final String NULL = "null";
|
||||||
|
|
||||||
|
@ -78,14 +80,19 @@ public class Parser {
|
||||||
Deque<EdmType> contextTypes = new ArrayDeque<EdmType>();
|
Deque<EdmType> contextTypes = new ArrayDeque<EdmType>();
|
||||||
boolean contextIsCollection = false;
|
boolean contextIsCollection = false;
|
||||||
|
|
||||||
final List<String> pathSegmentsDecoded = UriDecoder.splitAndDecodePath(path);
|
List<String> pathSegmentsDecoded = UriDecoder.splitAndDecodePath(path);
|
||||||
final int numberOfSegments = pathSegmentsDecoded.size();
|
int numberOfSegments = pathSegmentsDecoded.size();
|
||||||
|
// Remove an initial empty segment resulting from the expected '/' at the beginning of the path.
|
||||||
|
if (numberOfSegments > 1 && pathSegmentsDecoded.get(0).isEmpty()) {
|
||||||
|
pathSegmentsDecoded.remove(0);
|
||||||
|
numberOfSegments--;
|
||||||
|
}
|
||||||
|
|
||||||
// first, read the decoded path segments
|
// first, read the decoded path segments
|
||||||
final String firstSegment = numberOfSegments == 0 ? "" : pathSegmentsDecoded.get(0);
|
final String firstSegment = pathSegmentsDecoded.get(0);
|
||||||
|
|
||||||
if (firstSegment.isEmpty()) {
|
if (firstSegment.isEmpty()) {
|
||||||
ensureLastSegment(firstSegment, 0, numberOfSegments);
|
ensureLastSegment(firstSegment, 1, numberOfSegments);
|
||||||
contextUriInfo.setKind(UriInfoKind.service);
|
contextUriInfo.setKind(UriInfoKind.service);
|
||||||
|
|
||||||
} else if (firstSegment.equals("$batch")) {
|
} else if (firstSegment.equals("$batch")) {
|
||||||
|
@ -168,11 +175,12 @@ public class Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
// second, read the system query options and the custom query options
|
// second, read the system query options and the custom query options
|
||||||
final List<QueryOption> options = UriDecoder.splitAndDecodeOptions(query);
|
final List<QueryOption> options =
|
||||||
|
query == null ? Collections.<QueryOption> emptyList() : UriDecoder.splitAndDecodeOptions(query);
|
||||||
for (final QueryOption option : options) {
|
for (final QueryOption option : options) {
|
||||||
final String optionName = option.getName();
|
final String optionName = option.getName();
|
||||||
final String optionValue = option.getText();
|
final String optionValue = option.getText();
|
||||||
if (optionName.startsWith("$")) {
|
if (optionName.startsWith(DOLLAR)) {
|
||||||
SystemQueryOption systemOption = null;
|
SystemQueryOption systemOption = null;
|
||||||
if (optionName.equals(SystemQueryOptionKind.FILTER.toString())) {
|
if (optionName.equals(SystemQueryOptionKind.FILTER.toString())) {
|
||||||
UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
|
UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
|
||||||
|
@ -315,7 +323,7 @@ public class Parser {
|
||||||
UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS, optionName);
|
UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS, optionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (!optionName.isEmpty()) {
|
||||||
contextUriInfo.addCustomQueryOption((CustomQueryOption) option);
|
contextUriInfo.addCustomQueryOption((CustomQueryOption) option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ public class ParserHelper {
|
||||||
final List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
final List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
||||||
if (tokenizer.next(TokenKind.CLOSE)) {
|
if (tokenizer.next(TokenKind.CLOSE)) {
|
||||||
throw new UriParserSemanticException(
|
throw new UriParserSemanticException(
|
||||||
"Expected " + keyPropertyRefs.size() + " key predicates but none.",
|
"Expected " + keyPropertyRefs.size() + " key predicates but got none.",
|
||||||
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
|
||||||
Integer.toString(keyPropertyRefs.size()), "0");
|
Integer.toString(keyPropertyRefs.size()), "0");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
package org.apache.olingo.server.core.uri.parser;
|
package org.apache.olingo.server.core.uri.parser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -33,7 +31,7 @@ public class UriDecoder {
|
||||||
/** Splits the path string at '/' characters and percent-decodes the resulting path segments. */
|
/** Splits the path string at '/' characters and percent-decodes the resulting path segments. */
|
||||||
protected static List<String> splitAndDecodePath(final String path) throws UriParserSyntaxException {
|
protected static List<String> splitAndDecodePath(final String path) throws UriParserSyntaxException {
|
||||||
List<String> pathSegmentsDecoded = new ArrayList<String>();
|
List<String> pathSegmentsDecoded = new ArrayList<String>();
|
||||||
for (final String segment : splitSkipEmpty(path, '/')) {
|
for (final String segment : split(path, '/')) {
|
||||||
pathSegmentsDecoded.add(decode(segment));
|
pathSegmentsDecoded.add(decode(segment));
|
||||||
}
|
}
|
||||||
return pathSegmentsDecoded;
|
return pathSegmentsDecoded;
|
||||||
|
@ -42,58 +40,39 @@ public class UriDecoder {
|
||||||
/**
|
/**
|
||||||
* Splits the query-option string at '&' characters, the resulting parts at '=' characters,
|
* Splits the query-option string at '&' characters, the resulting parts at '=' characters,
|
||||||
* and separately percent-decodes names and values of the resulting name-value pairs.
|
* and separately percent-decodes names and values of the resulting name-value pairs.
|
||||||
|
* If there is no '=' character in an option, the whole option is considered as name.
|
||||||
*/
|
*/
|
||||||
protected static List<QueryOption> splitAndDecodeOptions(final String queryOptionString)
|
protected static List<QueryOption> splitAndDecodeOptions(final String queryOptionString)
|
||||||
throws UriParserSyntaxException {
|
throws UriParserSyntaxException {
|
||||||
if (queryOptionString == null || queryOptionString.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<QueryOption> queryOptions = new ArrayList<QueryOption>();
|
List<QueryOption> queryOptions = new ArrayList<QueryOption>();
|
||||||
for (final String option : splitSkipEmpty(queryOptionString, '&')) {
|
for (final String option : split(queryOptionString, '&')) {
|
||||||
final List<String> pair = splitFirst(option, '=');
|
final int pos = option.indexOf('=');
|
||||||
|
final String name = pos >= 0 ? option.substring(0, pos) : option;
|
||||||
|
final String text = pos >= 0 ? option.substring(pos + 1) : "";
|
||||||
queryOptions.add(new CustomQueryOptionImpl()
|
queryOptions.add(new CustomQueryOptionImpl()
|
||||||
.setName(decode(pair.get(0)))
|
.setName(decode(name))
|
||||||
.setText(decode(pair.get(1))));
|
.setText(decode(text)));
|
||||||
}
|
}
|
||||||
return queryOptions;
|
return queryOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> splitFirst(final String input, final char c) {
|
|
||||||
int pos = input.indexOf(c);
|
|
||||||
if (pos >= 0) {
|
|
||||||
return Arrays.asList(input.substring(0, pos), input.substring(pos + 1));
|
|
||||||
} else {
|
|
||||||
return Arrays.asList(input, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits the input string at the given character and drops all empty elements.
|
* Splits the input string at the given character.
|
||||||
* @param input string to split
|
* @param input string to split
|
||||||
* @param c character at which to split
|
* @param c character at which to split
|
||||||
* @return list of elements (can be empty)
|
* @return list of elements (can be empty)
|
||||||
*/
|
*/
|
||||||
private static List<String> splitSkipEmpty(final String input, final char c) {
|
private static List<String> split(final String input, final char c) {
|
||||||
if (input.isEmpty() || input.length() == 1 && input.charAt(0) == c) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> list = new LinkedList<String>();
|
List<String> list = new LinkedList<String>();
|
||||||
|
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int end;
|
int end;
|
||||||
|
|
||||||
while ((end = input.indexOf(c, start)) >= 0) {
|
while ((end = input.indexOf(c, start)) >= 0) {
|
||||||
if (start != end) {
|
list.add(input.substring(start, end));
|
||||||
list.add(input.substring(start, end));
|
|
||||||
}
|
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.charAt(input.length() - 1) != c) {
|
list.add(input.substring(start));
|
||||||
list.add(input.substring(start));
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class SearchParser {
|
||||||
searchExpression = parse(tokenizer.tokenize(searchQuery));
|
searchExpression = parse(tokenizer.tokenize(searchQuery));
|
||||||
} catch (SearchTokenizerException e) {
|
} catch (SearchTokenizerException e) {
|
||||||
String message = e.getMessage();
|
String message = e.getMessage();
|
||||||
throw new SearchParserException("Tokenizer exception with message: " + message,
|
throw new SearchParserException("Tokenizer exception with message: " + message, e,
|
||||||
SearchParserException.MessageKeys.TOKENIZER_EXCEPTION, message);
|
SearchParserException.MessageKeys.TOKENIZER_EXCEPTION, message);
|
||||||
}
|
}
|
||||||
final SearchOptionImpl searchOption = new SearchOptionImpl();
|
final SearchOptionImpl searchOption = new SearchOptionImpl();
|
||||||
|
|
|
@ -286,9 +286,9 @@ public class UriValidator {
|
||||||
RowIndexForUriType.mediaStream : RowIndexForUriType.propertyPrimitiveValue;
|
RowIndexForUriType.mediaStream : RowIndexForUriType.propertyPrimitiveValue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UriValidationException("Unexpected kind in path segment before $value: "
|
throw new UriValidationException(
|
||||||
+ secondLastPathSegment.getKind(), UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_VALUE,
|
"Unexpected kind in path segment before $value: " + secondLastPathSegment.getKind(),
|
||||||
secondLastPathSegment.toString());
|
UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_VALUE, secondLastPathSegment.toString());
|
||||||
}
|
}
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
@ -302,9 +302,9 @@ public class UriValidator {
|
||||||
return ((UriResourcePartTyped) secondLastPathSegment).isCollection() ?
|
return ((UriResourcePartTyped) secondLastPathSegment).isCollection() ?
|
||||||
RowIndexForUriType.references : RowIndexForUriType.reference;
|
RowIndexForUriType.references : RowIndexForUriType.reference;
|
||||||
} else {
|
} else {
|
||||||
throw new UriValidationException("secondLastPathSegment not a class of UriResourcePartTyped: "
|
throw new UriValidationException(
|
||||||
+ lastPathSegment.getClass(), UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment
|
"secondLastPathSegment not a class of UriResourcePartTyped: " + lastPathSegment.getClass(),
|
||||||
.toString());
|
UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,40 +314,36 @@ public class UriValidator {
|
||||||
return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
|
return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
|
||||||
RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
|
RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
|
||||||
} else {
|
} else {
|
||||||
throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
|
throw new UriValidationException(
|
||||||
+ lastPathSegment.getClass(), UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment
|
"lastPathSegment not a class of UriResourcePartTyped: " + lastPathSegment.getClass(),
|
||||||
.toString());
|
UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RowIndexForUriType rowIndexForFunction(final UriResource lastPathSegment) throws UriValidationException {
|
private RowIndexForUriType rowIndexForFunction(final UriResource lastPathSegment) throws UriValidationException {
|
||||||
final UriResourceFunction uriFunction = (UriResourceFunction) lastPathSegment;
|
final UriResourceFunction uriFunction = (UriResourceFunction) lastPathSegment;
|
||||||
final EdmReturnType returnType = uriFunction.getFunction().getReturnType();
|
|
||||||
|
|
||||||
if (!uriFunction.getFunction().isComposable()) {
|
if (!uriFunction.getFunction().isComposable()) {
|
||||||
return RowIndexForUriType.none;
|
return RowIndexForUriType.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean isCollection = uriFunction.isCollection();
|
||||||
|
final EdmTypeKind typeKind = uriFunction.getFunction().getReturnType().getType().getKind();
|
||||||
RowIndexForUriType idx;
|
RowIndexForUriType idx;
|
||||||
switch (returnType.getType().getKind()) {
|
switch (typeKind) {
|
||||||
case ENTITY:
|
case ENTITY:
|
||||||
idx = returnType.isCollection() && uriFunction.getKeyPredicates().isEmpty() ?
|
idx = isCollection ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
|
||||||
RowIndexForUriType.entitySet : RowIndexForUriType.entity;
|
|
||||||
break;
|
break;
|
||||||
case PRIMITIVE:
|
case PRIMITIVE:
|
||||||
case ENUM:
|
case ENUM:
|
||||||
case DEFINITION:
|
case DEFINITION:
|
||||||
idx = returnType.isCollection() ? RowIndexForUriType.propertyPrimitiveCollection :
|
idx = isCollection ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
|
||||||
RowIndexForUriType.propertyPrimitive;
|
|
||||||
break;
|
break;
|
||||||
case COMPLEX:
|
case COMPLEX:
|
||||||
idx = returnType.isCollection() ? RowIndexForUriType.propertyComplexCollection :
|
idx = isCollection ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
|
||||||
RowIndexForUriType.propertyComplex;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UriValidationException("Unsupported function return type: " + returnType.getType().getKind(),
|
throw new UriValidationException("Unsupported function return type: " + typeKind,
|
||||||
UriValidationException.MessageKeys.UNSUPPORTED_FUNCTION_RETURN_TYPE,
|
UriValidationException.MessageKeys.UNSUPPORTED_FUNCTION_RETURN_TYPE, typeKind.toString());
|
||||||
returnType.getType().getKind().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
|
@ -512,18 +508,17 @@ public class UriValidator {
|
||||||
for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
|
for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
|
||||||
options.append(option.getName()).append(" ");
|
options.append(option.getName()).append(" ");
|
||||||
}
|
}
|
||||||
throw new UriValidationException("System query option " + options.toString() + " not allowed for method "
|
throw new UriValidationException(
|
||||||
+ httpMethod, UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
|
"System query option " + options.toString() + " not allowed for method " + httpMethod,
|
||||||
|
UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
|
||||||
options.toString(), httpMethod.toString());
|
options.toString(), httpMethod.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAction(final UriInfo uriInfo) {
|
private boolean isAction(final UriInfo uriInfo) {
|
||||||
List<UriResource> uriResourceParts = uriInfo.getUriResourceParts();
|
List<UriResource> uriResourceParts = uriInfo.getUriResourceParts();
|
||||||
if (uriResourceParts.isEmpty()) {
|
return !uriResourceParts.isEmpty()
|
||||||
return false;
|
&& UriResourceKind.action == uriResourceParts.get(uriResourceParts.size() - 1).getKind();
|
||||||
}
|
|
||||||
return UriResourceKind.action == uriResourceParts.get(uriResourceParts.size() - 1).getKind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateParameters(final UriInfo uriInfo) throws UriValidationException {
|
private void validateParameters(final UriInfo uriInfo) throws UriValidationException {
|
||||||
|
@ -531,18 +526,18 @@ public class UriValidator {
|
||||||
final boolean isFunction = pathSegment.getKind() == UriResourceKind.function;
|
final boolean isFunction = pathSegment.getKind() == UriResourceKind.function;
|
||||||
|
|
||||||
if (isFunction) {
|
if (isFunction) {
|
||||||
final UriResourceFunction functionPathSegement = (UriResourceFunction) pathSegment;
|
final UriResourceFunction functionPathSegment = (UriResourceFunction) pathSegment;
|
||||||
final EdmFunction edmFuntion = functionPathSegement.getFunction();
|
final EdmFunction edmFunction = functionPathSegment.getFunction();
|
||||||
|
|
||||||
final Map<String, UriParameter> parameters = new HashMap<String, UriParameter>();
|
final Map<String, UriParameter> parameters = new HashMap<String, UriParameter>();
|
||||||
for (final UriParameter parameter : functionPathSegement.getParameters()) {
|
for (final UriParameter parameter : functionPathSegment.getParameters()) {
|
||||||
parameters.put(parameter.getName(), parameter);
|
parameters.put(parameter.getName(), parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean firstParameter = true;
|
boolean firstParameter = true;
|
||||||
for (final String parameterName : edmFuntion.getParameterNames()) {
|
for (final String parameterName : edmFunction.getParameterNames()) {
|
||||||
final UriParameter parameter = parameters.get(parameterName);
|
final UriParameter parameter = parameters.get(parameterName);
|
||||||
final boolean isNullable = edmFuntion.getParameter(parameterName).isNullable();
|
final boolean isNullable = edmFunction.getParameter(parameterName).isNullable();
|
||||||
|
|
||||||
if (parameter != null) {
|
if (parameter != null) {
|
||||||
/** No alias, value explicit null */
|
/** No alias, value explicit null */
|
||||||
|
@ -560,7 +555,7 @@ public class UriValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.remove(parameterName);
|
parameters.remove(parameterName);
|
||||||
} else if (!isNullable && !(firstParameter && edmFuntion.isBound())) {
|
} else if (!isNullable && !(firstParameter && edmFunction.isBound())) {
|
||||||
// The first parameter of bound functions is implicit provided by the preceding path segment
|
// The first parameter of bound functions is implicit provided by the preceding path segment
|
||||||
throw new UriValidationException("Missing non nullable parameter " + parameterName,
|
throw new UriValidationException("Missing non nullable parameter " + parameterName,
|
||||||
UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
|
UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
|
||||||
|
@ -586,11 +581,11 @@ public class UriValidator {
|
||||||
if (isEntitySet || pathSegment.getKind() == UriResourceKind.navigationProperty || isEntityColFunction) {
|
if (isEntitySet || pathSegment.getKind() == UriResourceKind.navigationProperty || isEntityColFunction) {
|
||||||
final List<UriParameter> keyPredicates = isEntitySet ?
|
final List<UriParameter> keyPredicates = isEntitySet ?
|
||||||
((UriResourceEntitySet) pathSegment).getKeyPredicates() :
|
((UriResourceEntitySet) pathSegment).getKeyPredicates() :
|
||||||
isEntityColFunction ? ((UriResourceFunction) pathSegment).getKeyPredicates()
|
isEntityColFunction ?
|
||||||
: ((UriResourceNavigation) pathSegment).getKeyPredicates();
|
((UriResourceFunction) pathSegment).getKeyPredicates() :
|
||||||
|
((UriResourceNavigation) pathSegment).getKeyPredicates();
|
||||||
|
|
||||||
if (keyPredicates != null) {
|
if (keyPredicates != null) {
|
||||||
|
|
||||||
final EdmEntityType entityType = isEntitySet ?
|
final EdmEntityType entityType = isEntitySet ?
|
||||||
((UriResourceEntitySet) pathSegment).getEntityType() :
|
((UriResourceEntitySet) pathSegment).getEntityType() :
|
||||||
isEntityColFunction ? (EdmEntityType) ((UriResourceFunction) pathSegment).getType()
|
isEntityColFunction ? (EdmEntityType) ((UriResourceFunction) pathSegment).getType()
|
||||||
|
|
|
@ -290,15 +290,13 @@ public class ExpressionParserTest {
|
||||||
}
|
}
|
||||||
expressionString += ')';
|
expressionString += ')';
|
||||||
|
|
||||||
Expression expression = parseExpression(expressionString);
|
return parseExpression(expressionString);
|
||||||
assertNotNull(expression);
|
|
||||||
return expression;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression parseExpression(final String expressionString)
|
private Expression parseExpression(final String expressionString)
|
||||||
throws UriParserException, UriValidationException {
|
throws UriParserException, UriValidationException {
|
||||||
UriTokenizer tokenizer = new UriTokenizer(expressionString);
|
UriTokenizer tokenizer = new UriTokenizer(expressionString);
|
||||||
Expression expression = new ExpressionParser(mock(Edm.class), odata).parse(tokenizer, null, null);
|
final Expression expression = new ExpressionParser(mock(Edm.class), odata).parse(tokenizer, null, null);
|
||||||
assertNotNull(expression);
|
assertNotNull(expression);
|
||||||
assertTrue(tokenizer.next(TokenKind.EOF));
|
assertTrue(tokenizer.next(TokenKind.EOF));
|
||||||
return expression;
|
return expression;
|
||||||
|
@ -306,7 +304,7 @@ public class ExpressionParserTest {
|
||||||
|
|
||||||
private void wrongExpression(final String expressionString) {
|
private void wrongExpression(final String expressionString) {
|
||||||
try {
|
try {
|
||||||
new ExpressionParser(mock(Edm.class), odata).parse(new UriTokenizer(expressionString), null, null);
|
parseExpression(expressionString);
|
||||||
fail("Expected exception not thrown.");
|
fail("Expected exception not thrown.");
|
||||||
} catch (final UriParserException e) {
|
} catch (final UriParserException e) {
|
||||||
assertNotNull(e);
|
assertNotNull(e);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.uri.antlr;
|
package org.apache.olingo.server.core.uri.parser;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -28,21 +28,9 @@ import org.junit.Test;
|
||||||
/**
|
/**
|
||||||
* Tests originally written for the ANTLR lexer.
|
* Tests originally written for the ANTLR lexer.
|
||||||
*/
|
*/
|
||||||
public class TestLexer {
|
public class LexerTest {
|
||||||
|
|
||||||
private TokenValidator test = null;
|
private TokenValidator test = new TokenValidator();
|
||||||
|
|
||||||
// The last two chars are not in cPCT_ENCODED_UNESCAPED.
|
|
||||||
private static final String cPCT_ENCODED = "%45%46%47" + "%22" + "%5C";
|
|
||||||
private static final String cUNRESERVED = "ABCabc123-._~";
|
|
||||||
private static final String cOTHER_DELIMS = "!()*+,;";
|
|
||||||
private static final String cSUB_DELIMS = "$&'=" + cOTHER_DELIMS;
|
|
||||||
|
|
||||||
private static final String cPCHAR = cUNRESERVED + cPCT_ENCODED + cSUB_DELIMS + ":@";
|
|
||||||
|
|
||||||
public TestLexer() {
|
|
||||||
test = new TokenValidator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unary() {
|
public void unary() {
|
||||||
|
@ -271,7 +259,14 @@ public class TestLexer {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void delims() {
|
public void delims() {
|
||||||
final String reserved = "/";
|
// The last two chars are not in cPCT_ENCODED_UNESCAPED.
|
||||||
|
// final String cPCT_ENCODED = "%45%46%47" + "%22" + "%5C";
|
||||||
|
// final String cUNRESERVED = "ABCabc123-._~";
|
||||||
|
// final String cOTHER_DELIMS = "!()*+,;";
|
||||||
|
// final String cSUB_DELIMS = "$&'=" + cOTHER_DELIMS;
|
||||||
|
|
||||||
|
// private static final String cPCHAR = cUNRESERVED + cPCT_ENCODED + cSUB_DELIMS + ":@";
|
||||||
|
// final String reserved = "/";
|
||||||
// Test lexer rule UNRESERVED
|
// Test lexer rule UNRESERVED
|
||||||
// test.run("$format=A/" + cUNRESERVED).has(TokenKind.FORMAT).isInput();
|
// test.run("$format=A/" + cUNRESERVED).has(TokenKind.FORMAT).isInput();
|
||||||
// test.run("$format=A/" + cUNRESERVED + reserved).has(TokenKind.FORMAT).isText(cUNRESERVED);
|
// test.run("$format=A/" + cUNRESERVED + reserved).has(TokenKind.FORMAT).isText(cUNRESERVED);
|
|
@ -19,7 +19,6 @@
|
||||||
package org.apache.olingo.server.core.uri.parser;
|
package org.apache.olingo.server.core.uri.parser;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -32,13 +31,14 @@ public class UriDecoderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void split() throws Exception {
|
public void split() throws Exception {
|
||||||
assertTrue(UriDecoder.splitAndDecodePath("").isEmpty());
|
assertEquals(Arrays.asList(""), UriDecoder.splitAndDecodePath(""));
|
||||||
assertTrue(UriDecoder.splitAndDecodePath("/").isEmpty());
|
assertEquals(Arrays.asList("", ""), UriDecoder.splitAndDecodePath("/"));
|
||||||
assertEquals(Arrays.asList("a"), UriDecoder.splitAndDecodePath("a"));
|
assertEquals(Arrays.asList("a"), UriDecoder.splitAndDecodePath("a"));
|
||||||
assertEquals(Arrays.asList("a"), UriDecoder.splitAndDecodePath("a/"));
|
assertEquals(Arrays.asList("a", ""), UriDecoder.splitAndDecodePath("a/"));
|
||||||
assertEquals(Arrays.asList("a"), UriDecoder.splitAndDecodePath("/a"));
|
assertEquals(Arrays.asList("", "a"), UriDecoder.splitAndDecodePath("/a"));
|
||||||
assertEquals(Arrays.asList("a", "a"), UriDecoder.splitAndDecodePath("a/a"));
|
assertEquals(Arrays.asList("a", "b"), UriDecoder.splitAndDecodePath("a/b"));
|
||||||
assertEquals(Arrays.asList("a", "a"), UriDecoder.splitAndDecodePath("/a/a"));
|
assertEquals(Arrays.asList("", "a", "b"), UriDecoder.splitAndDecodePath("/a/b"));
|
||||||
|
assertEquals(Arrays.asList("", "a", "", "", "b", ""), UriDecoder.splitAndDecodePath("/a///b/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -49,7 +49,7 @@ public class UriDecoderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void options() throws Exception {
|
public void options() throws Exception {
|
||||||
assertTrue(UriDecoder.splitAndDecodeOptions("").isEmpty());
|
checkOption("", "", "");
|
||||||
|
|
||||||
checkOption("a", "a", "");
|
checkOption("a", "a", "");
|
||||||
checkOption("a=b", "a", "b");
|
checkOption("a=b", "a", "b");
|
||||||
|
@ -67,6 +67,7 @@ public class UriDecoderTest {
|
||||||
|
|
||||||
checkOption("=&=", "", "");
|
checkOption("=&=", "", "");
|
||||||
assertEquals(2, UriDecoder.splitAndDecodeOptions("=&=").size());
|
assertEquals(2, UriDecoder.splitAndDecodeOptions("=&=").size());
|
||||||
|
assertEquals(13, UriDecoder.splitAndDecodeOptions("&&&&&&&&&&&&").size());
|
||||||
|
|
||||||
checkOption("=&c=d", "", "");
|
checkOption("=&c=d", "", "");
|
||||||
checkOption("=&c=d", "c", "d");
|
checkOption("=&c=d", "c", "d");
|
||||||
|
|
|
@ -194,7 +194,7 @@ public class SearchParserAndTokenizerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Validator assertQuery(final String searchQuery) {
|
private static Validator assertQuery(final String searchQuery) {
|
||||||
return Validator.init(searchQuery);
|
return new Validator(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Validator {
|
private static class Validator {
|
||||||
|
@ -204,18 +204,12 @@ public class SearchParserAndTokenizerTest {
|
||||||
this.searchQuery = searchQuery;
|
this.searchQuery = searchQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Validator init(final String searchQuery) {
|
private void resultsIn(final SearchParserException.MessageKey key) throws SearchTokenizerException {
|
||||||
return new Validator(searchQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resultsIn(final SearchParserException.MessageKey key)
|
|
||||||
throws SearchTokenizerException {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
resultsIn(searchQuery);
|
resultsIn(searchQuery);
|
||||||
} catch (SearchParserException e) {
|
} catch (final SearchParserException e) {
|
||||||
Assert.assertEquals("SearchParserException with unexpected message '" + e.getMessage() +
|
Assert.assertEquals("SearchParserException with unexpected message '" + e.getMessage() + "' was thrown.",
|
||||||
"' was thrown.", key, e.getMessageKey());
|
key, e.getMessageKey());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Assert.fail("SearchParserException with message key " + key.getKey() + " was not thrown.");
|
Assert.fail("SearchParserException with message key " + key.getKey() + " was not thrown.");
|
||||||
|
@ -224,23 +218,22 @@ public class SearchParserAndTokenizerTest {
|
||||||
public void resultsInExpectedTerm(final String actualToken) throws SearchTokenizerException {
|
public void resultsInExpectedTerm(final String actualToken) throws SearchTokenizerException {
|
||||||
try {
|
try {
|
||||||
resultsIn(searchQuery);
|
resultsIn(searchQuery);
|
||||||
} catch (SearchParserException e) {
|
} catch (final SearchParserException e) {
|
||||||
Assert.assertEquals(SearchParserException.MessageKeys.EXPECTED_DIFFERENT_TOKEN, e.getMessageKey());
|
Assert.assertEquals(SearchParserException.MessageKeys.EXPECTED_DIFFERENT_TOKEN, e.getMessageKey());
|
||||||
Assert.assertEquals("Expected PHRASE||WORD found: " + actualToken, e.getMessage());
|
Assert.assertEquals("Expected PHRASE||WORD found: " + actualToken, e.getMessage());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
Assert.fail("SearchParserException with message key "
|
||||||
|
+ SearchParserException.MessageKeys.EXPECTED_DIFFERENT_TOKEN + " was not thrown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resultsIn(String expectedSearchExpression) throws SearchTokenizerException, SearchParserException {
|
private void resultsIn(final String expectedSearchExpression)
|
||||||
final SearchExpression searchExpression = getSearchExpression();
|
throws SearchTokenizerException, SearchParserException {
|
||||||
Assert.assertEquals(expectedSearchExpression, searchExpression.toString());
|
final SearchOption result = new SearchParser().parse(searchQuery);
|
||||||
}
|
|
||||||
|
|
||||||
private SearchExpression getSearchExpression() throws SearchParserException, SearchTokenizerException {
|
|
||||||
SearchOption result = new SearchParser().parse(searchQuery);
|
|
||||||
Assert.assertNotNull(result);
|
Assert.assertNotNull(result);
|
||||||
final SearchExpression searchExpression = result.getSearchExpression();
|
final SearchExpression searchExpression = result.getSearchExpression();
|
||||||
Assert.assertNotNull(searchExpression);
|
Assert.assertNotNull(searchExpression);
|
||||||
return searchExpression;
|
Assert.assertEquals(expectedSearchExpression, searchExpression.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,34 +224,34 @@ public class SearchParserTest extends SearchParser {
|
||||||
private void runEx(final MessageKeys key, final Token... tokenArray) {
|
private void runEx(final MessageKeys key, final Token... tokenArray) {
|
||||||
try {
|
try {
|
||||||
run(tokenArray);
|
run(tokenArray);
|
||||||
fail("Expected UriParserSyntaxException with key " + key);
|
fail("Expected SearchParserException with key " + key);
|
||||||
} catch (SearchParserException e) {
|
} catch (SearchParserException e) {
|
||||||
assertEquals(key, e.getMessageKey());
|
assertEquals(key, e.getMessageKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchExpression run(final SearchQueryToken.Token... tokenArray) throws SearchParserException {
|
private SearchExpression run(final Token... tokenArray) throws SearchParserException {
|
||||||
List<SearchQueryToken> tokenList = prepareTokens(tokenArray);
|
List<SearchQueryToken> tokenList = prepareTokens(tokenArray);
|
||||||
SearchExpression se = parse(tokenList);
|
SearchExpression se = parse(tokenList);
|
||||||
assertNotNull(se);
|
assertNotNull(se);
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SearchQueryToken> prepareTokens(final SearchQueryToken.Token... tokenArray) {
|
public List<SearchQueryToken> prepareTokens(final Token... tokenArray) {
|
||||||
ArrayList<SearchQueryToken> tokenList = new ArrayList<SearchQueryToken>();
|
ArrayList<SearchQueryToken> tokenList = new ArrayList<SearchQueryToken>();
|
||||||
int wordNumber = 1;
|
int wordNumber = 1;
|
||||||
int phraseNumber = 1;
|
int phraseNumber = 1;
|
||||||
for (Token aTokenArray : tokenArray) {
|
for (Token aToken : tokenArray) {
|
||||||
SearchQueryToken token = mock(SearchQueryToken.class);
|
SearchQueryToken token = mock(SearchQueryToken.class);
|
||||||
when(token.getToken()).thenReturn(aTokenArray);
|
when(token.getToken()).thenReturn(aToken);
|
||||||
if (aTokenArray == Token.WORD) {
|
if (aToken == Token.WORD) {
|
||||||
when(token.getLiteral()).thenReturn("word" + wordNumber);
|
when(token.getLiteral()).thenReturn("word" + wordNumber);
|
||||||
wordNumber++;
|
wordNumber++;
|
||||||
} else if (aTokenArray == Token.PHRASE) {
|
} else if (aToken == Token.PHRASE) {
|
||||||
when(token.getLiteral()).thenReturn("\"phrase" + phraseNumber + "\"");
|
when(token.getLiteral()).thenReturn("\"phrase" + phraseNumber + "\"");
|
||||||
phraseNumber++;
|
phraseNumber++;
|
||||||
}
|
}
|
||||||
when(token.toString()).thenReturn("" + aTokenArray);
|
when(token.toString()).thenReturn("" + aToken);
|
||||||
tokenList.add(token);
|
tokenList.add(token);
|
||||||
}
|
}
|
||||||
return tokenList;
|
return tokenList;
|
||||||
|
|
|
@ -269,7 +269,7 @@ public class SearchTokenizerTest {
|
||||||
assertQuery("\"\"").resultsIn(SearchTokenizerException.MessageKeys.INVALID_TOKEN_STATE);
|
assertQuery("\"\"").resultsIn(SearchTokenizerException.MessageKeys.INVALID_TOKEN_STATE);
|
||||||
assertQuery("some AND)").resultsIn(SearchTokenizerException.MessageKeys.FORBIDDEN_CHARACTER);
|
assertQuery("some AND)").resultsIn(SearchTokenizerException.MessageKeys.FORBIDDEN_CHARACTER);
|
||||||
assertQuery("some OR)").resultsIn(SearchTokenizerException.MessageKeys.FORBIDDEN_CHARACTER);
|
assertQuery("some OR)").resultsIn(SearchTokenizerException.MessageKeys.FORBIDDEN_CHARACTER);
|
||||||
assertQuery("some NOT)").enableLogging().resultsIn(SearchTokenizerException.MessageKeys.FORBIDDEN_CHARACTER);
|
assertQuery("some NOT)").resultsIn(SearchTokenizerException.MessageKeys.FORBIDDEN_CHARACTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -308,7 +308,6 @@ public class SearchTokenizerTest {
|
||||||
|
|
||||||
private static class Validator {
|
private static class Validator {
|
||||||
private List<Tuple> validations = new ArrayList<Tuple>();
|
private List<Tuple> validations = new ArrayList<Tuple>();
|
||||||
private boolean log;
|
|
||||||
private final String searchQuery;
|
private final String searchQuery;
|
||||||
|
|
||||||
public void resultsIn(final SearchQueryToken.Token... tokens) throws SearchTokenizerException {
|
public void resultsIn(final SearchQueryToken.Token... tokens) throws SearchTokenizerException {
|
||||||
|
@ -345,11 +344,6 @@ public class SearchTokenizerTest {
|
||||||
this.searchQuery = searchQuery;
|
this.searchQuery = searchQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Validator enableLogging() {
|
|
||||||
log = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Validator addExpected(final SearchQueryToken.Token token, final String literal) {
|
private Validator addExpected(final SearchQueryToken.Token token, final String literal) {
|
||||||
validations.add(new Tuple(token, literal));
|
validations.add(new Tuple(token, literal));
|
||||||
return this;
|
return this;
|
||||||
|
@ -368,10 +362,6 @@ public class SearchTokenizerTest {
|
||||||
validate();
|
validate();
|
||||||
} catch (SearchTokenizerException e) {
|
} catch (SearchTokenizerException e) {
|
||||||
Assert.assertEquals("SearchTokenizerException with unexpected message was thrown.", key, e.getMessageKey());
|
Assert.assertEquals("SearchTokenizerException with unexpected message was thrown.", key, e.getMessageKey());
|
||||||
if (log) {
|
|
||||||
System.out.println("Caught SearchTokenizerException with message key " +
|
|
||||||
e.getMessageKey() + " and message " + e.getMessage());
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Assert.fail("No SearchTokenizerException was not thrown.");
|
Assert.fail("No SearchTokenizerException was not thrown.");
|
||||||
|
@ -381,9 +371,6 @@ public class SearchTokenizerTest {
|
||||||
SearchTokenizer tokenizer = new SearchTokenizer();
|
SearchTokenizer tokenizer = new SearchTokenizer();
|
||||||
List<SearchQueryToken> result = tokenizer.tokenize(searchQuery);
|
List<SearchQueryToken> result = tokenizer.tokenize(searchQuery);
|
||||||
Assert.assertNotNull(result);
|
Assert.assertNotNull(result);
|
||||||
if (log) {
|
|
||||||
System.out.println(result);
|
|
||||||
}
|
|
||||||
if (validations.size() != 0) {
|
if (validations.size() != 0) {
|
||||||
Assert.assertEquals(validations.size(), result.size());
|
Assert.assertEquals(validations.size(), result.size());
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.uri.antlr;
|
package org.apache.olingo.server.core.uri.parser;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -3011,6 +3011,11 @@ public class TestFullResourcePath {
|
||||||
testUri.run("$batch")
|
testUri.run("$batch")
|
||||||
.isKind(UriInfoKind.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("$metadata/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
|
||||||
testUri.runEx("$batch/$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("$all/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core.uri.antlr;
|
package org.apache.olingo.server.core.uri.parser;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
|
@ -33,11 +33,11 @@ import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||||
import org.apache.olingo.server.core.uri.UriInfoImpl;
|
import org.apache.olingo.server.core.uri.UriInfoImpl;
|
||||||
|
import org.apache.olingo.server.core.uri.parser.search.SearchTermImpl;
|
||||||
import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl;
|
import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl;
|
||||||
import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
|
import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
//TOOD add getKind check to all
|
|
||||||
public class QueryOptionTest {
|
public class QueryOptionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -196,6 +196,7 @@ public class QueryOptionTest {
|
||||||
@Test
|
@Test
|
||||||
public void testOrderByOptionImpl() {
|
public void testOrderByOptionImpl() {
|
||||||
OrderByOptionImpl option = new OrderByOptionImpl();
|
OrderByOptionImpl option = new OrderByOptionImpl();
|
||||||
|
assertEquals(SystemQueryOptionKind.ORDERBY, option.getKind());
|
||||||
|
|
||||||
OrderByItemImpl order0 = new OrderByItemImpl();
|
OrderByItemImpl order0 = new OrderByItemImpl();
|
||||||
OrderByItemImpl order1 = new OrderByItemImpl();
|
OrderByItemImpl order1 = new OrderByItemImpl();
|
||||||
|
@ -217,14 +218,17 @@ public class QueryOptionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchOptionImpl() {
|
public void searchOptionImpl() {
|
||||||
SearchOptionImpl option = new SearchOptionImpl();
|
SearchOptionImpl option = new SearchOptionImpl();
|
||||||
assertEquals(SystemQueryOptionKind.SEARCH, option.getKind());
|
assertEquals(SystemQueryOptionKind.SEARCH, option.getKind());
|
||||||
// $search is not supported yet
|
|
||||||
|
final SearchTermImpl searchExpression = new SearchTermImpl("A");
|
||||||
|
option.setSearchExpression(searchExpression);
|
||||||
|
assertEquals(searchExpression, option.getSearchExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectItemImpl() {
|
public void selectItemImpl() {
|
||||||
SelectItemImpl option = new SelectItemImpl();
|
SelectItemImpl option = new SelectItemImpl();
|
||||||
|
|
||||||
// no typed collection else case ( e.g. if not path is added)
|
// no typed collection else case ( e.g. if not path is added)
|
||||||
|
@ -244,7 +248,7 @@ public class QueryOptionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectOptionImpl() {
|
public void selectOptionImpl() {
|
||||||
SelectOptionImpl option = new SelectOptionImpl();
|
SelectOptionImpl option = new SelectOptionImpl();
|
||||||
assertEquals(SystemQueryOptionKind.SELECT, option.getKind());
|
assertEquals(SystemQueryOptionKind.SELECT, option.getKind());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue