[OLINGO-663] conditional handling in technical service, part 2
Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
parent
ea89f7213e
commit
7ad5b0fb54
|
@ -18,20 +18,35 @@
|
|||
*/
|
||||
package org.apache.olingo.fit.tecsvc.client;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.UpdateType;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
|
||||
import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.client.api.domain.ClientEntity;
|
||||
import org.apache.olingo.client.api.domain.ClientProperty;
|
||||
import org.apache.olingo.client.api.http.HttpClientException;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.commons.api.ODataError;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
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;
|
||||
|
@ -39,31 +54,27 @@ import org.junit.Test;
|
|||
|
||||
public final class ConditionalITCase extends AbstractBaseTestITCase {
|
||||
|
||||
private final ODataClient client = getClient();
|
||||
|
||||
private final URI uriEntity = client.newURIBuilder(TecSvcConst.BASE_URI)
|
||||
.appendEntitySetSegment("ESCompAllPrim").appendKeySegment(0).build();
|
||||
private final URI uriProperty = client.newURIBuilder(uriEntity.toASCIIString())
|
||||
.appendPropertySegment("PropertyComp").appendPropertySegment("PropertyDuration").build();
|
||||
private final URI uriPropertyValue = client.newURIBuilder(uriProperty.toASCIIString()).appendValueSegment().build();
|
||||
private final URI uriMedia = client.newURIBuilder(TecSvcConst.BASE_URI)
|
||||
.appendEntitySetSegment("ESMedia").appendKeySegment(1).appendValueSegment().build();
|
||||
|
||||
@Test
|
||||
public void readWithWrongIfMatch() throws Exception {
|
||||
final ODataClient client = getClient();
|
||||
ODataEntityRequest<ClientEntity> request = client.getRetrieveRequestFactory().getEntityRequest(
|
||||
client.newURIBuilder(TecSvcConst.BASE_URI)
|
||||
.appendEntitySetSegment("ESCompAllPrim").appendKeySegment(0).build());
|
||||
ODataEntityRequest<ClientEntity> request = client.getRetrieveRequestFactory().getEntityRequest(uriEntity);
|
||||
request.setIfMatch("W/\"1\"");
|
||||
assertNotNull(request);
|
||||
|
||||
try {
|
||||
request.execute();
|
||||
fail("Expected Exception not thrown!");
|
||||
} catch (final ODataClientErrorException e) {
|
||||
assertEquals(HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||
final ODataError error = e.getODataError();
|
||||
assertThat(error.getMessage(), containsString("condition"));
|
||||
}
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readNotModified() throws Exception {
|
||||
final ODataClient client = getClient();
|
||||
ODataEntityRequest<ClientEntity> request = client.getRetrieveRequestFactory().getEntityRequest(
|
||||
client.newURIBuilder(TecSvcConst.BASE_URI)
|
||||
.appendEntitySetSegment("ESCompAllPrim").appendKeySegment(0).build());
|
||||
ODataEntityRequest<ClientEntity> request = client.getRetrieveRequestFactory().getEntityRequest(uriEntity);
|
||||
request.setIfNoneMatch("W/\"0\"");
|
||||
assertNotNull(request);
|
||||
|
||||
|
@ -71,6 +82,115 @@ public final class ConditionalITCase extends AbstractBaseTestITCase {
|
|||
assertEquals(HttpStatusCode.NOT_MODIFIED.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateWithoutIfMatch() throws Exception {
|
||||
executeAndExpectError(
|
||||
client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||
uriEntity, UpdateType.PATCH, client.getObjectFactory().newEntity(null)),
|
||||
HttpStatusCode.PRECONDITION_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateWithWrongIfMatch() throws Exception {
|
||||
ODataEntityUpdateRequest<ClientEntity> request = client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||
uriEntity, UpdateType.PATCH, client.getObjectFactory().newEntity(null));
|
||||
request.setIfMatch("W/\"1\"");
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateMediaWithWrongIfMatch() throws Exception {
|
||||
ODataMediaEntityUpdateRequest<ClientEntity> request = client.getCUDRequestFactory().getMediaEntityUpdateRequest(
|
||||
uriMedia, IOUtils.toInputStream("ignored"));
|
||||
request.setIfMatch("W/\"42\"");
|
||||
|
||||
try {
|
||||
request.payloadManager().getResponse();
|
||||
fail("Expected Exception not thrown!");
|
||||
} catch (final HttpClientException e) {
|
||||
final ODataClientErrorException ex = (ODataClientErrorException) e.getCause().getCause();
|
||||
assertEquals(HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), ex.getStatusLine().getStatusCode());
|
||||
assertThat(ex.getODataError().getMessage(), containsString("condition"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteWithWrongIfMatch() throws Exception {
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriEntity);
|
||||
request.setIfMatch("W/\"1\"");
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteMediaWithWrongIfMatch() throws Exception {
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriMedia);
|
||||
request.setIfMatch("W/\"42\"");
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indirectEntityChange() throws Exception {
|
||||
final String eTag = "W/\"0\"";
|
||||
ODataDeleteRequest deleteRequest = client.getCUDRequestFactory().getDeleteRequest(uriProperty);
|
||||
deleteRequest.setIfMatch(eTag);
|
||||
final ODataDeleteResponse response = deleteRequest.execute();
|
||||
|
||||
ODataEntityUpdateRequest<ClientEntity> request = client.getCUDRequestFactory().getEntityUpdateRequest(
|
||||
uriEntity, UpdateType.PATCH, client.getObjectFactory().newEntity(null));
|
||||
request.setIfMatch(eTag);
|
||||
// This request has to be in the same session as the first in order to access the same data provider.
|
||||
request.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next());
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readPropertyNotModified() throws Exception {
|
||||
ODataPropertyRequest<ClientProperty> request = client.getRetrieveRequestFactory().getPropertyRequest(uriProperty);
|
||||
request.setIfNoneMatch("W/\"0\"");
|
||||
assertEquals(HttpStatusCode.NOT_MODIFIED.getStatusCode(), request.execute().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readPropertyValueNotModified() throws Exception {
|
||||
ODataValueRequest request = client.getRetrieveRequestFactory().getPropertyValueRequest(uriPropertyValue);
|
||||
request.setIfNoneMatch("W/\"0\"");
|
||||
assertEquals(HttpStatusCode.NOT_MODIFIED.getStatusCode(), request.execute().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePropertyWithWrongIfMatch() throws Exception {
|
||||
ODataPropertyUpdateRequest request = client.getCUDRequestFactory().getPropertyPrimitiveValueUpdateRequest(
|
||||
uriProperty,
|
||||
client.getObjectFactory().newPrimitiveProperty("PropertyDuration",
|
||||
client.getObjectFactory().newPrimitiveValueBuilder().buildString("PT42S")));
|
||||
request.setIfMatch("W/\"1\"");
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePropertyWithWrongIfMatch() throws Exception {
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriProperty);
|
||||
request.setIfMatch("W/\"1\"");
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePropertyValueWithWrongIfMatch() throws Exception {
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriPropertyValue);
|
||||
request.setIfMatch("W/\"1\"");
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
private void executeAndExpectError(ODataBasicRequest<?> request, final HttpStatusCode status) {
|
||||
try {
|
||||
request.execute();
|
||||
fail("Expected Exception not thrown!");
|
||||
} catch (final ODataClientErrorException e) {
|
||||
assertEquals(status.getStatusCode(), e.getStatusLine().getStatusCode());
|
||||
assertThat(e.getODataError().getMessage(), anyOf(containsString("condition"), containsString("match")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataClient getClient() {
|
||||
ODataClient odata = ODataClientFactory.getClient();
|
||||
|
|
|
@ -75,7 +75,8 @@ public final class MediaITCase extends AbstractBaseTestITCase {
|
|||
final ODataClient client = getClient();
|
||||
final URI uri = client.newURIBuilder(TecSvcConst.BASE_URI)
|
||||
.appendEntitySetSegment("ESMedia").appendKeySegment(4).appendValueSegment().build();
|
||||
final ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uri);
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uri);
|
||||
request.setIfMatch("W/\"4\"");
|
||||
assertNotNull(request);
|
||||
|
||||
final ODataDeleteResponse response = request.execute();
|
||||
|
@ -102,6 +103,7 @@ public final class MediaITCase extends AbstractBaseTestITCase {
|
|||
client.getCUDRequestFactory().getMediaEntityUpdateRequest(uri,
|
||||
IOUtils.toInputStream("just a test"));
|
||||
request.setContentType(ContentType.TEXT_PLAIN.toContentTypeString());
|
||||
request.setIfMatch("W/\"4\"");
|
||||
assertNotNull(request);
|
||||
|
||||
final ODataMediaEntityUpdateResponse<ClientEntity> response = request.payloadManager().getResponse();
|
||||
|
@ -143,7 +145,7 @@ public final class MediaITCase extends AbstractBaseTestITCase {
|
|||
// This check has to be in the same session in order to access the same data provider.
|
||||
ODataMediaRequest mediaRequest = client.getRetrieveRequestFactory().getMediaRequest(
|
||||
client.newURIBuilder(TecSvcConst.BASE_URI).appendEntitySetSegment("ESMedia")
|
||||
.appendKeySegment(5).appendValueSegment().build());
|
||||
.appendKeySegment(5).appendValueSegment().build());
|
||||
mediaRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next());
|
||||
ODataRetrieveResponse<InputStream> mediaResponse = mediaRequest.execute();
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), mediaResponse.getStatusCode());
|
||||
|
|
|
@ -20,23 +20,31 @@ package org.apache.olingo.fit.tecsvc.client;
|
|||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
|
||||
import org.apache.olingo.client.api.communication.request.cud.UpdateType;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataPropertyUpdateResponse;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.client.api.domain.ClientCollectionValue;
|
||||
import org.apache.olingo.client.api.domain.ClientComplexValue;
|
||||
import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
|
||||
import org.apache.olingo.client.api.domain.ClientProperty;
|
||||
import org.apache.olingo.client.api.domain.ClientValue;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
|
@ -52,13 +60,12 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
|
|||
|
||||
@Test
|
||||
public void readSimpleProperty() throws Exception {
|
||||
ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
final ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
.getPropertyRequest(getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESTwoPrim")
|
||||
.appendKeySegment(32766)
|
||||
.appendPropertySegment("PropertyString")
|
||||
.build());
|
||||
|
||||
assertNotNull(request);
|
||||
|
||||
ODataRetrieveResponse<ClientProperty> response = request.execute();
|
||||
|
@ -135,7 +142,7 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
|
|||
|
||||
@Test
|
||||
public void readComplexProperty() throws Exception {
|
||||
ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
final ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
.getPropertyRequest(getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESMixPrimCollComp")
|
||||
.appendKeySegment(7)
|
||||
|
@ -153,7 +160,7 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
|
|||
|
||||
@Test
|
||||
public void readComplexPropertyContextURL() throws Exception {
|
||||
ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
final ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
.getPropertyRequest(getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESMixPrimCollComp")
|
||||
.appendKeySegment(7)
|
||||
|
@ -185,7 +192,7 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
|
|||
|
||||
@Test
|
||||
public void readUnknownProperty() throws Exception {
|
||||
ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
final ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
.getPropertyRequest(getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESTwoPrim")
|
||||
.appendKeySegment(32766)
|
||||
|
@ -201,16 +208,114 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
|
|||
|
||||
@Test
|
||||
public void readNoContentProperty() throws Exception {
|
||||
ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
final ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
|
||||
.getPropertyRequest(getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESTwoPrim")
|
||||
.appendKeySegment(-32766)
|
||||
.appendPropertySegment("PropertyString")
|
||||
.build());
|
||||
ODataRetrieveResponse<ClientProperty> response = request.execute();
|
||||
final ODataRetrieveResponse<ClientProperty> response = request.execute();
|
||||
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePrimitiveProperty() throws Exception {
|
||||
final ODataPropertyUpdateRequest request =
|
||||
getClient().getCUDRequestFactory().getPropertyPrimitiveValueUpdateRequest(
|
||||
getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESTwoPrim").appendKeySegment(32766)
|
||||
.appendPropertySegment("PropertyString")
|
||||
.build(),
|
||||
getClient().getObjectFactory().newPrimitiveProperty("PropertyString",
|
||||
getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test String1")));
|
||||
assertNotNull(request);
|
||||
|
||||
final ODataPropertyUpdateResponse response = request.execute();
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
assertThat(response.getContentType(), containsString(ContentType.APPLICATION_JSON.toContentTypeString()));
|
||||
|
||||
final ClientProperty property = response.getBody();
|
||||
assertNotNull(property);
|
||||
assertNotNull(property.getPrimitiveValue());
|
||||
assertEquals("Test String1", property.getPrimitiveValue().toValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchComplexProperty() throws Exception {
|
||||
final ODataPropertyUpdateRequest request =
|
||||
getClient().getCUDRequestFactory().getPropertyComplexValueUpdateRequest(
|
||||
getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESMixPrimCollComp").appendKeySegment(7)
|
||||
.appendPropertySegment("PropertyComp")
|
||||
.build(),
|
||||
UpdateType.PATCH,
|
||||
getClient().getObjectFactory().newComplexProperty("PropertyComp",
|
||||
getClient().getObjectFactory().newComplexValue(null).add(
|
||||
getClient().getObjectFactory().newPrimitiveProperty("PropertyString",
|
||||
getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test String42")))));
|
||||
assertNotNull(request);
|
||||
|
||||
final ODataPropertyUpdateResponse response = request.execute();
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
final ClientProperty property = response.getBody();
|
||||
assertNotNull(property);
|
||||
assertNotNull(property.getComplexValue());
|
||||
final ClientComplexValue value = property.getComplexValue();
|
||||
assertEquals("Test String42", value.get("PropertyString").getPrimitiveValue().toValue());
|
||||
assertEquals(222, value.get("PropertyInt16").getPrimitiveValue().toValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePrimitiveCollection() throws Exception {
|
||||
final ODataPropertyUpdateRequest request =
|
||||
getClient().getCUDRequestFactory().getPropertyCollectionValueUpdateRequest(
|
||||
getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESMixPrimCollComp").appendKeySegment(7)
|
||||
.appendPropertySegment("CollPropertyString")
|
||||
.build(),
|
||||
getClient().getObjectFactory().newCollectionProperty("CollPropertyString",
|
||||
getClient().getObjectFactory().newCollectionValue(null)
|
||||
.add(getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test String1"))
|
||||
.add(getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test String2"))));
|
||||
assertNotNull(request);
|
||||
|
||||
final ODataPropertyUpdateResponse response = request.execute();
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
final ClientProperty property = response.getBody();
|
||||
assertNotNull(property);
|
||||
final ClientCollectionValue<ClientValue> value = property.getCollectionValue();
|
||||
assertNotNull(value);
|
||||
Iterator<ClientValue> iterator = value.iterator();
|
||||
assertTrue(iterator.hasNext());
|
||||
assertEquals("Test String1", iterator.next().asPrimitive().toValue());
|
||||
assertEquals("Test String2", iterator.next().asPrimitive().toValue());
|
||||
assertFalse(iterator.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateComplexCollection() throws Exception {
|
||||
final ODataPropertyUpdateRequest request =
|
||||
getClient().getCUDRequestFactory().getPropertyCollectionValueUpdateRequest(
|
||||
getClient().newURIBuilder(SERVICE_URI)
|
||||
.appendEntitySetSegment("ESMixPrimCollComp").appendKeySegment(7)
|
||||
.appendPropertySegment("CollPropertyComp")
|
||||
.build(),
|
||||
getClient().getObjectFactory().newCollectionProperty("CollPropertyComp",
|
||||
getClient().getObjectFactory().newCollectionValue(null)));
|
||||
assertNotNull(request);
|
||||
|
||||
final ODataPropertyUpdateResponse response = request.execute();
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
final ClientProperty property = response.getBody();
|
||||
assertNotNull(property);
|
||||
final ClientCollectionValue<ClientValue> value = property.getCollectionValue();
|
||||
assertNotNull(value);
|
||||
assertFalse(value.iterator().hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readPropertyValue() throws Exception {
|
||||
final ODataValueRequest request = getClient().getRetrieveRequestFactory()
|
||||
|
@ -220,7 +325,7 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
|
|||
.appendPropertySegment("PropertyString")
|
||||
.appendValueSegment()
|
||||
.build());
|
||||
ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute();
|
||||
final ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute();
|
||||
assertEquals("Test String1", response.getBody().toValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,9 @@ public class EtagInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Checks whether a given ETag value is matched by this ETag information.</p>
|
||||
* <p>Checks whether a given ETag value is matched by this ETag information,
|
||||
* using weak comparison as described in
|
||||
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
|
||||
* <p>If the given value is <code>null</code>, or if this ETag information
|
||||
* does not contain anything, the result is <code>false</code>.</p>
|
||||
* @param etag the ETag value to match
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.tecsvc;
|
||||
|
||||
import org.apache.olingo.server.api.CustomETagSupport;
|
||||
|
||||
public class ETagSupport implements CustomETagSupport {
|
||||
|
||||
@Override
|
||||
public boolean hasETag(final String entitySetName) {
|
||||
return entitySetName.equals("ESCompAllPrim");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMediaETag(final String entitySetName) {
|
||||
return entitySetName.equals("ESMedia");
|
||||
}
|
||||
}
|
|
@ -48,7 +48,7 @@ public class TechnicalServlet extends HttpServlet {
|
|||
private static final Logger LOG = LoggerFactory.getLogger(TechnicalServlet.class);
|
||||
|
||||
@Override
|
||||
protected void service(final HttpServletRequest req, final HttpServletResponse resp)
|
||||
protected void service(final HttpServletRequest request, final HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
OData odata = OData.newInstance();
|
||||
|
@ -57,7 +57,7 @@ public class TechnicalServlet extends HttpServlet {
|
|||
final List<EdmxReference> references = Arrays.asList(reference);
|
||||
final ServiceMetadata serviceMetadata = odata.createServiceMetadata(new EdmTechProvider(references), references);
|
||||
|
||||
HttpSession session = req.getSession(true);
|
||||
HttpSession session = request.getSession(true);
|
||||
DataProvider dataProvider = (DataProvider) session.getAttribute(DataProvider.class.getName());
|
||||
if (dataProvider == null) {
|
||||
dataProvider = new DataProvider();
|
||||
|
@ -69,7 +69,8 @@ public class TechnicalServlet extends HttpServlet {
|
|||
handler.register(new TechnicalEntityProcessor(dataProvider, serviceMetadata));
|
||||
handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider, serviceMetadata));
|
||||
handler.register(new TechnicalBatchProcessor(dataProvider));
|
||||
handler.process(req, resp);
|
||||
handler.register(new ETagSupport());
|
||||
handler.process(request, response);
|
||||
} catch (RuntimeException e) {
|
||||
LOG.error("Server Error", e);
|
||||
throw new ServletException(e);
|
||||
|
|
|
@ -275,6 +275,10 @@ public class DataProvider {
|
|||
}
|
||||
|
||||
// Update the ETag if present.
|
||||
updateETag(entity);
|
||||
}
|
||||
|
||||
public void updateETag(Entity entity) {
|
||||
if (entity.getETag() != null) {
|
||||
entity.setETag("W/\"" + System.nanoTime() + "\"");
|
||||
}
|
||||
|
@ -411,8 +415,8 @@ public class DataProvider {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void updateProperty(final EdmProperty edmProperty, final Property property, final Property newProperty,
|
||||
@SuppressWarnings("unchecked")
|
||||
public void updateProperty(final EdmProperty edmProperty, Property property, final Property newProperty,
|
||||
final boolean patch) throws DataProviderException {
|
||||
if (edmProperty.isPrimitive()) {
|
||||
if (newProperty != null || !patch) {
|
||||
|
@ -420,7 +424,7 @@ public class DataProvider {
|
|||
property.setValue(property.getValueType(), value);
|
||||
}
|
||||
} else if (edmProperty.isCollection()) {
|
||||
// Updating collection properties mean replacing all entites with the given ones
|
||||
// Updating collection properties means replacing all entries with the given ones.
|
||||
property.asCollection().clear();
|
||||
|
||||
if (newProperty != null) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
|
@ -34,7 +35,6 @@ import org.apache.olingo.commons.api.http.HttpContentType;
|
|||
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.server.api.EtagInformation;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
|
@ -57,9 +57,11 @@ import org.apache.olingo.server.api.serializer.ODataSerializer;
|
|||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.serializer.SerializerResult;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceValue;
|
||||
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
|
@ -98,7 +100,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
public void processActionEntityCollection(final ODataRequest request, final ODataResponse response,
|
||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||
blockBoundActions(uriInfo);
|
||||
final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0))
|
||||
.getAction();
|
||||
|
||||
DeserializerResult deserializerResult =
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.actionParameters(request.getBody(), action);
|
||||
|
@ -148,7 +153,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
processEntity(request, response, uriInfo, requestedContentType, false);
|
||||
readEntity(request, response, uriInfo, requestedContentType, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -238,6 +243,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
checkChangePreconditions(entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
checkRequestFormat(requestFormat);
|
||||
final ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
|
||||
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity();
|
||||
|
@ -252,10 +261,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
||||
request.getMethod() == HttpMethod.PATCH, false);
|
||||
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
final ODataFormat format = ODataFormat.fromContentType(responseFormat);
|
||||
response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, format, null, null)
|
||||
.getContent());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
if (entity.getETag() != null) {
|
||||
response.setHeader(HttpHeader.ETAG, entity.getETag());
|
||||
|
@ -270,6 +279,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||
|
||||
Entity entity = readEntity(uriInfo);
|
||||
checkChangePreconditions(entity.getMediaETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
checkRequestFormat(requestFormat);
|
||||
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
|
||||
requestFormat.toContentTypeString());
|
||||
|
@ -285,10 +297,16 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void deleteEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
|
||||
public void deleteEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
||||
final Entity entity = readEntity(uriInfo);
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
final boolean isValue = resourcePaths.get(resourcePaths.size() - 1) instanceof UriResourceValue;
|
||||
|
||||
checkChangePreconditions(isValue ? entity.getMediaETag() : entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
dataProvider.delete(edmEntitySet, entity);
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
}
|
||||
|
@ -297,7 +315,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
public void processActionEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
final EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||
blockBoundActions(uriInfo);
|
||||
final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0))
|
||||
.getAction();
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final EdmEntityType type = (EdmEntityType) action.getReturnType().getType();
|
||||
|
||||
|
@ -319,9 +339,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
final ODataFormat format = ODataFormat.fromContentType(responseFormat);
|
||||
response.setContent(serializeEntity(entityResult.getEntity(), edmEntitySet, type, format, null, null)
|
||||
.getContent());
|
||||
response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK).getStatusCode
|
||||
|
||||
());
|
||||
response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK)
|
||||
.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
if (entityResult.getEntity().getETag() != null) {
|
||||
response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag());
|
||||
|
@ -343,17 +362,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
}
|
||||
|
||||
private void checkRequestFormat(final ContentType requestFormat) throws ODataApplicationException {
|
||||
if (requestFormat == null) {
|
||||
throw new ODataApplicationException("The content type has not been set in the request.",
|
||||
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType,
|
||||
final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws
|
||||
|
||||
SerializerException {
|
||||
final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
Builder builder = ContextURL.with();
|
||||
builder = entitySet == null ?
|
||||
isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) :
|
||||
|
@ -365,30 +375,26 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readReference(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void readReference(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
|
||||
processEntity(request, response, uriInfo, requestedContentType, true);
|
||||
readEntity(request, response, uriInfo, requestedContentType, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createReference(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void createReference(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat) throws ODataApplicationException, DeserializerException {
|
||||
|
||||
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateReference(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void updateReference(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat) throws ODataApplicationException, DeserializerException {
|
||||
|
||||
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteReference(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
|
||||
public void deleteReference(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
|
||||
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
|
@ -399,7 +405,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
processEntityCollection(request, response, uriInfo, requestedContentType, true);
|
||||
}
|
||||
|
||||
private void processEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
private void readEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType, final boolean isReference)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
|
||||
|
@ -410,18 +416,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
|
||||
final Entity entity = readEntity(uriInfo);
|
||||
|
||||
if (entity.getETag() != null) {
|
||||
final EtagInformation ifMatch = odata.createEtagInformation(request.getHeaders(HttpHeader.IF_MATCH));
|
||||
if (!ifMatch.isMatchedBy(entity.getETag()) && !ifMatch.getEtags().isEmpty()) {
|
||||
throw new ODataApplicationException("The If-Match precondition is not fulfilled.",
|
||||
HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
if (odata.createEtagInformation(request.getHeaders(HttpHeader.IF_NONE_MATCH))
|
||||
.isMatchedBy(entity.getETag())) {
|
||||
throw new ODataApplicationException("The entity has not been modified.",
|
||||
HttpStatusCode.NOT_MODIFIED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
checkReadPreconditions(entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
|
@ -430,12 +427,11 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
|
||||
final Entity entitySerialization = expandHandler.transformEntityGraphToTree(entity, edmEntitySet, expand);
|
||||
expandHandler.applyExpandQueryOptions(entitySerialization, edmEntitySet, expand);
|
||||
|
||||
final SerializerResult serializerResult = (isReference) ?
|
||||
serializeReference(entity, edmEntitySet, format)
|
||||
: serializeEntity(entitySerialization, edmEntitySet, edmEntityType, format, expand, select);
|
||||
|
||||
|
||||
|
||||
final SerializerResult serializerResult = isReference ?
|
||||
serializeReference(entity, edmEntitySet, format) :
|
||||
serializeEntity(entitySerialization, edmEntitySet, edmEntityType, format, expand, select);
|
||||
|
||||
if (entity.getETag() != null) {
|
||||
response.setHeader(HttpHeader.ETAG, entity.getETag());
|
||||
}
|
||||
|
@ -495,15 +491,15 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
// Serialize
|
||||
final SerializerResult serializerResult = (isReference) ?
|
||||
serializeReferenceCollection(entitySetSerialization, edmEntitySet, format) :
|
||||
serializeEntiyCollection(entitySetSerialization, edmEntitySet, edmEntityType, format,
|
||||
expand, select, countOption);
|
||||
serializeEntityCollection(entitySetSerialization, edmEntitySet, edmEntityType, format,
|
||||
expand, select, countOption);
|
||||
|
||||
response.setContent(serializerResult.getContent());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
}
|
||||
|
||||
private SerializerResult serializeEntiyCollection(final EntityCollection entityCollection,
|
||||
private SerializerResult serializeEntityCollection(final EntityCollection entityCollection,
|
||||
final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ODataFormat format,
|
||||
final ExpandOption expand, final SelectOption select, final CountOption countOption)
|
||||
throws SerializerException {
|
||||
|
@ -541,7 +537,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
|||
private SerializerResult serializeEntity(final Entity entity,
|
||||
final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ODataFormat format,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
|
||||
return odata.createSerializer(format).entity(
|
||||
serviceMetadata,
|
||||
edmEntityType,
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
|
|||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
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.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
|
@ -68,6 +69,7 @@ import org.apache.olingo.server.api.uri.UriHelper;
|
|||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
|
@ -90,30 +92,31 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitive(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void readPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.PRIMITIVE);
|
||||
readProperty(request, response, uriInfo, contentType, RepresentationType.PRIMITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePrimitive(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void updatePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
throw new ODataApplicationException("Not supported yet.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.PRIMITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePrimitive(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
|
||||
public void deletePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(response, uriInfo);
|
||||
deleteProperty(request, response, uriInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processActionPrimitive(final ODataRequest request, final ODataResponse response,
|
||||
public void processActionPrimitive(final ODataRequest request, ODataResponse response,
|
||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||
blockBoundActions(uriInfo);
|
||||
final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0))
|
||||
.getAction();
|
||||
DeserializerResult deserializerResult =
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.actionParameters(request.getBody(), action);
|
||||
|
@ -124,8 +127,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
if (action.getReturnType().isNullable()) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
// Not nullable return type so we have to give back a 500
|
||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||
// Not nullable return type so we have to give back an Internal Server Error
|
||||
throw new ODataApplicationException("The action could not be executed.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
} else {
|
||||
ContextURL contextURL = ContextURL.with().type(type).build();
|
||||
|
@ -141,31 +145,31 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
|
||||
readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePrimitiveCollection(final ODataRequest request, final ODataResponse response,
|
||||
public void updatePrimitiveCollection(final ODataRequest request, ODataResponse response,
|
||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
throw new ODataApplicationException("Not supported yet.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COLLECTION_PRIMITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void
|
||||
deletePrimitiveCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(response, uriInfo);
|
||||
public void deletePrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(request, response, uriInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processActionPrimitiveCollection(final ODataRequest request, final ODataResponse response,
|
||||
public void processActionPrimitiveCollection(final ODataRequest request, ODataResponse response,
|
||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||
blockBoundActions(uriInfo);
|
||||
final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0))
|
||||
.getAction();
|
||||
DeserializerResult deserializerResult =
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.actionParameters(request.getBody(), action);
|
||||
|
@ -175,10 +179,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
|
||||
if (property == null || property.isNull()) {
|
||||
// Collection Propertys must never be null
|
||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||
throw new ODataApplicationException("The action could not be executed.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
} else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) {
|
||||
// Not nullable return type but array contains a null value
|
||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||
throw new ODataApplicationException("The action could not be executed.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType();
|
||||
ContextURL contextURL = ContextURL.with().type(type).asCollection().build();
|
||||
|
@ -194,24 +200,31 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.COMPLEX);
|
||||
readProperty(request, response, uriInfo, contentType, RepresentationType.COMPLEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void updateComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
throw new ODataApplicationException("Not supported yet.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COMPLEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processActionComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void deleteComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(request, response, uriInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processActionComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||
blockBoundActions(uriInfo);
|
||||
final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0))
|
||||
.getAction();
|
||||
DeserializerResult deserializerResult =
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.actionParameters(request.getBody(), action);
|
||||
|
@ -222,8 +235,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
if (action.getReturnType().isNullable()) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
// Not nullable return type so we have to give back a 500
|
||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||
// Not nullable return type so we have to give back an Internal Server Error
|
||||
throw new ODataApplicationException("The action could not be executed.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
} else {
|
||||
ContextURL contextURL = ContextURL.with().type(type).build();
|
||||
|
@ -240,30 +254,31 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void deleteComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(response, uriInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readComplexCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
|
||||
readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateComplexCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void updateComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
throw new ODataApplicationException("Not supported yet.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COLLECTION_COMPLEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processActionComplexCollection(final ODataRequest request, final ODataResponse response,
|
||||
public void deleteComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(request, response, uriInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processActionComplexCollection(final ODataRequest request, ODataResponse response,
|
||||
final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
EdmAction action = checkBoundAndExtractAction(uriInfo);
|
||||
blockBoundActions(uriInfo);
|
||||
final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0))
|
||||
.getAction();
|
||||
DeserializerResult deserializerResult =
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.actionParameters(request.getBody(), action);
|
||||
|
@ -273,10 +288,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
|
||||
if (property == null || property.isNull()) {
|
||||
// Collection Propertys must never be null
|
||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||
throw new ODataApplicationException("The action could not be executed.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
} else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) {
|
||||
// Not nullable return type but array contains a null value
|
||||
throw new ODataApplicationException("The action could no be executed", 500, Locale.ROOT);
|
||||
throw new ODataApplicationException("The action could not be executed.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
EdmComplexType type = (EdmComplexType) action.getReturnType().getType();
|
||||
ContextURL contextURL = ContextURL.with().type(type).asCollection().build();
|
||||
|
@ -291,14 +308,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteComplexCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
deleteProperty(response, uriInfo);
|
||||
}
|
||||
|
||||
private void readProperty(final ODataResponse response, final UriInfo uriInfo, final ContentType contentType,
|
||||
final RepresentationType representationType) throws ODataApplicationException, SerializerException {
|
||||
private void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType, final RepresentationType representationType)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validateOptions(resource);
|
||||
validatePath(resource);
|
||||
|
@ -308,9 +320,16 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
final List<String> path = getPropertyPath(resourceParts, 0);
|
||||
|
||||
final Entity entity = readEntity(uriInfo);
|
||||
|
||||
if (entity != null && entity.getETag() != null) {
|
||||
checkReadPreconditions(entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
}
|
||||
|
||||
final Property property = entity == null ?
|
||||
getPropertyData(dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0))
|
||||
.getFunction(),
|
||||
getPropertyData(
|
||||
dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0)).getFunction(),
|
||||
((UriResourceFunction) resourceParts.get(0)).getParameters()), path) :
|
||||
getPropertyData(entity, path);
|
||||
|
||||
|
@ -320,6 +339,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
if (property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
final EdmProperty edmProperty = path.isEmpty() ? null :
|
||||
((UriResourceProperty) resourceParts.get(resourceParts.size() - 1)).getProperty();
|
||||
final EdmType type = edmProperty == null ?
|
||||
|
@ -328,69 +348,82 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ?
|
||||
((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : null;
|
||||
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(edmEntitySet, entity, path, type, representationType, expand, select);
|
||||
switch (representationType) {
|
||||
case PRIMITIVE:
|
||||
response.setContent(serializer.primitive((EdmPrimitiveType) type, property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL)
|
||||
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
|
||||
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
|
||||
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
|
||||
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
|
||||
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
|
||||
.build()).getContent());
|
||||
break;
|
||||
case COMPLEX:
|
||||
response.setContent(serializer.complex(serviceMetadata, (EdmComplexType) type, property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL)
|
||||
.expand(expand).select(select)
|
||||
.build()).getContent());
|
||||
break;
|
||||
case COLLECTION_PRIMITIVE:
|
||||
response.setContent(serializer.primitiveCollection((EdmPrimitiveType) type, property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL)
|
||||
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
|
||||
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
|
||||
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
|
||||
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
|
||||
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
|
||||
.build()).getContent());
|
||||
break;
|
||||
case COLLECTION_COMPLEX:
|
||||
response.setContent(serializer.complexCollection(serviceMetadata, (EdmComplexType) type, property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL)
|
||||
.expand(expand).select(select)
|
||||
.build()).getContent());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
final SerializerResult result = serializeProperty(entity, edmEntitySet, path, property, edmProperty,
|
||||
type, returnType, representationType, format, expand, select);
|
||||
response.setContent(result.getContent());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
}
|
||||
if (entity != null && entity.getETag() != null) {
|
||||
response.setHeader(HttpHeader.ETAG, entity.getETag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteProperty(final ODataResponse response, final UriInfo uriInfo) throws ODataApplicationException {
|
||||
private void updateProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestFormat, final ContentType responseFormat, final RepresentationType representationType)
|
||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validatePath(resource);
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
|
||||
|
||||
Entity entity = readEntity(uriInfo);
|
||||
checkChangePreconditions(entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
|
||||
final List<UriResource> resourceParts = resource.getUriResourceParts();
|
||||
final List<String> path = getPropertyPath(resourceParts, 0);
|
||||
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - 1))
|
||||
.getProperty();
|
||||
|
||||
checkRequestFormat(requestFormat);
|
||||
final Property changedProperty = odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.property(request.getBody(), edmProperty).getProperty();
|
||||
if (changedProperty.isNull() && !edmProperty.isNullable()) {
|
||||
throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
Property property = getPropertyData(entity, path);
|
||||
|
||||
dataProvider.updateProperty(edmProperty, property, changedProperty, request.getMethod() == HttpMethod.PATCH);
|
||||
dataProvider.updateETag(entity);
|
||||
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
final ODataFormat format = ODataFormat.fromContentType(responseFormat);
|
||||
final SerializerResult result = serializeProperty(entity, edmEntitySet, path, property, edmProperty,
|
||||
edmProperty.getType(), null, representationType, format, null, null);
|
||||
response.setContent(result.getContent());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
if (entity.getETag() != null) {
|
||||
response.setHeader(HttpHeader.ETAG, entity.getETag());
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validatePath(resource);
|
||||
getEdmEntitySet(uriInfo); // including checks
|
||||
|
||||
Entity entity = readEntity(uriInfo);
|
||||
checkChangePreconditions(entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
|
||||
final List<UriResource> resourceParts = resource.getUriResourceParts();
|
||||
final List<String> path = getPropertyPath(resourceParts, 0);
|
||||
|
||||
final Property property = getPropertyData(readEntity(uriInfo), path);
|
||||
Property property = getPropertyData(entity, path);
|
||||
|
||||
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - 1))
|
||||
.getProperty();
|
||||
|
||||
if (edmProperty.isNullable()) {
|
||||
property.setValue(property.getValueType(), edmProperty.isCollection() ? Collections.emptyList() : null);
|
||||
dataProvider.updateETag(entity);
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||
|
@ -436,6 +469,54 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
private SerializerResult serializeProperty(final Entity entity, final EdmEntitySet edmEntitySet,
|
||||
final List<String> path, final Property property, final EdmProperty edmProperty,
|
||||
final EdmType type, final EdmReturnType returnType,
|
||||
final RepresentationType representationType, final ODataFormat format,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(edmEntitySet, entity, path, type, representationType, expand, select);
|
||||
SerializerResult result = null;
|
||||
switch (representationType) {
|
||||
case PRIMITIVE:
|
||||
result = serializer.primitive((EdmPrimitiveType) type, property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL)
|
||||
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
|
||||
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
|
||||
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
|
||||
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
|
||||
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
|
||||
.build());
|
||||
break;
|
||||
case COMPLEX:
|
||||
result = serializer.complex(serviceMetadata, (EdmComplexType) type, property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL)
|
||||
.expand(expand).select(select)
|
||||
.build());
|
||||
break;
|
||||
case COLLECTION_PRIMITIVE:
|
||||
result = serializer.primitiveCollection((EdmPrimitiveType) type, property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL)
|
||||
.nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
|
||||
.maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
|
||||
.precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
|
||||
.scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
|
||||
.unicode(edmProperty == null ? null : edmProperty.isUnicode())
|
||||
.build());
|
||||
break;
|
||||
case COLLECTION_COMPLEX:
|
||||
result = serializer.complexCollection(serviceMetadata, (EdmComplexType) type, property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL)
|
||||
.expand(expand).select(select)
|
||||
.build());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private ContextURL getContextUrl(final EdmEntitySet entitySet, final Entity entity, final List<String> path,
|
||||
final EdmType type, final RepresentationType representationType,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
|
@ -455,7 +536,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveValue(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
|
||||
public void readPrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validateOptions(resource);
|
||||
|
@ -466,6 +547,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
final List<String> path = getPropertyPath(resourceParts, 1);
|
||||
|
||||
final Entity entity = readEntity(uriInfo);
|
||||
if (entity != null && entity.getETag() != null) {
|
||||
checkReadPreconditions(entity.getETag(),
|
||||
request.getHeaders(HttpHeader.IF_MATCH),
|
||||
request.getHeaders(HttpHeader.IF_NONE_MATCH));
|
||||
}
|
||||
|
||||
final Property property = entity == null ?
|
||||
getPropertyData(dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0))
|
||||
.getFunction(),
|
||||
|
@ -496,6 +583,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
|||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
}
|
||||
if (entity != null && entity.getETag() != null) {
|
||||
response.setHeader(HttpHeader.ETAG, entity.getETag());
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
|
|
|
@ -18,19 +18,21 @@
|
|||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunction;
|
||||
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.EtagInformation;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
|
@ -218,12 +220,49 @@ public abstract class TechnicalProcessor implements Processor {
|
|||
}
|
||||
}
|
||||
|
||||
protected EdmAction checkBoundAndExtractAction(final UriInfo uriInfo) throws ODataApplicationException {
|
||||
protected void blockBoundActions(final UriInfo uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> uriResourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||
if (uriResourceParts.size() > 1) {
|
||||
if (uriResourceParts.size() > 1
|
||||
&& uriResourceParts.get(uriResourceParts.size() - 1) instanceof UriResourceAction) {
|
||||
throw new ODataApplicationException("Bound actions are not supported yet.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
return ((UriResourceAction) uriResourceParts.get(0)).getAction();
|
||||
}
|
||||
|
||||
protected void checkRequestFormat(final ContentType requestFormat) throws ODataApplicationException {
|
||||
if (requestFormat == null) {
|
||||
throw new ODataApplicationException("The content type has not been set in the request.",
|
||||
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkReadPreconditions(final String eTag,
|
||||
final Collection<String> ifMatchHeaders, final Collection<String> ifNoneMatchHeaders)
|
||||
throws ODataApplicationException {
|
||||
if (eTag != null) {
|
||||
final EtagInformation ifMatch = odata.createEtagInformation(ifMatchHeaders);
|
||||
if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getEtags().isEmpty()) {
|
||||
throw new ODataApplicationException("The If-Match precondition is not fulfilled.",
|
||||
HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
if (odata.createEtagInformation(ifNoneMatchHeaders).isMatchedBy(eTag)) {
|
||||
throw new ODataApplicationException("The entity has not been modified.",
|
||||
HttpStatusCode.NOT_MODIFIED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkChangePreconditions(final String eTag,
|
||||
final Collection<String> ifMatchHeaders, final Collection<String> ifNoneMatchHeaders)
|
||||
throws ODataApplicationException {
|
||||
if (eTag != null) {
|
||||
final EtagInformation ifMatch = odata.createEtagInformation(ifMatchHeaders);
|
||||
final EtagInformation ifNoneMatch = odata.createEtagInformation(ifNoneMatchHeaders);
|
||||
if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getEtags().isEmpty()
|
||||
|| ifNoneMatch.isMatchedBy(eTag)) {
|
||||
throw new ODataApplicationException("The preconditions are not fulfilled.",
|
||||
HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue