Repository: olingo-odata4 Updated Branches: refs/heads/master 44ec57874 -> 39f0708d0
[OLINGO-692] improved server processor interface inheritance Change-Id: Ic4c0774be8c6c4bbbbeaef6baab17fdd6677cd6c Signed-off-by: Christian Amend <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/39f0708d Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/39f0708d Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/39f0708d Branch: refs/heads/master Commit: 39f0708d0c8ffb34ebae4fbafc5bd2e9fd4e282a Parents: 44ec578 Author: Klaus Straubinger <[email protected]> Authored: Wed Jun 10 10:24:11 2015 +0200 Committer: Christian Amend <[email protected]> Committed: Wed Jun 10 10:34:07 2015 +0200 ---------------------------------------------------------------------- .../olingo/fit/tecsvc/client/BasicITCase.java | 18 ++ .../fit/tecsvc/client/ConditionalITCase.java | 22 ++ .../tecsvc/client/PrimitiveComplexITCase.java | 83 ++++++- .../olingo/client/api/uri/URIBuilder.java | 6 + .../olingo/client/core/uri/URIBuilderImpl.java | 6 + .../api/deserializer/DeserializerException.java | 2 +- .../deserializer/FixedFormatDeserializer.java | 10 +- .../CountComplexCollectionProcessor.java | 2 +- .../CountEntityCollectionProcessor.java | 2 +- .../CountPrimitiveCollectionProcessor.java | 2 +- .../api/processor/MediaEntityProcessor.java | 13 +- .../api/processor/PrimitiveValueProcessor.java | 29 ++- .../server/core/requests/DataRequest.java | 2 +- .../olingo/server/core/ODataDispatcher.java | 8 +- .../FixedFormatDeserializerImpl.java | 32 ++- .../json/ODataJsonDeserializer.java | 8 +- .../server-core-exceptions-i18n.properties | 2 +- .../FixedFormatDeserializerTest.java | 27 ++- .../processor/TechnicalEntityProcessor.java | 20 +- .../TechnicalPrimitiveComplexProcessor.java | 219 +++++++++++-------- .../olingo/server/core/ODataHandlerTest.java | 6 +- .../ODataDeserializerEntityCollectionTest.java | 2 +- .../json/ODataJsonDeserializerEntityTest.java | 6 +- .../server/sample/processor/CarsProcessor.java | 16 ++ 24 files changed, 411 insertions(+), 132 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java index 39d73b1..819aab7 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java @@ -45,6 +45,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRe import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataServiceDocumentRequest; +import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest; import org.apache.olingo.client.api.communication.request.retrieve.XMLMetadataRequest; import org.apache.olingo.client.api.communication.response.ODataDeleteResponse; import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse; @@ -57,6 +58,7 @@ import org.apache.olingo.client.api.domain.ClientEntitySet; import org.apache.olingo.client.api.domain.ClientInlineEntity; import org.apache.olingo.client.api.domain.ClientInlineEntitySet; import org.apache.olingo.client.api.domain.ClientObjectFactory; +import org.apache.olingo.client.api.domain.ClientPrimitiveValue; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientServiceDocument; import org.apache.olingo.client.api.domain.ClientValue; @@ -163,6 +165,22 @@ public class BasicITCase extends AbstractBaseTestITCase { } @Test + public void readEntityCollectionCount() { + final ODataValueRequest request = getClient().getRetrieveRequestFactory() + .getValueRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESServerSidePaging").appendCountSegment().build()); + assertNotNull(request); + + final ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + assertEquals(ContentType.TEXT_PLAIN.toContentTypeString(), response.getContentType()); + + final ClientPrimitiveValue value = response.getBody(); + assertNotNull(value); + assertEquals("503", value.toValue()); + } + + @Test public void readException() throws Exception { final ODataEntityRequest<ClientEntity> request = getClient().getRetrieveRequestFactory() .getEntityRequest(getClient().newURIBuilder(SERVICE_URI) http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java index c5d2926..9f5efc3 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ConditionalITCase.java @@ -21,6 +21,7 @@ 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.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; @@ -34,6 +35,7 @@ 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.ODataValueUpdateRequest; import org.apache.olingo.client.api.communication.request.cud.UpdateType; import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; @@ -203,6 +205,16 @@ public final class ConditionalITCase extends AbstractBaseTestITCase { } @Test + public void updatePropertyValueWithWrongIfMatch() throws Exception { + ODataValueUpdateRequest request = client.getCUDRequestFactory().getValueUpdateRequest( + uriPropertyValue, + UpdateType.REPLACE, + 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\""); @@ -210,6 +222,16 @@ public final class ConditionalITCase extends AbstractBaseTestITCase { } @Test + public void deletePropertyValue() throws Exception { + ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriPropertyValue); + request.setIfMatch("W/\"0\""); + final ODataDeleteResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + assertNotNull(response.getETag()); + assertNotEquals(request.getIfMatch(), response.getETag()); + } + + @Test public void deletePropertyValueWithWrongIfMatch() throws Exception { ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriPropertyValue); request.setIfMatch("W/\"1\""); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java index 04f9768..1dbd0e6 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.InputStream; import java.net.URI; import java.util.Iterator; @@ -34,12 +35,14 @@ 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.ODataValueUpdateRequest; 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.communication.response.ODataValueUpdateResponse; import org.apache.olingo.client.api.domain.ClientCollectionValue; import org.apache.olingo.client.api.domain.ClientComplexValue; import org.apache.olingo.client.api.domain.ClientPrimitiveValue; @@ -318,15 +321,87 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase { public void readPropertyValue() throws Exception { final ODataValueRequest request = getClient().getRetrieveRequestFactory() .getPropertyValueRequest(getClient().newURIBuilder(SERVICE_URI) - .appendEntitySetSegment("ESTwoPrim") - .appendKeySegment(32766) - .appendPropertySegment("PropertyString") - .appendValueSegment() + .appendEntitySetSegment("ESTwoPrim").appendKeySegment(32766) + .appendPropertySegment("PropertyString").appendValueSegment() .build()); final ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute(); assertEquals("Test String1", response.getBody().toValue()); } + @Test + public void deletePropertyValue() throws Exception { + final URI uri = getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESKeyNav").appendKeySegment(1) + .appendPropertySegment("PropertyCompAllPrim").appendPropertySegment("PropertyString") + .appendValueSegment() + .build(); + final ODataDeleteRequest request = getClient().getCUDRequestFactory().getDeleteRequest(uri); + final ODataDeleteResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + + // Check that the property is really gone. + // This check has to be in the same session in order to access the same data provider. + ODataValueRequest valueRequest = getClient().getRetrieveRequestFactory().getPropertyValueRequest(uri); + valueRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next()); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), valueRequest.execute().getStatusCode()); + } + + @Test + public void updatePropertyValue() throws Exception { + final ODataValueUpdateRequest request = + getClient().getCUDRequestFactory().getValueUpdateRequest( + getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESTwoPrim").appendKeySegment(32766) + .appendPropertySegment("PropertyString") + .build(), + UpdateType.REPLACE, + getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test String1")); + assertNotNull(request); + + final ODataValueUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + assertEquals(ContentType.TEXT_PLAIN.toContentTypeString(), response.getContentType()); + + final ClientPrimitiveValue value = response.getBody(); + assertNotNull(value); + assertEquals("Test String1", IOUtils.toString((InputStream) value.toValue(), "UTF-8")); + } + + @Test + public void readPrimitiveCollectionCount() { + final ODataValueRequest request = getClient().getRetrieveRequestFactory() + .getValueRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESCollAllPrim").appendKeySegment(1) + .appendPropertySegment("CollPropertyBoolean").appendCountSegment().build()); + assertNotNull(request); + + final ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + assertEquals(ContentType.TEXT_PLAIN.toContentTypeString(), response.getContentType()); + + final ClientPrimitiveValue value = response.getBody(); + assertNotNull(value); + assertEquals("3", value.toValue()); + } + + @Test + public void readComplexCollectionCount() { + final ODataValueRequest request = getClient().getRetrieveRequestFactory() + .getValueRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESCompCollAllPrim").appendKeySegment(5678) + .appendPropertySegment("PropertyComp").appendPropertySegment("CollPropertyBoolean").appendCountSegment() + .build()); + assertNotNull(request); + + final ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + assertEquals(ContentType.TEXT_PLAIN.toContentTypeString(), response.getContentType()); + + final ClientPrimitiveValue value = response.getBody(); + assertNotNull(value); + assertEquals("3", value.toValue()); + } + @Override protected ODataClient getClient() { ODataClient odata = ODataClientFactory.getClient(); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/URIBuilder.java ---------------------------------------------------------------------- diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/URIBuilder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/URIBuilder.java index 1c8f89d..7cf0177 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/URIBuilder.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/URIBuilder.java @@ -121,6 +121,12 @@ public interface URIBuilder { URIBuilder appendValueSegment(); /** + * Appends count segment to the URI. + * @return current URIBuilder instance + */ + URIBuilder appendCountSegment(); + + /** * Appends operation (action or function) segment to the URI. * * @param operation Operation (action or function) name http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java index 82f090e..8950dd5 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java @@ -180,6 +180,12 @@ public class URIBuilderImpl implements URIBuilder { } @Override + public URIBuilder appendCountSegment() { + segments.add(new Segment(SegmentType.COUNT, SegmentType.COUNT.getValue())); + return this; + } + + @Override public URIBuilder appendActionCallSegment(final String action) { segments.add(new Segment( segments.size() == 1 ? SegmentType.UNBOUND_ACTION : SegmentType.BOUND_ACTION, action)); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java index fd7e0ee..56567f2 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java @@ -35,7 +35,7 @@ public class DeserializerException extends ODataLibraryException { /** parameter: propertyName */ INVALID_NULL_PROPERTY, /** parameter: keyName */ - UNKOWN_CONTENT, + UNKNOWN_CONTENT, /** parameter: propertyName */ INVALID_VALUE_FOR_PROPERTY, /** parameter: propertyName */ http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java index 6ad10eb..bded690 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/FixedFormatDeserializer.java @@ -21,6 +21,7 @@ package org.apache.olingo.server.api.deserializer; import java.io.InputStream; import java.util.List; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.server.api.batch.exception.BatchDeserializerException; import org.apache.olingo.server.api.deserializer.batch.BatchOptions; import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart; @@ -32,7 +33,14 @@ public interface FixedFormatDeserializer { * @param content the binary data as input stream * @return the binary data */ - byte[] binary(InputStream content) throws DeserializerException; + public byte[] binary(InputStream content) throws DeserializerException; + + /** + * Reads primitive-type data from an InputStream. + * @param content the textual value as input stream + * @param property EDM property + */ + public Object primitiveValue(InputStream content, EdmProperty property) throws DeserializerException; public List<BatchRequestPart> parseBatchRequest(InputStream content, String boundary, BatchOptions options) throws BatchDeserializerException; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountComplexCollectionProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountComplexCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountComplexCollectionProcessor.java index 29e96d6..fb25ab7 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountComplexCollectionProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountComplexCollectionProcessor.java @@ -27,7 +27,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling counting a collection of complex properties, e.g. an EdmComplexType. */ -public interface CountComplexCollectionProcessor extends Processor { +public interface CountComplexCollectionProcessor extends ComplexCollectionProcessor { /** * Counts complex properties from persistence and puts serialized content and status into the response. http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityCollectionProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityCollectionProcessor.java index 65935dc..a19419d 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityCollectionProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityCollectionProcessor.java @@ -27,7 +27,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling counting a collection of entities, e.g. an Entity Set. */ -public interface CountEntityCollectionProcessor extends Processor { +public interface CountEntityCollectionProcessor extends EntityCollectionProcessor { /** * Counts entities from persistence and puts serialized content and status into the response. http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountPrimitiveCollectionProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountPrimitiveCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountPrimitiveCollectionProcessor.java index e9fe641..0d6ee1a 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountPrimitiveCollectionProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountPrimitiveCollectionProcessor.java @@ -27,7 +27,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling counting a collection of primitive properties, e.g. an collection of EdmString. */ -public interface CountPrimitiveCollectionProcessor extends Processor { +public interface CountPrimitiveCollectionProcessor extends PrimitiveCollectionProcessor { /** * Counts primitive properties from persistence and puts serialized content and status into the response. http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaEntityProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaEntityProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaEntityProcessor.java index 75bb21e..aedce5a 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaEntityProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/MediaEntityProcessor.java @@ -43,7 +43,7 @@ public interface MediaEntityProcessor extends EntityProcessor { throws ODataApplicationException, ODataLibraryException; /** - * Creates an entity with send media data in the persistence and puts content, status and Location into the response. + * Creates an entity with sent media data in the persistence and puts content, status and Location into the response. * @param request OData request object containing raw HTTP information * @param response OData response object for collecting response data * @param uriInfo information of a parsed OData URI @@ -67,4 +67,15 @@ public interface MediaEntityProcessor extends EntityProcessor { */ void updateMediaEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException; + + /** + * Deletes entity media data and associated entity from persistence and puts the status into the response. + * @param request OData request object containing raw HTTP information + * @param response OData response object for collecting response data + * @param uriInfo information of a parsed OData URI + * @throws ODataApplicationException if the service implementation encounters a failure + * @throws ODataLibraryException + */ + void deleteMediaEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) + throws ODataApplicationException, ODataLibraryException; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveValueProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveValueProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveValueProcessor.java index 7478ec6..797ee85 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveValueProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveValueProcessor.java @@ -38,9 +38,36 @@ public interface PrimitiveValueProcessor extends PrimitiveProcessor { * @param response OData response object for collecting response data * @param uriInfo information of a parsed OData URI * @param responseFormat requested content type after content negotiation - * @throws org.apache.olingo.server.api.ODataApplicationException if the service implementation encounters a failure + * @throws ODataApplicationException if the service implementation encounters a failure * @throws ODataLibraryException */ void readPrimitiveValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException; + + /** + * Update primitive-type instance with sent raw data in the persistence and + * puts content, status, and Location into the response. + * @param request OData request object containing raw HTTP information + * @param response OData response object for collecting response data + * @param uriInfo information of a parsed OData URI + * @param requestFormat content type of body sent with request + * @param responseFormat requested content type after content negotiation + * @throws ODataApplicationException if the service implementation encounters a failure + * @throws ODataLibraryException + */ + void updatePrimitiveValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, + ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, ODataLibraryException; + + /** + * Deletes primitive-type raw value from an entity and puts the status into the response. + * Deletion of a primitive-type value is equivalent to setting the value to <code>null</code>. + * @param request OData request object containing raw HTTP information + * @param response OData response object for collecting response data + * @param uriInfo information of a parsed OData URI + * @throws ODataApplicationException if the service implementation encounters a failure + * @throws ODataLibraryException + */ + void deletePrimitiveValue(ODataRequest request, ODataResponse response, UriInfo uriInfo) + throws ODataApplicationException, ODataLibraryException; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java ---------------------------------------------------------------------- diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java index c92af8a..0d98de5 100644 --- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java +++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java @@ -441,7 +441,7 @@ public class DataRequest extends ServiceRequest { handler.deleteReference(DataRequest.this, new URI(id), getETag(), new NoContentResponse( getServiceMetaData(), response)); } catch (URISyntaxException e) { - throw new DeserializerException("failed to read $id", e, MessageKeys.UNKOWN_CONTENT); + throw new DeserializerException("failed to read $id", e, MessageKeys.UNKNOWN_CONTENT); } } } else if (isPUT()) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java index 45b3eb8..e444cf4 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java @@ -327,9 +327,10 @@ public class ODataDispatcher { final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, handler.getCustomContentTypeSupport(), valueRepresentationType); handler.selectProcessor(PrimitiveValueProcessor.class) - .updatePrimitive(request, response, uriInfo, requestFormat, responseFormat); + .updatePrimitiveValue(request, response, uriInfo, requestFormat, responseFormat); } else if (method == HttpMethod.DELETE && resource instanceof UriResourceProperty) { - handler.selectProcessor(PrimitiveValueProcessor.class).deletePrimitive(request, response, uriInfo); + handler.selectProcessor(PrimitiveValueProcessor.class) + .deletePrimitiveValue(request, response, uriInfo); } else { throw new ODataHandlerException("HTTP method " + method + " is not allowed.", ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString()); @@ -349,7 +350,8 @@ public class ODataDispatcher { .updateMediaEntity(request, response, uriInfo, requestFormat, responseFormat); } else if (method == HttpMethod.DELETE && resource instanceof UriResourceEntitySet) { validatePreconditions(request, true); - handler.selectProcessor(MediaEntityProcessor.class).deleteEntity(request, response, uriInfo); + handler.selectProcessor(MediaEntityProcessor.class) + .deleteMediaEntity(request, response, uriInfo); } else { throw new ODataHandlerException("HTTP method " + method + " is not allowed.", ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString()); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java index fe12ca7..46910f1 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerImpl.java @@ -21,8 +21,13 @@ package org.apache.olingo.server.core.deserializer; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; import java.util.List; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.server.api.batch.exception.BatchDeserializerException; import org.apache.olingo.server.api.deserializer.DeserializerException; import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer; @@ -50,9 +55,34 @@ public class FixedFormatDeserializerImpl implements FixedFormatDeserializer { } @Override + public Object primitiveValue(InputStream content, final EdmProperty property) throws DeserializerException { + if (property == null || !property.isPrimitive()) { + throw new DeserializerException("Wrong property.", DeserializerException.MessageKeys.NOT_IMPLEMENTED); + } + try { + StringWriter writer = new StringWriter(); + InputStreamReader reader = new InputStreamReader(content, "UTF-8"); + int c = -1; + while ((c = reader.read()) != -1) { + writer.append((char) c); + } + final EdmPrimitiveType type = (EdmPrimitiveType) property.getType(); + return type.valueOfString(writer.toString(), + property.isNullable(), property.getMaxLength(), property.getPrecision(), property.getScale(), + property.isUnicode(), type.getDefaultType()); + } catch (final EdmPrimitiveTypeException e) { + throw new DeserializerException("The value is not valid.", e, + DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, property.getName()); + } catch (final IOException e) { + throw new DeserializerException("An I/O exception occurred.", e, + DeserializerException.MessageKeys.IO_EXCEPTION); + } + } + + @Override public List<BatchRequestPart> parseBatchRequest(final InputStream content, final String boundary, final BatchOptions options) - throws BatchDeserializerException { + throws BatchDeserializerException { final BatchParser parser = new BatchParser(); return parser.parseBatchRequest(content, boundary, options); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java index 2d8b057..a03206b 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java @@ -709,7 +709,7 @@ public class ODataJsonDeserializer implements ODataDeserializer { if (node.size() != 0) { final String unknownField = node.fieldNames().next(); throw new DeserializerException("Tree should be empty but still has content left: " + unknownField, - DeserializerException.MessageKeys.UNKOWN_CONTENT, unknownField); + DeserializerException.MessageKeys.UNKNOWN_CONTENT, unknownField); } } @@ -822,7 +822,7 @@ public class ODataJsonDeserializer implements ODataDeserializer { } } } else { - throw new DeserializerException("Value must be an array", DeserializerException.MessageKeys.UNKOWN_CONTENT); + throw new DeserializerException("Value must be an array", DeserializerException.MessageKeys.UNKNOWN_CONTENT); } tree.remove(Constants.VALUE); // if this is value there can be only one property @@ -831,7 +831,7 @@ public class ODataJsonDeserializer implements ODataDeserializer { if(tree.get(key) != null) { parsedValues.add(new URI(tree.get(key).asText())); } else { - throw new DeserializerException("Missing entity reference", DeserializerException.MessageKeys.UNKOWN_CONTENT); + throw new DeserializerException("Missing entity reference", DeserializerException.MessageKeys.UNKNOWN_CONTENT); } return DeserializerResultImpl.with().entityReferences(parsedValues).build(); } catch (JsonParseException e) { @@ -845,7 +845,7 @@ public class ODataJsonDeserializer implements ODataDeserializer { DeserializerException.MessageKeys.IO_EXCEPTION); } catch (URISyntaxException e) { throw new DeserializerException("failed to read @odata.id", e, - DeserializerException.MessageKeys.UNKOWN_CONTENT); + DeserializerException.MessageKeys.UNKNOWN_CONTENT); } } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties index 797aae2..fbb4d62 100644 --- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties +++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties @@ -104,7 +104,7 @@ DeserializerException.IO_EXCEPTION=An I/O exception occurred. DeserializerException.UNSUPPORTED_FORMAT=The format '%1$s' is not supported. DeserializerException.JSON_SYNTAX_EXCEPTION=The syntax of the JSON document is not valid. DeserializerException.INVALID_NULL_PROPERTY=The property '%1$s' must not be null. -DeserializerException.UNKOWN_CONTENT='%1$s' can not be mapped as a property or an annotation. +DeserializerException.UNKNOWN_CONTENT='%1$s' can not be mapped as a property or an annotation. DeserializerException.INVALID_VALUE_FOR_PROPERTY=Invalid value for property '%1$s'. DeserializerException.INVALID_TYPE_FOR_PROPERTY=Invalid JSON type for property '%1$s'. DeserializerException.VALUE_ARRAY_NOT_PRESENT=Cannot find the value array. A collection needs at least an empty array. http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java index 565c32a..7f061ee 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/FixedFormatDeserializerTest.java @@ -22,17 +22,21 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import org.apache.commons.io.IOUtils; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer; import org.apache.olingo.server.api.serializer.SerializerException; import org.junit.Test; +import org.mockito.Mockito; public class FixedFormatDeserializerTest { + private static final OData oData = OData.newInstance(); private final FixedFormatDeserializer deserializer; public FixedFormatDeserializerTest() throws SerializerException { - deserializer = OData.newInstance().createFixedFormatDeserializer(); + deserializer = oData.createFixedFormatDeserializer(); } @Test @@ -50,4 +54,25 @@ public class FixedFormatDeserializerTest { + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ")).length); } + + @Test + public void primitiveValue() throws Exception { + EdmProperty property = Mockito.mock(EdmProperty.class); + Mockito.when(property.getType()).thenReturn(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int64)); + Mockito.when(property.isPrimitive()).thenReturn(true); + assertEquals(42L, deserializer.primitiveValue(IOUtils.toInputStream("42"), property)); + } + + @Test + public void primitiveValueLong() throws Exception { + EdmProperty property = Mockito.mock(EdmProperty.class); + Mockito.when(property.getType()).thenReturn(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String)); + Mockito.when(property.isPrimitive()).thenReturn(true); + Mockito.when(property.isUnicode()).thenReturn(true); + Mockito.when(property.getMaxLength()).thenReturn(61); + final String value = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ\n" + + "ÃÃÃâ¬\uFDFC\n" + + String.valueOf(Character.toChars(0x1F603)); + assertEquals(value, deserializer.primitiveValue(IOUtils.toInputStream(value), property)); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index 086f69c..aae4f7a 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -18,7 +18,6 @@ */ package org.apache.olingo.server.tecsvc.processor; -import java.util.List; import java.util.Locale; import org.apache.olingo.commons.api.data.ContextURL; @@ -51,11 +50,9 @@ import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions import org.apache.olingo.server.api.serializer.EntitySerializerOptions; 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.UriResourceEntitySet; import org.apache.olingo.server.api.uri.UriResourceFunction; import org.apache.olingo.server.api.uri.UriResourceNavigation; -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.IdOption; @@ -252,10 +249,21 @@ public class TechnicalEntityProcessor extends TechnicalProcessor throws ODataLibraryException, 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; - odata.createETagHelper().checkChangePreconditions(isValue ? entity.getMediaETag() : entity.getETag(), + odata.createETagHelper().checkChangePreconditions(entity.getETag(), + request.getHeaders(HttpHeader.IF_MATCH), + request.getHeaders(HttpHeader.IF_NONE_MATCH)); + dataProvider.delete(edmEntitySet, entity); + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + + @Override + public void deleteMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) + throws ODataLibraryException, ODataApplicationException { + final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo); + final Entity entity = readEntity(uriInfo); + + odata.createETagHelper().checkChangePreconditions(entity.getMediaETag(), request.getHeaders(HttpHeader.IF_MATCH), request.getHeaders(HttpHeader.IF_NONE_MATCH)); dataProvider.delete(edmEntitySet, entity); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java index 4ff7634..1c0d049 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java @@ -18,6 +18,7 @@ */ package org.apache.olingo.server.tecsvc.processor; +import java.io.InputStream; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -46,8 +47,11 @@ import org.apache.olingo.server.api.ODataLibraryException; import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer; import org.apache.olingo.server.api.processor.ComplexCollectionProcessor; import org.apache.olingo.server.api.processor.ComplexProcessor; +import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor; +import org.apache.olingo.server.api.processor.CountPrimitiveCollectionProcessor; import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor; import org.apache.olingo.server.api.processor.PrimitiveProcessor; import org.apache.olingo.server.api.processor.PrimitiveValueProcessor; @@ -57,6 +61,7 @@ import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions; import org.apache.olingo.server.api.serializer.RepresentationType; +import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriHelper; import org.apache.olingo.server.api.uri.UriInfo; @@ -73,8 +78,9 @@ import org.apache.olingo.server.tecsvc.data.DataProvider; * Technical Processor which provides functionality related to primitive and complex types and collections thereof. */ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor - implements PrimitiveProcessor, PrimitiveValueProcessor, PrimitiveCollectionProcessor, - ComplexProcessor, ComplexCollectionProcessor { + implements PrimitiveProcessor, PrimitiveValueProcessor, + PrimitiveCollectionProcessor, CountPrimitiveCollectionProcessor, + ComplexProcessor, ComplexCollectionProcessor, CountComplexCollectionProcessor { public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider, final ServiceMetadata serviceMetadata) { @@ -88,6 +94,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor } @Override + public void readPrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, + final ContentType contentType) throws ODataApplicationException, ODataLibraryException { + readProperty(request, response, uriInfo, contentType, RepresentationType.VALUE); + } + + @Override public void updatePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { @@ -95,9 +107,22 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor } @Override + public void updatePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, ODataLibraryException { + updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.VALUE); + } + + @Override public void deletePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - deleteProperty(request, response, uriInfo); + deleteProperty(request, response, uriInfo, false); + } + + @Override + public void deletePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) + throws ODataApplicationException, ODataLibraryException { + deleteProperty(request, response, uriInfo, true); } @Override @@ -107,6 +132,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor } @Override + public void countPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) + throws ODataApplicationException, ODataLibraryException { + readProperty(request, response, uriInfo, ContentType.TEXT_PLAIN, RepresentationType.COUNT); + } + + @Override public void updatePrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { @@ -116,7 +147,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor @Override public void deletePrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - deleteProperty(request, response, uriInfo); + deleteProperty(request, response, uriInfo, false); } @Override @@ -135,7 +166,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor @Override public void deleteComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - deleteProperty(request, response, uriInfo); + deleteProperty(request, response, uriInfo, false); } @Override @@ -145,6 +176,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor } @Override + public void countComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) + throws ODataApplicationException, ODataLibraryException { + readProperty(request, response, uriInfo, ContentType.TEXT_PLAIN, RepresentationType.COUNT); + } + + @Override public void updateComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { @@ -154,7 +191,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor @Override public void deleteComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - deleteProperty(request, response, uriInfo); + deleteProperty(request, response, uriInfo, false); } private void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, @@ -166,7 +203,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor final EdmEntitySet edmEntitySet = getEdmEntitySet(resource); final List<UriResource> resourceParts = resource.getUriResourceParts(); - final List<String> path = getPropertyPath(resourceParts, 0); + final int trailing = + representationType == RepresentationType.COUNT || representationType == RepresentationType.VALUE ? 1 : 0; + final List<String> path = getPropertyPath(resourceParts, trailing); final Entity entity = readEntity(uriInfo); @@ -186,27 +225,40 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor ((UriResourceFunction) resourceParts.get(0)).getParameters()), path) : getPropertyData(entity, path); - if (property == null) { - throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); + if (property == null && representationType != RepresentationType.COUNT) { + if (representationType == RepresentationType.VALUE) { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } else { + throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); + } } else { - if (property.getValue() == null) { + if (property.getValue() == null && representationType != RepresentationType.COUNT) { 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 ? - ((UriResourceFunction) resourceParts.get(0)).getType() : - edmProperty.getType(); - final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ? - ((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : null; - - final ExpandOption expand = uriInfo.getExpandOption(); - final SelectOption select = uriInfo.getSelectOption(); - 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()); + if (representationType == RepresentationType.COUNT) { + response.setContent(odata.createFixedFormatSerializer().count( + property.asCollection().size())); + } else { + final EdmProperty edmProperty = path.isEmpty() ? null : + ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1)).getProperty(); + final EdmType type = edmProperty == null ? + ((UriResourceFunction) resourceParts.get(0)).getType() : + edmProperty.getType(); + final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ? + ((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : null; + + if (representationType == RepresentationType.VALUE) { + response.setContent(serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) type, returnType)); + } else { + final ExpandOption expand = uriInfo.getExpandOption(); + final SelectOption select = uriInfo.getSelectOption(); + 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) { @@ -217,7 +269,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor private void updateProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat, final RepresentationType representationType) - throws ODataApplicationException, ODataLibraryException { + throws ODataApplicationException, ODataLibraryException { final UriInfoResource resource = uriInfo.asUriInfoResource(); validatePath(resource); final EdmEntitySet edmEntitySet = getEdmEntitySet(resource); @@ -228,35 +280,49 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor 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)) + final int trailing = representationType == RepresentationType.VALUE ? 1 : 0; + final List<String> path = getPropertyPath(resourceParts, trailing); + final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1)) .getProperty(); + Property property = getPropertyData(entity, path); + 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); + if (representationType == RepresentationType.VALUE) { + final FixedFormatDeserializer deserializer = odata.createFixedFormatDeserializer(); + final Object value = edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ? + deserializer.binary(request.getBody()) : + deserializer.primitiveValue(request.getBody(), edmProperty); + dataProvider.updatePropertyValue(property, value); + } else { + 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); + } + dataProvider.updateProperty(edmProperty, property, changedProperty, request.getMethod() == HttpMethod.PATCH); } - 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()); + if (representationType == RepresentationType.VALUE) { + response.setContent( + serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) edmProperty.getType(), null)); + } else { + 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 ODataLibraryException, ODataApplicationException { + private void deleteProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, + final boolean isValue) throws ODataLibraryException, ODataApplicationException { final UriInfoResource resource = uriInfo.asUriInfoResource(); validatePath(resource); getEdmEntitySet(uriInfo); // including checks @@ -267,11 +333,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor request.getHeaders(HttpHeader.IF_NONE_MATCH)); final List<UriResource> resourceParts = resource.getUriResourceParts(); - final List<String> path = getPropertyPath(resourceParts, 0); + final int trailing = isValue ? 1 : 0; + final List<String> path = getPropertyPath(resourceParts, trailing); Property property = getPropertyData(entity, path); - final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - 1)) + final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1)) .getProperty(); if (edmProperty.isNullable()) { @@ -391,61 +458,19 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor return builder.build(); } - @Override - public void readPrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, - final ContentType contentType) throws ODataApplicationException, ODataLibraryException { - final UriInfoResource resource = uriInfo.asUriInfoResource(); - validateOptions(resource); - validatePath(resource); - getEdmEntitySet(uriInfo); // including checks - - final List<UriResource> resourceParts = resource.getUriResourceParts(); - final List<String> path = getPropertyPath(resourceParts, 1); - - final Entity entity = readEntity(uriInfo); - if (entity != null && entity.getETag() != null) { - if (odata.createETagHelper().checkReadPreconditions(entity.getETag(), - request.getHeaders(HttpHeader.IF_MATCH), - request.getHeaders(HttpHeader.IF_NONE_MATCH))) { - response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode()); - response.setHeader(HttpHeader.ETAG, entity.getETag()); - return; - } - } - - final Property property = entity == null ? - getPropertyData(dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0)) - .getFunction(), - ((UriResourceFunction) resourceParts.get(0)).getParameters()), path) : - getPropertyData(entity, path); - - if (property == null || property.getValue() == null) { - response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); - } else { - final EdmProperty edmProperty = path.isEmpty() ? null : - ((UriResourceProperty) resourceParts.get(resourceParts.size() - 2)).getProperty(); - final EdmPrimitiveType type = (EdmPrimitiveType) (edmProperty == null ? - ((UriResourceFunction) resourceParts.get(0)).getType() : - edmProperty.getType()); - final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ? - ((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : null; - final FixedFormatSerializer serializer = odata.createFixedFormatSerializer(); - response.setContent(type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ? - serializer.binary((byte[]) property.getValue()) : - serializer.primitiveValue(type, property.getValue(), - PrimitiveValueSerializerOptions.with() - .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())); - 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 InputStream serializePrimitiveValue(final Property property, final EdmProperty edmProperty, + final EdmPrimitiveType type, final EdmReturnType returnType) throws SerializerException { + final FixedFormatSerializer serializer = odata.createFixedFormatSerializer(); + return type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ? + serializer.binary((byte[]) property.getValue()) : + serializer.primitiveValue(type, property.getValue(), + PrimitiveValueSerializerOptions.with() + .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()); } private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java index a2339f5..755c4f1 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java @@ -493,7 +493,7 @@ public class ODataHandlerTest { any(ContentType.class), any(ContentType.class)); dispatch(HttpMethod.DELETE, uri, processor); - verify(processor).deleteEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class)); + verify(processor).deleteMediaEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class)); dispatchMethodNotAllowed(HttpMethod.POST, uri, processor); dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor); @@ -543,12 +543,12 @@ public class ODataHandlerTest { dispatch(HttpMethod.PUT, uri, null, HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString(), processor); - verify(processor).updatePrimitive( + verify(processor).updatePrimitiveValue( any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class), any(ContentType.class)); dispatch(HttpMethod.DELETE, uri, processor); - verify(processor).deletePrimitive(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class)); + verify(processor).deletePrimitiveValue(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class)); dispatchMethodNotAllowed(HttpMethod.POST, uri, processor); dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java index 609db35..c2294dd 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java @@ -232,7 +232,7 @@ public class ODataDeserializerEntityCollectionTest extends AbstractODataDeserial try { OData.newInstance().createDeserializer(ODataFormat.JSON).entityCollection(stream, edmEntityType); } catch (DeserializerException e) { - assertEquals(DeserializerException.MessageKeys.UNKOWN_CONTENT, e.getMessageKey()); + assertEquals(DeserializerException.MessageKeys.UNKNOWN_CONTENT, e.getMessageKey()); throw e; } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java index 35e9faa..0956c91 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java @@ -891,7 +891,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp"))); } catch (DeserializerException e) { - assertEquals(DeserializerException.MessageKeys.UNKOWN_CONTENT, e.getMessageKey()); + assertEquals(DeserializerException.MessageKeys.UNKNOWN_CONTENT, e.getMessageKey()); throw e; } } @@ -913,7 +913,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp"))); } catch (DeserializerException e) { - assertEquals(DeserializerException.MessageKeys.UNKOWN_CONTENT, e.getMessageKey()); + assertEquals(DeserializerException.MessageKeys.UNKNOWN_CONTENT, e.getMessageKey()); throw e; } } @@ -935,7 +935,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp"))); } catch (DeserializerException e) { - assertEquals(DeserializerException.MessageKeys.UNKOWN_CONTENT, e.getMessageKey()); + assertEquals(DeserializerException.MessageKeys.UNKNOWN_CONTENT, e.getMessageKey()); throw e; } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/39f0708d/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java ---------------------------------------------------------------------- diff --git a/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java b/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java index 17c9a29..caffcd5 100644 --- a/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java +++ b/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java @@ -40,6 +40,7 @@ import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.ODataLibraryException; import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ServiceMetadata; @@ -322,6 +323,14 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor } @Override + public void updatePrimitiveValue(final ODataRequest request, ODataResponse response, + final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, ODataLibraryException { + throw new ODataApplicationException("Primitive property update is not supported yet.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH); + } + + @Override public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { throw new ODataApplicationException("Primitive property delete is not supported yet.", @@ -329,6 +338,13 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor } @Override + public void deletePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) + throws ODataApplicationException, ODataLibraryException { + throw new ODataApplicationException("Primitive property update is not supported yet.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH); + } + + @Override public void updateComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
