You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/08/12 10:49:34 UTC
git commit: [OLINGO-388] Duplicate system query options throw
exception
Repository: olingo-odata2
Updated Branches:
refs/heads/master d9e90388f -> 575c59ff7
[OLINGO-388] Duplicate system query options throw exception
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/575c59ff
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/575c59ff
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/575c59ff
Branch: refs/heads/master
Commit: 575c59ff7106ddcb542c9e806c0302775f83c140
Parents: d9e9038
Author: Christian Holzer <c....@sap.com>
Authored: Mon Aug 11 14:25:08 2014 +0200
Committer: Michael Bolz <mi...@apache.org>
Committed: Tue Aug 12 10:33:06 2014 +0200
----------------------------------------------------------------------
.../odata2/api/processor/ODataRequest.java | 14 ++++-
.../apache/olingo/odata2/api/uri/UriParser.java | 16 +++++
.../odata2/api/uri/UriSyntaxException.java | 2 +
.../olingo/odata2/core/ODataRequestHandler.java | 2 +-
.../olingo/odata2/core/ODataRequestImpl.java | 45 +++++++++++---
.../odata2/core/rest/ODataSubLocator.java | 2 +-
.../odata2/core/servlet/ODataServlet.java | 2 +-
.../olingo/odata2/core/servlet/RestUtil.java | 30 ++++++++++
.../olingo/odata2/core/uri/UriParserImpl.java | 62 +++++++++++++++-----
.../src/main/resources/i18n.properties | 1 +
.../core/ODataRequestHandlerValidationTest.java | 16 +++++
.../olingo/odata2/core/uri/UriParserTest.java | 42 +++++++++----
.../fit/basic/HttpExceptionResponseTest.java | 13 +++-
.../fit/basic/LanguageNegotiationTest.java | 6 +-
.../src/test/resources/i18n.properties | 22 -------
.../src/test/resources/i18n_it.properties | 1 +
16 files changed, 212 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataRequest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataRequest.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataRequest.java
index 7dfa43e..8c3190f 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataRequest.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/processor/ODataRequest.java
@@ -50,7 +50,9 @@ public abstract class ODataRequest {
public abstract List<String> getAcceptHeaders();
public abstract Map<String, String> getQueryParameters();
-
+
+ public abstract Map<String, List<String>> getAllQueryParameters();
+
public static ODataRequestBuilder requestHeaders(final Map<String, List<String>> headers) {
return newBuilder().requestHeaders(headers);
}
@@ -82,7 +84,11 @@ public abstract class ODataRequest {
public static ODataRequestBuilder queryParameters(final Map<String, String> queryParameters) {
return newBuilder().queryParameters(queryParameters);
}
-
+
+ public static ODataRequestBuilder allQueryParameters(final Map<String, List<String>> allQueryParameters) {
+ return newBuilder().allQueryParameters(allQueryParameters);
+ }
+
public static ODataRequestBuilder fromRequest(final ODataRequest request) {
return newBuilder().fromRequest(request);
}
@@ -119,7 +125,9 @@ public abstract class ODataRequest {
public abstract ODataRequestBuilder acceptHeaders(List<String> acceptHeaders);
public abstract ODataRequestBuilder queryParameters(Map<String, String> queryParameters);
-
+
+ public abstract ODataRequestBuilder allQueryParameters(Map<String, List<String>> queryParameters);
+
public abstract ODataRequestBuilder fromRequest(ODataRequest request);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java
index 8db63e8..4032306 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriParser.java
@@ -55,6 +55,8 @@ public abstract class UriParser {
/**
* Parses path segments and query parameters.
+ * This method ignores redundant system query parameters.
+ *
* @param pathSegments list of path segments
* @param queryParameters query parameters
* @return {@link UriInfo} information about the parsed URI
@@ -66,6 +68,20 @@ public abstract class UriParser {
throws UriSyntaxException, UriNotMatchingException, EdmException;
/**
+ * Parses path segments and query parameters.
+ * Throws an exception if there are redundant system query parameters.
+ *
+ * @param pathSegments list of path segments
+ * @param queryParameters query parameters
+ * @return {@link UriInfo} information about the parsed URI
+ * @throws UriSyntaxException
+ * @throws UriNotMatchingException
+ * @throws EdmException
+ */
+ public abstract UriInfo parseAll(List<PathSegment> pathSegments, Map<String, List<String>> allQueryParameters)
+ throws UriSyntaxException, UriNotMatchingException, EdmException;
+
+ /**
* Parses a $filter expression string and create an expression tree.
* <p>The current expression parser supports expressions as defined in the
* OData specification 2.0 with the following restrictions:
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriSyntaxException.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriSyntaxException.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriSyntaxException.java
index f719343..480f38d 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriSyntaxException.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/UriSyntaxException.java
@@ -44,6 +44,8 @@ public class UriSyntaxException extends ODataBadRequestException {
"MISSINGKEYPREDICATENAME");
public static final MessageReference DUPLICATEKEYNAMES = createMessageReference(UriSyntaxException.class,
"DUPLICATEKEYNAMES");
+ public static final MessageReference DUPLICATESYSTEMQUERYPARAMETES = createMessageReference(UriSyntaxException.class,
+ "DUPLICATESYSTEMQUERYPARAMETES");
public static final MessageReference EMPTYSEGMENT = createMessageReference(UriSyntaxException.class, "EMPTYSEGMENT");
public static final MessageReference MUSTNOTBELASTSEGMENT = createMessageReference(UriSyntaxException.class,
"MUSTNOTBELASTSEGMENT");
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
index 0b1da19..2f169aa 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
@@ -104,7 +104,7 @@ public class ODataRequestHandler {
final List<PathSegment> pathSegments = context.getPathInfo().getODataSegments();
int timingHandle2 = context.startRuntimeMeasurement("UriParserImpl", "parse");
- uriInfo = (UriInfoImpl) uriParser.parse(pathSegments, request.getQueryParameters());
+ uriInfo = (UriInfoImpl) uriParser.parseAll(pathSegments, request.getAllQueryParameters());
context.stopRuntimeMeasurement(timingHandle2);
final ODataHttpMethod method = request.getMethod();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestImpl.java
index 67e77b4..41a45a7 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestImpl.java
@@ -21,6 +21,7 @@ package org.apache.olingo.odata2.core;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -41,6 +42,7 @@ public class ODataRequestImpl extends ODataRequest {
private InputStream body;
private PathInfo pathInfo;
private Map<String, String> queryParameters;
+ private Map<String, List<String>> allQueryParameters;
private List<String> acceptHeaders;
private ContentType contentType;
private List<Locale> acceptableLanguages;
@@ -91,12 +93,17 @@ public class ODataRequestImpl extends ODataRequest {
return pathInfo;
}
+ @Override
+ public Map<String, List<String>> getAllQueryParameters() {
+ return allQueryParameters;
+ }
+
public class ODataRequestBuilderImpl extends ODataRequestBuilder {
private ODataHttpMethod method;
private CaseInsensitiveMap requestHeaders = new CaseInsensitiveMap();
private InputStream body;
private PathInfo pathInfo;
- private Map<String, String> queryParameters;
+ private Map<String, List<String>> allQueryParameters = new HashMap<String, List<String>>();
private List<String> acceptHeaders;
private ContentType contentType;
private List<Locale> acceptableLanguages;
@@ -107,10 +114,12 @@ public class ODataRequestImpl extends ODataRequest {
ODataRequestImpl.this.requestHeaders = requestHeaders;
ODataRequestImpl.this.body = body;
ODataRequestImpl.this.pathInfo = pathInfo;
- ODataRequestImpl.this.queryParameters = queryParameters;
+ queryParameters = convertMultiMaptoSingleMap(allQueryParameters);
+ ODataRequestImpl.this.allQueryParameters = allQueryParameters;
ODataRequestImpl.this.acceptHeaders = acceptHeaders;
ODataRequestImpl.this.contentType = contentType;
ODataRequestImpl.this.acceptableLanguages = acceptableLanguages;
+
return ODataRequestImpl.this;
}
@@ -156,7 +165,18 @@ public class ODataRequestImpl extends ODataRequest {
@Override
public ODataRequestBuilder queryParameters(final Map<String, String> queryParameters) {
- this.queryParameters = queryParameters;
+ for (String key : queryParameters.keySet()) {
+ List<String> parameterValues = new LinkedList<String>();
+ parameterValues.add(queryParameters.get(key));
+
+ allQueryParameters.put(key, parameterValues);
+ }
+ return this;
+ }
+
+ @Override
+ public ODataRequestBuilder allQueryParameters(final Map<String, List<String>> allQueryParameters) {
+ this.allQueryParameters = new HashMap<String, List<String>>(allQueryParameters);
return this;
}
@@ -192,16 +212,25 @@ public class ODataRequestImpl extends ODataRequest {
acceptableLanguages.add(acceptLanguage);
}
}
- if (request.getQueryParameters() != null) {
- queryParameters = new HashMap<String, String>();
- for (Map.Entry<String, String> queryParameter : request.getQueryParameters().entrySet()) {
+ if (request.getAllQueryParameters() != null) {
+ allQueryParameters = new HashMap<String, List<String>>();
+ for (Map.Entry<String, List<String>> queryParameter : request.getAllQueryParameters().entrySet()) {
String queryParameterName = queryParameter.getKey();
- queryParameters.put(queryParameterName, queryParameter.getValue());
+ allQueryParameters.put(queryParameterName, request.getAllQueryParameters().get(queryParameterName));
}
}
return this;
}
+ private <T, K> Map<T, K> convertMultiMaptoSingleMap(final Map<T, List<K>> multiMap) {
+ final Map<T, K> singleMap = new HashMap<T, K>();
+
+ for (T key : multiMap.keySet()) {
+ singleMap.put(key, multiMap.get(key).get(0));
+ }
+
+ return singleMap;
+ }
}
private class CaseInsensitiveMap extends HashMap<String, List<String>> {
@@ -224,4 +253,4 @@ public class ODataRequestImpl extends ODataRequest {
return super.get(skey.toLowerCase());
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataSubLocator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataSubLocator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataSubLocator.java
index 2c207bb..7ab9ee1 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataSubLocator.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataSubLocator.java
@@ -166,7 +166,7 @@ public final class ODataSubLocator {
.acceptHeaders(RestUtil.extractAcceptHeaders(param))
.body(RestUtil.contentAsStream(RestUtil.extractRequestContent(param)))
.pathInfo(RestUtil.buildODataPathInfo(param))
- .queryParameters(RestUtil.convertToSinglevaluedMap(param.getUriInfo().getQueryParameters()))
+ .allQueryParameters(param.getUriInfo().getQueryParameters())
.requestHeaders(param.getHttpHeaders().getRequestHeaders())
.contentType(RestUtil.extractRequestContentType(param).toContentTypeString())
.build();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
index 5078e4b..1d4dfe3 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
@@ -166,7 +166,7 @@ public class ODataServlet extends HttpServlet {
.acceptHeaders(RestUtil.extractAcceptHeaders(req.getHeader(HttpHeaders.ACCEPT)))
.acceptableLanguages(RestUtil.extractAcceptableLanguage(req.getHeader(HttpHeaders.ACCEPT_LANGUAGE)))
.pathInfo(RestUtil.buildODataPathInfo(req, pathSplit))
- .queryParameters(RestUtil.extractQueryParameters(req.getQueryString()))
+ .allQueryParameters(RestUtil.extractAllQueryParameters(req.getQueryString()))
.requestHeaders(RestUtil.extractHeaders(req))
.body(req.getInputStream())
.build();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
index 36a1f65..6e06bc1 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -104,6 +105,35 @@ public class RestUtil {
return queryParametersMap;
}
+ public static Map<String, List<String>> extractAllQueryParameters(final String queryString) {
+ Map<String, List<String>> allQueryParameterMap = new HashMap<String, List<String>>();
+
+ if (queryString != null) {
+ // At first the queryString will be decoded.
+ List<String> queryParameters = Arrays.asList(Decoder.decode(queryString).split("\\&"));
+ for (String param : queryParameters) {
+ int indexOfEqualSign = param.indexOf("=");
+
+ if (indexOfEqualSign < 0) {
+ final List<String> parameterList = allQueryParameterMap.containsKey(param) ? allQueryParameterMap.get(param)
+ : new LinkedList<String>();
+ allQueryParameterMap.put(param, parameterList);
+
+ parameterList.add("");
+ } else {
+ final String key = param.substring(0, indexOfEqualSign);
+ final List<String> parameterList = allQueryParameterMap.containsKey(key) ? allQueryParameterMap.get(key)
+ : new LinkedList<String>();
+
+ allQueryParameterMap.put(key, parameterList);
+ parameterList.add(param.substring(indexOfEqualSign + 1));
+ }
+ }
+ }
+
+ return allQueryParameterMap;
+ }
+
/*
* Parses Accept-Language header. Returns a list sorted by quality parameter
*/
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java
index 2f0a286..c58f7ae 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java
@@ -21,6 +21,7 @@ package org.apache.olingo.odata2.core.uri;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@@ -102,6 +103,14 @@ public class UriParserImpl extends UriParser {
@Override
public UriInfo parse(final List<PathSegment> pathSegments, final Map<String, String> queryParameters)
throws UriSyntaxException, UriNotMatchingException, EdmException {
+
+ return parseAll(pathSegments, convertFromSingleMapToMultiMap(queryParameters));
+ }
+
+ @Override
+ public UriInfo parseAll(final List<PathSegment> pathSegments, final Map<String, List<String>> allQueryParameters)
+ throws UriSyntaxException, UriNotMatchingException, EdmException {
+
this.pathSegments = copyPathSegmentList(pathSegments);
systemQueryOptions = new HashMap<SystemQueryOption, String>();
otherQueryParameters = new HashMap<String, String>();
@@ -111,7 +120,7 @@ public class UriParserImpl extends UriParser {
handleResourcePath();
- distributeQueryParameters(queryParameters);
+ distributeQueryParameters(allQueryParameters);
checkSystemQueryOptionsCompatibility();
handleSystemQueryOptions();
handleOtherQueryParameters();
@@ -119,6 +128,19 @@ public class UriParserImpl extends UriParser {
return uriResult;
}
+ private <T, K> Map<T, List<K>> convertFromSingleMapToMultiMap(final Map<T, K> singleMap) {
+ Map<T, List<K>> multiMap = new HashMap<T, List<K>>();
+
+ for (T key : singleMap.keySet()) {
+ List<K> valueList = new LinkedList<K>();
+ valueList.add(singleMap.get(key));
+
+ multiMap.put(key, valueList);
+ }
+
+ return multiMap;
+ }
+
private void preparePathSegments() throws UriSyntaxException {
// Remove an empty path segment at the start of the OData part of the resource path.
if (!pathSegments.isEmpty() && pathSegments.get(0).equals("")) {
@@ -508,23 +530,35 @@ public class UriParserImpl extends UriParser {
ensureLastSegment();
}
- private void distributeQueryParameters(final Map<String, String> queryParameters) throws UriSyntaxException {
+ private void distributeQueryParameters(final Map<String, List<String>> queryParameters) throws UriSyntaxException {
for (final String queryOptionString : queryParameters.keySet()) {
- final String value = queryParameters.get(queryOptionString);
- if (queryOptionString.startsWith("$")) {
- SystemQueryOption queryOption;
- try {
- queryOption = SystemQueryOption.valueOf(queryOptionString);
- } catch (IllegalArgumentException e) {
- throw new UriSyntaxException(UriSyntaxException.INVALIDSYSTEMQUERYOPTION.addContent(queryOptionString), e);
- }
- if ("".equals(value)) {
- throw new UriSyntaxException(UriSyntaxException.INVALIDNULLVALUE.addContent(queryOptionString));
+ final List<String> valueList = queryParameters.get(queryOptionString);
+
+ if (valueList.size() >= 1) {
+ String value = valueList.get(0);
+
+ if (queryOptionString.startsWith("$")) {
+ SystemQueryOption queryOption;
+ try {
+ queryOption = SystemQueryOption.valueOf(queryOptionString);
+ } catch (IllegalArgumentException e) {
+ throw new UriSyntaxException(UriSyntaxException.INVALIDSYSTEMQUERYOPTION.addContent(queryOptionString), e);
+ }
+ if ("".equals(value)) {
+ throw new UriSyntaxException(UriSyntaxException.INVALIDNULLVALUE.addContent(queryOptionString));
+ } else {
+ if (valueList.size() == 1 && !systemQueryOptions.containsKey(queryOption)) {
+ systemQueryOptions.put(queryOption, value);
+ } else {
+ throw new UriSyntaxException(UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES
+ .addContent(queryOptionString));
+ }
+ }
} else {
- systemQueryOptions.put(queryOption, value);
+ otherQueryParameters.put(queryOptionString, value);
}
} else {
- otherQueryParameters.put(queryOptionString, value);
+ throw new UriSyntaxException(UriSyntaxException.INVALIDNULLVALUE.addContent(queryOptionString));
}
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/main/resources/i18n.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/resources/i18n.properties b/odata2-lib/odata-core/src/main/resources/i18n.properties
index cc2ca5f..90b7045 100644
--- a/odata2-lib/odata-core/src/main/resources/i18n.properties
+++ b/odata2-lib/odata-core/src/main/resources/i18n.properties
@@ -40,6 +40,7 @@ org.apache.olingo.odata2.api.uri.UriSyntaxException.NONAVIGATIONPROPERTY=Propert
org.apache.olingo.odata2.api.uri.UriSyntaxException.MISSINGPARAMETER=Missing parameter.
org.apache.olingo.odata2.api.uri.UriSyntaxException.MISSINGKEYPREDICATENAME=Missing key predicate name for key: '%1$s'.
org.apache.olingo.odata2.api.uri.UriSyntaxException.DUPLICATEKEYNAMES=Duplicate key names: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES=Duplicate system query parameter names: '%1$s'.
org.apache.olingo.odata2.api.uri.UriSyntaxException.EMPTYSEGMENT=No empty segment allowed.
org.apache.olingo.odata2.api.uri.UriSyntaxException.MUSTNOTBELASTSEGMENT='%1$s' must not be the last segment.
org.apache.olingo.odata2.api.uri.UriSyntaxException.MUSTBELASTSEGMENT='%1$s' must be the last segment.
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
index b46da46..7105c93 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -232,6 +233,8 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
when(request.getPathInfo()).thenReturn(pathInfo);
when(request.getQueryParameters()).thenReturn(
queryParameters == null ? Collections.<String, String> emptyMap() : queryParameters);
+ when(request.getAllQueryParameters()).thenReturn(queryParameters == null ?
+ Collections.<String, List<String>> emptyMap() : convertToMultiMap(queryParameters));
when(request.getContentType()).thenReturn(
requestContentType == null ? HttpContentType.APPLICATION_JSON : requestContentType);
when(request.getRequestHeaderValue(httpHeaderName)).thenReturn(httpHeaderValue);
@@ -241,6 +244,19 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
return request;
}
+ private Map<String, List<String>> convertToMultiMap(final Map<String, String> queryParameters) {
+ Map<String, List<String>> multiMap = new HashMap<String, List<String>>();
+
+ for (final String key : queryParameters.keySet()) {
+ List<String> parameterList = new LinkedList<String>();
+ parameterList.add(queryParameters.get(key));
+
+ multiMap.put(key, parameterList);
+ }
+
+ return multiMap;
+ }
+
private ODataService mockODataService(final ODataServiceFactory serviceFactory) throws ODataException {
ODataService service = DispatcherTest.getMockService();
when(service.getEntityDataModel()).thenReturn(edm);
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java
index c3e457d..0c64844 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -81,19 +82,25 @@ public class UriParserTest extends BaseTest {
final List<PathSegment> pathSegments =
MockFacade.getPathSegmentsAsODataPathSegmentMock(Arrays.asList(path[0].split("/", -1)));
- final Map<String, String> queryParameters =
- getQueryParameters(path.length == 2 ? unescape(path[1]) : "");
+ final Map<String, List<String>> queryParameters = getQueryParameters(path.length == 2 ? unescape(path[1]) : "");
- return (UriInfoImpl) new UriParserImpl(edm).parse(pathSegments, queryParameters);
+ return (UriInfoImpl) new UriParserImpl(edm).parseAll(pathSegments, queryParameters);
}
- private Map<String, String> getQueryParameters(final String uri) {
- Map<String, String> queryParameters = new HashMap<String, String>();
+ private Map<String, List<String>> getQueryParameters(final String uri) {
+ Map<String, List<String>> allQueryParameters = new HashMap<String, List<String>>();
+
for (final String option : uri.split("&")) {
final String[] keyAndValue = option.split("=");
- queryParameters.put(keyAndValue[0], keyAndValue.length == 2 ? keyAndValue[1] : "");
+ List<String> list = allQueryParameters.containsKey(keyAndValue[0]) ?
+ allQueryParameters.get(keyAndValue[0]) : new LinkedList<String>();
+
+ list.add(keyAndValue.length == 2 ? keyAndValue[1] : "");
+
+ allQueryParameters.put(keyAndValue[0], list);
}
- return queryParameters;
+
+ return allQueryParameters;
}
private String unescape(final String s) throws UriSyntaxException {
@@ -667,9 +674,6 @@ public class UriParserTest extends BaseTest {
assertEquals("xml", result.getFormat());
assertNull(result.getTop());
- result = parse("Employees?$format=xml&$format=json");
- assertEquals("json", result.getFormat());
-
result = parse("Employees?$format=custom/*");
assertNotNull(result.getFormat());
assertEquals("custom/*", result.getFormat().toString());
@@ -708,6 +712,24 @@ public class UriParserTest extends BaseTest {
}
@Test
+ public void parseWrongRedundantSystemQueryOptions() throws Exception {
+ parseWrongUri("Employees?$top=1&$top=2", UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$top=1&$skip=1&$top=2", UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$top=1&$top=1", UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$skip=1&$skip=2", UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$expand=ne_Manager&$expand=ne_Manager", UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$orderby=Name%20desc&$orderby=Birthday%20desc",
+ UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$select=EmployeeName&$select=EmployeeName",
+ UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$filter=EmployeeName%20eq%20'Foo'&$filter=EmployeeName%20ne%20'Bar'",
+ UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$inlinecount=allpages&$inlinecount=none",
+ UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ parseWrongUri("Employees?$format=xml&$format=json", UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES);
+ }
+
+ @Test
public void parseWrongSystemQueryOptionSkip() throws Exception {
parseWrongUri("Employees?$skip=-1", UriSyntaxException.INVALIDNEGATIVEVALUE);
parseWrongUri("Employees?$skip=-0", UriSyntaxException.INVALIDNEGATIVEVALUE);
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/HttpExceptionResponseTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/HttpExceptionResponseTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/HttpExceptionResponseTest.java
index 8fbba2f..1bb8f69 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/HttpExceptionResponseTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/HttpExceptionResponseTest.java
@@ -95,7 +95,18 @@ public class HttpExceptionResponseTest extends AbstractBasicTest {
assertXpathValuesEqual("\"" + MessageService.getMessage(Locale.ENGLISH, ODataNotFoundException.ENTITY).getText()
+ "\"", "/a:error/a:message", content);
}
-
+
+ @Test
+ public void test400BadRequestRedundantSystemQueryOptions() throws Exception {
+ HttpResponse response = executeGetRequest("Employees?$top=1&$top=3");
+ assertEquals(HttpStatusCodes.BAD_REQUEST.getStatusCode(), response.getStatusLine().getStatusCode());
+
+ final String content = StringHelper.inputStreamToString(response.getEntity().getContent());
+ assertEquals("<?xml version='1.0' encoding='UTF-8'?><error xmlns=\"http://schemas.microsoft.com/ado/2007/"
+ + "08/dataservices/metadata\"><code/><message xml:lang=\"en\">Duplicate system query parameter names: "
+ + "'$top'.</message></error>", content);
+ }
+
@Test
public void genericHttpExceptions() throws Exception {
disableLogging();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/LanguageNegotiationTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/LanguageNegotiationTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/LanguageNegotiationTest.java
index 3d46b45..ecbd893 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/LanguageNegotiationTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/LanguageNegotiationTest.java
@@ -100,7 +100,7 @@ public class LanguageNegotiationTest extends AbstractBasicTest {
assertXpathExists("/m:error/m:message", content);
assertXpathExists("/m:error/m:message[@xml:lang=\"it\"]", content);
- assertXpathEvaluatesTo("itLanguage", "/m:error/m:message/text()", content);
+ assertXpathEvaluatesTo("eccezione comune", "/m:error/m:message/text()", content);
}
@@ -114,11 +114,11 @@ public class LanguageNegotiationTest extends AbstractBasicTest {
assertXpathExists("/m:error/m:message", content);
assertXpathExists("/m:error/m:message[@xml:lang=\"en\"]", content);
- assertXpathEvaluatesTo("fallbackLanguage", "/m:error/m:message/text()", content);
+ assertXpathEvaluatesTo("Common exception", "/m:error/m:message/text()", content);
}
private static class MyException extends ODataMessageException {
- private static final MessageReference TEST = createMessageReference(MyException.class, "TEST");
+ private static final MessageReference TEST = createMessageReference(ODataMessageException.class, "COMMON");
private static final long serialVersionUID = 1L;
/**
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-fit/src/test/resources/i18n.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/resources/i18n.properties b/odata2-lib/odata-fit/src/test/resources/i18n.properties
deleted file mode 100644
index ae7c98b..0000000
--- a/odata2-lib/odata-fit/src/test/resources/i18n.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-#-------------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#-------------------------------------------------------------------------------
-# Language Negotiation Test
-#
-
-org.apache.olingo.odata2.fit.basic.LanguageNegotiationTest$MyException.TEST=fallbackLanguage
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/575c59ff/odata2-lib/odata-fit/src/test/resources/i18n_it.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/resources/i18n_it.properties b/odata2-lib/odata-fit/src/test/resources/i18n_it.properties
index 12d072b..1320e74 100644
--- a/odata2-lib/odata-fit/src/test/resources/i18n_it.properties
+++ b/odata2-lib/odata-fit/src/test/resources/i18n_it.properties
@@ -20,3 +20,4 @@
#
org.apache.olingo.odata2.fit.basic.LanguageNegotiationTest$MyException.TEST=itLanguage
+org.apache.olingo.odata2.api.exception.ODataMessageException.COMMON=eccezione comune