You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2018/03/12 08:37:31 UTC
olingo-odata4 git commit: [OLINGO-1238] Code Improvements in handling
exceptions with odataVersion headers and accept headers
Repository: olingo-odata4
Updated Branches:
refs/heads/master 75cc7197e -> eb112032d
[OLINGO-1238] Code Improvements in handling exceptions with odataVersion headers and accept headers
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/eb112032
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/eb112032
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/eb112032
Branch: refs/heads/master
Commit: eb112032ddc0fa5264b91811d8a5ce4020326d0f
Parents: 75cc719
Author: ramya vasanth <ra...@sap.com>
Authored: Mon Mar 12 14:07:22 2018 +0530
Committer: ramya vasanth <ra...@sap.com>
Committed: Mon Mar 12 14:07:22 2018 +0530
----------------------------------------------------------------------
.../AcceptHeaderAcceptCharsetHeaderITCase.java | 336 +++++++++++++++++++
.../http/ODataVersionConformanceITCase.java | 179 ++++++++++
.../api/edm/constants/ODataServiceVersion.java | 15 +
.../commons/api/format/AcceptCharset.java | 155 +++++++++
.../olingo/commons/api/format/AcceptType.java | 31 +-
.../commons/api/format/AcceptCharsetTest.java | 132 ++++++++
.../commons/api/format/AcceptTypeTest.java | 93 ++++-
.../AcceptHeaderContentNegotiatorException.java | 53 +++
.../olingo/server/core/ContentNegotiator.java | 73 +++-
.../server/core/ContentNegotiatorException.java | 6 +-
.../server/core/ODataExceptionHelper.java | 7 +
.../olingo/server/core/ODataHandlerImpl.java | 20 +-
.../server-core-exceptions-i18n.properties | 6 +
.../server/core/ContentNegotiatorTest.java | 79 ++++-
.../server/core/ODataHandlerImplTest.java | 173 ++++++++++
15 files changed, 1327 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/AcceptHeaderAcceptCharsetHeaderITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/AcceptHeaderAcceptCharsetHeaderITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/AcceptHeaderAcceptCharsetHeaderITCase.java
new file mode 100644
index 0000000..b60ebb0
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/AcceptHeaderAcceptCharsetHeaderITCase.java
@@ -0,0 +1,336 @@
+/*
+ * 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.fit.tecsvc.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.junit.Test;
+
+public class AcceptHeaderAcceptCharsetHeaderITCase extends AbstractBaseTestITCase {
+
+ private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
+
+ @Test
+ public void validAcceptHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void invalidAcceptHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT, "abc");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The content-type range 'abc' is not supported "
+ + "as value of the Accept header."));
+ }
+
+ @Test
+ public void invalidAcceptHeader2() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/xyz");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The content-type range 'application/xyz' is "
+ + "not supported as value of the Accept header."));
+ }
+
+ @Test
+ public void validAcceptCharsetHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "utf-8;q=0.1");
+ connection.setRequestProperty(HttpHeader.ACCEPT, ContentType.APPLICATION_JSON.toContentTypeString());
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(3, contentType.getParameters().size());
+ assertEquals("0.1", contentType.getParameter("q"));
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+ assertEquals("utf-8", contentType.getParameter("charset"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void invalidAcceptCharsetHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "US-ASCII");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The charset specified in Accept charset header "
+ + "'US-ASCII' is not supported."));
+ }
+
+ @Test
+ public void invalidAcceptCharsetHeader2() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "abc");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The charset specified in Accept charset header 'abc' is not supported."));
+ }
+
+ @Test
+ public void unsupportedAcceptHeaderWithSupportedAcceptCharsetHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "utf8;q=0.1");
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;charset=iso8859-1");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(3, contentType.getParameters().size());
+ assertEquals("0.1", contentType.getParameter("q"));
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+ assertEquals("utf8", contentType.getParameter("charset"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void supportedAcceptHeaderWithUnSupportedAcceptCharsetHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "iso-8859-1");
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;charset=utf8");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The charset specified in Accept charset header "
+ + "'iso-8859-1' is not supported."));
+ }
+
+ @Test
+ public void validFormatWithAcceptCharsetHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim?$format=json");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "utf-8;q=0.1");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(3, contentType.getParameters().size());
+ assertEquals("0.1", contentType.getParameter("q"));
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+ assertEquals("utf-8", contentType.getParameter("charset"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void validFormatWithUnsupportedAcceptCharsetHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim?$format=json");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "iso-8859-1");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The charset specified in Accept charset header "
+ + "'iso-8859-1' is not supported."));
+ }
+
+ @Test
+ public void validFormatWithIllegalAcceptCharsetHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim?$format=json");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "abc");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("The charset specified in Accept charset "
+ + "header 'abc' is not supported."));
+ }
+
+ @Test
+ public void multipleValuesInAcceptCharsetHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "utf-8;q=0.1,iso-8859-1,unicode-1-1");
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(3, contentType.getParameters().size());
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+ assertEquals("utf-8", contentType.getParameter("charset"));
+ assertEquals("0.1", contentType.getParameter("q"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void multipleValuesInAcceptCharsetHeader2() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT_CHARSET, "utf-8;q=0.1,utf-8;q=0.8,utf8");
+ connection.setRequestProperty(HttpHeader.ACCEPT, ContentType.APPLICATION_JSON.toContentTypeString());
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(2, contentType.getParameters().size());
+ assertEquals("utf8", contentType.getParameter("charset"));
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void multipleValuesInAcceptHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json,"
+ + "application/json;q=0.1,application/json;q=0.8");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(1, contentType.getParameters().size());
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void multipleValuesInAcceptHeader2() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ACCEPT, "application/json,"
+ + "application/json;q=0.1,application/json;q=0.8,abc");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertNotNull(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ ContentType contentType = ContentType.parse(connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+ assertEquals("application", contentType.getType());
+ assertEquals("json", contentType.getSubtype());
+ assertEquals(1, contentType.getParameters().size());
+ assertEquals("minimal", contentType.getParameter("odata.metadata"));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Override
+ protected ODataClient getClient() {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/ODataVersionConformanceITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/ODataVersionConformanceITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/ODataVersionConformanceITCase.java
new file mode 100644
index 0000000..a8c8912
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/ODataVersionConformanceITCase.java
@@ -0,0 +1,179 @@
+/*
+ * 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.fit.tecsvc.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.junit.Test;
+
+public class ODataVersionConformanceITCase extends AbstractBaseTestITCase {
+
+ private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
+
+ @Test
+ public void invalidODataVersionHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_VERSION, "3.0");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("OData version '3.0' is not supported."));
+ }
+
+ @Test
+ public void invalidODataVersionHeader2() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_VERSION, "5.0");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("OData version '5.0' is not supported."));
+ }
+
+ @Test
+ public void invalidODataMaxVersionHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "3.0");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("OData version '3.0' is not supported."));
+ }
+
+ @Test
+ public void validODataMaxVersionHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "5.0");
+ connection.connect();
+
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void validODataVersionAndMaxVersionHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_VERSION, "4.0");
+ connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "5.0");
+ connection.connect();
+
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertNotNull(content);;
+ }
+
+ @Test
+ public void validODataVersionAndMaxVersionHeader1() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim?$format=json");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_VERSION, "4.0");
+ connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "4.01");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+ assertEquals("application/json; odata.metadata=minimal",
+ connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void validODataVersionAndMaxVersionHeader2() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim?$format=json");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_VERSION, "4.0");
+ connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "4.0");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+ assertEquals("application/json; odata.metadata=minimal",
+ connection.getHeaderField(HttpHeader.CONTENT_TYPE));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+ assertNotNull(content);
+ }
+
+ @Test
+ public void invalidODataVersionAndMaxVersionHeader() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty(HttpHeader.ODATA_VERSION, "5.0");
+ connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "5.0");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
+ assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
+
+ final String content = IOUtils.toString(connection.getErrorStream());
+ assertTrue(content.contains("OData version '5.0' is not supported."));
+ }
+
+ @Override
+ protected ODataClient getClient() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
index c781191..1ef8929 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
@@ -87,6 +87,21 @@ public enum ODataServiceVersion {
return me > other;
}
+ public static boolean isValidODataVersion(String value) {
+ final double version4 = Double.parseDouble(extractDataServiceVersionString(ODataServiceVersion.V40.toString()));
+ final double version401 = Double.parseDouble(extractDataServiceVersionString(ODataServiceVersion.V401.toString()));
+ final double other = Double.parseDouble(extractDataServiceVersionString(value));
+
+ return (other == version4) || (other == version401);
+ }
+
+ public static boolean isValidMaxODataVersion(String value) {
+ final double version4 = Double.parseDouble(extractDataServiceVersionString(ODataServiceVersion.V40.toString()));
+ final double other = Double.parseDouble(extractDataServiceVersionString(value));
+
+ return other >= version4;
+ }
+
/**
* Extract data service version and return it.
*
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptCharset.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptCharset.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptCharset.java
new file mode 100644
index 0000000..85eaf91
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptCharset.java
@@ -0,0 +1,155 @@
+/*
+ * 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.commons.api.format;
+
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class AcceptCharset {
+
+ private static final Pattern Q_PATTERN = Pattern.compile("\\A(?:0(?:\\.\\d{0,3})?)|(?:1(?:\\.0{0,3})?)\\Z");
+ private final String charset;
+ private final Map<String, String> parameters;
+ private final Float quality;
+
+ private AcceptCharset(final String charset) {
+ parameters = TypeUtil.createParameterMap();
+ this.charset = parse(charset, parameters);
+
+ if (TypeUtil.MEDIA_TYPE_WILDCARD.equals(this.charset)) {
+ throw new IllegalArgumentException("Unsupported charset in accept charset header:" + this.charset);
+ } else {
+ try {
+ Charset.forName(this.charset);
+ } catch (UnsupportedCharsetException e) {
+ throw new UnsupportedCharsetException("Illegal charset in accept charset header:" + this.charset);
+ }
+ if (!(this.charset.equalsIgnoreCase("utf8")) && !(this.charset.equalsIgnoreCase("utf-8"))) {
+ throw new IllegalArgumentException("Unsupported charset in accept charset header:" + this.charset);
+ }
+ }
+ final String q = parameters.get(TypeUtil.PARAMETER_Q);
+ if (q == null) {
+ quality = 1F;
+ } else if (Q_PATTERN.matcher(q).matches()) {
+ quality = Float.valueOf(q);
+ } else {
+ throw new IllegalArgumentException("Illegal quality parameter '" + q + "'.");
+ }
+ }
+
+ private String parse(String acceptCharset, Map<String, String> parameters) {
+ final String[] charsetAndParameters = acceptCharset.split(TypeUtil.PARAMETER_SEPARATOR, 2);
+ acceptCharset = charsetAndParameters[0];
+ final String params = (charsetAndParameters.length > 1 ? charsetAndParameters[1] : null);
+ TypeUtil.parseParameters(params, parameters);
+ return acceptCharset;
+ }
+
+ /**
+ * Creates a list of {@link AcceptCharset} objects based on given input string.
+ * @param acceptCharsets accept types, comma-separated, as specified for the HTTP header <code>Accept-Charset</code>
+ * @return a list of <code>AcceptType</code> objects
+ * @throws Exception
+ * @throws IllegalArgumentException if input string is not parseable
+ */
+ public static List<AcceptCharset> create(final String acceptCharsets) {
+ if (acceptCharsets == null) {
+ throw new IllegalArgumentException("Type parameter MUST NOT be null.");
+ }
+ List<AcceptCharset> result = new ArrayList<AcceptCharset>();
+ List<Exception> exceptionList = new ArrayList<Exception>();
+
+ String[] values = acceptCharsets.split(",");
+ for (String value : values) {
+ try {
+ result.add(new AcceptCharset(value.trim()));
+ } catch (UnsupportedCharsetException e) {
+ exceptionList.add(e);
+ } catch (IllegalArgumentException e) {
+ exceptionList.add(e);
+ }
+ }
+
+ if (result.isEmpty()) {
+ if (exceptionList.get(0) instanceof UnsupportedCharsetException) {
+ throw new UnsupportedCharsetException(exceptionList.get(0).getMessage());
+ } else if (exceptionList.get(0) instanceof IllegalArgumentException) {
+ throw new IllegalArgumentException(exceptionList.get(0).getMessage());
+ }
+ }
+ sort(result);
+
+ return result;
+ }
+
+ public String getCharset() {
+ return charset;
+ }
+
+ public Map<String, String> getParameters() {
+ return Collections.unmodifiableMap(parameters);
+ }
+
+ public String getParameter(final String name) {
+ return parameters.get(name.toLowerCase(Locale.ROOT));
+ }
+
+ public Float getQuality() {
+ return quality;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append(charset);
+ for (final Map.Entry<String, String> entry : parameters.entrySet()) {
+ result.append(';').append(entry.getKey()).append('=').append(entry.getValue());
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Sorts given list of Accept charsets
+ * according to their quality-parameter values and their specificity
+ * as defined in RFC 2616, chapters 14.2.
+ * @param toSort list which is sorted and hence re-arranged
+ */
+ private static void sort(List<AcceptCharset> toSort) {
+ Collections.sort(toSort,
+ new Comparator<AcceptCharset>() {
+ @Override
+ public int compare(final AcceptCharset a1, final AcceptCharset a2) {
+ int compare = a2.getQuality().compareTo(a1.getQuality());
+ if (compare != 0) {
+ return compare;
+ }
+ return a2.getParameters().size() - a1.getParameters().size();
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptType.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptType.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptType.java
index f864008..d2a1b24 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptType.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/AcceptType.java
@@ -63,9 +63,6 @@ public final class AcceptType {
}
private AcceptType(final String type) {
- if (type == null) {
- throw new IllegalArgumentException("Type parameter MUST NOT be null.");
- }
List<String> typeSubtype = new ArrayList<String>();
parameters = TypeUtil.createParameterMap();
@@ -119,13 +116,24 @@ public final class AcceptType {
* @throws IllegalArgumentException if input string is not parseable
*/
public static List<AcceptType> create(final String acceptTypes) {
+ if (acceptTypes == null) {
+ throw new IllegalArgumentException("Type parameter MUST NOT be null.");
+ }
List<AcceptType> result = new ArrayList<AcceptType>();
+ List<IllegalArgumentException> exceptionList = new ArrayList<IllegalArgumentException>();
String[] values = acceptTypes.split(",");
for (String value : values) {
- result.add(new AcceptType(value.trim()));
+ try {
+ result.add(new AcceptType(value.trim()));
+ } catch (IllegalArgumentException e) {
+ exceptionList.add(e);
+ }
}
+ if (result.isEmpty()) {
+ throw exceptionList.get(0);
+ }
sort(result);
return result;
@@ -198,13 +206,18 @@ public final class AcceptType {
}
Map<String, String> compareParameters = contentType.getParameters();
for (final Map.Entry<String, String> entry : parameters.entrySet()) {
- if (compareParameters.containsKey(entry.getKey()) || TypeUtil.PARAMETER_Q.equalsIgnoreCase(entry.getKey())) {
- String compare = compareParameters.get(entry.getKey());
- if (!entry.getValue().equalsIgnoreCase(compare) && !TypeUtil.PARAMETER_Q.equalsIgnoreCase(entry.getKey())) {
+ if (entry.getKey().equalsIgnoreCase(ContentType.PARAMETER_CHARSET) &&
+ compareParameters.containsKey(entry.getKey())) {
+ continue;
+ } else {
+ if (compareParameters.containsKey(entry.getKey()) || TypeUtil.PARAMETER_Q.equalsIgnoreCase(entry.getKey())) {
+ String compare = compareParameters.get(entry.getKey());
+ if (!entry.getValue().equalsIgnoreCase(compare) && !TypeUtil.PARAMETER_Q.equalsIgnoreCase(entry.getKey())) {
+ return false;
+ }
+ } else {
return false;
}
- } else {
- return false;
}
}
return true;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptCharsetTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptCharsetTest.java b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptCharsetTest.java
new file mode 100644
index 0000000..a963f66
--- /dev/null
+++ b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptCharsetTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.commons.api.format;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.List;
+
+import org.junit.Test;
+
+public class AcceptCharsetTest {
+ @Test
+ public void wildcard() {
+ expectCreateError("*");
+ }
+
+ @Test
+ public void illegalCharset() {
+ expectCreateError("abc");
+ }
+
+ @Test
+ public void unsupportedCharset() {
+ expectCreateError("iso-8859-1");
+ }
+
+ @Test
+ public void correctCharset() {
+ List<AcceptCharset> charsets = AcceptCharset.create("utf-8");
+ assertEquals("utf-8", charsets.get(0).getCharset());
+ }
+
+ @Test
+ public void correctCharsetWithQParams() {
+ List<AcceptCharset> charsets = AcceptCharset.create("utf-8;q=0.8");
+ assertEquals("utf-8", charsets.get(0).getCharset());
+ assertEquals(1, charsets.get(0).getParameters().size());
+ assertEquals("0.8", charsets.get(0).getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals(Float.parseFloat("0.8"),
+ charsets.get(0).getQuality().floatValue(), Float.parseFloat("0.8"));
+ }
+
+ @Test
+ public void multipleCharsetsWithQParams() {
+ List<AcceptCharset> charsets = AcceptCharset.create("utf-8;q=0.1, utf8;q=0.8");
+ assertEquals("utf8", charsets.get(0).getCharset());
+ assertEquals("utf-8", charsets.get(1).getCharset());
+ assertEquals(1, charsets.get(0).getParameters().size());
+ assertEquals(1, charsets.get(1).getParameters().size());
+ assertEquals("0.8", charsets.get(0).getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals("0.1", charsets.get(1).getParameter(TypeUtil.PARAMETER_Q));
+ }
+
+ @Test
+ public void multipleCharsetsWithQParamsAndUnsupportedCharsets() {
+ List<AcceptCharset> charsets = AcceptCharset.create("utf-8;q=0.1, utf8;q=0.8, iso-8859-1, abc");
+ assertEquals("utf8", charsets.get(0).getCharset());
+ assertEquals("utf-8", charsets.get(1).getCharset());
+ assertEquals(1, charsets.get(0).getParameters().size());
+ assertEquals(1, charsets.get(1).getParameters().size());
+ assertEquals("0.8", charsets.get(0).getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals("0.1", charsets.get(1).getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals("utf8;q=0.8", charsets.get(0).toString());
+ }
+
+ @Test
+ public void multipleCharsetsWithSameQParams() {
+ List<AcceptCharset> charsets = AcceptCharset.create("utf-8;q=0.1, utf8;q=0.1");
+ assertEquals("utf-8", charsets.get(0).getCharset());
+ assertEquals("utf8", charsets.get(1).getCharset());
+ assertEquals(1, charsets.get(0).getParameters().size());
+ assertEquals(1, charsets.get(1).getParameters().size());
+ assertEquals("0.1", charsets.get(0).getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals("0.1", charsets.get(1).getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals("utf-8;q=0.1", charsets.get(0).toString());
+ }
+
+ @Test
+ public void multipleCharsetsFail() {
+ expectCreateError("iso-8859-5, unicode-1-1;q=0.8");
+ }
+
+ private void expectCreateError(final String value) {
+ try {
+ AcceptCharset.create(value);
+ fail("Expected exception not thrown.");
+ } catch (UnsupportedCharsetException e) {
+ assertNotNull(e);
+ } catch (final IllegalArgumentException e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void illegalQParam() {
+ expectCreateError("utf-8;q=12");
+ }
+
+ @Test
+ public void emptyCharset() {
+ expectCreateError("");
+ }
+
+ @Test
+ public void nullCharset() {
+ expectCreateError(null);
+ }
+
+ @Test
+ public void trailingSemicolon() {
+ expectCreateError("utf-8;");
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptTypeTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptTypeTest.java b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptTypeTest.java
index 8902975..8fe0af1 100644
--- a/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptTypeTest.java
+++ b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/format/AcceptTypeTest.java
@@ -171,4 +171,95 @@ public class AcceptTypeTest {
assertNotNull(e);
}
}
-}
+
+ @Test
+ public void multipleTypeswithQParameter() {
+ List<AcceptType> acceptTypes = AcceptType.create("application/json;q=0.2,application/json;q=0.2");
+
+ assertEquals(2, acceptTypes.size());
+ final AcceptType acceptType = acceptTypes.get(0);
+ assertEquals("application", acceptType.getType());
+ assertEquals("json", acceptType.getSubtype());
+ assertEquals("0.2", acceptType.getParameters().get(TypeUtil.PARAMETER_Q));
+ assertEquals("0.2", acceptType.getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals(Float.valueOf(0.2F), acceptType.getQuality());
+ assertEquals("application/json;q=0.2", acceptType.toString());
+ }
+
+ @Test
+ public void multipleTypeswithIllegalTypes() {
+ List<AcceptType> acceptTypes = AcceptType.create("application/json;q=0.2,abc");
+
+ assertEquals(1, acceptTypes.size());
+ final AcceptType acceptType = acceptTypes.get(0);
+ assertEquals("application", acceptType.getType());
+ assertEquals("json", acceptType.getSubtype());
+ assertEquals("0.2", acceptType.getParameters().get(TypeUtil.PARAMETER_Q));
+ assertEquals("0.2", acceptType.getParameter(TypeUtil.PARAMETER_Q));
+ assertEquals(Float.valueOf(0.2F), acceptType.getQuality());
+ assertEquals("application/json;q=0.2", acceptType.toString());
+ }
+
+ @Test
+ public void multipleFormatErrors() {
+ expectCreateError("/,abc,a/a;parameter=");
+ }
+
+ @Test
+ public void nullAcceptType() {
+ expectCreateError(null);
+ }
+
+ @Test
+ public void emptyAcceptType() {
+ expectCreateError("");
+ }
+
+ @Test
+ public void noTypeAcceptType() {
+ expectCreateError("/json");
+ }
+
+ @Test
+ public void withCharset() {
+ List<AcceptType> acceptTypes = AcceptType.create("application/json;charset=utf-8");
+ assertEquals(1, acceptTypes.size());
+ final AcceptType acceptType = acceptTypes.get(0);
+ assertEquals("application", acceptType.getType());
+ assertEquals("json", acceptType.getSubtype());
+ assertEquals("utf-8", acceptType.getParameter(ContentType.PARAMETER_CHARSET));
+
+ assertTrue(acceptType.matches(ContentType.create("application/json;"
+ + "odata.metadata=minimal;charset=utf-8")));
+ assertFalse(acceptType.matches(ContentType.create("application/atom+xml;"
+ + "odata.metadata=minimal;charset=utf-8")));
+ assertFalse(acceptType.matches(ContentType.create("application/json;"
+ + "odata.metadata=minimal")));
+ }
+
+ @Test
+ public void withSubtypeStar1() {
+ List<AcceptType> acceptTypes = AcceptType.create("application/json,application/*");
+ assertEquals(2, acceptTypes.size());
+ final AcceptType acceptType1 = acceptTypes.get(0);
+ assertEquals("application", acceptType1.getType());
+ assertEquals("json", acceptType1.getSubtype());
+
+ final AcceptType acceptType2 = acceptTypes.get(1);
+ assertEquals("application", acceptType2.getType());
+ assertEquals("*", acceptType2.getSubtype());
+ }
+
+ @Test
+ public void withSubtypeStar2() {
+ List<AcceptType> acceptTypes = AcceptType.create("application/*,application/json");
+ assertEquals(2, acceptTypes.size());
+ final AcceptType acceptType1 = acceptTypes.get(0);
+ assertEquals("application", acceptType1.getType());
+ assertEquals("json", acceptType1.getSubtype());
+
+ final AcceptType acceptType2 = acceptTypes.get(1);
+ assertEquals("application", acceptType2.getType());
+ assertEquals("*", acceptType2.getSubtype());
+ }
+ }
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/main/java/org/apache/olingo/server/core/AcceptHeaderContentNegotiatorException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/AcceptHeaderContentNegotiatorException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/AcceptHeaderContentNegotiatorException.java
new file mode 100644
index 0000000..e051560
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/AcceptHeaderContentNegotiatorException.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+public class AcceptHeaderContentNegotiatorException extends ContentNegotiatorException {
+ private static final long serialVersionUID = -8112658467394158700L;
+
+ public static enum MessageKeys implements MessageKey {
+ /** parameter: list of content-type ranges */
+ UNSUPPORTED_ACCEPT_TYPES,
+ /** parameter: format string */
+ UNSUPPORTED_FORMAT_OPTION,
+ /** parameter: accept charset header*/
+ UNSUPPORTED_ACCEPT_CHARSET_HEADER_OPTIONS;
+
+ @Override
+ public String getKey() {
+ return name();
+ }
+ }
+
+ public AcceptHeaderContentNegotiatorException(final String developmentMessage, final MessageKey messageKey,
+ final String... parameters) {
+ super(developmentMessage, messageKey, parameters);
+ }
+
+ public AcceptHeaderContentNegotiatorException(final String developmentMessage, final Throwable cause,
+ final MessageKey messageKey,
+ final String... parameters) {
+ super(developmentMessage, cause, messageKey, parameters);
+ }
+
+ @Override
+ protected String getBundleName() {
+ return DEFAULT_SERVER_BUNDLE_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
index 4aaeee7..4ece2b8 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java
@@ -18,10 +18,14 @@
*/
package org.apache.olingo.server.core;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import org.apache.olingo.commons.api.format.AcceptCharset;
import org.apache.olingo.commons.api.format.AcceptType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
@@ -87,6 +91,23 @@ public final class ContentNegotiator {
final List<ContentType> supportedContentTypes =
getSupportedContentTypes(customContentTypeSupport, representationType);
final String acceptHeaderValue = request.getHeader(HttpHeader.ACCEPT);
+ String acceptCharset = request.getHeader(HttpHeader.ACCEPT_CHARSET);
+ List<AcceptCharset> charsets = null;
+ if (acceptCharset != null) {
+ try {
+ charsets = new ArrayList<AcceptCharset>();
+ charsets = AcceptCharset.create(acceptCharset);
+ } catch (UnsupportedCharsetException e) {
+ throw new AcceptHeaderContentNegotiatorException(e.getMessage(),
+ AcceptHeaderContentNegotiatorException.MessageKeys.UNSUPPORTED_ACCEPT_CHARSET_HEADER_OPTIONS,
+ e.getMessage().substring(e.getMessage().lastIndexOf(":") + 1));
+ } catch (IllegalArgumentException e) {
+ throw new ContentNegotiatorException(e.getMessage(),
+ ContentNegotiatorException.MessageKeys.UNSUPPORTED_ACCEPT_CHARSET,
+ e.getMessage().substring(e.getMessage().lastIndexOf(":") + 1));
+ }
+ }
+
ContentType result = null;
if (formatOption != null && formatOption.getFormat() != null) {
@@ -97,9 +118,11 @@ public final class ContentNegotiator {
result = getAcceptedType(
AcceptType.fromContentType(contentType == null ?
ContentType.create(formatOption.getFormat()) : contentType),
- supportedContentTypes);
+ supportedContentTypes, charsets);
} catch (final IllegalArgumentException e) {
- // Exception results in result = null for next check.
+ throw new AcceptHeaderContentNegotiatorException(
+ "Unsupported $format=" + formatString,
+ AcceptHeaderContentNegotiatorException.MessageKeys.UNSUPPORTED_FORMAT_OPTION, formatString);
}
if (result == null) {
throw new ContentNegotiatorException("Unsupported $format = " + formatString,
@@ -107,18 +130,25 @@ public final class ContentNegotiator {
}
} else if (acceptHeaderValue != null) {
try {
- result = getAcceptedType(AcceptType.create(acceptHeaderValue), supportedContentTypes);
+ result = getAcceptedType(AcceptType.create(acceptHeaderValue),
+ supportedContentTypes, charsets);
} catch (final IllegalArgumentException e) {
- result = null;
- }
+ throw new AcceptHeaderContentNegotiatorException(
+ "Unsupported or illegal Accept header value: " + acceptHeaderValue + " != " + supportedContentTypes,
+ AcceptHeaderContentNegotiatorException.MessageKeys.UNSUPPORTED_ACCEPT_TYPES, acceptHeaderValue);
+ }
if (result == null) {
+ List<AcceptType> types = AcceptType.create(acceptHeaderValue);
throw new ContentNegotiatorException(
- "Unsupported or illegal Accept header value: " + acceptHeaderValue + " != " + supportedContentTypes,
+ "The combination of type and subtype " + types.get(0) +
+ " != " + supportedContentTypes,
ContentNegotiatorException.MessageKeys.UNSUPPORTED_ACCEPT_TYPES, acceptHeaderValue);
}
} else {
final ContentType requestedContentType = getDefaultSupportedContentTypes(representationType).get(0);
- result = getAcceptedType(AcceptType.fromContentType(requestedContentType), supportedContentTypes);
+ result = getAcceptedType(AcceptType.fromContentType(requestedContentType),
+ supportedContentTypes, charsets);
+
if (result == null) {
throw new ContentNegotiatorException(
"unsupported accept content type: " + requestedContentType + " != " + supportedContentTypes,
@@ -145,16 +175,39 @@ public final class ContentNegotiator {
}
private static ContentType getAcceptedType(final List<AcceptType> acceptedContentTypes,
- final List<ContentType> supportedContentTypes) {
+ final List<ContentType> supportedContentTypes, List<AcceptCharset> charsets) throws ContentNegotiatorException {
+ if (charsets != null) {
+ for (AcceptCharset charset : charsets) {
+ return getContentType(acceptedContentTypes, supportedContentTypes, charset);
+ }
+ } else {
+ return getContentType(acceptedContentTypes, supportedContentTypes, null);
+ }
+ return null;
+ }
+
+ private static ContentType getContentType(List<AcceptType> acceptedContentTypes,
+ List<ContentType> supportedContentTypes, AcceptCharset charset) throws ContentNegotiatorException {
for (final AcceptType acceptedType : acceptedContentTypes) {
for (final ContentType supportedContentType : supportedContentTypes) {
ContentType contentType = supportedContentType;
final String charSetValue = acceptedType.getParameter(ContentType.PARAMETER_CHARSET);
- if (charSetValue != null) {
+ if (charset != null) {
+ contentType = ContentType.create(contentType, ContentType.PARAMETER_CHARSET, charset.toString());
+ } else if (charSetValue != null) {
+ try {
+ Charset.forName(charSetValue);
+ } catch (UnsupportedCharsetException e) {
+ throw new AcceptHeaderContentNegotiatorException(
+ "Illegal charset in Accept header: " + charSetValue,
+ AcceptHeaderContentNegotiatorException.MessageKeys.UNSUPPORTED_ACCEPT_CHARSET_HEADER_OPTIONS,
+ charSetValue);
+ }
if ("utf8".equalsIgnoreCase(charSetValue) || "utf-8".equalsIgnoreCase(charSetValue)) {
contentType = ContentType.create(contentType, ContentType.PARAMETER_CHARSET, "utf-8");
} else {
- throw new IllegalArgumentException("charset not supported: " + acceptedType);
+ throw new ContentNegotiatorException("Unsupported accept-header-charset = " + charSetValue,
+ ContentNegotiatorException.MessageKeys.UNSUPPORTED_ACCEPT_HEADER_CHARSET, acceptedType.toString());
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiatorException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiatorException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiatorException.java
index 12a0582..1b62d8f 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiatorException.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiatorException.java
@@ -31,7 +31,11 @@ public class ContentNegotiatorException extends ODataLibraryException {
/** no parameter */
NO_CONTENT_TYPE_SUPPORTED,
/** parameter: format string */
- UNSUPPORTED_FORMAT_OPTION;
+ UNSUPPORTED_FORMAT_OPTION,
+ /**parameter: accept charset */
+ UNSUPPORTED_ACCEPT_CHARSET,
+ /** parameter: accept header charset */
+ UNSUPPORTED_ACCEPT_HEADER_CHARSET;
@Override
public String getKey() {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
index 20c0634..1e0efb1 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
@@ -83,6 +83,13 @@ public class ODataExceptionHelper {
return serverError;
}
+ public static ODataServerError createServerErrorObject(final AcceptHeaderContentNegotiatorException e,
+ final Locale requestedLocale) {
+ ODataServerError serverError = basicTranslatedError(e, requestedLocale);
+ serverError.setStatusCode(HttpStatusCode.BAD_REQUEST.getStatusCode());
+ return serverError;
+ }
+
public static ODataServerError createServerErrorObject(final ODataHandlerException e, final Locale requestedLocale) {
ODataServerError serverError = basicTranslatedError(e, requestedLocale);
if (ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED.equals(e.getMessageKey())
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java
index 0bc59be..3c18e09 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerImpl.java
@@ -95,6 +95,9 @@ public class ODataHandlerImpl implements ODataHandler {
} catch (final UriParserException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError, e);
+ } catch (AcceptHeaderContentNegotiatorException e) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
+ handleException(request, response, serverError, e);
} catch (ContentNegotiatorException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError, e);
@@ -126,6 +129,7 @@ public class ODataHandlerImpl implements ODataHandler {
final int measurementHandle = debugger.startRuntimeMeasurement("ODataHandler", "processInternal");
response.setHeader(HttpHeader.ODATA_VERSION, ODataServiceVersion.V40.toString());
+
try {
validateODataVersion(request);
} catch (final ODataHandlerException e) {
@@ -180,6 +184,8 @@ public class ODataHandlerImpl implements ODataHandler {
final FormatOption formatOption = getFormatOption(request, uriInfo);
requestedContentType = ContentNegotiator.doContentNegotiation(formatOption, request,
getCustomContentTypeSupport(), RepresentationType.ERROR);
+ } catch (final AcceptHeaderContentNegotiatorException e) {
+ requestedContentType = ContentType.JSON;
} catch (final ContentNegotiatorException e) {
requestedContentType = ContentType.JSON;
}
@@ -221,11 +227,17 @@ public class ODataHandlerImpl implements ODataHandler {
}
private void validateODataVersion(final ODataRequest request) throws ODataHandlerException {
- final String maxVersion = request.getHeader(HttpHeader.ODATA_MAX_VERSION);
- if (maxVersion != null && ODataServiceVersion.isBiggerThan(ODataServiceVersion.V40.toString(), maxVersion)) {
- throw new ODataHandlerException("ODataVersion not supported: " + maxVersion,
- ODataHandlerException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, maxVersion);
+ final String odataVersion = request.getHeader(HttpHeader.ODATA_VERSION);
+ if (odataVersion != null && !ODataServiceVersion.isValidODataVersion(odataVersion)) {
+ throw new ODataHandlerException("ODataVersion not supported: " + odataVersion,
+ ODataHandlerException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, odataVersion);
}
+
+ final String maxVersion = request.getHeader(HttpHeader.ODATA_MAX_VERSION);
+ if (maxVersion != null && !ODataServiceVersion.isValidMaxODataVersion(maxVersion)) {
+ throw new ODataHandlerException("ODataVersion not supported: " + maxVersion,
+ ODataHandlerException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, maxVersion);
+ }
}
<T extends Processor> T selectProcessor(final Class<T> cls) throws ODataHandlerException {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index 6eb9620..19ae702 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -103,6 +103,12 @@ ContentNegotiatorException.UNSUPPORTED_ACCEPT_TYPES=The content-type range '%1$s
ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported.
ContentNegotiatorException.NO_CONTENT_TYPE_SUPPORTED=No content type has been specified as supported.
ContentNegotiatorException.UNSUPPORTED_FORMAT_OPTION=The $format option '%1$s' is not supported.
+ContentNegotiatorException.UNSUPPORTED_ACCEPT_CHARSET=The charset specified in Accept charset header '%1$s' is not supported.
+ContentNegotiatorException.UNSUPPORTED_ACCEPT_HEADER_CHARSET=The charset specified in Accept header '%1$s' is not supported.
+
+AcceptHeaderContentNegotiatorException.UNSUPPORTED_ACCEPT_TYPES=The content-type range '%1$s' is not supported as value of the Accept header.
+AcceptHeaderContentNegotiatorException.UNSUPPORTED_FORMAT_OPTION=The $format option '%1$s' is not supported.
+AcceptHeaderContentNegotiatorException.UNSUPPORTED_ACCEPT_CHARSET_HEADER_OPTIONS=The charset specified in Accept charset header '%1$s' is not supported.
SerializerException.NULL_METADATA_OR_EDM=The server does not define any service metadata.
SerializerException.NOT_IMPLEMENTED=The requested serialization method has not been implemented yet.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
index f863c70..46ec985 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java
@@ -18,9 +18,7 @@
*/
package org.apache.olingo.server.core;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Mockito.mock;
@@ -42,11 +40,15 @@ public class ContentNegotiatorTest {
static final private String ACCEPT_CASE_MIN = ContentType.JSON.toContentTypeString();
static final private String ACCEPT_CASE_MIN_UTF8 = "application/json;charset=UTF-8;odata.metadata=minimal";
+ static final private String ACCEPT_CASE_MIN_UTF81 = "application/json;charset=utf-8;odata.metadata=minimal";
+ static final private String ACCEPT_CASE_ISO_8859_1 = "application/json;charset=ISO-8859-1";
static final private String ACCEPT_CASE_FULL = ContentType.JSON_FULL_METADATA.toContentTypeString();
static final private String ACCEPT_CASE_NONE = ContentType.JSON_NO_METADATA.toContentTypeString();
static final private String ACCEPT_CASE_MIN_UTF8_IEEE754 =
"application/json;charset=UTF-8;odata.metadata=minimal;IEEE754Compatible=true";
static final private String ACCEPT_CASE_MIN_IEEE754 = ACCEPT_CASE_MIN + ";IEEE754Compatible=true";
+ String ACCEPT_CASE_MIN_IEEE754_1 = ACCEPT_CASE_MIN + ";IEEE754Compatible=false";
+ static final private String ACCEPT_CASE_MIN_IEEE754_FAIL = ACCEPT_CASE_MIN + ";IEEE754Compatible=xyz";
static final private String ACCEPT_CASE_JSONQ = "application/json;q=0.2";
static final private String ACCEPT_CASE_XML = ContentType.APPLICATION_XML.toContentTypeString();
static final private String ACCEPT_CASE_JSON = ContentType.APPLICATION_JSON.toContentTypeString();
@@ -79,7 +81,8 @@ public class ContentNegotiatorTest {
{ ACCEPT_CASE_MIN_UTF8_IEEE754, null, ACCEPT_CASE_MIN_UTF8_IEEE754, null },
{ ACCEPT_CASE_MIN_IEEE754, ACCEPT_CASE_MIN_IEEE754, ACCEPT_CASE_MIN , null },
{ ACCEPT_CASE_XML, "xml", null, null },
- { ACCEPT_CASE_XML, null, ACCEPT_CASE_XML, null }
+ { ACCEPT_CASE_XML, null, ACCEPT_CASE_XML, null },
+ { ACCEPT_CASE_MIN_IEEE754_1, null, ACCEPT_CASE_MIN_IEEE754_1, null }
};
String[][] casesMetadata = {
@@ -120,8 +123,31 @@ public class ContentNegotiatorTest {
{ null, null, "*", null },
{ null, "a/b;charset=ISO-8859-1", null, "a/b" },
{ null, null, "a/b;charset=ISO-8859-1", "a/b" },
- { null, null, null, "text/plain" }
+ { null, null, null, "text/plain" },
+ { null, "xxx", null, null },
+ { null, null, ACCEPT_CASE_MIN_IEEE754_FAIL,null }
};
+
+ String[][] casesAcceptCharset = {
+ /* expected $format accept modified content types acceptCharset*/
+ { ACCEPT_CASE_MIN_UTF8, null, null, null, "utf-8" },
+ { ACCEPT_CASE_MIN_UTF8, "json", ACCEPT_CASE_MIN_UTF8, null, "utf-8" },
+ { ACCEPT_CASE_MIN_UTF8, null, ACCEPT_CASE_ISO_8859_1, null, "utf-8" },
+ { ACCEPT_CASE_MIN_UTF81, null, ACCEPT_CASE_ISO_8859_1, null, "utf-8" },
+ { ACCEPT_CASE_MIN_UTF81, null, "application/json;charset=abc", null, "utf-8" },
+ { ACCEPT_CASE_MIN_UTF8, null, "application/json;charset=utf-8", null, null },
+ { ACCEPT_CASE_MIN_UTF8, null, "application/json;charset=utf8", null, null }
+ };
+
+ String[][] casesAcceptCharsetFail = {
+ /* expected $format accept modified content types acceptCharset*/
+ { null, null, null, null, "ISO-8859-1"},
+ { null, "json", ACCEPT_CASE_MIN_UTF8, null, "abc" },
+ { null, null, ACCEPT_CASE_ISO_8859_1, null, "*" },
+ { null, null, ACCEPT_CASE_ISO_8859_1, null, null },
+ { null, null, "application/json;charset=abc", null, null }
+ };
+
//CHECKSTYLE:ON
//@formatter:on
@@ -163,6 +189,8 @@ public class ContentNegotiatorTest {
try {
testContentNegotiation(useCase, RepresentationType.COLLECTION_ENTITY);
fail("Exception expected for '" + useCase[1] + '|' + useCase[2] + '|' + useCase[3] + "'!");
+ } catch (final AcceptHeaderContentNegotiatorException e) {
+ // Expected Exception
} catch (final ContentNegotiatorException e) {
// Expected Exception
}
@@ -207,7 +235,7 @@ public class ContentNegotiatorTest {
}
private void testContentNegotiation(final String[] useCase, final RepresentationType representationType)
- throws ContentNegotiatorException {
+ throws Exception {
FormatOption formatOption = null;
if (useCase[1] != null) {
@@ -219,6 +247,12 @@ public class ContentNegotiatorTest {
if (useCase[2] != null) {
request.addHeader(HttpHeader.ACCEPT, Arrays.asList(useCase[2]));
}
+
+ if (useCase.length > 4) {
+ if (useCase[4] != null) {
+ request.addHeader(HttpHeader.ACCEPT_CHARSET, Arrays.asList(useCase[4]));
+ }
+ }
final CustomContentTypeSupport customContentTypeSupport = useCase[3] == null ? null :
createCustomContentTypeSupport(useCase[3]);
@@ -244,4 +278,37 @@ public class ContentNegotiatorTest {
.thenReturn(types);
return customContentTypeSupport;
}
+
+ @Test
+ public void testAcceptCharset() throws Exception {
+ for (String[] useCase : casesAcceptCharset) {
+ testContentNegotiation(useCase, RepresentationType.ENTITY);
+ }
+ }
+
+ @Test
+ public void testAcceptCharsetFail() throws Exception {
+ for (String[] useCase : casesAcceptCharsetFail) {
+ try {
+ testContentNegotiation(useCase, RepresentationType.ENTITY);
+ fail("Exception expected for '" + useCase[1] + '|' + useCase[2] + '|' + useCase[3] + "'!");
+ } catch (final AcceptHeaderContentNegotiatorException e) {
+ // Expected Exception
+ } catch (final ContentNegotiatorException e) {
+ // Expected Exception
+ }
+ }
+ }
+
+ @Test
+ public void testSupportedTypes() throws ContentNegotiatorException, IllegalArgumentException {
+ assertTrue(ContentNegotiator.isSupported(ContentType.create("a/b"),
+ createCustomContentTypeSupport("a/b"), RepresentationType.ENTITY));
+ assertFalse(ContentNegotiator.isSupported(ContentType.create("a/b"),
+ createCustomContentTypeSupport("x/y"), RepresentationType.ENTITY));
+ assertTrue(ContentNegotiator.isSupported(ContentType.create("a/b"),
+ createCustomContentTypeSupport("a/b"), RepresentationType.BATCH));
+ assertTrue(ContentNegotiator.isSupported(ContentType.create("a/b"),
+ createCustomContentTypeSupport("a/b"), RepresentationType.BINARY));
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/eb112032/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerImplTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerImplTest.java
index bacb700..8e457b1 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerImplTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerImplTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@@ -33,7 +34,10 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
@@ -1138,4 +1142,173 @@ public class ODataHandlerImplTest {
assertEquals(statusCode.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
}
+
+ @Test
+ public void validateInvalidOdataVersion1() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> header = new HashMap<String, String>();
+ header.put(HttpHeader.ODATA_VERSION, "3.0");
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, header, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ assertEquals(400, response.getStatusCode());
+ assertNotNull(response.getContent());
+ String doc = IOUtils.toString(response.getContent());
+ assertTrue(doc.contains("OData version '3.0' is not supported."));
+ }
+
+ @Test
+ public void validateInvalidOdataVersion2() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> header = new HashMap<String, String>();
+ header.put(HttpHeader.ODATA_VERSION, "5.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, header, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ assertEquals(400, response.getStatusCode());
+ assertNotNull(response.getContent());
+ String doc = IOUtils.toString(response.getContent());
+ assertTrue(doc.contains("OData version '5.0' is not supported."));
+ }
+
+ @Test
+ public void validateInvalidOdataMaxVersion1() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> header = new HashMap<String, String>();
+ header.put(HttpHeader.ODATA_MAX_VERSION, "3.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, header, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ assertEquals(400, response.getStatusCode());
+ assertNotNull(response.getContent());
+ String doc = IOUtils.toString(response.getContent());
+ assertTrue(doc.contains("OData version '3.0' is not supported."));
+ }
+
+ @Test
+ public void validateValidOdataMaxVersion2() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> header = new HashMap<String, String>();
+ header.put(HttpHeader.ODATA_MAX_VERSION, "5.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, header, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ }
+
+ @Test
+ public void validateValidOdataVersionAndMaxVersion1() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> headers = new HashMap<String, String>();
+ headers.put(HttpHeader.ODATA_VERSION, "4.0");
+ headers.put(HttpHeader.ODATA_MAX_VERSION, "5.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, headers, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ }
+
+ @Test
+ public void validateInvalidOdataVersionAndMaxVersion2() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> headers = new HashMap<String, String>();
+ headers.put(HttpHeader.ODATA_VERSION, "3.0");
+ headers.put(HttpHeader.ODATA_MAX_VERSION, "4.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, headers, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ assertEquals(400, response.getStatusCode());
+ assertNotNull(response.getContent());
+ String doc = IOUtils.toString(response.getContent());
+ assertTrue(doc.contains("OData version '3.0' is not supported."));
+ }
+
+ @Test
+ public void validateInvalidOdataVersionAndMaxVersion3() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> headers = new HashMap<String, String>();
+ headers.put(HttpHeader.ODATA_VERSION, "5.0");
+ headers.put(HttpHeader.ODATA_MAX_VERSION, "5.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, headers, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ assertEquals(400, response.getStatusCode());
+ assertNotNull(response.getContent());
+ String doc = IOUtils.toString(response.getContent());
+ assertTrue(doc.contains("OData version '5.0' is not supported."));
+ }
+
+ @Test
+ public void validateValidOdataVersionAndMaxVersion2() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> headers = new HashMap<String, String>();
+ headers.put(HttpHeader.ODATA_VERSION, "4.0");
+ headers.put(HttpHeader.ODATA_MAX_VERSION, "4.01");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, headers, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ }
+
+ @Test
+ public void validateValidOdataVersionAndMaxVersion3() throws Exception {
+ final String uri = "ESAllPrim(0)";
+ final EntityProcessor processor = mock(EntityProcessor.class);
+
+ final Map<String, String> headers = new HashMap<String, String>();
+ headers.put(HttpHeader.ODATA_VERSION, "4.0");
+ headers.put(HttpHeader.ODATA_MAX_VERSION, "4.0");
+
+ final ODataResponse response = dispatchToValidateHeaders
+ (HttpMethod.GET, uri, null, headers, processor);
+ assertEquals("4.0", response.getHeader(HttpHeader.ODATA_VERSION));
+ }
+
+ private ODataResponse dispatchToValidateHeaders(final HttpMethod method, final String path, final String query,
+ final Map<String, String> headers, final Processor processor) throws ODataHandlerException {
+ ODataRequest request = new ODataRequest();
+ request.setMethod(method);
+ request.setRawBaseUri(BASE_URI);
+ for (Entry<String, String> header : headers.entrySet()) {
+ request.addHeader(header.getKey(), header.getValue());
+ }
+ if (path.isEmpty()) {
+ request.setRawRequestUri(BASE_URI);
+ }
+ request.setRawODataPath(path);
+ request.setRawQueryPath(query);
+
+ final OData odata = OData.newInstance();
+ final ServiceMetadata metadata = odata.createServiceMetadata(
+ new EdmTechProvider(), Collections.<EdmxReference> emptyList());
+
+ ODataHandlerImpl handler = new ODataHandlerImpl(odata, metadata, new ServerCoreDebugger(odata));
+
+ if (processor != null) {
+ handler.register(processor);
+ }
+
+ final ODataResponse response = handler.process(request);
+ return response;
+ }
}