[OLINGO-659] support for OData-EntityID header, more clean-up

Change-Id: I168a6efac6fc9ad85865f71dd534fd850d8e777e

Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
Klaus Straubinger 2015-06-26 15:34:23 +02:00 committed by Christian Amend
parent 2a841552f4
commit abf5bf79aa
25 changed files with 260 additions and 363 deletions

View File

@ -45,6 +45,7 @@ import org.apache.olingo.client.api.domain.ClientValue;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
@ -304,6 +305,25 @@ public class ActionImportITCase extends AbstractBaseTestITCase {
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntity.class, parameters)
.execute();
assertEquals(HttpStatusCode.CREATED.getStatusCode(), response.getStatusCode());
assertEquals(TecSvcConst.BASE_URI + "/ESAllPrim(1)", response.getHeader(HttpHeader.LOCATION).iterator().next());
}
@Test
public void entityActionETAllPrimNoContent() throws Exception {
final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
.appendActionCallSegment("AIRTESAllPrimParam").build();
final Map<String, ClientValue> parameters = Collections.singletonMap(
"ParameterDate",
(ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("2000-02-29"));
ODataInvokeRequest<ClientEntity> request = getClient().getInvokeRequestFactory()
.getActionInvokeRequest(actionURI, ClientEntity.class, parameters);
request.setPrefer(getClient().newPreferences().returnMinimal());
final ODataInvokeResponse<ClientEntity> response = request.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
assertEquals("return=minimal", response.getHeader(HttpHeader.PREFERENCE_APPLIED).iterator().next());
final String location = TecSvcConst.BASE_URI + "/ESAllPrim(1)";
assertEquals(location, response.getHeader(HttpHeader.LOCATION).iterator().next());
assertEquals(location, response.getHeader(HttpHeader.ODATA_ENTITY_ID).iterator().next());
}
@Override

View File

@ -25,6 +25,7 @@ import java.net.URL;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.commons.api.http.HttpHeader;
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;
@ -44,8 +45,7 @@ public class BasicHttpExceptionHandlingITCase extends AbstractBaseTestITCase {
connection.setRequestProperty(HttpHeader.X_HTTP_METHOD_OVERRIDE, "differentValue");
connection.connect();
int code = connection.getResponseCode();
assertEquals(400, code);
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
}
@Override

View File

@ -84,18 +84,18 @@ import org.junit.Test;
public class BasicITCase extends AbstractBaseTestITCase {
private static final String CONTENT_TYPE_JSON_IEEE754_COMPATIBLE = "application/json;odata.metadata=minimal;"
+ "IEEE754Compatible=true";
private static final String CONTENT_TYPE_JSON_IEEE754_COMPATIBLE =
ContentType.create(ContentType.JSON, ContentType.PARAMETER_IEEE754_COMPATIBLE, "true").toContentTypeString();
private static final String SERVICE_NAMESPACE = "olingo.odata.test1";
private static final String ET_ALL_PRIM_NAME = "ETAllPrim";
private static final FullQualifiedName ET_ALL_PRIM = new FullQualifiedName(SERVICE_NAMESPACE, ET_ALL_PRIM_NAME);
private static final String PROPERTY_INT16 = "PropertyInt16";
private static final String PROPERTY_INT64 = "PropertyInt64";
private static final String PROPERTY_DECIMAL = "PropertyDecimal";
private static final String PROPERTY_COMP_ALL_PRIM = "PropertyCompAllPrim";
private static final String NAV_PROPERTY_ET_TWO_PRIM_ONE = "NavPropertyETTwoPrimOne";
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
private static final String ES_ALL_PRIM = "ESAllPrim";
private static final String ES_TWO_PRIM = "ESTwoPrim";
@ -435,7 +435,9 @@ public class BasicITCase extends AbstractBaseTestITCase {
final ODataEntityCreateResponse<ClientEntity> response = request.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
assertEquals("return=minimal", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals(SERVICE_URI + "/ESTwoPrim(1)", response.getHeader(HttpHeader.LOCATION).iterator().next());
final String location = SERVICE_URI + "/ESTwoPrim(1)";
assertEquals(location, response.getHeader(HttpHeader.LOCATION).iterator().next());
assertEquals(location, response.getHeader(HttpHeader.ODATA_ENTITY_ID).iterator().next());
}
@Test
@ -1291,7 +1293,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
assertEquals(BigDecimal.valueOf(34), response.getBody().getPrimitiveValue().toValue());
}
@Override
protected ODataClient getClient() {
ODataClient odata = ODataClientFactory.getClient();

View File

@ -48,6 +48,7 @@ import org.apache.olingo.client.api.domain.ClientObjectFactory;
import org.apache.olingo.client.api.http.HttpClientException;
import org.apache.olingo.client.api.uri.URIBuilder;
import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem;
import org.apache.olingo.commons.api.ODataPreferenceNames;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ContentType;
@ -160,14 +161,14 @@ public class BatchClientITCase extends AbstractTestITCase {
ODataBatchResponseItem item = iter.next();
assertFalse(item.isChangeset());
ODataResponse oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
assertEquals("605", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
ODataResponse oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode());
assertEquals(1, oDataResponse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResponse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResponse.getHeader("Content-Length").size());
assertEquals("605", oDataResponse.getHeader("Content-Length").toArray()[0]);
assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType());
}
@Test
@ -191,14 +192,14 @@ public class BatchClientITCase extends AbstractTestITCase {
ODataBatchResponseItem item = iter.next();
assertFalse(item.isChangeset());
ODataResponse oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
assertEquals("605", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
ODataResponse oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode());
assertEquals(1, oDataResponse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResponse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResponse.getHeader("Content-Length").size());
assertEquals("605", oDataResponse.getHeader("Content-Length").toArray()[0]);
assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType());
}
@Test
@ -222,23 +223,23 @@ public class BatchClientITCase extends AbstractTestITCase {
ODataBatchResponseItem item = iter.next();
assertFalse(item.isChangeset());
ODataResponse oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
assertEquals(1, oDataResonse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResonse.getHeader("Content-Length").size());
assertEquals("605", oDataResonse.getHeader("Content-Length").toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
ODataResponse oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode());
assertEquals(1, oDataResponse.getHeader("OData-Version").size());
assertEquals("4.0", oDataResponse.getHeader("OData-Version").toArray()[0]);
assertEquals(1, oDataResponse.getHeader("Content-Length").size());
assertEquals("605", oDataResponse.getHeader("Content-Length").toArray()[0]);
assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType());
// Check second get request
assertTrue(iter.hasNext());
item = iter.next();
assertFalse(item.isChangeset());
oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResonse.getStatusCode());
oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResponse.getStatusCode());
// Check if third request is available
assertFalse(iter.hasNext());
@ -310,7 +311,8 @@ public class BatchClientITCase extends AbstractTestITCase {
// Fetch result
final ODataBatchResponse response = payload.getResponse();
assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode());
assertEquals("odata.continue-on-error", response.getHeader(HttpHeader.PREFERENCE_APPLIED).iterator().next());
assertEquals(ODataPreferenceNames.CONTINUE_ON_ERROR.toString(),
response.getHeader(HttpHeader.PREFERENCE_APPLIED).iterator().next());
final Iterator<ODataBatchResponseItem> bodyIterator = response.getBody();
@ -319,37 +321,37 @@ public class BatchClientITCase extends AbstractTestITCase {
ODataBatchResponseItem item = bodyIterator.next();
assertFalse(item.isChangeset());
ODataResponse oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
assertEquals(1, oDataResonse.getHeader(HttpHeader.ODATA_VERSION).size());
assertEquals("4.0", oDataResonse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]);
assertEquals(1, oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).size());
assertEquals("605", oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
ODataResponse oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode());
assertEquals(1, oDataResponse.getHeader(HttpHeader.ODATA_VERSION).size());
assertEquals("4.0", oDataResponse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]);
assertEquals(1, oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).size());
assertEquals("605", oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]);
assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType());
// Check second get request
assertTrue(bodyIterator.hasNext());
item = bodyIterator.next();
assertFalse(item.isChangeset());
oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResonse.getStatusCode());
oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), oDataResponse.getStatusCode());
// Check if third request is available
assertTrue(bodyIterator.hasNext());
item = bodyIterator.next();
assertFalse(item.isChangeset());
oDataResonse = item.next();
assertNotNull(oDataResonse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode());
assertEquals(1, oDataResonse.getHeader(HttpHeader.ODATA_VERSION).size());
assertEquals("4.0", oDataResonse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]);
assertEquals(1, oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).size());
assertEquals("513", oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]);
assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType());
oDataResponse = item.next();
assertNotNull(oDataResponse);
assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResponse.getStatusCode());
assertEquals(1, oDataResponse.getHeader(HttpHeader.ODATA_VERSION).size());
assertEquals("4.0", oDataResponse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]);
assertEquals(1, oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).size());
assertEquals("513", oDataResponse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]);
assertEquals(ContentType.JSON.toContentTypeString(), oDataResponse.getContentType());
}
@Test

View File

@ -1,63 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.fit.tecsvc.client;
import static org.junit.Assert.*;
import java.net.URI;
import org.apache.olingo.client.api.EdmEnabledODataClient;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
import org.junit.Test;
public class EdmEnabledClientITCase extends AbstractBaseTestITCase {
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
private static final String ES_KEY_NAV = "ESKeyNav";
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
@Test
public void readSingleValuedNavigationPropertyWithNullValue() {
final ODataClient client = getClient();
final URI uri = client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_KEY_NAV)
.appendKeySegment(3)
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE)
.build();
final ODataRetrieveResponse<ClientEntity> response = getClient().getRetrieveRequestFactory()
.getEntityRequest(uri)
.execute();
assertEquals(0, response.getBody().getNavigationLinks().size());
assertNull(response.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE));
}
@Override
protected ODataClient getClient() {
final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
return client;
}
}

View File

@ -149,6 +149,18 @@ public final class ExpandSelectITCase extends AbstractBaseTestITCase {
assertEquals("Test String4", innerEntity.getProperty("PropertyString").getPrimitiveValue().toValue());
}
@Test
public void expandSingleValuedNavigationPropertyWithNullValue() {
final ODataClient client = getClient();
final ODataRetrieveResponse<ClientEntity> response = client.getRetrieveRequestFactory()
.getEntityRequest(client.newURIBuilder(TecSvcConst.BASE_URI)
.appendEntitySetSegment("ESKeyNav").appendKeySegment(3).expand("NavPropertyETKeyNavOne").build())
.execute();
assertEquals(0, response.getBody().getNavigationLinks().size());
assertNull(response.getBody().getNavigationLink("NavPropertyETKeyNavOne"));
}
@Override
protected ODataClient getClient() {
return ODataClientFactory.getEdmEnabledClient(TecSvcConst.BASE_URI);

View File

@ -31,6 +31,7 @@ import java.net.ProtocolException;
import java.net.URL;
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;
@ -40,12 +41,16 @@ import org.junit.Test;
public class BasicBatchITCase extends AbstractBaseTestITCase {
private static final String HEADER_CONTENT_TRANSFER_ENCODING_BINARY = "Content-Transfer-Encoding: binary";
private static final String HEADER_CONTENT_TYPE_HTTP = "Content-Type: application/http";
private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
private static final String CONTENT_TYPE_HEADER_VALUE = " multipart/mixed;boundary=batch_123";
private static final String HEADER_CONTENT_TRANSFER_ENCODING_BINARY = "Content-Transfer-Encoding: binary";
private static final String HEADER_CONTENT_TYPE_HTTP =
HttpHeader.CONTENT_TYPE + ": " + ContentType.APPLICATION_HTTP.toContentTypeString();
private static final String CONTENT_TYPE_HEADER_VALUE = " "
+ ContentType.create(ContentType.MULTIPART_MIXED, "boundary", "batch_123").toContentTypeString();
private static final String ACCEPT_HEADER_VALUE = ContentType.APPLICATION_JSON.toContentTypeString();
private static final String CRLF = "\r\n";
private static final String ACCEPT_HEADER_VALUE = "application/json";
@Test
public void test() throws IOException {
@ -110,7 +115,7 @@ public class BasicBatchITCase extends AbstractBaseTestITCase {
}
private void blankLine(final BufferedReader reader) throws IOException {
assertEquals("", reader.readLine()); // CRLF becomes to an empty string
assertEquals("", reader.readLine()); // CRLF becomes an empty string
}
private String getRequest(final String uri) {

View File

@ -21,18 +21,17 @@ package org.apache.olingo.fit.tecsvc.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.io.InputStreamReader;
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.apache.olingo.server.core.deserializer.batch.BufferedReaderIncludingLineEndings;
import org.junit.Test;
public class BasicHttpITCase extends AbstractBaseTestITCase {
@ -44,13 +43,11 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
URL url = new URL(SERVICE_URI + "?$format=json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
String ct = connection.getHeaderField(HttpHeader.CONTENT_TYPE);
assertEquals(ContentType.create("application/json;odata.metadata=minimal"), ContentType.create(ct));
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
}
@Test
@ -59,15 +56,13 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;q=0.2;odata.metadata=minimal");
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
String ct = connection.getHeaderField(HttpHeader.CONTENT_TYPE);
assertEquals(ContentType.create("application/json;odata.metadata=minimal"), ContentType.create(ct));
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
}
@Test
@ -76,15 +71,13 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
String ct = connection.getHeaderField(HttpHeader.CONTENT_TYPE);
assertEquals(ContentType.create("application/json;odata.metadata=minimal"), ContentType.create(ct));
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
}
@Test
@ -93,15 +86,14 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;q=0.2;odata.metadata=minimal;charset=utf-8");
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
String ct = connection.getHeaderField(HttpHeader.CONTENT_TYPE);
assertEquals(ContentType.create("application/json;odata.metadata=minimal;charset=utf-8"), ContentType.create(ct));
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.create(ContentType.JSON, ContentType.PARAMETER_CHARSET, "utf-8"),
ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
}
@Test
@ -110,65 +102,50 @@ public class BasicHttpITCase extends AbstractBaseTestITCase {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ODATA_MAX_VERSION, "4.0");
connection.setRequestProperty(HttpHeader.ACCEPT, "*/*");
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
String v = connection.getHeaderField(HttpHeader.ODATA_VERSION);
assertEquals("4.0", v);
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals("4.0", connection.getHeaderField(HttpHeader.ODATA_VERSION));
}
@Test
public void testIEEE754ParameterContentNegotiation() throws Exception {
final URL url = new URL(SERVICE_URI + "/ESAllPrim(32767)?$format=application/json;IEEE754Compatible=true");
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;IEEE754Compatible=false");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.create("application/json;IEEE754Compatible=true;odata.metadata=minimal"),
ContentType.create(connection.getContentType()));
final String content = inputStreamToString(connection.getInputStream());
assertEquals(ContentType.create(ContentType.JSON, ContentType.PARAMETER_IEEE754_COMPATIBLE, "true"),
ContentType.create(connection.getContentType()));
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains("\"PropertyDecimal\":\"34\""));
assertTrue(content.contains("\"PropertyInt64\":\"9223372036854775807\""));
}
@Test
public void testIEEE754ParameterViaAcceptHeader() throws Exception {
final URL url = new URL(SERVICE_URI + "/ESAllPrim(32767)");
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;IEEE754Compatible=true");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.create("application/json;IEEE754Compatible=true;odata.metadata=minimal"),
ContentType.create(connection.getContentType()));
final String content = inputStreamToString(connection.getInputStream());
assertEquals(ContentType.create(ContentType.JSON, ContentType.PARAMETER_IEEE754_COMPATIBLE, "true"),
ContentType.create(connection.getContentType()));
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains("\"PropertyDecimal\":\"34\""));
assertTrue(content.contains("\"PropertyInt64\":\"9223372036854775807\""));
}
private String inputStreamToString(final InputStream in) throws Exception {
final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
final StringBuffer buffer = new StringBuffer();
String current;
while((current = reader.readLine()) != null) {
buffer.append(current);
}
reader.close();
return buffer.toString();
}
@Override
protected ODataClient getClient() {
return null;

View File

@ -21,16 +21,17 @@ package org.apache.olingo.fit.tecsvc.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.io.InputStreamReader;
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.apache.olingo.server.core.deserializer.batch.BufferedReaderIncludingLineEndings;
import org.junit.Test;
public class EntityReferenceITCase extends AbstractBaseTestITCase {
@ -41,49 +42,34 @@ public class EntityReferenceITCase extends AbstractBaseTestITCase {
@Test
public void testContextURlSingleEntity() throws Exception {
URL url = new URL(SERVICE_URI + "/ESAllPrim(0)/$ref");
URL url = new URL(SERVICE_URI + "/ESAllPrim(0)/$ref");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
connection.setRequestMethod("GET");
connection.connect();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty(HttpHeader.ACCEPT, ContentType.APPLICATION_JSON.toContentTypeString());
connection.setRequestMethod(HttpMethod.GET.name());
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
final String content = getString(connection.getInputStream());
assertTrue(content.contains(CONTEXT_ENTITY_REFERENCE));
}
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains(CONTEXT_ENTITY_REFERENCE));
}
@Test
public void testContextURLEntityCollection() throws Exception {
URL url = new URL(SERVICE_URI + "/ESAllPrim/$ref");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
connection.setRequestMethod("GET");
connection.setRequestProperty(HttpHeader.ACCEPT, ContentType.APPLICATION_JSON.toContentTypeString());
connection.setRequestMethod(HttpMethod.GET.name());
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
final String content = getString(connection.getInputStream());
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains(CONTEXT_COLLECTION_REFERENCE));
}
private String getString(final InputStream in) throws Exception {
final StringBuilder builder = new StringBuilder();
final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
String line;
while((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
return builder.toString();
}
@Override
protected ODataClient getClient() {
return null;

View File

@ -25,6 +25,8 @@ import java.net.URL;
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;
@ -41,12 +43,11 @@ public class PingITCase extends AbstractBaseTestITCase {
LOG.debug("ping request: " + SERVICE_URI);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "*/*");
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
}
@Test
@ -57,12 +58,11 @@ public class PingITCase extends AbstractBaseTestITCase {
LOG.debug("redirect request: " + REDIRECT_URI);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "*/*");
connection.connect();
int code = connection.getResponseCode();
assertEquals(200, code);
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
}
@Override

View File

@ -70,7 +70,8 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
assertEquals("Edm.GeographyPoint", entity.getProperty("Home").getPrimitiveValue().getTypeName());
// In JSON with minimal metadata, links are not provided
if(contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML)
if (contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)
|| (contentType.isCompatible(ContentType.JSON)
&& ContentType.VALUE_ODATA_METADATA_FULL
.equals(contentType.getParameter(ContentType.PARAMETER_ODATA_METADATA)))) {

View File

@ -85,7 +85,8 @@ public class ClientEntitySetIterator<ES extends ClientEntitySet, E extends Clien
this.contentType = contentType;
this.osEntitySet = new ByteArrayOutputStream();
if(contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML)) {
if(contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) {
namespaces = getAllElementAttributes(stream, "feed", osEntitySet);
} else {
namespaces = null;
@ -103,14 +104,12 @@ public class ClientEntitySetIterator<ES extends ClientEntitySet, E extends Clien
}
}
/**
* {@inheritDoc }
*/
@Override
@SuppressWarnings("unchecked")
@Override
public boolean hasNext() {
if (available && cached == null) {
if (contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML)) {
if (contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) {
cached = nextAtomEntityFromEntitySet(stream, osEntitySet, namespaces);
} else {
cached = nextJSONEntityFromEntitySet(stream, osEntitySet);
@ -131,9 +130,6 @@ public class ClientEntitySetIterator<ES extends ClientEntitySet, E extends Clien
return available;
}
/**
* {@inheritDoc }
*/
@Override
public E next() {
if (hasNext()) {

View File

@ -95,7 +95,7 @@ public class ODataClientImpl implements ODataClient {
public ODataWriter getWriter() {
return writer;
}
@Override
public ODataServiceVersion getServiceVersion() {
return ODataServiceVersion.V40;
@ -113,7 +113,7 @@ public class ODataClientImpl implements ODataClient {
public URIBuilder newURIBuilder(final String serviceRoot) {
return new URIBuilderImpl(getConfiguration(), serviceRoot);
}
@Override
public FilterFactory getFilterFactory() {
return filterFactory;
@ -131,10 +131,10 @@ public class ODataClientImpl implements ODataClient {
@Override
public ODataSerializer getSerializer(final ContentType contentType) {
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML,
ContentType.APPLICATION_XML) ?
new AtomSerializer() : new JsonSerializer(false, contentType);
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)
|| contentType.isCompatible(ContentType.APPLICATION_XML) ?
new AtomSerializer() : new JsonSerializer(false, contentType);
}
@Override

View File

@ -96,9 +96,10 @@ public abstract class AbstractODataInvokeRequest<T extends ClientInvokeResult>
}
private String getActualFormat(final ContentType contentType) {
return ((ClientProperty.class.isAssignableFrom(reference)
&& contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML))
? ContentType.APPLICATION_XML : contentType).toContentTypeString();
return (ClientProperty.class.isAssignableFrom(reference)
&& (contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) ?
ContentType.APPLICATION_XML : contentType).toContentTypeString();
}
@Override

View File

@ -54,13 +54,13 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class ClientODataDeserializerImpl implements ClientODataDeserializer {
private final ODataDeserializer deserializer;
private final ContentType contentType;
public ClientODataDeserializerImpl(final boolean serverMode, final ContentType contentType) {
this.contentType = contentType;
if(contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML,
ContentType.APPLICATION_XML )) {
if (contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)
|| contentType.isCompatible(ContentType.APPLICATION_XML)) {
deserializer = new AtomDeserializer();
} else {
deserializer = new JsonDeserializer(serverMode);
@ -127,10 +127,11 @@ public class ClientODataDeserializerImpl implements ClientODataDeserializer {
@Override
public ResWrap<Delta> toDelta(final InputStream input) throws ODataDeserializerException {
try {
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML) ?
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML) ?
new AtomDeserializer().delta(input) :
new JsonDeltaDeserializer(false).toDelta(input);
} catch (XMLStreamException e) {
} catch (final XMLStreamException e) {
throw new ODataDeserializerException(e);
} catch (final EdmPrimitiveTypeException e) {
throw new ODataDeserializerException(e);

View File

@ -44,7 +44,8 @@ public abstract class AbstractTest {
}
protected String getSuffix(final ContentType contentType) {
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML,
ContentType.APPLICATION_XML) ? "xml": "json";
return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)
|| contentType.isCompatible(ContentType.APPLICATION_XML) ? "xml": "json";
}
}

View File

@ -102,7 +102,8 @@ public class EntityTest extends AbstractTest {
}
if ("Orders".equals(link.getName())) {
checked++;
if(contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC, ContentType.APPLICATION_ATOM_XML)) {
if (contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
|| contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) {
assertEquals(ClientLinkType.ENTITY_SET_NAVIGATION, link.getType());
}
}

View File

@ -24,7 +24,6 @@ import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
/**
* Internally used {@link AcceptType} for OData library.
@ -55,26 +54,17 @@ public class AcceptType {
final Float quality) {
this.type = type;
this.subtype = subtype;
this.parameters = createParameterMap();
this.parameters = TypeUtil.createParameterMap();
this.parameters.putAll(parameters);
this.quality = quality;
}
private static TreeMap<String, String> createParameterMap() {
return new TreeMap<String, String>(new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return o1.compareToIgnoreCase(o2);
}
});
}
private AcceptType(final String type) {
if (type == null) {
throw new IllegalArgumentException("Type parameter MUST NOT be null.");
}
List<String> typeSubtype = new ArrayList<String>();
parameters = createParameterMap();
parameters = TypeUtil.createParameterMap();
parse(type, typeSubtype, parameters);
this.type = typeSubtype.get(0);
@ -122,15 +112,15 @@ public class AcceptType {
}
/**
* Creates a list of {@link AcceptType} objects based on given input string (<code>format</code>).
* @param contentType accept types, comma-separated, as specified for the HTTP header <code>Accept</code>
* Creates a list of {@link AcceptType} objects based on given input string.
* @param acceptTypes accept types, comma-separated, as specified for the HTTP header <code>Accept</code>
* @return a list of <code>AcceptType</code> objects
* @throws IllegalArgumentException if input string is not parseable
*/
public static List<AcceptType> create(final String contentType) {
public static List<AcceptType> create(final String acceptTypes) {
List<AcceptType> result = new ArrayList<AcceptType>();
String[] values = contentType.split(",");
String[] values = acceptTypes.split(",");
for (String value : values) {
result.add(new AcceptType(value.trim()));
}
@ -220,12 +210,12 @@ public class AcceptType {
}
/**
* Sort given list of Accept types
* Sorts given list of Accept types
* according to their quality-parameter values and their specificity
* as defined in RFC 7231, chapters 3.1.1.1, 5.3.1, and 5.3.2.
* @param toSort list which is sorted and hence re-arranged
*/
private static void sort(final List<AcceptType> toSort) {
private static void sort(List<AcceptType> toSort) {
Collections.sort(toSort,
new Comparator<AcceptType>() {
@Override

View File

@ -20,14 +20,12 @@ package org.apache.olingo.commons.api.format;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
/**
* Internally used {@link ContentType} for OData library.
@ -96,10 +94,9 @@ public final class ContentType {
/**
* Creates a content type from type, subtype, and parameters.
*
* @param type
* @param subtype
* @param parameters
* @param type type
* @param subtype subtype
* @param parameters parameters as map from names to values
*/
private ContentType(final String type, final String subtype, final Map<String, String> parameters) {
this.type = validateType(type);
@ -108,17 +105,12 @@ public final class ContentType {
if (parameters == null) {
this.parameters = Collections.emptyMap();
} else {
this.parameters = new TreeMap<String, String>(new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return o1.compareToIgnoreCase(o2);
}
});
this.parameters = TypeUtil.createParameterMap();
this.parameters.putAll(parameters);
}
}
private String validateType(final String type) {
private String validateType(final String type) throws IllegalArgumentException {
if (type == null || type.isEmpty() || "*".equals(type)) {
throw new IllegalArgumentException("Illegal type '" + type + "'.");
}
@ -128,20 +120,6 @@ public final class ContentType {
return type;
}
/**
* Validates if given <code>format</code> is parseable and can be used as input for {@link #create(String)} method.
*
* @param format to be validated string
* @return <code>true</code> if format is parseable otherwise <code>false</code>
*/
public static boolean isParseable(final String format) {
try {
return ContentType.create(format) != null;
} catch (IllegalArgumentException e) {
return false;
}
}
/**
* Creates a content type from an existing content type and an additional parameter as key-value pair.
* @param contentType an existing content type
@ -150,17 +128,12 @@ public final class ContentType {
* @return a new {@link ContentType} object
*/
public static ContentType create(final ContentType contentType,
final String parameterName, final String parameterValue) {
if (parameterName == null || parameterName.isEmpty() || parameterName.indexOf(TypeUtil.WHITESPACE_CHAR) >= 0) {
throw new IllegalArgumentException("Illegal parameter name '" + parameterName + "'.");
}
if (Character.isWhitespace(parameterValue.charAt(0))) {
throw new IllegalArgumentException("Value of parameter '" + parameterName + "' starts with whitespace.");
}
final String parameterName, final String parameterValue) throws IllegalArgumentException {
TypeUtil.validateParameterNameAndValue(parameterName, parameterValue);
ContentType ct = new ContentType(contentType.type, contentType.subtype, contentType.parameters);
ct.parameters.put(parameterName.toLowerCase(Locale.ROOT), parameterValue);
return ct;
ContentType type = new ContentType(contentType.type, contentType.subtype, contentType.parameters);
type.parameters.put(parameterName.toLowerCase(Locale.ROOT), parameterValue);
return type;
}
/**
@ -168,15 +141,15 @@ public final class ContentType {
* <code>Media Type</code> format as defined in RFC 7231, chapter 3.1.1.1.
*
* @param format a string in format as defined in RFC 7231, chapter 3.1.1.1
* @return a new <code>ContentType</code> object
* @return a new {@link ContentType} object
* @throws IllegalArgumentException if input string is not parseable
*/
public static ContentType create(final String format) {
public static ContentType create(final String format) throws IllegalArgumentException {
if (format == null) {
throw new IllegalArgumentException("Parameter format MUST NOT be NULL.");
}
final List<String> typeSubtype = new ArrayList<String>();
final Map<String, String> parameters = new HashMap<String, String>();
List<String> typeSubtype = new ArrayList<String>();
Map<String, String> parameters = new HashMap<String, String>();
parse(format, typeSubtype, parameters);
return new ContentType(typeSubtype.get(0), typeSubtype.get(1), parameters);
}
@ -198,7 +171,8 @@ public final class ContentType {
}
}
private static void parse(final String format, final List<String> typeSubtype, final Map<String, String> parameters) {
private static void parse(final String format, List<String> typeSubtype, Map<String, String> parameters)
throws IllegalArgumentException {
final String[] typesAndParameters = format.split(TypeUtil.PARAMETER_SEPARATOR, 2);
final String types = typesAndParameters[0];
final String params = (typesAndParameters.length > 1 ? typesAndParameters[1] : null);
@ -246,8 +220,7 @@ public final class ContentType {
/**
* Returns the value of a given parameter.
* If the parameter does not exists the method returns null.
*
* If the parameter does not exist the method returns null.
* @param name the name of the parameter to get (case-insensitive)
* @return the value of the parameter or <code>null</code> if the parameter is not present
*/
@ -310,26 +283,8 @@ public final class ContentType {
return type.equalsIgnoreCase(other.type) && subtype.equalsIgnoreCase(other.subtype);
}
/**
* <p>{@link ContentType}s are <b>compatible</b>
* if <code>type</code> and <code>subtype</code> have the same value.</p>
* <p>The set <code>parameters</code> are <b>always</b> ignored
* (for compare with parameters see {@link #equals(Object)}).</p>
* @return <code>true</code> if both instances are compatible (see definition above), otherwise <code>false</code>.
*/
public boolean isCompatible(final ContentType... otherTypes) {
for (final ContentType otherType : otherTypes) {
if (isCompatible(otherType)) {
return true;
}
}
return false;
}
/**
* Checks whether both strings are equal ignoring the case of the strings.
*
* @param first first string
* @param second second string
* @return <code>true</code> if both strings are equal (ignoring the case), otherwise <code>false</code>
@ -340,10 +295,8 @@ public final class ContentType {
/**
* Gets {@link ContentType} as string as defined in
* <a href="http://www.ietf.org/rfc/rfc7231.txt">RFC 7231</a>, chapter 3.1.1.1:
* Media Type.
*
* @return string representation of <code>ContentType</code> object
* <a href="http://www.ietf.org/rfc/rfc7231.txt">RFC 7231</a>, chapter 3.1.1.1: Media Type.
* @return string representation of {@link ContentType} object
*/
public String toContentTypeString() {
final StringBuilder sb = new StringBuilder();

View File

@ -18,8 +18,10 @@
*/
package org.apache.olingo.commons.api.format;
import java.util.Comparator;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
class TypeUtil {
@ -32,6 +34,16 @@ class TypeUtil {
static final String TYPE_SUBTYPE_SEPARATOR = "/";
static final String TYPE_SUBTYPE_WILDCARD = "*";
/** Creates a parameter map with predictable order. */
protected static Map<String, String> createParameterMap() {
return new TreeMap<String, String>(new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return o1.compareToIgnoreCase(o2);
}
});
}
/**
* Valid input are <code>;</code> separated <code>key=value</code> pairs
* without spaces between key and value.
@ -60,19 +72,23 @@ class TypeUtil {
if (parameter.isEmpty()) {
throw new IllegalArgumentException("An empty parameter is not allowed.");
}
String[] keyValue = parameter.trim().split(TypeUtil.PARAMETER_KEY_VALUE_SEPARATOR);
if (keyValue.length != 2 || keyValue[0].isEmpty()) {
throw new IllegalArgumentException(
"Parameter '" + parameter + "' must have exactly one '" + TypeUtil.PARAMETER_KEY_VALUE_SEPARATOR +
"' that separates the name and the value.");
String[] keyValue = parameter.trim().split(PARAMETER_KEY_VALUE_SEPARATOR);
if (keyValue.length != 2) {
throw new IllegalArgumentException("Parameter '" + parameter + "' must have exactly one '"
+ PARAMETER_KEY_VALUE_SEPARATOR + "' that separates the name and the value.");
}
validateParameterNameAndValue(keyValue[0], keyValue[1]);
keyValue[0] = keyValue[0].toLowerCase(Locale.ENGLISH);
if (keyValue[0].indexOf(WHITESPACE_CHAR) >= 0) {
throw new IllegalArgumentException("Parameter name '" + keyValue[0] + "' contains whitespace.");
}
if (Character.isWhitespace(keyValue[1].charAt(0))) {
throw new IllegalArgumentException("Value of parameter '" + keyValue[0] + "' starts with whitespace.");
}
return keyValue;
}
protected static void validateParameterNameAndValue(final String parameterName, final String parameterValue)
throws IllegalArgumentException {
if (parameterName == null || parameterName.isEmpty() || parameterName.indexOf(WHITESPACE_CHAR) >= 0) {
throw new IllegalArgumentException("Illegal parameter name '" + parameterName + "'.");
}
if (Character.isWhitespace(parameterValue.charAt(0))) {
throw new IllegalArgumentException("Value of parameter '" + parameterName + "' starts with whitespace.");
}
}
}

View File

@ -165,23 +165,15 @@ public interface HttpHeader {
*/
public static final String SET_COOKIE = "Set-Cookie";
/**
* non standard header
*/
/** Non standard header. */
public static final String X_HTTP_METHOD = "X-HTTP-Method";
/**
* non standard header
*/
/** Non standard header. */
public static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override";
/**
* OData Custom Header
*/
/** Custom Header defined in the OData standard. */
public static final String ODATA_VERSION = "OData-Version";
/**
* OData Custom Header
*/
/** Custom Header defined in the OData standard. */
public static final String ODATA_MAX_VERSION = "OData-MaxVersion";
/** Custom Header defined in the OData standard. */
public static final String ODATA_ENTITY_ID = "OData-EntityID";
}

View File

@ -100,7 +100,6 @@ public class ContentTypeTest {
@Test
public void testParse() {
assertNull(ContentType.parse("a"));
assertFalse(ContentType.isParseable("a"));
}
@Test(expected = IllegalArgumentException.class)

View File

@ -158,9 +158,12 @@ public class TechnicalActionProcessor extends TechnicalProcessor
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
if (entityResult.isCreated()) {
response.setHeader(HttpHeader.LOCATION,
request.getRawBaseUri() + '/'
+ odata.createUriHelper().buildCanonicalURL(edmEntitySet, entityResult.getEntity()));
final String location = request.getRawBaseUri() + '/'
+ odata.createUriHelper().buildCanonicalURL(edmEntitySet, entityResult.getEntity());
response.setHeader(HttpHeader.LOCATION, location);
if (returnPreference == Return.MINIMAL) {
response.setHeader(HttpHeader.ODATA_ENTITY_ID, location);
}
}
if (entityResult.getEntity().getETag() != null) {
response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag());

View File

@ -164,6 +164,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
expand = deserializerResult.getExpandTree();
}
final String location = request.getRawBaseUri() + '/'
+ odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity);
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, expand, null)
@ -172,13 +174,13 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
} else {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
response.setHeader(HttpHeader.ODATA_ENTITY_ID, location);
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
response.setHeader(HttpHeader.LOCATION,
request.getRawBaseUri() + '/' + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity));
response.setHeader(HttpHeader.LOCATION, location);
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
}

View File

@ -50,12 +50,12 @@ import org.apache.olingo.server.tecsvc.data.DataProvider;
*/
public abstract class TechnicalProcessor implements Processor {
protected final DataProvider dataProvider;
protected OData odata;
protected DataProvider dataProvider;
protected ServiceMetadata serviceMetadata;
protected TechnicalProcessor(final DataProvider dataProvider) {
this.dataProvider = dataProvider;
this(dataProvider, null);
}
protected TechnicalProcessor(final DataProvider dataProvider, final ServiceMetadata serviceMetadata) {