From 39f0708d0c8ffb34ebae4fbafc5bd2e9fd4e282a Mon Sep 17 00:00:00 2001 From: Klaus Straubinger Date: Wed, 10 Jun 2015 10:24:11 +0200 Subject: [PATCH 01/16] [OLINGO-692] improved server processor interface inheritance Change-Id: Ic4c0774be8c6c4bbbbeaef6baab17fdd6677cd6c Signed-off-by: Christian Amend --- .../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 + .../client/core/uri/URIBuilderImpl.java | 6 + .../deserializer/DeserializerException.java | 2 +- .../deserializer/FixedFormatDeserializer.java | 10 +- .../CountComplexCollectionProcessor.java | 2 +- .../CountEntityCollectionProcessor.java | 2 +- .../CountPrimitiveCollectionProcessor.java | 2 +- .../api/processor/MediaEntityProcessor.java | 13 +- .../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 +- .../sample/processor/CarsProcessor.java | 16 ++ 24 files changed, 411 insertions(+), 132 deletions(-) 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 39d73b1c8..819aab7d1 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; @@ -162,6 +164,22 @@ public class BasicITCase extends AbstractBaseTestITCase { assertEquals(0, property.getPrimitiveValue().toValue()); } + @Test + public void readEntityCollectionCount() { + final ODataValueRequest request = getClient().getRetrieveRequestFactory() + .getValueRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESServerSidePaging").appendCountSegment().build()); + assertNotNull(request); + + final ODataRetrieveResponse 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 request = getClient().getRetrieveRequestFactory() 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 c5d292668..9f5efc39e 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; @@ -202,6 +204,16 @@ public final class ConditionalITCase extends AbstractBaseTestITCase { executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED); } + @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); @@ -209,6 +221,16 @@ public final class ConditionalITCase extends AbstractBaseTestITCase { executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED); } + @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); 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 04f9768a8..1dbd0e616 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 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 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 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(); 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 1c8f89d1e..7cf017772 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 @@ -120,6 +120,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. * 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 82f090e7a..8950dd504 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 @@ -179,6 +179,12 @@ public class URIBuilderImpl implements URIBuilder { return this; } + @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( 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 fd7e0eefb..56567f2f9 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 */ 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 6ad10eba4..bded6903c 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 parseBatchRequest(InputStream content, String boundary, BatchOptions options) throws BatchDeserializerException; 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 29e96d64b..fb25ab7bf 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. 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 65935dc31..a19419de9 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. 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 e9fe641de..0d6ee1a72 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. 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 75bb21e21..aedce5a87 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; } 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 7478ec61d..797ee85b4 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 null. + * @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; } 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 c92af8a03..0d98de501 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()) { 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 45b3eb8e9..e444cf47c 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()); 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 fe12ca70a..46910f19b 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; @@ -49,10 +54,35 @@ public class FixedFormatDeserializerImpl implements FixedFormatDeserializer { return result.toByteArray(); } + @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 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); 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 2d8b05766..a03206be2 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); } } } 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 797aae200..fbb4d62f8 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. 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 565c32a68..7f061ee9f 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)); + } } 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 086f69c5c..aae4f7a94 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 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); 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 4ff76341f..1c0d04928 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) { @@ -87,6 +93,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor readProperty(request, response, uriInfo, contentType, RepresentationType.PRIMITIVE); } + @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) @@ -94,10 +106,23 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.PRIMITIVE); } + @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 @@ -106,6 +131,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE); } + @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) @@ -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 @@ -144,6 +175,12 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX); } + @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) @@ -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 resourceParts = resource.getUriResourceParts(); - final List path = getPropertyPath(resourceParts, 0); + final int trailing = + representationType == RepresentationType.COUNT || representationType == RepresentationType.VALUE ? 1 : 0; + final List 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; + 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; - 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.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 resourceParts = resource.getUriResourceParts(); - final List path = getPropertyPath(resourceParts, 0); - final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - 1)) + final int trailing = representationType == RepresentationType.VALUE ? 1 : 0; + final List path = getPropertyPath(resourceParts, trailing); + final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 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); + checkRequestFormat(requestFormat); + 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); + } + 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 resourceParts = resource.getUriResourceParts(); - final List path = getPropertyPath(resourceParts, 0); + final int trailing = isValue ? 1 : 0; + final List 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 resourceParts = resource.getUriResourceParts(); - final List 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 { 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 a2339f572..755c4f140 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); 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 609db3599..c2294dda3 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; } } 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 35e9faa9b..0956c91ce 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; } } 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 17c9a29d3..caffcd5ab 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; @@ -321,6 +322,14 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH); } + @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 { @@ -328,6 +337,13 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH); } + @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, From 5501e8e3315b642ca904a598856dc9f7f1d0b2d7 Mon Sep 17 00:00:00 2001 From: Klaus Straubinger Date: Wed, 10 Jun 2015 15:06:33 +0200 Subject: [PATCH 02/16] [OLINGO-663] ETag annotation again in entity collections of technical service Change-Id: Ia150ba1705fa22e36c3821d5295f1b7f464a4852 Signed-off-by: Christian Amend --- .../client/FilterSystemQueryITCase.java | 247 ++++++++---------- .../client/SystemQueryOptionITCase.java | 27 +- .../commons/api/data/AbstractODataObject.java | 4 +- .../core/serialization/AtomDeserializer.java | 6 +- .../core/serialization/AtomSerializer.java | 2 +- .../serialization/JsonDeltaDeserializer.java | 2 +- .../serialization/JsonEntityDeserializer.java | 2 +- .../JsonEntitySetDeserializer.java | 2 +- .../processor/TechnicalEntityProcessor.java | 2 +- .../ExpandSystemQueryOptionHandler.java | 17 +- .../json/ODataJsonSerializerTest.java | 17 +- 11 files changed, 159 insertions(+), 169 deletions(-) diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java index 75d58afc7..1e27357b1 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java @@ -32,7 +32,6 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; import org.apache.olingo.client.api.domain.ClientObjectFactory; -import org.apache.olingo.client.api.domain.ClientValuable; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ODataFormat; @@ -62,7 +61,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -71,15 +70,15 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, response.getBody().getEntities().size()); ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = response.getBody().getEntities().get(1); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); response = sendRequest(ES_ALL_PRIM, "PropertyBoolean eq true"); assertEquals(1, response.getBody().getEntities().size()); clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -88,7 +87,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -98,7 +97,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -109,7 +108,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -121,7 +120,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -130,12 +129,12 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -145,8 +144,8 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -166,8 +165,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); ClientEntity clientEntity = response.getBody().getEntities().get(0); - - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -176,7 +174,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -185,18 +183,18 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { sendRequest(ES_TWO_KEY_NAV, "PropertyString eq '2' and PropertyInt16 eq 1"); assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); result = sendRequest(ES_TWO_KEY_NAV, "PropertyString eq '2' or PropertyInt16 eq 1"); assertEquals(2, result.getBody().getEntities().size()); clientEntity = result.getBody().getEntities().get(0); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -296,26 +294,17 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { .appendKeySegment(32766) .build())); - final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").build(); + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_ALL_PRIM).build(); ODataEntityCreateResponse createResponse = client.getCUDRequestFactory().getEntityCreateRequest(uri, entity).execute(); - final URI receiveURI = - client.newURIBuilder(SERVICE_URI) - .appendEntitySetSegment("ESAllPrim") - .filter(filterString) - .build(); - - ODataEntitySetRequest filterRequest = - client.getRetrieveRequestFactory().getEntitySetRequest(receiveURI); - filterRequest.addCustomHeader(HttpHeader.COOKIE, createResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next()); - ODataRetrieveResponse filterResponse = filterRequest.execute(); - + ODataRetrieveResponse filterResponse = sendRequest(ES_ALL_PRIM, filterString, + createResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next()); assertEquals(1, filterResponse.getBody().getEntities().size()); } @Test - public void testNumericComparisionOperators() { + public void numericComparisonOperators() { ODataRetrieveResponse result = sendRequest(ES_TWO_KEY_NAV, "PropertyInt16 ge 1"); assertEquals(4, result.getBody().getEntities().size()); @@ -355,25 +344,22 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(3, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); - assertEquals("11", ((ClientValuable) ((ClientValuable) clientEntity.getProperty("PropertyComp")).getComplexValue() - .get("PropertyInt16")).getValue() - .toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); + assertEquals(11, clientEntity.getProperty("PropertyComp").getComplexValue().get("PropertyInt16") + .getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); - assertEquals("11", ((ClientValuable) ((ClientValuable) clientEntity.getProperty("PropertyComp")).getComplexValue() - .get("PropertyInt16")).getValue() - .toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); + assertEquals(11, clientEntity.getProperty("PropertyComp").getComplexValue().get("PropertyInt16") + .getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(2); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); - assertEquals("11", ((ClientValuable) ((ClientValuable) clientEntity.getProperty("PropertyComp")).getComplexValue() - .get("PropertyInt16")).getValue() - .toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); + assertEquals(11, clientEntity.getProperty("PropertyComp").getComplexValue().get("PropertyInt16") + .getPrimitiveValue().toValue()); } @Test @@ -382,12 +368,12 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(2, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -396,12 +382,12 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(2, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -410,12 +396,12 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(2, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -444,7 +430,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -455,30 +441,27 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(4, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(2); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(2, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(3); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test public void testSubstringDouble() { - try { - sendRequest(ES_ALL_PRIM, "substring(PropertyString, length('First')" - + "add 1, 2.0 * 4) eq ('Resource')"); - } catch (ODataClientErrorException e) { - assertEquals(400, e.getStatusLine().getStatusCode()); - } + fail(ES_ALL_PRIM, + "substring(PropertyString, length('First') add 1, 2.0 * 4) eq ('Resource')", + HttpStatusCode.BAD_REQUEST); } @Test @@ -487,7 +470,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -496,7 +479,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -505,13 +488,13 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(3, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(2); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -520,7 +503,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -529,13 +512,13 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(3, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(2); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -544,7 +527,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -553,10 +536,10 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -565,7 +548,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -574,7 +557,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -583,7 +566,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -592,7 +575,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -601,7 +584,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -611,10 +594,12 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, response.getBody().getEntities().size()); ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("W/\"32767\"", clientEntity.getETag()); clientEntity = response.getBody().getEntities().get(1); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("W/\"0\"", clientEntity.getETag()); } @Test @@ -653,15 +638,15 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); result = sendRequest(ES_TWO_KEY_NAV, "PropertyInt16 eq floor(3.1)"); assertEquals(1, result.getBody().getEntities().size()); clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -670,15 +655,15 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); result = sendRequest(ES_TWO_KEY_NAV, "PropertyInt16 eq ceiling(2.6)"); assertEquals(1, result.getBody().getEntities().size()); clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -687,29 +672,29 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); result = sendRequest(ES_TWO_KEY_NAV, "PropertyInt16 eq round(2.4)"); assertEquals(1, result.getBody().getEntities().size()); clientEntity = result.getBody().getEntities().get(0); - assertEquals("2", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(2, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); result = sendRequest(ES_TWO_KEY_NAV, "PropertyInt16 eq round(2.6)"); assertEquals(1, result.getBody().getEntities().size()); clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); result = sendRequest(ES_TWO_KEY_NAV, "PropertyInt16 eq round(3.1)"); assertEquals(1, result.getBody().getEntities().size()); clientEntity = result.getBody().getEntities().get(0); - assertEquals("3", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); - assertEquals("1", ((ClientValuable) clientEntity.getProperty("PropertyString")).getValue().toString()); + assertEquals(3, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); + assertEquals("1", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -718,10 +703,10 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(2, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); clientEntity = result.getBody().getEntities().get(1); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -731,7 +716,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -740,7 +725,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -750,7 +735,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -760,7 +745,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -770,7 +755,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -780,7 +765,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -790,7 +775,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, result.getBody().getEntities().size()); ClientEntity clientEntity = result.getBody().getEntities().get(0); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -808,7 +793,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -818,7 +803,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -835,7 +820,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -845,7 +830,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -855,7 +840,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -865,7 +850,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -875,7 +860,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test @@ -885,7 +870,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { assertEquals(1, response.getBody().getEntities().size()); final ClientEntity clientEntity = response.getBody().getEntities().get(0); - assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString()); + assertEquals(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue()); } @Test diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java index c8d1d0c01..bbd9d51f6 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java @@ -28,7 +28,6 @@ import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; -import org.apache.olingo.client.api.uri.QueryOption; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpStatusCode; @@ -47,7 +46,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_ALL_PRIM) - .addQueryOption(QueryOption.COUNT, "true") + .count(true) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -63,7 +62,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) - .addQueryOption(QueryOption.COUNT, "true") + .count(true) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -79,7 +78,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) - .addQueryOption(QueryOption.TOP, new Integer(5).toString()) + .top(5) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -99,7 +98,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) - .addQueryOption(QueryOption.SKIP, new Integer(5).toString()) + .skip(5) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -119,8 +118,8 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) - .addQueryOption(QueryOption.TOP, new Integer(20).toString()) - .addQueryOption(QueryOption.SKIP, new Integer(503).toString()) + .top(20) + .skip(503) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -135,7 +134,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) - .addQueryOption(QueryOption.SKIP, new Integer(10000).toString()) + .skip(10000) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -152,9 +151,9 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) .filter("PropertyInt16 le 105") // 1, 2, ... , 105 .orderBy("PropertyInt16 desc") // 105, 104, ..., 2, 1 - .addQueryOption(QueryOption.COUNT, Boolean.TRUE.toString()) // 105 - .addQueryOption(QueryOption.SKIP, new Integer(3).toString()) // 102, 101, ..., 2, 1 - .addQueryOption(QueryOption.TOP, new Integer(43).toString()) // 102, 101, ...., 59 + .count(true) // 105 + .skip(3) // 102, 101, ..., 2, 1 + .top(43) // 102, 101, ...., 59 .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -228,7 +227,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING) - .addQueryOption(QueryOption.COUNT, Boolean.TRUE.toString()) + .count(true) .build(); ODataRetrieveResponse response = client.getRetrieveRequestFactory() @@ -264,7 +263,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_ALL_PRIM) - .addQueryOption(QueryOption.SKIP, new Integer(-5).toString()) + .skip(-5) .build(); try { @@ -282,7 +281,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { ODataClient client = getClient(); URI uri = client.newURIBuilder(SERVICE_URI) .appendEntitySetSegment(ES_ALL_PRIM) - .addQueryOption(QueryOption.TOP, new Integer(-5).toString()) + .top(-5) .build(); try { client.getRetrieveRequestFactory() diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/AbstractODataObject.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/AbstractODataObject.java index 237b8ef60..7e89123f9 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/AbstractODataObject.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/AbstractODataObject.java @@ -36,8 +36,8 @@ public abstract class AbstractODataObject extends Annotatable { return baseURI; } - public void setBaseURI(final String baseURI) { - this.baseURI = baseURI == null ? null : URI.create(baseURI); + public void setBaseURI(final URI baseURI) { + this.baseURI = baseURI; } /** diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java index c25da60ac..b8b51670b 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java @@ -431,7 +431,7 @@ public class AtomDeserializer extends AbstractAtomDealer implements ODataDeseria final Delta delta = new Delta(); final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE); if (xmlBase != null) { - delta.setBaseURI(xmlBase.getValue()); + delta.setBaseURI(URI.create(xmlBase.getValue())); } boolean foundEndFeed = false; @@ -579,7 +579,7 @@ public class AtomDeserializer extends AbstractAtomDealer implements ODataDeseria entity = new Entity(); final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE); if (xmlBase != null) { - entity.setBaseURI(xmlBase.getValue()); + entity.setBaseURI(URI.create(xmlBase.getValue())); } final Attribute etag = start.getAttributeByName(etagQName); @@ -737,7 +737,7 @@ public class AtomDeserializer extends AbstractAtomDealer implements ODataDeseria final EntityCollection entitySet = new EntityCollection(); final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE); if (xmlBase != null) { - entitySet.setBaseURI(xmlBase.getValue()); + entitySet.setBaseURI(URI.create(xmlBase.getValue())); } boolean foundEndFeed = false; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java index 1ef177adb..ecd7be07f 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java @@ -550,7 +550,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize if (container.getContextURL() != null) { final ContextURL contextURL = ContextURLParser.parse(container.getContextURL()); - String base = contextURL.getServiceRoot().toASCIIString(); + final URI base = contextURL.getServiceRoot(); if (container.getPayload() instanceof EntityCollection) { ((EntityCollection) container.getPayload()).setBaseURI(base); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java index 64f6c8a9b..89f327fc9 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java @@ -52,7 +52,7 @@ public class JsonDeltaDeserializer extends JsonDeserializer { final URI contextURL = tree.hasNonNull(Constants.JSON_CONTEXT) ? URI.create(tree.get(Constants.JSON_CONTEXT).textValue()) : null; if (contextURL != null) { - delta.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA)); + delta.setBaseURI(URI.create(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA))); } if (tree.hasNonNull(Constants.JSON_COUNT)) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java index 99abccb5e..10cc3bbc3 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java @@ -76,7 +76,7 @@ public class JsonEntityDeserializer extends JsonDeserializer { contextURL = null; } if (contextURL != null) { - entity.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA)); + entity.setBaseURI(URI.create(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA))); } final String metadataETag; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java index 01f2f657f..354d4ddf2 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java @@ -66,7 +66,7 @@ public class JsonEntitySetDeserializer extends JsonDeserializer { contextURL = null; } if (contextURL != null) { - entitySet.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA)); + entitySet.setBaseURI(URI.create(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA))); } final String metadataETag; 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 aae4f7a94..575b914df 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 @@ -435,7 +435,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final CountOption countOption = uriInfo.getCountOption(); // Serialize - final SerializerResult serializerResult = (isReference) ? + final SerializerResult serializerResult = isReference ? serializeReferenceCollection(entitySetSerialization, edmEntitySet, format) : serializeEntityCollection(entitySetSerialization, edmEntitySet, edmEntityType, format, expand, select, countOption); diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java index f9ac6e779..c641516cf 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java @@ -41,6 +41,7 @@ import org.apache.olingo.server.api.uri.queryoption.FilterOption; import org.apache.olingo.server.api.uri.queryoption.OrderByOption; import org.apache.olingo.server.api.uri.queryoption.SkipOption; import org.apache.olingo.server.api.uri.queryoption.TopOption; +import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler; import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler; import org.apache.olingo.server.tecsvc.processor.queryoptions.options.OrderByHandler; import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler; @@ -105,7 +106,7 @@ public class ExpandSystemQueryOptionHandler { FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmBindingTarget); OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmBindingTarget); - // TODO Add CountHandler + CountHandler.applyCountSystemQueryOption(countOption, entitySet); SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet); TopHandler.applyTopSystemQueryOption(topOption, entitySet); @@ -168,25 +169,29 @@ public class ExpandSystemQueryOptionHandler { newEntitySet.setCount(entitySet.getCount()); newEntitySet.setDeltaLink(entitySet.getDeltaLink()); newEntitySet.setNext(entitySet.getNext()); + newEntitySet.setId(entitySet.getId()); + newEntitySet.setBaseURI(entitySet.getBaseURI()); return newEntitySet; } private Entity newEntity(final Entity entity) { - final Entity newEntity = new Entity(); + Entity newEntity = new Entity(); newEntity.getProperties().addAll(entity.getProperties()); newEntity.getAnnotations().addAll(entity.getAnnotations()); - newEntity.getAssociationLinks().addAll(entity.getAssociationLinks()); - newEntity.setEditLink(entity.getEditLink()); newEntity.setId(entity.getId()); + newEntity.setBaseURI(entity.getBaseURI()); + newEntity.setType(entity.getType()); + newEntity.setETag(entity.getETag()); newEntity.setMediaContentSource(entity.getMediaContentSource()); newEntity.setMediaContentType(entity.getMediaContentType()); newEntity.setMediaETag(entity.getMediaETag()); - newEntity.getOperations().addAll(entity.getOperations()); newEntity.setSelfLink(entity.getSelfLink()); - newEntity.setType(entity.getType()); + newEntity.setEditLink(entity.getEditLink()); + newEntity.getAssociationLinks().addAll(entity.getAssociationLinks()); newEntity.getNavigationBindings().addAll(entity.getNavigationBindings()); + newEntity.getOperations().addAll(entity.getOperations()); return newEntity; } diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java index 311ec082e..c9cfde9f5 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java @@ -37,7 +37,6 @@ import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.serializer.ComplexSerializerOptions; @@ -53,6 +52,7 @@ import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectItem; import org.apache.olingo.server.api.uri.queryoption.SelectOption; +import org.apache.olingo.server.core.ServiceMetadataImpl; import org.apache.olingo.server.core.serializer.ExpandSelectMock; import org.apache.olingo.server.core.uri.UriHelperImpl; import org.apache.olingo.server.tecsvc.MetadataETagSupport; @@ -64,7 +64,7 @@ import org.junit.Test; import org.mockito.Mockito; public class ODataJsonSerializerTest { - private static final ServiceMetadata metadata = OData.newInstance().createServiceMetadata( + private static final ServiceMetadata metadata = new ServiceMetadataImpl( new EdmTechProvider(), Collections. emptyList(), new MetadataETagSupport("W/\"metadataETag\"")); private static final EdmEntityContainer entityContainer = metadata.getEdm().getEntityContainer(); private final DataProvider data = new DataProvider(); @@ -157,8 +157,8 @@ public class ODataJsonSerializerTest { } @Test - public void entitySetAllPrim() throws Exception { - final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + public void entitySetCompAllPrim() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompAllPrim"); EntityCollection entitySet = data.readAll(edmEntitySet); entitySet.setCount(entitySet.getEntities().size()); entitySet.setNext(URI.create("/next")); @@ -172,10 +172,11 @@ public class ODataJsonSerializerTest { final String resultString = IOUtils.toString(result); Assert.assertThat(resultString, CoreMatchers.startsWith("{" - + "\"@odata.context\":\"$metadata#ESAllPrim\"," + + "\"@odata.context\":\"$metadata#ESCompAllPrim\"," + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," - + "\"@odata.count\":3,\"value\":[")); - Assert.assertThat(resultString, CoreMatchers.endsWith("]," + + "\"@odata.count\":3,\"value\":[" + + "{\"@odata.etag\":\"W/\\\"32767\\\"\",")); + Assert.assertThat(resultString, CoreMatchers.endsWith("\"}}]," + "\"@odata.nextLink\":\"/next\"}")); int count = 0; @@ -183,7 +184,7 @@ public class ODataJsonSerializerTest { while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) { count++; } - Assert.assertEquals(3, count); + Assert.assertEquals(6, count); } @Test From 3b506eaade59d5596a2465b7ec0686d6c425a172 Mon Sep 17 00:00:00 2001 From: "x.x@sap.com" Date: Wed, 10 Jun 2015 22:02:36 +0200 Subject: [PATCH 03/16] PATCH Signed-off-by: Christian Amend --- .../org/apache/olingo/server/api/OData.java | 8 + .../olingo/server/api/prefer/Preferences.java | 107 +++++++++++ .../server/api/prefer/PreferencesApplied.java | 164 +++++++++++++++++ .../api/prefer/PreferencesAppliedTest.java | 67 +++++++ .../apache/olingo/server/core/ODataImpl.java | 8 + .../server/core/prefer/PreferParser.java | 150 ++++++++++++++++ .../server/core/prefer/PreferencesImpl.java | 117 ++++++++++++ .../server/core/prefer/PreferencesTest.java | 168 ++++++++++++++++++ 8 files changed, 789 insertions(+) create mode 100644 lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/Preferences.java create mode 100644 lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/PreferencesApplied.java create mode 100644 lib/server-api/src/test/java/org/apache/olingo/server/api/prefer/PreferencesAppliedTest.java create mode 100644 lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferParser.java create mode 100644 lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferencesImpl.java create mode 100644 lib/server-core/src/test/java/org/apache/olingo/server/core/prefer/PreferencesTest.java diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java index 3a9c1cb7f..e9dc225f8 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java @@ -18,6 +18,7 @@ */ package org.apache.olingo.server.api; +import java.util.Collection; import java.util.List; import org.apache.olingo.commons.api.ODataRuntimeException; @@ -31,6 +32,7 @@ import org.apache.olingo.server.api.deserializer.ODataDeserializer; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.etag.ETagHelper; import org.apache.olingo.server.api.etag.ServiceMetadataETagSupport; +import org.apache.olingo.server.api.prefer.Preferences; import org.apache.olingo.server.api.serializer.FixedFormatSerializer; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerException; @@ -135,4 +137,10 @@ public abstract class OData { * It can be used in Processor implementations. */ public abstract ETagHelper createETagHelper(); + + /** + * Creates a new Preferences object out of Prefer HTTP request headers. + * It can be used in Processor implementations. + */ + public abstract Preferences createPreferences(Collection preferHeaders); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/Preferences.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/Preferences.java new file mode 100644 index 000000000..91f0d4531 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/Preferences.java @@ -0,0 +1,107 @@ +/* + * 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.api.prefer; + +import java.net.URI; +import java.util.Map; + +/** + * Provides access methods to the preferences set in Prefer HTTP request headers + * as described in RFC 7240. + * Preferences defined in the OData standard can be accessed with named methods. + */ +public interface Preferences { + + /** + * Gets named preference. Names are case insensitive. + * @param name name of the preference + * @return {@link Preference} or null if no such preference has been set + */ + public Preference getPreference(String name); + + /** Whether the preference odata.allow-entityreferences has been set. */ + public boolean hasAllowEntityReferences(); + + /** + * Gets the value of the url parameter of the preference + * odata.callback or null if not set or the URI is not valid. + * @return the callback URI + */ + public URI getCallback(); + + /** Whether the preference odata.continue-on-error has been set. */ + public boolean hasContinueOnError(); + + /** + * Gets the value of the preference odata.maxpagesize + * or null if not set or an invalid value has been set. + * @return the page size for server-driven paging + */ + public Integer getMaxPageSize(); + + /** Whether the preference odata.track-changes has been set. */ + public boolean hasTrackChanges(); + + public enum Return { REPRESENTATION, MINIMAL } + /** + * Gets the value of the preference return or null if not set + * or the value is not valid. + */ + public Return getReturn(); + + /** Whether the preference respond-async has been set. */ + public boolean hasRespondAsync(); + + /** + * Gets the value of the preference wait or null if not set + * or the value is not valid. + * @return the number of seconds the client is prepared to wait for the service + * to process the request synchronously + */ + public Integer getWait(); + + /** Generic preference object. */ + public class Preference { + private final String value; + private final Map parameters; + + public Preference(final String value, final Map parameters) { + this.value = value; + this.parameters = parameters; + } + + /** + * Gets the value of the preference. It may be null if the preference has + * no value; this is not the same as the preference not set. + */ + public String getValue() { + return value; + } + + /** + * Gets the parameters of the preference. The value of a parameter may be + * null if the parameter has no value; this is not the same as + * the parameter not set. Parameter names are all lowercase. + * @return a map from parameter names to parameter values + */ + public Map getParameters() { + return parameters; + } + } +} diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/PreferencesApplied.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/PreferencesApplied.java new file mode 100644 index 000000000..fd89a3ae3 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/prefer/PreferencesApplied.java @@ -0,0 +1,164 @@ +/* + * 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.api.prefer; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +import org.apache.olingo.server.api.prefer.Preferences.Return; + +/** + * Provides methods to set values suitable for the Preference-Applied HTTP response header + * as described in RFC 7240. + * There are named methods for preferences defined in the OData standard. + */ +public class PreferencesApplied { + + private Map applied; + + private PreferencesApplied() { + applied = new LinkedHashMap(); + } + + /** + * Gets the applied preferences. + * @return a map from preference names to preference values + */ + public Map getAppliedPreferences() { + return Collections.unmodifiableMap(applied); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for (final String name : applied.keySet()) { + if (result.length() > 0) { + result.append(',').append(' '); + } + result.append(name); + if (applied.get(name) != null) { + result.append('=').append('"') + .append(applied.get(name).replaceAll("\\\\|\"", "\\\\$0")) + .append('"'); + } + } + return result.toString(); + } + + /** Initializes the builder. */ + public static Builder with() { + return new Builder(); + } + + /** Builder of OData serializer options. */ + public static final class Builder { + + private static final String ALLOW_ENTITY_REFERENCES = "odata.allow-entityreferences"; + private static final String CALLBACK = "odata.callback"; + private static final String CONTINUE_ON_ERROR = "odata.continue-on-error"; + // private static final String INCLUDE_ANNOTATIONS = "odata.include-annotations"; + private static final String MAX_PAGE_SIZE = "odata.maxpagesize"; + private static final String TRACK_CHANGES = "odata.track-changes"; + private static final String RETURN = "return"; + private static final String RESPOND_ASYNC = "respond-async"; + private static final String WAIT = "wait"; + + private final PreferencesApplied preferencesApplied; + + private Builder() { + preferencesApplied = new PreferencesApplied(); + } + + /** Sets odata.allow-entityreferences. */ + public Builder allowEntityReferences() { + add(ALLOW_ENTITY_REFERENCES, null); + return this; + } + + /** Sets odata.callback. */ + public Builder callback() { + add(CALLBACK, null); + return this; + } + + /** Sets odata.continue-on-error. */ + public Builder continueOnError() { + add(CONTINUE_ON_ERROR, null); + return this; + } + + /** Sets the value of the applied preference odata.maxpagesize. */ + public Builder maxPageSize(final Integer maxPageSize) { + add(MAX_PAGE_SIZE, Integer.toString(maxPageSize)); + return this; + } + + /** Sets odata.track-changes. */ + public Builder trackChanges() { + add(TRACK_CHANGES, null); + return this; + } + + /** Sets the value of the applied preference return. */ + public Builder returnRepresentation(final Return returnRepresentation) { + add(RETURN, returnRepresentation.name().toLowerCase(Locale.ROOT)); + return this; + } + + /** Sets odata.respond-async. */ + public Builder respondAsync() { + add(RESPOND_ASYNC, null); + return this; + } + + /** Sets the value of the applied preference wait. */ + public Builder waitPreference(final Integer wait) { + add(WAIT, Integer.toString(wait)); + return this; + } + + /** + * Sets an arbitrary preference as applied. + * The preference name is converted to lowercase. + * The value of this preference may be null. + * Name and value are not checked for validity. + * @param name preference name + * @param value preference value + */ + public Builder preference(final String name, final String value) { + if (name != null) { + add(name.toLowerCase(Locale.ROOT), value); + } + return this; + } + + /** Builds the applied preferences. */ + public PreferencesApplied build() { + return preferencesApplied; + } + + private void add(final String name, final String value) { + if (!preferencesApplied.applied.containsKey(name)) { + preferencesApplied.applied.put(name, value); + } + } + } +} diff --git a/lib/server-api/src/test/java/org/apache/olingo/server/api/prefer/PreferencesAppliedTest.java b/lib/server-api/src/test/java/org/apache/olingo/server/api/prefer/PreferencesAppliedTest.java new file mode 100644 index 000000000..0d5edf9f4 --- /dev/null +++ b/lib/server-api/src/test/java/org/apache/olingo/server/api/prefer/PreferencesAppliedTest.java @@ -0,0 +1,67 @@ +/* + * 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.api.prefer; + +import static org.junit.Assert.assertEquals; + +import org.apache.olingo.server.api.prefer.Preferences.Return; +import org.junit.Test; + +public class PreferencesAppliedTest { + + @Test + public void empty() { + assertEquals("", PreferencesApplied.with().build().toString()); + } + + @Test + public void all() { + assertEquals("odata.allow-entityreferences, odata.callback," + + " odata.continue-on-error, odata.include-annotations=\"*\", odata.maxpagesize=\"42\"," + + " odata.track-changes, return=\"representation\", respond-async, wait=\"12345\"", + PreferencesApplied.with().allowEntityReferences().callback().continueOnError() + .preference("odata.include-annotations", "*").maxPageSize(42).trackChanges() + .returnRepresentation(Return.REPRESENTATION).respondAsync().waitPreference(12345) + .build().toString()); + } + + @Test + public void caseSensitivity() { + assertEquals("odata.include-annotations=\"*\", odata.maxpagesize=\"255\"", + PreferencesApplied.with() + .preference("OData.Include-Annotations", "*").maxPageSize(0xFF) + .build().toString()); + } + + @Test + public void multipleValues() { + assertEquals("return=\"minimal\", wait=\"1\"", + PreferencesApplied.with() + .returnRepresentation(Return.MINIMAL).returnRepresentation(Return.REPRESENTATION) + .preference(null, null).preference(null, "nullValue") + .waitPreference(1).waitPreference(2).waitPreference(3) + .build().toString()); + } + + @Test + public void quotedValue() { + assertEquals("strangepreference=\"x\\\\y,\\\"abc\\\"z\"", + PreferencesApplied.with().preference("strangePreference", "x\\y,\"abc\"z").build().toString()); + } +} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java index 57cceaf31..35c1ccf93 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java @@ -18,6 +18,7 @@ */ package org.apache.olingo.server.core; +import java.util.Collection; import java.util.List; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; @@ -34,6 +35,7 @@ import org.apache.olingo.server.api.deserializer.ODataDeserializer; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.etag.ETagHelper; import org.apache.olingo.server.api.etag.ServiceMetadataETagSupport; +import org.apache.olingo.server.api.prefer.Preferences; import org.apache.olingo.server.api.serializer.FixedFormatSerializer; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerException; @@ -41,6 +43,7 @@ import org.apache.olingo.server.api.uri.UriHelper; import org.apache.olingo.server.core.deserializer.FixedFormatDeserializerImpl; import org.apache.olingo.server.core.deserializer.json.ODataJsonDeserializer; import org.apache.olingo.server.core.etag.ETagHelperImpl; +import org.apache.olingo.server.core.prefer.PreferencesImpl; import org.apache.olingo.server.core.serializer.FixedFormatSerializerImpl; import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer; import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializerImpl; @@ -128,4 +131,9 @@ public class ODataImpl extends OData { return new ETagHelperImpl(); } + @Override + public Preferences createPreferences(final Collection preferHeaders) { + return new PreferencesImpl(preferHeaders); + } + } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferParser.java new file mode 100644 index 000000000..a3a2a423b --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferParser.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.prefer; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.olingo.server.api.prefer.Preferences.Preference; + +/** + *

Parses the values of Prefer HTTP header fields.

+ *

See RFC 7240 for details; + * there the following grammar is defined:

+ *
+ *     Prefer        = "Prefer" ":" 1#preference
+ *     preference    = token [ BWS "=" BWS word ] *( OWS ";" [ OWS parameter ] )
+ *     parameter     = token [ BWS "=" BWS word ]
+ *     token         = 1*tchar
+ *     tchar         = "!" / "#" / "$" / "%" / "&" / "'" / "*"
+                     / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
+ *     word          = token / quoted-string
+ *     quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
+ *     qdtext        = HTAB / SP / %x21 / %x23-5B / %x5D-7E / %x80-FF
+ *     quoted-pair   = "\" ( HTAB / SP / %x21-7E /  %x80-FF )
+ *     OWS           = *( SP / HTAB )  ; optional whitespace
+ *     BWS           = OWS             ; "bad" whitespace
+ * 
+ *

Values with illegal syntax do not contribute to the result but no exception is thrown.

+ */ +public class PreferParser { + + private static final String token = "(?:[-!#$%&'*+.^_`|~]|\\w)+"; + private static final String quotedString = "(?:\"(?:[\\t !#-\\[\\]-~\\x80-\\xFF]|" + + "(?:\\\\[\\t !-~\\x80-\\xFF]))*\")"; + private static final String namedValue = + "(" + token + ")(?:\\s*=\\s*(" + token + "|" + quotedString + "))?"; + private static final Pattern PREFERENCE = Pattern.compile("\\s*(,\\s*)+|" + + "(?:" + namedValue + "((?:\\s*;\\s*(?:" + namedValue + ")?)*))"); + private static final Pattern PARAMETER = Pattern.compile("\\s*(;\\s*)+|(?:" + namedValue + ")"); + + protected static Map parse(final Collection values) { + if (values == null || values.isEmpty()) { + return Collections.emptyMap(); + } + + Map result = new HashMap(); + for (final String value : values) { + if (value != null && !value.isEmpty()) { + parse(value, result); + } + } + return result; + } + + private static void parse(final String value, Map result) { + Map partResult = new HashMap(); + String separator = ""; + int start = 0; + Matcher matcher = PREFERENCE.matcher(value.trim()); + while (matcher.find() && matcher.start() == start) { + start = matcher.end(); + if (matcher.group(1) != null) { + separator = matcher.group(1); + } else if (separator != null) { + final String name = matcher.group(2).toLowerCase(Locale.ROOT); + // RFC 7240: + // If any preference is specified more than once, only the first instance is to be + // considered. All subsequent occurrences SHOULD be ignored without signaling + // an error or otherwise altering the processing of the request. + if (!partResult.containsKey(name)) { + final String preferenceValue = getValue(matcher.group(3)); + final Map parameters = + matcher.group(4) == null || matcher.group(4).isEmpty() ? null : + parseParameters(matcher.group(4)); + partResult.put(name, new Preference(preferenceValue, parameters)); + } + separator = null; + } else { + return; + } + } + if (matcher.hitEnd()) { + // Here we also have to keep already existing preferences. + for (final String key : partResult.keySet()) { + if (!result.containsKey(key)) { + result.put(key, partResult.get(key)); + } + } + } + } + + private static Map parseParameters(final String parameters) { + Map result = new HashMap(); + String separator = ""; + int start = 0; + Matcher matcher = PARAMETER.matcher(parameters.trim()); + while (matcher.find() && matcher.start() == start) { + start = matcher.end(); + if (matcher.group(1) != null) { + separator = matcher.group(1); + } else if (separator != null) { + final String name = matcher.group(2).toLowerCase(Locale.ROOT); + // We have to keep already existing parameters. + if (!result.containsKey(name)) { + result.put(name, getValue(matcher.group(3))); + } + separator = null; + } else { + return null; + } + } + return matcher.hitEnd() ? Collections.unmodifiableMap(result) : null; + } + + private static String getValue(final String value) { + if (value == null) { + return null; + } + String result = value; + if (value.startsWith("\"")) { + result = value.substring(1, value.length() - 1); + } + // Unquote backslash-quoted characters. + if (result.indexOf('\\') >= 0) { + result = result.replaceAll("\\\\(.)", "$1"); + } + return result; + } +} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferencesImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferencesImpl.java new file mode 100644 index 000000000..9661cd363 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/prefer/PreferencesImpl.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.prefer; + +import java.net.URI; +import java.util.Collection; +import java.util.Locale; +import java.util.Map; + +import org.apache.olingo.server.api.prefer.Preferences; + +/** + * Provides access methods to the preferences set in the Prefer HTTP request + * header as described in RFC 7240. + * Preferences defined in the OData standard can be accessed with named methods. + */ +public class PreferencesImpl implements Preferences { + + private static final String ALLOW_ENTITY_REFERENCES = "odata.allow-entityreferences"; + private static final String CALLBACK = "odata.callback"; + private static final String CONTINUE_ON_ERROR = "odata.continue-on-error"; + // private static final String INCLUDE_ANNOTATIONS = "odata.include-annotations"; + private static final String MAX_PAGE_SIZE = "odata.maxpagesize"; + private static final String TRACK_CHANGES = "odata.track-changes"; + private static final String RETURN = "return"; + private static final String RESPOND_ASYNC = "respond-async"; + private static final String WAIT = "wait"; + + private static final String URL = "url"; // parameter name for odata.callback + + private final Map preferences; + + public PreferencesImpl(final Collection preferHeaders) { + preferences = PreferParser.parse(preferHeaders); + } + + public Preference getPreference(final String name) { + return preferences.get(name.toLowerCase(Locale.ROOT)); + } + + public boolean hasAllowEntityReferences() { + return preferences.containsKey(ALLOW_ENTITY_REFERENCES); + } + + public URI getCallback() { + if (preferences.containsKey(CALLBACK) + && preferences.get(CALLBACK).getParameters() != null + && preferences.get(CALLBACK).getParameters().get(URL) != null) { + try { + return URI.create(preferences.get(CALLBACK).getParameters().get(URL)); + } catch (final IllegalArgumentException e) { + return null; + } + } + return null; + } + + public boolean hasContinueOnError() { + return preferences.containsKey(CONTINUE_ON_ERROR); + } + + public Integer getMaxPageSize() { + return getNonNegativeIntegerPreference(MAX_PAGE_SIZE); + } + + public boolean hasTrackChanges() { + return preferences.containsKey(TRACK_CHANGES); + } + + public Return getReturn() { + if (preferences.containsKey(RETURN)) { + final String value = preferences.get(RETURN).getValue(); + if (Return.REPRESENTATION.toString().toLowerCase(Locale.ROOT).equals(value)) { + return Return.REPRESENTATION; + } else if (Return.MINIMAL.toString().toLowerCase(Locale.ROOT).equals(value)) { + return Return.MINIMAL; + } + } + return null; + } + + public boolean hasRespondAsync() { + return preferences.containsKey(RESPOND_ASYNC); + } + + public Integer getWait() { + return getNonNegativeIntegerPreference(WAIT); + } + + private Integer getNonNegativeIntegerPreference(final String name) { + if (preferences.containsKey(name) && preferences.get(name).getValue() != null) { + try { + final Integer result = Integer.valueOf(preferences.get(name).getValue()); + return result < 0 ? null : result; + } catch (final NumberFormatException e) { + return null; + } + } + return null; + } +} diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/prefer/PreferencesTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/prefer/PreferencesTest.java new file mode 100644 index 000000000..b0e8d74af --- /dev/null +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/prefer/PreferencesTest.java @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.prefer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import org.apache.olingo.server.api.prefer.Preferences; +import org.apache.olingo.server.api.prefer.Preferences.Preference; +import org.apache.olingo.server.api.prefer.Preferences.Return; +import org.junit.Test; + +public class PreferencesTest { + + @Test + public void empty() { + final Preferences preferences = new PreferencesImpl(null); + assertFalse(preferences.hasAllowEntityReferences()); + assertNull(preferences.getCallback()); + assertFalse(preferences.hasContinueOnError()); + assertNull(preferences.getMaxPageSize()); + assertFalse(preferences.hasTrackChanges()); + assertNull(preferences.getReturn()); + assertFalse(preferences.hasRespondAsync()); + assertNull(preferences.getWait()); + } + + @Test + public void all() { + final Preferences preferences = new PreferencesImpl(Collections.singleton( + "odata.allow-entityreferences, odata.callback;url=\"callbackURI\"," + + "odata.continue-on-error, odata.include-annotations=\"*\", odata.maxpagesize=42," + + "odata.track-changes, return=representation, respond-async, wait=12345")); + assertTrue(preferences.hasAllowEntityReferences()); + assertEquals(URI.create("callbackURI"), preferences.getCallback()); + assertNotNull(preferences.getPreference("odata.callback")); + assertNull(preferences.getPreference("odata.callback").getValue()); + assertEquals("callbackURI", preferences.getPreference("odata.callback").getParameters().get("url")); + assertTrue(preferences.hasContinueOnError()); + assertEquals("*", preferences.getPreference("odata.Include-Annotations").getValue()); + assertEquals(Integer.valueOf(42), preferences.getMaxPageSize()); + assertEquals("42", preferences.getPreference("odata.MaxPageSize").getValue()); + assertTrue(preferences.hasTrackChanges()); + assertEquals(Return.REPRESENTATION, preferences.getReturn()); + assertTrue(preferences.hasRespondAsync()); + assertEquals(Integer.valueOf(12345), preferences.getWait()); + } + + @Test + public void caseSensitivity() { + final Preferences preferences = new PreferencesImpl(Collections.singleton( + "OData.Callback;URL=\"callbackURI\", return=REPRESENTATION, Wait=42")); + assertEquals(URI.create("callbackURI"), preferences.getCallback()); + assertNull(preferences.getReturn()); + assertEquals(Integer.valueOf(42), preferences.getWait()); + } + + @Test + public void multipleValues() { + final Preferences preferences = new PreferencesImpl(Collections.singleton( + ",return=minimal, ,, return=representation, wait=1, wait=2, wait=3,")); + assertEquals(Return.MINIMAL, preferences.getReturn()); + assertEquals(Integer.valueOf(1), preferences.getWait()); + } + + @Test + public void multipleValuesDifferentHeaders() { + final Preferences preferences = new PreferencesImpl(Arrays.asList( + null, "", + "return=representation, wait=1", + "return=minimal, wait=2", + "wait=3")); + assertEquals(Return.REPRESENTATION, preferences.getReturn()); + assertEquals(Integer.valueOf(1), preferences.getWait()); + } + + @Test + public void multipleParameters() { + final Preferences preferences = new PreferencesImpl(Collections.singleton( + "preference=a;;b=c; d = e; f;; ; g; h=\"i\";, wait=42")); + final Preference preference = preferences.getPreference("preference"); + assertEquals("a", preference.getValue()); + final Map parameters = preference.getParameters(); + assertEquals(5, parameters.size()); + assertEquals("c", parameters.get("b")); + assertEquals("e", parameters.get("d")); + assertTrue(parameters.containsKey("f")); + assertNull(parameters.get("f")); + assertTrue(parameters.containsKey("g")); + assertNull(parameters.get("g")); + assertEquals("i", parameters.get("h")); + assertEquals(Integer.valueOf(42), preferences.getWait()); + } + + @Test + public void quotedValue() { + final Preferences preferences = new PreferencesImpl(Collections.singleton( + "strangePreference=\"x\\\\y,\\\"abc\\\"z\", wait=42")); + assertEquals("x\\y,\"abc\"z", preferences.getPreference("strangePreference").getValue()); + assertEquals(Integer.valueOf(42), preferences.getWait()); + } + + @Test + public void specialCharacters() { + final Preferences preferences = new PreferencesImpl(Collections.singleton( + "!#$%&'*+-.^_`|~ = \"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\", wait=42")); + assertEquals("!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF", + preferences.getPreference("!#$%&'*+-.^_`|~").getValue()); + assertEquals(Integer.valueOf(42), preferences.getWait()); + } + + @Test + public void wrongContent() { + final Preferences preferences = new PreferencesImpl(Arrays.asList( + "odata.callback;url=\":\"", + "odata.maxpagesize=12345678901234567890", + "return=something", + "wait=-1")); + assertNull(preferences.getCallback()); + assertEquals(":", preferences.getPreference("odata.callback").getParameters().get("url")); + assertNull(preferences.getMaxPageSize()); + assertEquals("12345678901234567890", preferences.getPreference("odata.maxpagesize").getValue()); + assertNull(preferences.getReturn()); + assertEquals("something", preferences.getPreference("return").getValue()); + assertNull(preferences.getWait()); + assertEquals("-1", preferences.getPreference("wait").getValue()); + } + + @Test + public void wrongFormat() { + final Preferences preferences = new PreferencesImpl(Arrays.asList( + "return=, wait=1", + "return=;, wait=2", + "return=representation=, wait=3", + "return=\"representation\"respond-async, wait=4", + "respond-async[], wait=5", + "odata.callback;=, wait=6", + "odata.callback;url=, wait=7", + "odata.callback;[], wait=8", + "odata.callback;url=\"url\"parameter, wait=9", + "wait=10")); + assertEquals(Integer.valueOf(10), preferences.getWait()); + } +} From a6d20f627b006bfe8007780ab407212a9775af52 Mon Sep 17 00:00:00 2001 From: Christian Amend Date: Mon, 15 Jun 2015 10:23:10 +0200 Subject: [PATCH 04/16] [OLINGO-693] Removed Serializable interface from csdNamed --- .../org/apache/olingo/commons/api/edm/provider/CsdlNamed.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlNamed.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlNamed.java index 4529014fc..f82edc266 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlNamed.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/provider/CsdlNamed.java @@ -18,9 +18,8 @@ */ package org.apache.olingo.commons.api.edm.provider; -import java.io.Serializable; -public interface CsdlNamed extends Serializable { +public interface CsdlNamed { String getName(); } From 20351253e2c00f6593cf4136375f1157c9310af5 Mon Sep 17 00:00:00 2001 From: Christian Amend Date: Mon, 15 Jun 2015 10:48:03 +0200 Subject: [PATCH 05/16] [OLINGO-699] Moved serializer code to client module --- fit/pom.xml | 12 ++++++------ .../org/apache/olingo/fit/AbstractServices.java | 10 +++++----- .../olingo/fit/serializer/FITAtomDeserializer.java | 2 +- .../apache/olingo/fit/utils/AbstractUtilities.java | 14 +++++++------- .../org/apache/olingo/fit/utils/FSManager.java | 6 +++--- .../apache/olingo/fit/AbstractBaseTestITCase.java | 2 +- .../org/apache/olingo/client/api/ODataClient.java | 2 +- .../client/api/domain/ClientEntitySetIterator.java | 2 +- .../api/serialization/ClientODataDeserializer.java | 2 -- .../api/serialization/ODataDeserializer.java | 2 +- .../serialization/ODataDeserializerException.java | 2 +- .../client/api/serialization/ODataReader.java | 1 - .../client}/api/serialization/ODataSerializer.java | 2 +- .../serialization/ODataSerializerException.java | 2 +- .../client/api/serialization/ODataWriter.java | 1 - .../apache/olingo/client/core/ODataClientImpl.java | 6 +++--- .../header/ODataErrorResponseChecker.java | 2 +- .../request/cud/ODataEntityCreateRequestImpl.java | 4 ++-- .../request/cud/ODataEntityUpdateRequestImpl.java | 4 ++-- .../cud/ODataPropertyUpdateRequestImpl.java | 4 ++-- .../cud/ODataReferenceAddingRequestImpl.java | 2 +- .../request/invoke/AbstractODataInvokeRequest.java | 4 ++-- .../request/retrieve/ODataDeltaRequestImpl.java | 2 +- .../request/retrieve/ODataEntityRequestImpl.java | 2 +- .../retrieve/ODataEntitySetRequestImpl.java | 2 +- .../request/retrieve/ODataPropertyRequestImpl.java | 2 +- .../request/retrieve/ODataRawRequestImpl.java | 2 +- .../retrieve/ODataServiceDocumentRequestImpl.java | 2 +- .../ODataMediaEntityCreateRequestImpl.java | 2 +- .../ODataMediaEntityUpdateRequestImpl.java | 2 +- .../core/data/JSONServiceDocumentDeserializer.java | 4 ++-- .../core/data/XMLServiceDocumentDeserializer.java | 4 ++-- .../core/serialization/AbstractAtomDealer.java | 2 +- .../core/serialization/AtomDeserializer.java | 6 +++--- .../serialization/AtomGeoValueDeserializer.java | 2 +- .../core/serialization/AtomGeoValueSerializer.java | 2 +- .../client}/core/serialization/AtomSerializer.java | 6 +++--- .../serialization/ClientODataDeserializerImpl.java | 7 ++----- .../core/serialization/ContextURLParser.java | 2 +- .../core/serialization/JsonDeltaDeserializer.java | 4 ++-- .../core/serialization/JsonDeserializer.java | 6 +++--- .../core/serialization/JsonEntityDeserializer.java | 2 +- .../core/serialization/JsonEntitySerializer.java | 2 +- .../serialization/JsonEntitySetDeserializer.java | 2 +- .../serialization/JsonEntitySetSerializer.java | 2 +- .../serialization/JsonGeoValueDeserializer.java | 2 +- .../core/serialization/JsonGeoValueSerializer.java | 2 +- .../serialization/JsonODataErrorDeserializer.java | 2 +- .../JsonODataErrorDetailDeserializer.java | 2 +- .../serialization/JsonPropertyDeserializer.java | 2 +- .../core/serialization/JsonPropertySerializer.java | 2 +- .../client}/core/serialization/JsonSerializer.java | 6 +++--- .../client/core/serialization/ODataBinderImpl.java | 3 +-- .../client/core/serialization/ODataReaderImpl.java | 2 +- .../client/core/serialization/ODataWriterImpl.java | 2 +- .../core/serialization/AtomDeserializerTest.java | 3 ++- .../core/serialization/ContextURLParserTest.java | 3 ++- .../olingo/client/core/v4/EntitySetTest.java | 2 +- .../apache/olingo/client/core/v4/ErrorTest.java | 2 +- .../apache/olingo/client/core/v4/PropertyTest.java | 4 ++-- .../olingo/client/core/v4/ServiceDocumentTest.java | 2 +- 61 files changed, 96 insertions(+), 102 deletions(-) rename lib/{commons-api/src/main/java/org/apache/olingo/commons => client-api/src/main/java/org/apache/olingo/client}/api/serialization/ODataDeserializer.java (97%) mode change 100755 => 100644 rename lib/{commons-api/src/main/java/org/apache/olingo/commons => client-api/src/main/java/org/apache/olingo/client}/api/serialization/ODataDeserializerException.java (95%) mode change 100755 => 100644 rename lib/{commons-api/src/main/java/org/apache/olingo/commons => client-api/src/main/java/org/apache/olingo/client}/api/serialization/ODataSerializer.java (95%) rename lib/{commons-api/src/main/java/org/apache/olingo/commons => client-api/src/main/java/org/apache/olingo/client}/api/serialization/ODataSerializerException.java (95%) mode change 100755 => 100644 rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/AbstractAtomDealer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/AtomDeserializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/AtomGeoValueDeserializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/AtomGeoValueSerializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/AtomSerializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/ContextURLParser.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonDeltaDeserializer.java (96%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonDeserializer.java (98%) mode change 100755 => 100644 rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonEntityDeserializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonEntitySerializer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonEntitySetDeserializer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonEntitySetSerializer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonGeoValueDeserializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonGeoValueSerializer.java (99%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonODataErrorDeserializer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonODataErrorDetailDeserializer.java (97%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonPropertyDeserializer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonPropertySerializer.java (98%) rename lib/{commons-core/src/main/java/org/apache/olingo/commons => client-core/src/main/java/org/apache/olingo/client}/core/serialization/JsonSerializer.java (98%) mode change 100755 => 100644 rename lib/{commons-core/src/test/java/org/apache/olingo/commons => client-core/src/test/java/org/apache/olingo/client}/core/serialization/AtomDeserializerTest.java (99%) rename lib/{commons-core/src/test/java/org/apache/olingo/commons => client-core/src/test/java/org/apache/olingo/client}/core/serialization/ContextURLParserTest.java (98%) diff --git a/fit/pom.xml b/fit/pom.xml index b35d5ae80..de9743d44 100644 --- a/fit/pom.xml +++ b/fit/pom.xml @@ -41,6 +41,12 @@ ${project.version} + + org.apache.olingo + odata-client-core + ${project.version} + + org.apache.olingo odata-client-proxy @@ -116,12 +122,6 @@ commons-vfs2 - - org.apache.olingo - odata-client-core - ${project.version} - test - org.apache.olingo odata-server-tecsvc diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java index a5ca33334..690e00497 100644 --- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java +++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java @@ -68,6 +68,11 @@ import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; +import org.apache.olingo.client.api.serialization.ODataDeserializer; +import org.apache.olingo.client.api.serialization.ODataSerializer; +import org.apache.olingo.client.core.serialization.AtomSerializer; +import org.apache.olingo.client.core.serialization.JsonDeserializer; +import org.apache.olingo.client.core.serialization.JsonSerializer; import org.apache.olingo.commons.api.data.ComplexValue; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; @@ -79,12 +84,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.serialization.ODataDeserializer; -import org.apache.olingo.commons.api.serialization.ODataSerializer; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; -import org.apache.olingo.commons.core.serialization.AtomSerializer; -import org.apache.olingo.commons.core.serialization.JsonDeserializer; -import org.apache.olingo.commons.core.serialization.JsonSerializer; import org.apache.olingo.fit.metadata.EntityType; import org.apache.olingo.fit.metadata.Metadata; import org.apache.olingo.fit.metadata.NavigationProperty; diff --git a/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java b/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java index 8ad62feb1..d02475d47 100644 --- a/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java +++ b/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java @@ -27,8 +27,8 @@ import java.nio.charset.CodingErrorAction; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; +import org.apache.olingo.client.core.serialization.AtomDeserializer; import org.apache.olingo.commons.api.Constants; -import org.apache.olingo.commons.core.serialization.AtomDeserializer; public class FITAtomDeserializer extends AtomDeserializer { diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java index 7fa920150..73eae08f7 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java @@ -42,19 +42,19 @@ import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.vfs2.FileObject; +import org.apache.olingo.client.api.serialization.ODataDeserializer; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializer; +import org.apache.olingo.client.api.serialization.ODataSerializerException; +import org.apache.olingo.client.core.serialization.AtomSerializer; +import org.apache.olingo.client.core.serialization.JsonDeserializer; +import org.apache.olingo.client.core.serialization.JsonSerializer; 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.data.Property; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; -import org.apache.olingo.commons.api.serialization.ODataDeserializer; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializer; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; -import org.apache.olingo.commons.core.serialization.AtomSerializer; -import org.apache.olingo.commons.core.serialization.JsonDeserializer; -import org.apache.olingo.commons.core.serialization.JsonSerializer; import org.apache.olingo.fit.UnsupportedMediaTypeException; import org.apache.olingo.fit.metadata.Metadata; import org.apache.olingo.fit.metadata.NavigationProperty; diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java index 02dcadd23..0dad1e673 100644 --- a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java +++ b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java @@ -38,12 +38,12 @@ import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemManager; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.VFS; +import org.apache.olingo.client.api.serialization.ODataSerializerException; +import org.apache.olingo.client.core.serialization.AtomSerializer; +import org.apache.olingo.client.core.serialization.JsonSerializer; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; -import org.apache.olingo.commons.core.serialization.AtomSerializer; -import org.apache.olingo.commons.core.serialization.JsonSerializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/fit/src/test/java/org/apache/olingo/fit/AbstractBaseTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/AbstractBaseTestITCase.java index 523aedd51..58dd2a35d 100644 --- a/fit/src/test/java/org/apache/olingo/fit/AbstractBaseTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/AbstractBaseTestITCase.java @@ -33,10 +33,10 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientValue; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.apache.olingo.fit.server.TomcatTestServer; import org.apache.olingo.server.tecsvc.TechnicalServlet; import org.junit.BeforeClass; diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java index 214ab98dd..b8d58305e 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java @@ -28,6 +28,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.RetrieveReque import org.apache.olingo.client.api.serialization.ClientODataDeserializer; import org.apache.olingo.client.api.serialization.ODataBinder; import org.apache.olingo.client.api.serialization.ODataReader; +import org.apache.olingo.client.api.serialization.ODataSerializer; import org.apache.olingo.client.api.serialization.ODataWriter; import org.apache.olingo.client.api.uri.FilterFactory; import org.apache.olingo.client.api.uri.SearchFactory; @@ -35,7 +36,6 @@ import org.apache.olingo.client.api.uri.URIBuilder; import org.apache.olingo.client.api.domain.ClientObjectFactory; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializer; public interface ODataClient { diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ClientEntitySetIterator.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ClientEntitySetIterator.java index accfce616..801ef1ace 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ClientEntitySetIterator.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ClientEntitySetIterator.java @@ -30,11 +30,11 @@ import java.util.NoSuchElementException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java index 56c2e130a..8317c2292 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ClientODataDeserializer.java @@ -24,8 +24,6 @@ import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.edm.xml.XMLMetadata; import org.apache.olingo.commons.api.data.Delta; import org.apache.olingo.commons.api.data.ResWrap; -import org.apache.olingo.commons.api.serialization.ODataDeserializer; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; public interface ClientODataDeserializer extends ODataDeserializer { diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataDeserializer.java old mode 100755 new mode 100644 similarity index 97% rename from lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataDeserializer.java index d288cf992..e91ba93c0 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializer.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.api.serialization; +package org.apache.olingo.client.api.serialization; import java.io.InputStream; diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataDeserializerException.java old mode 100755 new mode 100644 similarity index 95% rename from lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataDeserializerException.java index e5d7df6f3..c21b8cbdc --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataDeserializerException.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataDeserializerException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.api.serialization; +package org.apache.olingo.client.api.serialization; import org.apache.olingo.commons.api.ODataException; diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java index 7e4aa963f..4360cd848 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataReader.java @@ -30,7 +30,6 @@ import org.apache.olingo.client.api.domain.ClientServiceDocument; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * OData reader. diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataSerializer.java similarity index 95% rename from lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataSerializer.java index 0c0f79585..6d819816a 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializer.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataSerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.api.serialization; +package org.apache.olingo.client.api.serialization; import java.io.Writer; diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataSerializerException.java old mode 100755 new mode 100644 similarity index 95% rename from lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java rename to lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataSerializerException.java index 797c40ae8..b54696e05 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/serialization/ODataSerializerException.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataSerializerException.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.api.serialization; +package org.apache.olingo.client.api.serialization; import org.apache.olingo.commons.api.ODataException; diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java index 5287c94d9..7b5dc5b76 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java @@ -27,7 +27,6 @@ import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientLink; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; /** * OData writer. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientImpl.java index a934e3e2f..c490daeaa 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataClientImpl.java @@ -31,6 +31,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.RetrieveReque import org.apache.olingo.client.api.serialization.ClientODataDeserializer; import org.apache.olingo.client.api.serialization.ODataBinder; import org.apache.olingo.client.api.serialization.ODataReader; +import org.apache.olingo.client.api.serialization.ODataSerializer; import org.apache.olingo.client.api.serialization.ODataWriter; import org.apache.olingo.client.api.uri.FilterFactory; import org.apache.olingo.client.api.uri.SearchFactory; @@ -41,7 +42,9 @@ import org.apache.olingo.client.core.communication.request.batch.BatchRequestFac import org.apache.olingo.client.core.communication.request.cud.CUDRequestFactoryImpl; import org.apache.olingo.client.core.communication.request.invoke.InvokeRequestFactoryImpl; import org.apache.olingo.client.core.communication.request.retrieve.RetrieveRequestFactoryImpl; +import org.apache.olingo.client.core.serialization.AtomSerializer; import org.apache.olingo.client.core.serialization.ClientODataDeserializerImpl; +import org.apache.olingo.client.core.serialization.JsonSerializer; import org.apache.olingo.client.core.serialization.ODataBinderImpl; import org.apache.olingo.client.core.serialization.ODataReaderImpl; import org.apache.olingo.client.core.serialization.ODataWriterImpl; @@ -50,10 +53,7 @@ import org.apache.olingo.client.core.uri.URIBuilderImpl; import org.apache.olingo.client.api.domain.ClientObjectFactory; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializer; import org.apache.olingo.client.core.domain.ClientObjectFactoryImpl; -import org.apache.olingo.commons.core.serialization.AtomSerializer; -import org.apache.olingo.commons.core.serialization.JsonSerializer; public class ODataClientImpl implements ODataClient { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java index 2008149ed..e359e2990 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataErrorResponseChecker.java @@ -24,10 +24,10 @@ import org.apache.http.StatusLine; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.ODataServerErrorException; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.ODataError; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java index b2aba3d49..424ff8f80 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java @@ -34,10 +34,10 @@ import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; /** * This class implements an OData create request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java index 195eaeba2..44ff4715e 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java @@ -35,10 +35,10 @@ import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; /** * This class implements an OData update request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java index a88652fe3..33ec73afa 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java @@ -34,10 +34,10 @@ import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientProperty; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; /** * This class implements an OData update entity property request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataReferenceAddingRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataReferenceAddingRequestImpl.java index 477a91a89..933f22307 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataReferenceAddingRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataReferenceAddingRequestImpl.java @@ -28,6 +28,7 @@ import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.request.cud.ODataReferenceAddingRequest; import org.apache.olingo.client.api.communication.response.ODataReferenceAddingResponse; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.api.serialization.ODataWriter; import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; @@ -35,7 +36,6 @@ import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; /** * See {@link ODataReferenceAddingRequest} diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java index 5bd259c8c..29ad66ec0 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractODataInvokeRequest.java @@ -35,6 +35,8 @@ import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequ import org.apache.olingo.client.api.communication.request.invoke.ClientNoContent; import org.apache.olingo.client.api.communication.response.ODataInvokeResponse; import org.apache.olingo.client.api.http.HttpClientException; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; import org.apache.olingo.client.core.uri.URIUtils; @@ -45,8 +47,6 @@ import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientValue; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; /** * This class implements an OData invoke operation request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataDeltaRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataDeltaRequestImpl.java index 601e4bae0..5eb4d845b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataDeltaRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataDeltaRequestImpl.java @@ -27,11 +27,11 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.request.retrieve.ODataDeltaRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.http.HttpClientException; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.data.Delta; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientDelta; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; public class ODataDeltaRequestImpl extends AbstractODataRetrieveRequest implements ODataDeltaRequest { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java index 57acf2af4..d5a224f73 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java @@ -28,8 +28,8 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements an OData retrieve query request returning a single entity. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java index 620a88df3..7e0164b44 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java @@ -28,8 +28,8 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntitySet; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements an OData EntitySet query request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java index 36e9d0c29..b5a3d105d 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java @@ -27,11 +27,11 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.http.HttpClientException; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements an OData entity property query request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java index 4c22c312f..c29e7ee69 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java @@ -28,12 +28,12 @@ import org.apache.http.client.HttpClient; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest; import org.apache.olingo.client.api.communication.response.ODataRawResponse; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.client.core.communication.request.AbstractODataRequest; import org.apache.olingo.client.core.communication.response.AbstractODataResponse; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements a generic OData request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java index 363ba8741..b4888f488 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java @@ -28,8 +28,8 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientServiceDocument; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements an OData service document request. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java index 175258b7c..1443f8844 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java @@ -33,8 +33,8 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements an OData Media Entity create request. Get instance by using ODataStreamedRequestFactory. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java index d38533eea..8c02eca40 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java @@ -33,8 +33,8 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.http.HttpMethod; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; /** * This class implements an OData Media Entity create request. Get instance by using ODataStreamedRequestFactory. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java index e5bd7bd33..9a95459d4 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java @@ -25,10 +25,10 @@ import java.util.Iterator; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.client.api.data.ServiceDocument; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.core.serialization.JsonDeserializer; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.ResWrap; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.core.serialization.JsonDeserializer; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java index 0b3772290..2e9064c92 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java @@ -23,10 +23,10 @@ import java.io.InputStream; import java.net.URI; import org.apache.olingo.client.api.data.ServiceDocument; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.core.serialization.JsonDeserializer; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.data.ResWrap; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.core.serialization.JsonDeserializer; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractAtomDealer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractAtomDealer.java index d73daca08..242ef31a0 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AbstractAtomDealer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractAtomDealer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import javax.xml.XMLConstants; import javax.xml.namespace.QName; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java index b8b51670b..df88d2792 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.InputStream; import java.net.URI; @@ -35,6 +35,8 @@ import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.serialization.ODataDeserializer; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.ODataError; import org.apache.olingo.commons.api.ODataPropertyType; @@ -58,8 +60,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.geo.Geospatial; import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.serialization.ODataDeserializer; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.core.edm.EdmTypeInfo; import com.fasterxml.aalto.stax.InputFactoryImpl; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomGeoValueDeserializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomGeoValueDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomGeoValueDeserializer.java index 743b78c8f..38add8d77 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomGeoValueDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomGeoValueDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.util.ArrayList; import java.util.Collections; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomGeoValueSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomGeoValueSerializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomGeoValueSerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomGeoValueSerializer.java index 82545596d..103059760 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomGeoValueSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomGeoValueSerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.util.Collections; import java.util.Iterator; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java index ecd7be07f..bc56e48df 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.Writer; import java.net.URI; @@ -29,6 +29,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.serialization.ODataSerializer; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.data.AbstractODataObject; @@ -46,8 +48,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.geo.Geospatial; import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.serialization.ODataSerializer; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.apache.olingo.commons.core.edm.EdmTypeInfo; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java index 92bd57b9a..89dea3784 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ClientODataDeserializerImpl.java @@ -26,6 +26,8 @@ import javax.xml.stream.XMLStreamException; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.edm.xml.XMLMetadata; import org.apache.olingo.client.api.serialization.ClientODataDeserializer; +import org.apache.olingo.client.api.serialization.ODataDeserializer; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.client.core.data.JSONServiceDocumentDeserializer; import org.apache.olingo.client.core.data.XMLServiceDocumentDeserializer; import org.apache.olingo.client.core.edm.xml.ClientCsdlEdmx; @@ -38,11 +40,6 @@ import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.ODataError; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializer; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.core.serialization.AtomDeserializer; -import org.apache.olingo.commons.core.serialization.JsonDeltaDeserializer; -import org.apache.olingo.commons.core.serialization.JsonDeserializer; import com.fasterxml.aalto.stax.InputFactoryImpl; import com.fasterxml.aalto.stax.OutputFactoryImpl; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ContextURLParser.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ContextURLParser.java index 460cd1666..873ca4cae 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ContextURLParser.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.net.URI; import java.util.ArrayList; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeltaDeserializer.java similarity index 96% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeltaDeserializer.java index 89f327fc9..c9b962ad3 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeltaDeserializer.java @@ -16,20 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.io.InputStream; import java.net.URI; import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.DeletedEntity; import org.apache.olingo.commons.api.data.Delta; import org.apache.olingo.commons.api.data.DeltaLink; import org.apache.olingo.commons.api.data.ResWrap; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java old mode 100755 new mode 100644 similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java index 51634122b..ab7093174 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.io.InputStream; @@ -31,6 +31,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.serialization.ODataDeserializer; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.ODataError; import org.apache.olingo.commons.api.ODataPropertyType; @@ -49,8 +51,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.geo.Geospatial; -import org.apache.olingo.commons.api.serialization.ODataDeserializer; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.core.edm.EdmTypeInfo; import com.fasterxml.jackson.core.JsonFactory; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntityDeserializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntityDeserializer.java index 10cc3bbc3..258c02878 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntityDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.net.URI; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySerializer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySerializer.java index ddb789d19..9f2056dde 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java index 354d4ddf2..2fb7b2570 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.net.URI; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetSerializer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetSerializer.java index b7a21da00..6bcf82227 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetSerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonGeoValueDeserializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonGeoValueDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonGeoValueDeserializer.java index 6bd3d7ea8..75aab4ac6 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonGeoValueDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonGeoValueDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.util.ArrayList; import java.util.Collections; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonGeoValueSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonGeoValueSerializer.java similarity index 99% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonGeoValueSerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonGeoValueSerializer.java index 7cd382bef..12ac4f5d4 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonGeoValueSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonGeoValueSerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java index 3636db6ee..2d1f59f54 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.util.ArrayList; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDetailDeserializer.java similarity index 97% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDetailDeserializer.java index 1c6a18778..27a8eb9ef 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonODataErrorDetailDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDetailDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.net.URI; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonPropertyDeserializer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonPropertyDeserializer.java index 8738dd5d4..3a5965028 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonPropertyDeserializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.net.URI; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonPropertySerializer.java similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonPropertySerializer.java index cd2227fef..11c6821ce 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonPropertySerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.net.URI; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java old mode 100755 new mode 100644 similarity index 98% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java rename to lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java index 92ce269d8..484bbfab5 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import java.io.IOException; import java.io.Writer; @@ -28,6 +28,8 @@ import java.util.Map; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.serialization.ODataSerializer; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.Annotatable; import org.apache.olingo.commons.api.data.Annotation; @@ -44,8 +46,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.geo.Geospatial; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializer; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.apache.olingo.commons.core.edm.EdmTypeInfo; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java index adecc20a6..e953cae2a 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java @@ -31,6 +31,7 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.data.ServiceDocumentItem; import org.apache.olingo.client.api.serialization.ODataBinder; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.Annotatable; @@ -87,14 +88,12 @@ import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.geo.Geospatial; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.apache.olingo.client.core.domain.ClientAnnotationImpl; import org.apache.olingo.client.core.domain.ClientDeletedEntityImpl; import org.apache.olingo.client.core.domain.ClientDeltaLinkImpl; import org.apache.olingo.client.core.domain.ClientPropertyImpl; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.commons.core.edm.EdmTypeInfo; -import org.apache.olingo.commons.core.serialization.ContextURLParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java index 6c97cdb2e..6153cdb67 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataReaderImpl.java @@ -27,6 +27,7 @@ import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.api.domain.ClientEntitySetIterator; import org.apache.olingo.client.api.edm.xml.XMLMetadata; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.client.api.serialization.ODataReader; import org.apache.olingo.client.core.edm.ClientCsdlEdmProvider; import org.apache.olingo.commons.api.data.Entity; @@ -43,7 +44,6 @@ import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.core.edm.EdmProviderImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java index c891f1e14..584c4203b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java @@ -29,6 +29,7 @@ import java.util.Collections; import org.apache.commons.io.IOUtils; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.api.serialization.ODataWriter; import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.ResWrap; @@ -36,7 +37,6 @@ import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientLink; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; public class ODataWriterImpl implements ODataWriter { diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/AtomDeserializerTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java similarity index 99% rename from lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/AtomDeserializerTest.java rename to lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java index c1226b2e7..0b793f886 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/AtomDeserializerTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/AtomDeserializerTest.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -25,6 +25,7 @@ import static org.junit.Assert.assertNull; import java.io.ByteArrayInputStream; import java.io.InputStream; +import org.apache.olingo.client.core.serialization.AtomDeserializer; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.ResWrap; diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java similarity index 98% rename from lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java rename to lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java index 7c401e16d..009b100d9 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/ContextURLParserTest.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.olingo.commons.core.serialization; +package org.apache.olingo.client.core.serialization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue; import java.net.URI; +import org.apache.olingo.client.core.serialization.ContextURLParser; import org.apache.olingo.commons.api.data.ContextURL; import org.junit.Test; diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java index 5395472f9..d3746e1c4 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntitySetTest.java @@ -24,8 +24,8 @@ import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.junit.Test; import java.io.IOException; diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java index 057c0de1b..93b43dfbf 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java @@ -19,10 +19,10 @@ package org.apache.olingo.client.core.v4; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.client.core.AbstractTest; import org.apache.olingo.commons.api.ODataError; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.junit.Test; import static org.junit.Assert.assertEquals; diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java index 46e0d222d..b0423e748 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/PropertyTest.java @@ -24,9 +24,9 @@ import org.apache.olingo.client.api.domain.ClientCollectionValue; import org.apache.olingo.client.api.domain.ClientComplexValue; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientValue; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; +import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; -import org.apache.olingo.commons.api.serialization.ODataSerializerException; import org.junit.Test; import java.io.InputStream; diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java index 1a2de09ff..b0a769f76 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java @@ -23,8 +23,8 @@ import org.apache.olingo.client.api.data.ServiceDocument; import org.apache.olingo.client.core.AbstractTest; import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientServiceDocument; +import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.format.ODataFormat; -import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.junit.Test; import java.net.URI; From a298e1fb7c0e8f3669def849557775d5be5c0e1f Mon Sep 17 00:00:00 2001 From: Christian Amend Date: Tue, 16 Jun 2015 14:03:59 +0200 Subject: [PATCH 06/16] [OLINGO-659] FIx felix maven build warnings --- lib/client-api/pom.xml | 1 + lib/client-core/pom.xml | 1 + lib/commons-api/pom.xml | 1 + lib/commons-core/pom.xml | 1 + lib/server-api/pom.xml | 1 + lib/server-core/pom.xml | 1 + 6 files changed, 6 insertions(+) diff --git a/lib/client-api/pom.xml b/lib/client-api/pom.xml index 4bc7b7958..abd541536 100644 --- a/lib/client-api/pom.xml +++ b/lib/client-api/pom.xml @@ -55,6 +55,7 @@ org.apache.felix maven-bundle-plugin + ${maven.bundle.plugin.version} true diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml index 4e6068cbe..ce9fc2842 100644 --- a/lib/client-core/pom.xml +++ b/lib/client-core/pom.xml @@ -80,6 +80,7 @@ org.apache.felix maven-bundle-plugin + ${maven.bundle.plugin.version} true diff --git a/lib/commons-api/pom.xml b/lib/commons-api/pom.xml index 55ca40df9..dc71493d5 100644 --- a/lib/commons-api/pom.xml +++ b/lib/commons-api/pom.xml @@ -60,6 +60,7 @@ org.apache.felix maven-bundle-plugin + ${maven.bundle.plugin.version} true diff --git a/lib/commons-core/pom.xml b/lib/commons-core/pom.xml index c6d6f98fb..8b464a8d1 100644 --- a/lib/commons-core/pom.xml +++ b/lib/commons-core/pom.xml @@ -82,6 +82,7 @@ org.apache.felix maven-bundle-plugin + ${maven.bundle.plugin.version} true diff --git a/lib/server-api/pom.xml b/lib/server-api/pom.xml index 393939f77..0d636f0dc 100644 --- a/lib/server-api/pom.xml +++ b/lib/server-api/pom.xml @@ -56,6 +56,7 @@ org.apache.felix maven-bundle-plugin + ${maven.bundle.plugin.version} true diff --git a/lib/server-core/pom.xml b/lib/server-core/pom.xml index 1c2d1f57d..7d1758e24 100644 --- a/lib/server-core/pom.xml +++ b/lib/server-core/pom.xml @@ -118,6 +118,7 @@ org.apache.felix maven-bundle-plugin + ${maven.bundle.plugin.version} true From e5fe04aeeb1efb22404eec493fc341bf4cd0f251 Mon Sep 17 00:00:00 2001 From: Klaus Straubinger Date: Tue, 16 Jun 2015 16:47:39 +0200 Subject: [PATCH 07/16] [OLINGO-698] technical service supports preferences, part 1 Signed-off-by: Christian Amend --- .../fit/tecsvc/client/ActionImportITCase.java | 201 +++++++++--------- .../olingo/fit/tecsvc/client/BasicITCase.java | 127 ++++++----- .../tecsvc/client/PrimitiveComplexITCase.java | 16 ++ .../client/SystemQueryOptionITCase.java | 23 +- .../olingo/commons/api/http/HttpHeader.java | 15 +- .../processor/TechnicalActionProcessor.java | 180 ++++++++++------ .../processor/TechnicalEntityProcessor.java | 69 ++++-- .../TechnicalPrimitiveComplexProcessor.java | 29 ++- .../options/ServerSidePagingHandler.java | 125 ++++++----- 9 files changed, 486 insertions(+), 299 deletions(-) diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java index 0c40003c4..0e68a4ab7 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java @@ -25,6 +25,7 @@ import static org.junit.Assert.fail; import java.math.BigDecimal; import java.net.URI; import java.util.Calendar; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -32,6 +33,8 @@ import java.util.TimeZone; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; +import org.apache.olingo.client.api.communication.header.HeaderName; +import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest; import org.apache.olingo.client.api.communication.response.ODataInvokeResponse; import org.apache.olingo.client.api.domain.ClientCollectionValue; import org.apache.olingo.client.api.domain.ClientComplexValue; @@ -42,6 +45,7 @@ import org.apache.olingo.client.api.domain.ClientValue; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.format.ODataFormat; +import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.fit.AbstractBaseTestITCase; import org.apache.olingo.fit.tecsvc.TecSvcConst; import org.junit.Test; @@ -50,50 +54,62 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void noReturnTypeAction() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRT").build(); - ODataInvokeResponse response = - getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class).execute(); - assertEquals(204, response.getStatusCode()); - } - - @Test - public void primitveAction() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTString").build(); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRT").build(); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class).execute(); - assertEquals(200, response.getStatusCode()); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + } + + @Test + public void primitiveAction() throws Exception { + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTString").build(); + ODataInvokeResponse response = + getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class).execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); assertEquals("UARTString string value", response.getBody().getPrimitiveValue().toValue()); } @Test - public void primitveActionInvalidParameters() throws Exception { - Map parameters = new HashMap(); - parameters.put("Invalid", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(1)); - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTString").build(); + public void primitiveActionMinimalResponse() throws Exception { + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTString").build(); + ODataInvokeRequest request = getClient().getInvokeRequestFactory() + .getActionInvokeRequest(actionURI, ClientProperty.class); + request.setPrefer(getClient().newPreferences().returnMinimal()); + final ODataInvokeResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next()); + } + + @Test + public void primitiveActionInvalidParameters() throws Exception { + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTString").build(); + Map parameters = Collections.singletonMap("Invalid", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(1)); try { getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class, parameters) - .execute(); + .execute(); fail("Expected an ODataClientErrorException"); } catch (ODataClientErrorException e) { - assertEquals(400, e.getStatusLine().getStatusCode()); + assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode()); } } @Test - public void primitveCollectionAction() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollStringTwoParam").build(); + public void primitiveCollectionAction() throws Exception { + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollStringTwoParam").build(); Map parameters = new HashMap(); parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); - parameters.put("ParameterDuration", getClient().getObjectFactory().newPrimitiveValueBuilder().setType( - EdmPrimitiveTypeKind.Duration).setValue(new BigDecimal(1)).build()); + parameters.put("ParameterDuration", getClient().getObjectFactory().newPrimitiveValueBuilder() + .setType(EdmPrimitiveTypeKind.Duration).setValue(new BigDecimal(1)).build()); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientCollectionValue valueArray = response.getBody().getCollectionValue(); assertEquals(3, valueArray.size()); Iterator iterator = valueArray.iterator(); @@ -104,14 +120,14 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void complexAction() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCTTwoPrimParam").build(); - Map parameters = new HashMap(); - parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCTTwoPrimParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientComplexValue complexValue = response.getBody().getComplexValue(); ClientProperty propInt16 = complexValue.get("PropertyInt16"); assertNotNull(propInt16); @@ -123,28 +139,28 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void complexCollectionActionNoContent() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build(); - Map parameters = new HashMap(); - parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 0)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollCTTwoPrimParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 0)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientCollectionValue complexValueCollection = response.getBody().getCollectionValue(); assertEquals(0, complexValueCollection.size()); } @Test public void complexCollectionActionSubContent() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build(); - Map parameters = new HashMap(); - parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 1)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollCTTwoPrimParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 1)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientCollectionValue complexValueCollection = response.getBody().getCollectionValue(); assertEquals(1, complexValueCollection.size()); Iterator iterator = complexValueCollection.iterator(); @@ -156,14 +172,14 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void complexCollectionActionAllContent() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build(); - Map parameters = new HashMap(); - parameters.put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollCTTwoPrimParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientProperty.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientCollectionValue complexValueCollection = response.getBody().getCollectionValue(); assertEquals(3, complexValueCollection.size()); Iterator iterator = complexValueCollection.iterator(); @@ -183,15 +199,14 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void entityActionETTwoKeyTwoPrim() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTETTwoKeyTwoPrimParam").build(); - Map parameters = new HashMap(); - parameters - .put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) -365)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTETTwoKeyTwoPrimParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) -365)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntity.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientEntity entity = response.getBody(); ClientProperty propInt16 = entity.getProperty("PropertyInt16"); assertNotNull(propInt16); @@ -203,15 +218,14 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void entityCollectionActionETKeyNav() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build(); - Map parameters = new HashMap(); - parameters - .put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollETKeyNavParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 3)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntitySet.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientEntitySet entitySet = response.getBody(); assertEquals(3, entitySet.getEntities().size()); Integer key = 1; @@ -223,51 +237,49 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void entityCollectionActionETKeyNavEmptyCollection() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build(); - Map parameters = new HashMap(); - parameters - .put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 0)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollETKeyNavParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 0)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntitySet.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientEntitySet entitySet = response.getBody(); assertEquals(0, entitySet.getEntities().size()); } @Test public void entityCollectionActionETKeyNavNegativeParam() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build(); - Map parameters = new HashMap(); - parameters - .put("ParameterInt16", getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) -10)); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollETKeyNavParam").build(); + Map parameters = Collections.singletonMap("ParameterInt16", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) -10)); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntitySet.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientEntitySet entitySet = response.getBody(); assertEquals(0, entitySet.getEntities().size()); } @Test public void entityCollectionActionETAllPrim() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollESAllPrimParam").build(); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTCollESAllPrimParam").build(); Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT")); time.clear(); time.set(Calendar.HOUR_OF_DAY, 3); time.set(Calendar.MINUTE, 0); time.set(Calendar.SECOND, 0); - Map parameters = new HashMap(); - parameters - .put("ParameterTimeOfDay", getClient().getObjectFactory().newPrimitiveValueBuilder().setType( - EdmPrimitiveTypeKind.TimeOfDay).setValue(time).build()); + Map parameters = Collections.singletonMap( + "ParameterTimeOfDay", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder() + .setType(EdmPrimitiveTypeKind.TimeOfDay).setValue(time).build()); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntitySet.class, parameters) - .execute(); - assertEquals(200, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); ClientEntitySet entitySet = response.getBody(); assertEquals(3, entitySet.getEntities().size()); Integer key = 1; @@ -279,20 +291,19 @@ public class ActionImportITCase extends AbstractBaseTestITCase { @Test public void entityActionETAllPrim() throws Exception { - URI actionURI = - getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTESAllPrimParam").build(); + final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI) + .appendActionCallSegment("AIRTESAllPrimParam").build(); Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); dateTime.clear(); dateTime.set(1012, 2, 0, 0, 0, 0); - Map parameters = new HashMap(); - parameters - .put("ParameterDate", getClient().getObjectFactory().newPrimitiveValueBuilder().setType( - EdmPrimitiveTypeKind.Date).setValue(dateTime).build()); + Map parameters = Collections.singletonMap( + "ParameterDate", + (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder() + .setType(EdmPrimitiveTypeKind.Date).setValue(dateTime).build()); ODataInvokeResponse response = getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, ClientEntity.class, parameters) - .execute(); - // Check 201 - assertEquals(201, response.getStatusCode()); + .execute(); + assertEquals(HttpStatusCode.CREATED.getStatusCode(), response.getStatusCode()); } @Override 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 819aab7d1..0f3a0995a 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 @@ -37,6 +37,7 @@ import java.util.List; import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; +import org.apache.olingo.client.api.communication.header.HeaderName; import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest; import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest; import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest; @@ -400,6 +401,24 @@ public class BasicITCase extends AbstractBaseTestITCase { assertNull(property2.getPrimitiveValue()); } + @Test + public void createEntityMinimalResponse() throws Exception { + final ODataClient client = getClient(); + final ClientObjectFactory factory = client.getObjectFactory(); + ClientEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETTwoPrim")); + newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyString", + factory.newPrimitiveValueBuilder().buildString("new"))); + ODataEntityCreateRequest request = client.getCUDRequestFactory().getEntityCreateRequest( + client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").build(), + newEntity); + request.setPrefer(getClient().newPreferences().returnMinimal()); + + final ODataEntityCreateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next()); + assertEquals(SERVICE_URI + "/ESTwoPrim(1)", response.getHeader(HttpHeader.LOCATION).iterator().next()); + } + @Test public void readEntityWithExpandedNavigationProperty() { final ODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); @@ -459,30 +478,20 @@ public class BasicITCase extends AbstractBaseTestITCase { entity.getProperties().add( of.newCollectionProperty("CollPropertyComp", of.newCollectionValue("CTPrimComp") - .add( - of.newComplexValue("CTPrimComp") - .add( - of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder() - .buildInt16( - (short) 42))) - .add( - of.newComplexProperty("PropertyComp", of.newComplexValue("CTAllPrim") - .add( - of.newPrimitiveProperty("PropertyString", of - .newPrimitiveValueBuilder() - .buildString("42")))))) - .add( - of.newComplexValue("CTPrimComp") - .add( - of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder() - .buildInt16( - (short) 43))) - .add( - of.newComplexProperty("PropertyComp", of.newComplexValue("CTAllPrim") - .add( - of.newPrimitiveProperty("PropertyString", of - .newPrimitiveValueBuilder() - .buildString("43")))))))); + .add(of.newComplexValue("CTPrimComp") + .add(of.newPrimitiveProperty("PropertyInt16", + of.newPrimitiveValueBuilder().buildInt16((short) 42))) + .add(of.newComplexProperty("PropertyComp", + of.newComplexValue("CTAllPrim") + .add(of.newPrimitiveProperty("PropertyString", + of.newPrimitiveValueBuilder().buildString("42")))))) + .add(of.newComplexValue("CTPrimComp") + .add(of.newPrimitiveProperty("PropertyInt16", + of.newPrimitiveValueBuilder().buildInt16((short) 43))) + .add(of.newComplexProperty("PropertyComp", + of.newComplexValue("CTAllPrim") + .add(of.newPrimitiveProperty("PropertyString", + of.newPrimitiveValueBuilder().buildString("43")))))))); final URI uri = getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment("ESKeyNav") @@ -681,13 +690,15 @@ public class BasicITCase extends AbstractBaseTestITCase { entity.getProperties().add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder() .buildString(null))); - final ODataEntityUpdateResponse updateResponse = client.getCUDRequestFactory() - .getEntityUpdateRequest(targetURI, UpdateType.PATCH, entity) - .execute(); + ODataEntityUpdateRequest request = client.getCUDRequestFactory() + .getEntityUpdateRequest(targetURI, UpdateType.PATCH, entity); + request.setPrefer(getClient().newPreferences().returnRepresentation()); + final ODataEntityUpdateResponse response = request.execute(); - assertEquals(HttpStatusCode.OK.getStatusCode(), updateResponse.getStatusCode()); - assertTrue(updateResponse.getBody().getProperty("PropertyString").hasNullValue()); - assertEquals(34, updateResponse.getBody().getProperty("PropertyDecimal").getPrimitiveValue().toValue()); + assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + assertEquals("return=\"representation\"", response.getHeader(HeaderName.preferenceApplied).iterator().next()); + assertTrue(response.getBody().getProperty("PropertyString").hasNullValue()); + assertEquals(34, response.getBody().getProperty("PropertyDecimal").getPrimitiveValue().toValue()); } @Test(expected = ODataClientErrorException.class) @@ -743,23 +754,23 @@ public class BasicITCase extends AbstractBaseTestITCase { .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany") .build()); entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); - final ODataRetrieveResponse entitytResponse = entityRequest.execute(); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); - assertEquals(HttpStatusCode.OK.getStatusCode(), entitytResponse.getStatusCode()); - assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne") + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + assertEquals(1, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne") .asInlineEntity() .getEntity() .getProperty("PropertyInt16") .getPrimitiveValue() .toValue()); - assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(3, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() .size()); - assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(1, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() @@ -768,7 +779,7 @@ public class BasicITCase extends AbstractBaseTestITCase { .getPrimitiveValue() .toValue()); - assertEquals(2, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(2, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() @@ -777,7 +788,7 @@ public class BasicITCase extends AbstractBaseTestITCase { .getPrimitiveValue() .toValue()); - assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(3, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() @@ -786,7 +797,7 @@ public class BasicITCase extends AbstractBaseTestITCase { .getPrimitiveValue() .toValue()); - final Iterator collectionIterator = entitytResponse.getBody() + final Iterator collectionIterator = entityResponse.getBody() .getProperty("CollPropertyString") .getCollectionValue() .iterator(); @@ -794,7 +805,7 @@ public class BasicITCase extends AbstractBaseTestITCase { assertEquals("Single entry!", collectionIterator.next().asPrimitive().toValue()); assertFalse(collectionIterator.hasNext()); - final ClientComplexValue complexValue = entitytResponse.getBody() + final ClientComplexValue complexValue = entityResponse.getBody() .getProperty("PropertyCompAllPrim") .getComplexValue(); @@ -825,14 +836,14 @@ public class BasicITCase extends AbstractBaseTestITCase { .add(of.newPrimitiveValueBuilder().buildString("Single entry!")))); entity.getProperties().add(of.newComplexProperty("PropertyCompAllPrim", of.newComplexValue("CTAllPrim") - .add(of.newPrimitiveProperty("PropertyString", - of.newPrimitiveValueBuilder().buildString("Changed"))))); + .add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder().buildString("Changed"))))); - final ODataEntityUpdateResponse response = client.getCUDRequestFactory() - .getEntityUpdateRequest(targetURI, UpdateType.REPLACE, entity) - .execute(); - - assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); + ODataEntityUpdateRequest request = client.getCUDRequestFactory() + .getEntityUpdateRequest(targetURI, UpdateType.REPLACE, entity); + request.setPrefer(getClient().newPreferences().returnMinimal()); + final ODataEntityUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next()); final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next(); final ODataEntityRequest entityRequest = client.getRetrieveRequestFactory() @@ -843,23 +854,23 @@ public class BasicITCase extends AbstractBaseTestITCase { .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany") .build()); entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); - final ODataRetrieveResponse entitytResponse = entityRequest.execute(); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); - assertEquals(HttpStatusCode.OK.getStatusCode(), entitytResponse.getStatusCode()); - assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne") + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + assertEquals(1, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne") .asInlineEntity() .getEntity() .getProperty("PropertyInt16") .getPrimitiveValue() .toValue()); - assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(3, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() .size()); - assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(1, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() @@ -868,7 +879,7 @@ public class BasicITCase extends AbstractBaseTestITCase { .getPrimitiveValue() .toValue()); - assertEquals(2, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(2, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() @@ -877,7 +888,7 @@ public class BasicITCase extends AbstractBaseTestITCase { .getPrimitiveValue() .toValue()); - assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + assertEquals(3, entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") .asInlineEntitySet() .getEntitySet() .getEntities() @@ -886,7 +897,7 @@ public class BasicITCase extends AbstractBaseTestITCase { .getPrimitiveValue() .toValue()); - final Iterator collectionIterator = entitytResponse.getBody() + final Iterator collectionIterator = entityResponse.getBody() .getProperty("CollPropertyString") .getCollectionValue() .iterator(); @@ -894,7 +905,7 @@ public class BasicITCase extends AbstractBaseTestITCase { assertEquals("Single entry!", collectionIterator.next().asPrimitive().toValue()); assertFalse(collectionIterator.hasNext()); - final ClientComplexValue propCompAllPrim = entitytResponse.getBody() + final ClientComplexValue propCompAllPrim = entityResponse.getBody() .getProperty("PropertyCompAllPrim") .getComplexValue(); @@ -902,15 +913,15 @@ public class BasicITCase extends AbstractBaseTestITCase { assertTrue(propCompAllPrim.get("PropertyInt16").hasNullValue()); assertTrue(propCompAllPrim.get("PropertyDate").hasNullValue()); - final ClientComplexValue propCompTwoPrim = entitytResponse.getBody() + final ClientComplexValue propCompTwoPrim = entityResponse.getBody() .getProperty("PropertyCompTwoPrim") .getComplexValue(); assertEquals("Must not be null", propCompTwoPrim.get("PropertyString").getPrimitiveValue().toValue()); assertEquals(42, propCompTwoPrim.get("PropertyInt16").getPrimitiveValue().toValue()); - assertNotNull(entitytResponse.getBody().getProperty("PropertyCompNav").getComplexValue()); - assertTrue(entitytResponse.getBody() + assertNotNull(entityResponse.getBody().getProperty("PropertyCompNav").getComplexValue()); + assertTrue(entityResponse.getBody() .getProperty("PropertyCompNav") .getComplexValue() .get("PropertyInt16") 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 1dbd0e616..485aace87 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 @@ -33,6 +33,7 @@ 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.header.HeaderName; 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; @@ -367,6 +368,21 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase { assertEquals("Test String1", IOUtils.toString((InputStream) value.toValue(), "UTF-8")); } + @Test + public void updatePropertyValueMinimalResponse() throws Exception { + ODataValueUpdateRequest request = getClient().getCUDRequestFactory().getValueUpdateRequest( + getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").appendKeySegment(32766) + .appendPropertySegment("PropertyString") + .build(), + UpdateType.REPLACE, + getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test String1")); + request.setPrefer(getClient().newPreferences().returnMinimal()); + + final ODataValueUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next()); + } + @Test public void readPrimitiveCollectionCount() { final ODataValueRequest request = getClient().getRetrieveRequestFactory() diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java index bbd9d51f6..9cd8e3466 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java @@ -25,6 +25,8 @@ import java.net.URI; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; +import org.apache.olingo.client.api.communication.header.HeaderName; +import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; @@ -211,7 +213,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { // Check initial next link format URI nextLink = response.getBody().getNext(); - assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=1", nextLink.toASCIIString()); + assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=1%2A10", nextLink.toASCIIString()); // Check subsequent next links response = client.getRetrieveRequestFactory() @@ -219,7 +221,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { .execute(); nextLink = response.getBody().getNext(); - assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=2", nextLink.toASCIIString()); + assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=2%2A10", nextLink.toASCIIString()); } @Test @@ -236,7 +238,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { // Check initial next link format URI nextLink = response.getBody().getNext(); - assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=1", + assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=1%2A10", nextLink.toASCIIString()); int token = 1; @@ -250,7 +252,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { nextLink = response.getBody().getNext(); if (nextLink != null) { - assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=" + token, + assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=" + token + "%2A10", nextLink.toASCIIString()); } } @@ -258,6 +260,19 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase { assertEquals(50 + 1, token); } + @Test + public void nextLinkFormatWithClientPageSize() { + final ODataClient client = getClient(); + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_SERVER_SIDE_PAGING).build(); + ODataEntitySetRequest request = client.getRetrieveRequestFactory().getEntitySetRequest(uri); + request.setPrefer(getClient().newPreferences().maxPageSize(7)); + + final ODataRetrieveResponse response = request.execute(); + assertEquals("odata.maxpagesize=\"7\"", response.getHeader(HeaderName.preferenceApplied).iterator().next()); + assertEquals(SERVICE_URI + '/' + ES_SERVER_SIDE_PAGING + "?%24skiptoken=1%2A" + 7, + response.getBody().getNext().toASCIIString()); + } + @Test public void testNegativeSkip() { ODataClient client = getClient(); diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java index ab284b1f6..de804fc44 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java @@ -162,12 +162,17 @@ public interface HttpHeader { */ public static final String ODATA_MAX_VERSION = "OData-MaxVersion"; - // CHECKSTYLE:OFF /** - * OData Prefer Header - * See - * {@link OData Version 4.0 Part 1: Protocol Plus Errata 01} + * OData Prefer Header. + * See + * OData Version 4.0 Part 1: Protocol and RFC 7240. */ public static final String PREFER = "Prefer"; - // CHECKSTYLE:ON + + /** + * OData Preference-Applied Header. + * See + * OData Version 4.0 Part 1: Protocol and RFC 7240. + */ + public static final String PREFERENCE_APPLIED = "Preference-Applied"; } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java index da8c5cc38..b2a9ca421 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java @@ -40,6 +40,8 @@ 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.DeserializerResult; +import org.apache.olingo.server.api.prefer.Preferences.Return; +import org.apache.olingo.server.api.prefer.PreferencesApplied; import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor; import org.apache.olingo.server.api.processor.ActionComplexProcessor; import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor; @@ -58,7 +60,7 @@ import org.apache.olingo.server.tecsvc.data.DataProvider; import org.apache.olingo.server.tecsvc.data.EntityActionResult; /** - * Technical Processor for entity-related functionality. + * Technical Processor for action-related functionality. */ public class TechnicalActionProcessor extends TechnicalProcessor implements ActionEntityCollectionProcessor, ActionEntityProcessor, @@ -92,16 +94,26 @@ public class TechnicalActionProcessor extends TechnicalProcessor throw new ODataApplicationException("The action could not be executed.", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); } - final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); - final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); - final ODataFormat format = ODataFormat.fromContentType(responseFormat); - EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions.with() - .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, type, false)) - .build(); - response.setContent(odata.createSerializer(format) - .entityCollection(serviceMetadata, type, collection, options).getContent()); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); + final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); + final ODataFormat format = ODataFormat.fromContentType(responseFormat); + final EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions.with() + .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, type, false)) + .build(); + response.setContent(odata.createSerializer(format) + .entityCollection(serviceMetadata, type, collection, options).getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } } @Override @@ -129,18 +141,32 @@ public class TechnicalActionProcessor extends TechnicalProcessor HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); } } else { - final ODataFormat format = ODataFormat.fromContentType(responseFormat); - response.setContent(odata.createSerializer(format).entity( - serviceMetadata, - type, - entityResult.getEntity(), - EntitySerializerOptions.with() - .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, type, true)) - .build()) - .getContent()); - response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK) - .getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final ODataFormat format = ODataFormat.fromContentType(responseFormat); + response.setContent(odata.createSerializer(format).entity( + serviceMetadata, + type, + entityResult.getEntity(), + EntitySerializerOptions.with() + .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, type, true)) + .build()) + .getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK) + .getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } + if (entityResult.isCreated()) { + response.setHeader(HttpHeader.LOCATION, + request.getRawBaseUri() + '/' + + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entityResult.getEntity())); + } if (entityResult.getEntity().getETag() != null) { response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag()); } @@ -170,17 +196,25 @@ public class TechnicalActionProcessor extends TechnicalProcessor 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(); - PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); - SerializerResult result = - odata.createSerializer(ODataFormat.fromContentType(responseFormat)) - .primitiveCollection(serviceMetadata, type, property, options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); + final ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); + final PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); + final SerializerResult result = + odata.createSerializer(ODataFormat.fromContentType(responseFormat)) + .primitiveCollection(serviceMetadata, type, property, options); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } } @Override @@ -205,15 +239,22 @@ public class TechnicalActionProcessor extends TechnicalProcessor HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); } } else { - ContextURL contextURL = ContextURL.with().type(type).build(); - PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); - - SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat)) - .primitive(serviceMetadata, type, property, options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final ContextURL contextURL = ContextURL.with().type(type).build(); + final PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); + final SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat)) + .primitive(serviceMetadata, type, property, options); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } } } @@ -240,17 +281,25 @@ public class TechnicalActionProcessor extends TechnicalProcessor 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(); - ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); - SerializerResult result = - odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complexCollection(serviceMetadata, type, - property, options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final EdmComplexType type = (EdmComplexType) action.getReturnType().getType(); + final ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); + final ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); + final SerializerResult result = + odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complexCollection(serviceMetadata, type, + property, options); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } } @Override @@ -275,16 +324,23 @@ public class TechnicalActionProcessor extends TechnicalProcessor HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); } } else { - ContextURL contextURL = ContextURL.with().type(type).build(); - ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); - - SerializerResult result = - odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata, type, property, - options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final ContextURL contextURL = ContextURL.with().type(type).build(); + final ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); + final SerializerResult result = + odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata, type, property, + options); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } } } 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 575b914df..217d7689e 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 @@ -40,6 +40,8 @@ import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.deserializer.DeserializerResult; import org.apache.olingo.server.api.deserializer.ODataDeserializer; +import org.apache.olingo.server.api.prefer.PreferencesApplied; +import org.apache.olingo.server.api.prefer.Preferences.Return; import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor; import org.apache.olingo.server.api.processor.EntityCollectionProcessor; import org.apache.olingo.server.api.processor.EntityProcessor; @@ -162,11 +164,20 @@ public class TechnicalEntityProcessor extends TechnicalProcessor expand = deserializerResult.getExpandTree(); } - final ODataFormat format = ODataFormat.fromContentType(responseFormat); - response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, format, expand, null) - .getContent()); - response.setStatusCode(HttpStatusCode.CREATED.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + final ODataFormat format = ODataFormat.fromContentType(responseFormat); + response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, format, expand, null) + .getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.CREATED.getStatusCode()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } response.setHeader(HttpHeader.LOCATION, request.getRawBaseUri() + '/' + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity)); if (entity.getETag() != null) { @@ -209,11 +220,20 @@ 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.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + final ODataFormat format = ODataFormat.fromContentType(responseFormat); + response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, format, null, null) + .getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } if (entity.getETag() != null) { response.setHeader(HttpHeader.ETAG, entity.getETag()); } @@ -234,11 +254,20 @@ public class TechnicalEntityProcessor extends TechnicalProcessor dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), requestFormat.toContentTypeString()); - 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()); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + 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()); + } else { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); + } if (entity.getETag() != null) { response.setHeader(HttpHeader.ETAG, entity.getETag()); } @@ -414,10 +443,12 @@ public class TechnicalEntityProcessor extends TechnicalProcessor SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet); TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet); - ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(), + final Integer pageSize = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getMaxPageSize(); + final Integer serverPageSize = ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(), entitySet, edmEntitySet, - request.getRawRequestUri()); + request.getRawRequestUri(), + pageSize); // Apply expand system query option final ODataFormat format = ODataFormat.fromContentType(requestedContentType); @@ -443,6 +474,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor response.setContent(serializerResult.getContent()); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); + if (pageSize != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().maxPageSize(serverPageSize).build().toString()); + } } private SerializerResult serializeEntityCollection(final EntityCollection entityCollection, 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 1c0d04928..6a9af47ec 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 @@ -48,6 +48,8 @@ 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.prefer.PreferencesApplied; +import org.apache.olingo.server.api.prefer.Preferences.Return; import org.apache.olingo.server.api.processor.ComplexCollectionProcessor; import org.apache.olingo.server.api.processor.ComplexProcessor; import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor; @@ -305,17 +307,26 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor dataProvider.updateETag(entity); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - if (representationType == RepresentationType.VALUE) { - response.setContent( - serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) edmProperty.getType(), null)); + final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); + if (returnPreference == null || returnPreference == Return.REPRESENTATION) { + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + 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()); } 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.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + if (returnPreference != null) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().returnRepresentation(returnPreference).build().toString()); } - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); if (entity.getETag() != null) { response.setHeader(HttpHeader.ETAG, entity.getETag()); } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java index 9c6b68849..71496fd64 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java @@ -34,68 +34,63 @@ public class ServerSidePagingHandler { private static final int MAX_PAGE_SIZE = 10; private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging"; - public static void applyServerSidePaging(final SkipTokenOption skipTokenOption, final EntityCollection entitySet, - final EdmEntitySet edmEntitySet, final String rawRequestUri) throws ODataApplicationException { + /** + *

Applies server-side paging to the given entity collection.

+ *

The next link is constructed and set in the data. It must support client-specified + * page sizes. Therefore, the format page*pageSize (with a literal asterisk) + * has been chosen for the skiptoken.

+ * @param skipTokenOption the current skiptoken option (from a previous response's next link) + * @param entityCollection the data + * @param edmEntitySet the EDM entity set to decide whether paging must be done + * @param rawRequestUri the request URI (used to construct the next link) + * @param preferredPageSize the client's preference for page size + * @return the chosen page size (or null if no paging has been done); + * could be used in the Preference-Applied HTTP header + * @throws ODataApplicationException + */ + public static Integer applyServerSidePaging(final SkipTokenOption skipTokenOption, EntityCollection entityCollection, + final EdmEntitySet edmEntitySet, final String rawRequestUri, final Integer preferredPageSize) + throws ODataApplicationException { if (edmEntitySet != null && shouldApplyServerSidePaging(edmEntitySet)) { - final int maxPageSize = getMaxPageSize(); + final int pageSize = getPageSize(getPageSize(skipTokenOption), preferredPageSize); final int page = getPage(skipTokenOption); - final int itemsToSkip = maxPageSize * page; + final int itemsToSkip = pageSize * page; - if (itemsToSkip <= entitySet.getEntities().size()) { - SkipHandler.popAtMost(entitySet, itemsToSkip); - final int remainingItems = entitySet.getEntities().size(); - TopHandler.reduceToSize(entitySet, maxPageSize); + if (itemsToSkip <= entityCollection.getEntities().size()) { + SkipHandler.popAtMost(entityCollection, itemsToSkip); + final int remainingItems = entityCollection.getEntities().size(); + TopHandler.reduceToSize(entityCollection, pageSize); - // Determine if a new next Link has to be provided - if (remainingItems > maxPageSize) { - entitySet.setNext(createNextLink(rawRequestUri, page + 1)); + // Determine if a new next Link has to be provided. + if (remainingItems > pageSize) { + entityCollection.setNext(createNextLink(rawRequestUri, page + 1, pageSize)); } } else { throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); } + return pageSize; } + return null; } - private static URI createNextLink(final String rawRequestUri, final Integer page) + private static URI createNextLink(final String rawRequestUri, final Integer page, final int pageSize) throws ODataApplicationException { + // Remove a maybe existing skiptoken, making sure that the query part is not empty. + String nextlink = rawRequestUri.contains("?") ? + rawRequestUri.replaceAll("(\\$|%24)skiptoken=.+&?", "").replaceAll("(\\?|&)$", "") : + rawRequestUri; + // Add a question mark or an ampersand, depending on the current query part. + nextlink += nextlink.contains("?") ? '&' : '?'; + + // Append the new skiptoken. try { - // Remove skip token - String nextlink = rawRequestUri; - - // Remove a may existing skiptoken, make sure that the query part is not empty - if (rawRequestUri.contains("?")) { - nextlink = rawRequestUri.replaceAll("(\\$|%24)skiptoken=.+&?", "").replaceAll("(\\?|&)$", ""); - } - - // Add a question mark or an ampersand, depending of the current query part - if (!nextlink.contains("?")) { - nextlink = nextlink + "?"; - } else { - nextlink = nextlink + "&"; - } - - // Append the new nextlink - return new URI(nextlink + Encoder.encode(SystemQueryOptionKind.SKIPTOKEN.toString()) + "=" - + Encoder.encode(page.toString())); - - } catch (URISyntaxException e) { + return new URI(nextlink + Encoder.encode(SystemQueryOptionKind.SKIPTOKEN.toString()) + '=' + + Encoder.encode(page.toString() + '*' + pageSize)); + } catch (final URISyntaxException e) { throw new ODataApplicationException("Exception while constructing next link", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - } - - private static int getPage(final SkipTokenOption skipTokenOption) throws ODataApplicationException { - if (skipTokenOption != null) { - try { - return Integer.parseInt(skipTokenOption.getValue()); - } catch (NumberFormatException e) { - throw new ODataApplicationException("Invalid skip token", HttpStatusCode.BAD_REQUEST.getStatusCode(), - Locale.ROOT); - } - } else { - return 0; + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e); } } @@ -103,8 +98,40 @@ public class ServerSidePagingHandler { return ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName()); } - private static int getMaxPageSize() { - // TODO Consider odata.maxpagesize preference? - return MAX_PAGE_SIZE; + private static int getPageSize(final int skipTokenPageSize, final Integer preferredPageSize) { + return skipTokenPageSize > 0 ? skipTokenPageSize : + preferredPageSize == null || preferredPageSize >= MAX_PAGE_SIZE ? + MAX_PAGE_SIZE : + preferredPageSize; + } + + private static int getPageSize(final SkipTokenOption skipTokenOption) throws ODataApplicationException { + if (skipTokenOption != null && skipTokenOption.getValue().length() >= 3 + && skipTokenOption.getValue().contains("*")) { + final String value = skipTokenOption.getValue(); + try { + return Integer.parseInt(value.substring(value.indexOf('*') + 1)); + } catch (final NumberFormatException e) { + throw new ODataApplicationException("Invalid skip token", HttpStatusCode.BAD_REQUEST.getStatusCode(), + Locale.ROOT, e); + } + } else { + return 0; + } + } + + private static int getPage(final SkipTokenOption skipTokenOption) throws ODataApplicationException { + if (skipTokenOption != null && skipTokenOption.getValue().length() >= 3 + && skipTokenOption.getValue().contains("*")) { + final String value = skipTokenOption.getValue(); + try { + return Integer.parseInt(value.substring(0, value.indexOf('*'))); + } catch (final NumberFormatException e) { + throw new ODataApplicationException("Invalid skip token", HttpStatusCode.BAD_REQUEST.getStatusCode(), + Locale.ROOT, e); + } + } else { + return 0; + } } } From 0938f1179df9e22710e60b06c1e240b2ab4d9db0 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Tue, 16 Jun 2015 21:20:02 +0200 Subject: [PATCH 08/16] [OLINGO-659] Minor code clean up, javadoc and typo fixes --- .../apache/olingo/server/api/uri/UriInfo.java | 19 +++++++++---------- .../server/api/uri/UriInfoEntityId.java | 13 ++++++------- .../server/api/uri/UriInfoMetadata.java | 4 ++-- .../olingo/server/api/uri/UriParameter.java | 11 +++++------ .../server/api/uri/UriResourceFunction.java | 2 +- .../server/api/uri/UriResourceLambdaAll.java | 5 ++--- .../server/api/uri/UriResourceLambdaAny.java | 4 ++-- .../api/uri/UriResourceLambdaVariable.java | 3 +-- .../server/api/uri/UriResourceNavigation.java | 2 +- .../core/uri/UriResourceLambdaAnyImpl.java | 2 +- .../core/uri/UriResourceWithKeysImpl.java | 17 +++++++++-------- .../server/core/uri/UriResourceImplTest.java | 2 +- .../core/uri/testutil/FilterTreeToText.java | 2 +- .../core/uri/testutil/ResourceValidator.java | 2 +- 14 files changed, 42 insertions(+), 46 deletions(-) diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfo.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfo.java index c7f1e7e0f..ead6113a1 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfo.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfo.java @@ -31,22 +31,21 @@ public interface UriInfo extends UriInfoService, UriInfoAll, UriInfoBatch, UriInfoCrossjoin, UriInfoEntityId, UriInfoMetadata, UriInfoResource { - public UriInfoKind getKind(); + UriInfoKind getKind(); - public UriInfoService asUriInfoService(); + UriInfoService asUriInfoService(); - public UriInfoAll asUriInfoAll(); + UriInfoAll asUriInfoAll(); - public UriInfoBatch asUriInfoBatch(); + UriInfoBatch asUriInfoBatch(); - public UriInfoCrossjoin asUriInfoCrossjoin(); + UriInfoCrossjoin asUriInfoCrossjoin(); - public UriInfoEntityId asUriInfoEntityId(); + UriInfoEntityId asUriInfoEntityId(); - public UriInfoMetadata asUriInfoMetadata(); + UriInfoMetadata asUriInfoMetadata(); - public UriInfoResource asUriInfoResource(); - - public Collection getSystemQueryOptions(); + UriInfoResource asUriInfoResource(); + Collection getSystemQueryOptions(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoEntityId.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoEntityId.java index 6736ddcdc..2579b6db9 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoEntityId.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoEntityId.java @@ -36,33 +36,32 @@ public interface UriInfoEntityId { /** * @return List of custom query options used in the URI */ - public List getCustomQueryOptions(); + List getCustomQueryOptions(); /** * Behind $entity a optional type cast can be used in the URI. * For example: http://.../serviceroot/$entity/namespace.entitytype * @return Type cast if found, otherwise null */ - public EdmEntityType getEntityTypeCast(); + EdmEntityType getEntityTypeCast(); /** * @return Object containing information of the $expand option */ - public ExpandOption getExpandOption(); + ExpandOption getExpandOption(); /** * @return Object containing information of the $format option */ - public FormatOption getFormatOption(); + FormatOption getFormatOption(); /** * @return Object containing information of the $id option */ - public IdOption getIdOption(); + IdOption getIdOption(); /** * @return Object containing information of the $select option */ - public SelectOption getSelectOption(); - + SelectOption getSelectOption(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoMetadata.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoMetadata.java index b16f76c13..7bf8d91fb 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoMetadata.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriInfoMetadata.java @@ -29,11 +29,11 @@ public interface UriInfoMetadata { /** * @return Object containing information of the $id option */ - public FormatOption getFormatOption(); + FormatOption getFormatOption(); /** * @return Object containing information of the URI fragment */ - public String getFragment(); + String getFragment(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java index db2f9d0e2..ab8bfec2c 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java @@ -28,26 +28,25 @@ public interface UriParameter { /** * @return Alias name if the parameters values is an alias, otherwise null */ - public String getAlias(); + String getAlias(); /** * @return Text of the parameters value */ - public String getText(); + String getText(); /** * @return If the parameters value is a expression and expression is returned, otherwise null */ - public Expression getExpression(); + Expression getExpression(); /** * @return Name of the parameter */ - public String getName(); + String getName(); /** * @return Name of the referenced property when referential constrains are used */ - public String getReferencedProperty(); - + String getReferencedProperty(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceFunction.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceFunction.java index d92dd8907..f509bd722 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceFunction.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceFunction.java @@ -45,7 +45,7 @@ public interface UriResourceFunction extends UriResourcePartTyped { EdmFunctionImport getFunctionImport(); /** - * @return Key predicates if used, otherwise null + * @return Key predicates if used, otherwise an empty list */ List getKeyPredicates(); diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAll.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAll.java index cbb9edfc6..2abe93e1b 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAll.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAll.java @@ -29,11 +29,10 @@ public interface UriResourceLambdaAll extends UriResourcePartTyped { /** * @return Name of the lambda variable */ - public String getLambdaVariable(); + String getLambdaVariable(); /** * @return Lambda expression */ - public Expression getExpression(); - + Expression getExpression(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAny.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAny.java index 890828477..198ac3ceb 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAny.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaAny.java @@ -29,11 +29,11 @@ public interface UriResourceLambdaAny extends UriResourcePartTyped { /** * @return Name of the lambda variable */ - public String getLamdaVariable(); + String getLambdaVariable(); /** * @return Lambda expression */ - public Expression getExpression(); + Expression getExpression(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaVariable.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaVariable.java index 67a5d3d48..376e88fff 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaVariable.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceLambdaVariable.java @@ -27,6 +27,5 @@ public interface UriResourceLambdaVariable extends UriResourcePartTyped { /** * @return Name of the lambda variable */ - public String getVariableName(); - + String getVariableName(); } diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceNavigation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceNavigation.java index 3ef4c059f..fab09a3e3 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceNavigation.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriResourceNavigation.java @@ -35,7 +35,7 @@ public interface UriResourceNavigation extends UriResourcePartTyped { EdmNavigationProperty getProperty(); /** - * @return Key predicates if used, otherwise null + * @return Key predicates if used, otherwise an empty list */ List getKeyPredicates(); diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java index e66a37c44..81059dd9d 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java @@ -50,7 +50,7 @@ public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements Ur } @Override - public String getLamdaVariable() { + public String getLambdaVariable() { return lambdaVariable; } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java index aef580017..320ad0d7f 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java @@ -73,29 +73,30 @@ public abstract class UriResourceWithKeysImpl extends UriResourceImpl implements @Override public String toString(final boolean includeFilters) { - if (includeFilters == true) { - String tmp = ""; + if (includeFilters) { + StringBuilder tmp = new StringBuilder(); if (collectionTypeFilter != null) { - tmp += getFQN(collectionTypeFilter).toString(); + tmp.append(getFQN(collectionTypeFilter)); } if (entryTypeFilter != null) { if (tmp.length() == 0) { - tmp = getFQN(entryTypeFilter).toString(); + tmp.append(getFQN(entryTypeFilter)); } else { - tmp += "/()" + getFQN(entryTypeFilter).toString(); + tmp.append("/()").append(getFQN(entryTypeFilter)); } } + if (tmp.length() != 0) { - return toString() + "/" + tmp; + return toString() + "/" + tmp.toString(); } } return toString(); } - private FullQualifiedName getFQN(final EdmType type) { - return new FullQualifiedName(type.getNamespace(), type.getName()); + private String getFQN(final EdmType type) { + return new FullQualifiedName(type.getNamespace(), type.getName()).getFullQualifiedNameAsString(); } } \ No newline at end of file diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java index 1945fe583..e9f16ea69 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java @@ -125,7 +125,7 @@ public class UriResourceImplTest { assertEquals(false, impl.isCollection()); assertEquals(expression, impl.getExpression()); - assertEquals("A", impl.getLamdaVariable()); + assertEquals("A", impl.getLambdaVariable()); assertEquals(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean), impl.getType()); assertEquals("any", impl.toString()); } diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java index d24c77fa0..7b0752f41 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java @@ -97,7 +97,7 @@ public class FilterTreeToText implements ExpressionVisitor { tmp = visitLambdaExpression("ALL", all.getLambdaVariable(), all.getExpression()); } else if (item instanceof UriResourceLambdaAny) { UriResourceLambdaAny any = (UriResourceLambdaAny) item; - tmp = visitLambdaExpression("ANY", any.getLamdaVariable(), any.getExpression()); + tmp = visitLambdaExpression("ANY", any.getLambdaVariable(), any.getExpression()); } else if (item instanceof UriResourcePartTyped) { UriResourcePartTyped typed = (UriResourcePartTyped) item; tmp = typed.toString(true); diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ResourceValidator.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ResourceValidator.java index 817602a5a..f6c99378a 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ResourceValidator.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ResourceValidator.java @@ -224,7 +224,7 @@ public class ResourceValidator implements TestValidator { if (uriPathInfo.getKind() == UriResourceKind.lambdaAll) { actualVar = ((UriResourceLambdaAllImpl) uriPathInfo).getLambdaVariable(); } else if (uriPathInfo.getKind() == UriResourceKind.lambdaAny) { - actualVar = ((UriResourceLambdaAnyImpl) uriPathInfo).getLamdaVariable(); + actualVar = ((UriResourceLambdaAnyImpl) uriPathInfo).getLambdaVariable(); } else { fail("invalid resource kind: " + uriPathInfo.getKind().toString()); } From afda326d7538ddb970fd4237321d1c420b8ac31b Mon Sep 17 00:00:00 2001 From: Klaus Straubinger Date: Wed, 17 Jun 2015 09:59:23 +0200 Subject: [PATCH 09/16] [OLINGO-698] technical service supports preferences, part 2 Signed-off-by: Christian Amend --- .../fit/tecsvc/client/BatchClientITCase.java | 64 ++++----- .../deserializer/batch/ODataResponsePart.java | 29 ++-- .../core/batchhandler/BatchPartHandler.java | 14 +- .../apache/olingo/server/tecsvc/Encoder.java | 132 ------------------ .../processor/TechnicalBatchProcessor.java | 26 ++-- .../options/ServerSidePagingHandler.java | 12 +- 6 files changed, 64 insertions(+), 213 deletions(-) delete mode 100644 lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/Encoder.java diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java index 72a4ef394..e56165dbf 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java @@ -60,7 +60,6 @@ import org.junit.Before; import org.junit.Test; public class BatchClientITCase extends AbstractTestITCase { - private final static String ACCEPT = ContentType.APPLICATION_OCTET_STREAM.toContentTypeString(); private static final String SERVICE_URI = TecSvcConst.BASE_URI; private static final String SERVICE_NAMESPACE = "olingo.odata.test1"; private static final String ES_NOT_AVAILABLE_NAME = "ESNotAvailable"; @@ -70,6 +69,7 @@ public class BatchClientITCase extends AbstractTestITCase { @Before public void setup() { + client.getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM); client.getConfiguration().setContinueOnError(false); } @@ -98,7 +98,6 @@ public class BatchClientITCase extends AbstractTestITCase { entity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder() .buildString("1"))); final ODataBatchRequest batchRequest = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - batchRequest.setAccept(ACCEPT); final BatchManager payloadManager = batchRequest.payloadManager(); final ODataChangeset changeset = payloadManager.addChangeset(); final URI targetURI = client.newURIBuilder(SERVICE_URI) @@ -130,12 +129,11 @@ public class BatchClientITCase extends AbstractTestITCase { public void emptyBatchRequest() { // create your request final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); assertEquals("Accepted", response.getStatusMessage()); final Iterator iter = response.getBody(); @@ -145,7 +143,6 @@ public class BatchClientITCase extends AbstractTestITCase { @Test public void getBatchRequestWithRelativeUris() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); @@ -155,7 +152,7 @@ public class BatchClientITCase extends AbstractTestITCase { // Fetch result final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); assertEquals("Accepted", response.getStatusMessage()); final Iterator iter = response.getBody(); @@ -177,7 +174,6 @@ public class BatchClientITCase extends AbstractTestITCase { @Test public void getBatchRequest() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); @@ -187,7 +183,7 @@ public class BatchClientITCase extends AbstractTestITCase { // Fetch result final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); assertEquals("Accepted", response.getStatusMessage()); final Iterator iter = response.getBody(); @@ -209,7 +205,6 @@ public class BatchClientITCase extends AbstractTestITCase { @Test public void testErrorWithoutContinueOnErrorPreferHeader() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); @@ -219,7 +214,7 @@ public class BatchClientITCase extends AbstractTestITCase { // Fetch result final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); final Iterator iter = response.getBody(); @@ -253,7 +248,6 @@ public class BatchClientITCase extends AbstractTestITCase { @Test public void testInvalidAbsoluteUri() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); final URI uri = new URI(SERVICE_URI + "/../ESAllPrim(32767)"); @@ -263,7 +257,7 @@ public class BatchClientITCase extends AbstractTestITCase { // Fetch result final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); final Iterator bodyIterator = response.getBody(); assertTrue(bodyIterator.hasNext()); @@ -272,13 +266,12 @@ public class BatchClientITCase extends AbstractTestITCase { assertFalse(item.isChangeset()); final ODataResponse oDataResponse = item.next(); - assertEquals(400, oDataResponse.getStatusCode()); + assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), oDataResponse.getStatusCode()); } @Test(expected = HttpClientException.class) public void testInvalidHost() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); final URI uri = new URI("http://otherhost/odata/ESAllPrim(32767)"); @@ -293,7 +286,6 @@ public class BatchClientITCase extends AbstractTestITCase { @Test(expected = HttpClientException.class) public void testInvalidAbsoluteRequest() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); final URI uri = new URI("/ESAllPrim(32767)"); @@ -306,10 +298,9 @@ public class BatchClientITCase extends AbstractTestITCase { } @Test - public void testErrorWithContinueOnErrorPreferHeader() throws URISyntaxException { + public void errorWithContinueOnErrorPreferHeader() throws Exception { client.getConfiguration().setContinueOnError(true); final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); @@ -319,7 +310,8 @@ public class BatchClientITCase extends AbstractTestITCase { // Fetch result final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); + assertEquals("odata.continue-on-error", response.getHeader(HttpHeader.PREFERENCE_APPLIED).iterator().next()); final Iterator bodyIterator = response.getBody(); @@ -331,10 +323,10 @@ public class BatchClientITCase extends AbstractTestITCase { ODataResponse oDataResonse = item.next(); assertNotNull(oDataResonse); assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode()); - assertEquals(1, oDataResonse.getHeader("OData-Version").size()); - assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]); - assertEquals(1, oDataResonse.getHeader("Content-Length").size()); - assertEquals("605", oDataResonse.getHeader("Content-Length").toArray()[0]); + assertEquals(1, oDataResonse.getHeader(HttpHeader.ODATA_VERSION).size()); + assertEquals("4.0", oDataResonse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]); + assertEquals(1, oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).size()); + assertEquals("605", oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]); assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType()); // Check second get request @@ -354,20 +346,18 @@ public class BatchClientITCase extends AbstractTestITCase { oDataResonse = item.next(); assertNotNull(oDataResonse); assertEquals(HttpStatusCode.OK.getStatusCode(), oDataResonse.getStatusCode()); - assertEquals(1, oDataResonse.getHeader("OData-Version").size()); - assertEquals("4.0", oDataResonse.getHeader("OData-Version").toArray()[0]); - assertEquals(1, oDataResonse.getHeader("Content-Length").size()); - assertEquals("513", oDataResonse.getHeader("Content-Length").toArray()[0]); + assertEquals(1, oDataResonse.getHeader(HttpHeader.ODATA_VERSION).size()); + assertEquals("4.0", oDataResonse.getHeader(HttpHeader.ODATA_VERSION).toArray()[0]); + assertEquals(1, oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).size()); + assertEquals("513", oDataResonse.getHeader(HttpHeader.CONTENT_LENGTH).toArray()[0]); assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType()); } @Test - @SuppressWarnings("unchecked") public void changesetWithReferences() throws EdmPrimitiveTypeException, URISyntaxException { // create your request final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); final ClientObjectFactory of = client.getObjectFactory(); - request.setAccept(ACCEPT); final BatchManager streamManager = request.payloadManager(); final ODataChangeset changeset = streamManager.addChangeset(); @@ -421,7 +411,7 @@ public class BatchClientITCase extends AbstractTestITCase { ODataResponse res = chgitem.next(); assertEquals(HttpStatusCode.CREATED.getStatusCode(), res.getStatusCode()); assertTrue(res instanceof ODataEntityCreateResponse); - final ODataEntityCreateResponse createResponse = ((ODataEntityCreateResponse) res); + final ODataEntityCreateResponse createResponse = ((ODataEntityCreateResponse) res); res = chgitem.next(); assertEquals(HttpStatusCode.OK.getStatusCode(), res.getStatusCode()); @@ -442,11 +432,9 @@ public class BatchClientITCase extends AbstractTestITCase { } @Test - @SuppressWarnings("unchecked") public void changesetBatchRequest() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); final ClientObjectFactory of = client.getObjectFactory(); - request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); // ----------------------------- @@ -530,7 +518,7 @@ public class BatchClientITCase extends AbstractTestITCase { // - Fetch result // ----------------------------- final ODataBatchResponse response = payload.getResponse(); - assertEquals(202, response.getStatusCode()); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); final Iterator bodyIterator = response.getBody(); // Check first get request @@ -540,7 +528,9 @@ public class BatchClientITCase extends AbstractTestITCase { assertTrue(item.hasNext()); final ODataResponse response0 = item.next(); assertTrue(response0 instanceof ODataRetrieveResponse); - assertEquals(34, ((ODataRetrieveResponse) response0).getBody() + @SuppressWarnings("unchecked") + ODataRetrieveResponse retrieveResponse = (ODataRetrieveResponse) response0; + assertEquals(34, retrieveResponse.getBody() .getProperty("PropertyDecimal") .getPrimitiveValue() .toValue()); @@ -555,7 +545,7 @@ public class BatchClientITCase extends AbstractTestITCase { final ODataResponse response1 = item.next(); assertEquals(HttpStatusCode.CREATED.getStatusCode(), response1.getStatusCode()); assertTrue(response1 instanceof ODataEntityCreateResponse); - assertEquals(3.1415, ((ODataEntityCreateResponse) response1).getBody().getProperty("PropertyDouble") + assertEquals(3.1415, ((ODataEntityCreateResponse) response1).getBody().getProperty("PropertyDouble") .getPrimitiveValue() .toValue()); // Update @@ -569,7 +559,7 @@ public class BatchClientITCase extends AbstractTestITCase { final ODataResponse response3 = item.next(); assertEquals(HttpStatusCode.CREATED.getStatusCode(), response3.getStatusCode()); assertTrue(response3 instanceof ODataEntityUpdateResponse); - assertEquals(3.1415, ((ODataEntityUpdateResponse) response3).getBody().getProperty("PropertyDouble") + assertEquals(3.1415, ((ODataEntityUpdateResponse) response3).getBody().getProperty("PropertyDouble") .getPrimitiveValue() .toValue()); @@ -580,7 +570,9 @@ public class BatchClientITCase extends AbstractTestITCase { assertTrue(item.hasNext()); final ODataResponse response4 = item.next(); assertTrue(response4 instanceof ODataRetrieveResponse); - assertEquals(3.1415, ((ODataRetrieveResponse) response4).getBody() + @SuppressWarnings("unchecked") + final ODataRetrieveResponse retrieveResponse2 = (ODataRetrieveResponse) response4; + assertEquals(3.1415, retrieveResponse2.getBody() .getProperty("PropertyDouble") .getPrimitiveValue() .toValue()); diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/batch/ODataResponsePart.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/batch/ODataResponsePart.java index 56c0084ce..8b0bd5225 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/batch/ODataResponsePart.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/batch/ODataResponsePart.java @@ -24,23 +24,23 @@ import java.util.List; import org.apache.olingo.server.api.ODataResponse; /** - * An ODataResponsePart represents a collections of ODataResponses. + * An ODataResponsePart represents a collection of ODataResponses. * A list of ODataResponseParts can be combined by the BatchSerializer to a single * OData batch response. */ public class ODataResponsePart { - private List responses; - private boolean isChangeSet; + private final List responses; + private final boolean isChangeSet; /** * Creates a new ODataResponsePart. * - * An ODataResponsePart represents a collections of ODataResponses. + * An ODataResponsePart represents a collection of ODataResponses. * A list of ODataResponseParts can be combined by the BatchSerializer to a single * OData batch response. * * @param responses A list of {@link ODataResponse} - * @param isChangeSet True this ODataResponsePart represents a change set, otherwise false + * @param isChangeSet whether this ODataResponsePart represents a change set */ public ODataResponsePart(final List responses, final boolean isChangeSet) { this.responses = responses; @@ -50,12 +50,12 @@ public class ODataResponsePart { /** * Creates a new ODataResponsePart. * - * An ODataResponsePart represents a collections of ODataResponses. + * An ODataResponsePart represents a collection of ODataResponses. * A list of ODataResponseParts can be combined by the BatchSerializer to a single * OData batch response. * * @param response A single {@link ODataResponse} - * @param isChangeSet True this ODataResponsePart represents a change set, otherwise false + * @param isChangeSet whether this ODataResponsePart represents a change set */ public ODataResponsePart(final ODataResponse response, final boolean isChangeSet) { responses = Arrays.asList(response); @@ -63,21 +63,18 @@ public class ODataResponsePart { } /** - * Returns true if the current instance represents a change set. - * - * @return true or false + * Returns a collection of ODataResponses. + * Each collection contains at least one {@link ODataResponse}. + * If this instance represents a change set, there may be many ODataResponses. + * @return a list of {@link ODataResponse} */ public List getResponses() { return responses; } /** - * Returns a collection of ODataResponses. - * Each collections contains at least one {@link ODataResponse}. - * - * If this instance represents a change set, there are may many ODataResponses - * - * @return a list of {@link ODataResponse} + * Returns true if the current instance represents a change set. + * @return true or false */ public boolean isChangeSet() { return isChangeSet; diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchPartHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchPartHandler.java index c3cf73aa0..de1dcb1d0 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchPartHandler.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchPartHandler.java @@ -34,14 +34,14 @@ import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon; public class BatchPartHandler { private final ODataHandler oDataHandler; private final BatchProcessor batchProcessor; - private final BatchFacade batchFascade; + private final BatchFacade batchFacade; private final BatchReferenceRewriter rewriter; public BatchPartHandler(final ODataHandler oDataHandler, final BatchProcessor processor, - final BatchFacade batchFascade) { + final BatchFacade batchFacade) { this.oDataHandler = oDataHandler; batchProcessor = processor; - this.batchFascade = batchFascade; + this.batchFacade = batchFacade; rewriter = new BatchReferenceRewriter(); } @@ -49,8 +49,8 @@ public class BatchPartHandler { return handle(request, true); } - public ODataResponsePart handleBatchRequest(final BatchRequestPart request) throws ODataApplicationException, - ODataLibraryException { + public ODataResponsePart handleBatchRequest(final BatchRequestPart request) + throws ODataApplicationException, ODataLibraryException { if (request.isChangeSet()) { return handleChangeSet(request); } else { @@ -62,7 +62,7 @@ public class BatchPartHandler { public ODataResponse handle(final ODataRequest request, final boolean isChangeSet) throws BatchDeserializerException { - final ODataResponse response; + ODataResponse response; if (isChangeSet) { rewriter.replaceReference(request); @@ -85,7 +85,7 @@ public class BatchPartHandler { private ODataResponsePart handleChangeSet(final BatchRequestPart request) throws ODataApplicationException, ODataLibraryException { - return batchProcessor.processChangeSet(batchFascade, request.getRequests()); + return batchProcessor.processChangeSet(batchFacade, request.getRequests()); } } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/Encoder.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/Encoder.java deleted file mode 100644 index 33956b5a2..000000000 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/Encoder.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ******************************************************************************/ -package org.apache.olingo.server.tecsvc; - -import java.io.UnsupportedEncodingException; - -/** - * Encodes a Java String (in its internal UTF-16 encoding) into its - * percent-encoded UTF-8 representation according to - * RFC 3986 - * (with consideration of its predecessor RFC 2396). - * - */ -public class Encoder { - - // TODO: Should we really copy this class? - - /** - * Encodes a Java String (in its internal UTF-16 encoding) into its - * percent-encoded UTF-8 representation according to - * RFC 3986, - * suitable for parts of an OData path segment. - * @param value the Java String - * @return the encoded String - */ - public static String encode(final String value) { - return encoder.encodeInternal(value); - } - - // OData has special handling for "'", so we allow that to remain unencoded. - // Other sub-delims not used neither by JAX-RS nor by OData could be added - // if the encoding is considered to be too aggressive. - // RFC 3986 would also allow the gen-delims ":" and "@" to appear literally - // in path-segment parts. - private static final String ODATA_UNENCODED = "'"; - - // Character classes from RFC 3986 - private final static String UNRESERVED = "-._~"; // + ALPHA + DIGIT - // RFC 3986 says: "For consistency, URI producers and normalizers should - // use uppercase hexadecimal digits for all percent-encodings." - private final static String[] hex = { "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09", "%0A", - "%0B", "%0C", "%0D", "%0E", "%0F", "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", "%18", "%19", "%1A", - "%1B", "%1C", "%1D", "%1E", "%1F", "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27", "%28", "%29", "%2A", - "%2B", "%2C", "%2D", "%2E", "%2F", "%30", "%31", "%32", "%33", "%34", "%35", "%36", "%37", "%38", "%39", "%3A", - "%3B", "%3C", "%3D", "%3E", "%3F", "%40", "%41", "%42", "%43", "%44", "%45", "%46", "%47", "%48", "%49", "%4A", - "%4B", "%4C", "%4D", "%4E", "%4F", "%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57", "%58", "%59", "%5A", - "%5B", "%5C", "%5D", "%5E", "%5F", "%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67", "%68", "%69", "%6A", - "%6B", "%6C", "%6D", "%6E", "%6F", "%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77", "%78", "%79", "%7A", - "%7B", "%7C", "%7D", "%7E", "%7F", "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", "%88", - "%89", "%8A", "%8B", "%8C", "%8D", "%8E", "%8F", "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", "%98", - "%99", "%9A", "%9B", "%9C", "%9D", "%9E", "%9F", "%A0", "%A1", "%A2", "%A3", "%A4", "%A5", "%A6", "%A7", "%A8", - "%A9", "%AA", "%AB", "%AC", "%AD", "%AE", "%AF", "%B0", "%B1", "%B2", "%B3", "%B4", "%B5", "%B6", "%B7", "%B8", - "%B9", "%BA", "%BB", "%BC", "%BD", "%BE", "%BF", "%C0", "%C1", "%C2", "%C3", "%C4", "%C5", "%C6", "%C7", "%C8", - "%C9", "%CA", "%CB", "%CC", "%CD", "%CE", "%CF", "%D0", "%D1", "%D2", "%D3", "%D4", "%D5", "%D6", "%D7", "%D8", - "%D9", "%DA", "%DB", "%DC", "%DD", "%DE", "%DF", "%E0", "%E1", "%E2", "%E3", "%E4", "%E5", "%E6", "%E7", "%E8", - "%E9", "%EA", "%EB", "%EC", "%ED", "%EE", "%EF", "%F0", "%F1", "%F2", "%F3", "%F4", "%F5", "%F6", "%F7", "%F8", - "%F9", "%FA", "%FB", "%FC", "%FD", "%FE", "%FF" }; - - private static final Encoder encoder = new Encoder(ODATA_UNENCODED); - - /** characters to remain unencoded in addition to {@link #UNRESERVED} */ - private final String unencoded; - - private Encoder(final String unencoded) { - this.unencoded = unencoded == null ? "" : unencoded; - } - - /** - *

Returns the percent-encoded UTF-8 representation of a String.

- *

In order to avoid producing percent-encoded CESU-8 (as described in - * the Unicode Consortium's - * Technical Report #26), this is done in two steps: - *

    - *
  1. Re-encode the characters from their Java-internal UTF-16 representations - * into their UTF-8 representations.
  2. - *
  3. Percent-encode each of the bytes in the UTF-8 representation. - * This is possible on byte level because all characters that do not have - * a %xx representation are represented in one byte in UTF-8.
  4. - *

- * @param input input String - * @return encoded representation - */ - private String encodeInternal(final String input) { - StringBuilder resultStr = new StringBuilder(); - - try { - for (byte utf8Byte : input.getBytes("UTF-8")) { - final char character = (char) utf8Byte; - if (isUnreserved(character)) { - resultStr.append(character); - } else if (isUnencoded(character)) { - resultStr.append(character); - } else if (utf8Byte >= 0) { - resultStr.append(hex[utf8Byte]); - } else { - // case UTF-8 continuation byte - resultStr.append(hex[256 + utf8Byte]); // index adjusted for the usage of signed bytes - } - } - } catch (final UnsupportedEncodingException e) { // should never happen; UTF-8 is always there - return null; - } - return resultStr.toString(); - } - - private static boolean isUnreserved(final char character) { - return 'A' <= character && character <= 'Z' // case A..Z - || 'a' <= character && character <= 'z' // case a..z - || '0' <= character && character <= '9' // case 0..9 - || UNRESERVED.indexOf(character) >= 0; - } - - private boolean isUnencoded(final char character) { - return unencoded.indexOf(character) >= 0; - } -} diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java index b96ab827e..fbdeb908c 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java @@ -34,11 +34,11 @@ import org.apache.olingo.server.api.batch.BatchFacade; import org.apache.olingo.server.api.deserializer.batch.BatchOptions; import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart; import org.apache.olingo.server.api.deserializer.batch.ODataResponsePart; +import org.apache.olingo.server.api.prefer.PreferencesApplied; import org.apache.olingo.server.api.processor.BatchProcessor; import org.apache.olingo.server.tecsvc.data.DataProvider; public class TechnicalBatchProcessor extends TechnicalProcessor implements BatchProcessor { - private static final String PREFERENCE_CONTINUE_ON_ERROR = "odata.continue-on-error"; public TechnicalBatchProcessor(final DataProvider dataProvider) { super(dataProvider); @@ -47,7 +47,8 @@ public class TechnicalBatchProcessor extends TechnicalProcessor implements Batch @Override public void processBatch(final BatchFacade facade, final ODataRequest request, final ODataResponse response) throws ODataApplicationException, ODataLibraryException { - boolean continueOnError = isContinueOnError(request); + final boolean continueOnError = + odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasContinueOnError(); final String boundary = facade.extractBoundaryFromContentType(request.getHeader(HttpHeader.CONTENT_TYPE)); final BatchOptions options = BatchOptions.with() @@ -59,15 +60,15 @@ public class TechnicalBatchProcessor extends TechnicalProcessor implements Batch for (BatchRequestPart part : parts) { final ODataResponsePart responsePart = facade.handleBatchRequest(part); - responseParts.add(responsePart); // Also add failed responses + responseParts.add(responsePart); // Also add failed responses. final int statusCode = responsePart.getResponses().get(0).getStatusCode(); if ((statusCode >= 400 && statusCode <= 600) && !continueOnError) { - // Perform some additions actions + // Perform some additional actions. // ... - break; // Stop processing, but serialize all recent requests + break; // Stop processing, but serialize responses to all recent requests. } } @@ -77,19 +78,10 @@ public class TechnicalBatchProcessor extends TechnicalProcessor implements Batch response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.MULTIPART_MIXED + ";boundary=" + responseBoundary); response.setContent(responseContent); response.setStatusCode(HttpStatusCode.ACCEPTED.getStatusCode()); - } - - private boolean isContinueOnError(final ODataRequest request) { - final List preferValues = request.getHeaders(HttpHeader.PREFER); - - if (preferValues != null) { - for (final String preference : preferValues) { - if (PREFERENCE_CONTINUE_ON_ERROR.equals(preference)) { - return true; - } - } + if (continueOnError) { + response.setHeader(HttpHeader.PREFERENCE_APPLIED, + PreferencesApplied.with().continueOnError().build().toString()); } - return false; } @Override diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java index 71496fd64..ad8b7dd44 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java @@ -28,7 +28,6 @@ import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption; import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind; -import org.apache.olingo.server.tecsvc.Encoder; public class ServerSidePagingHandler { private static final int MAX_PAGE_SIZE = 10; @@ -45,7 +44,7 @@ public class ServerSidePagingHandler { * @param rawRequestUri the request URI (used to construct the next link) * @param preferredPageSize the client's preference for page size * @return the chosen page size (or null if no paging has been done); - * could be used in the Preference-Applied HTTP header + * could be used in the Preference-Applied HTTP header * @throws ODataApplicationException */ public static Integer applyServerSidePaging(final SkipTokenOption skipTokenOption, EntityCollection entityCollection, @@ -74,7 +73,7 @@ public class ServerSidePagingHandler { return null; } - private static URI createNextLink(final String rawRequestUri, final Integer page, final int pageSize) + private static URI createNextLink(final String rawRequestUri, final int page, final int pageSize) throws ODataApplicationException { // Remove a maybe existing skiptoken, making sure that the query part is not empty. String nextlink = rawRequestUri.contains("?") ? @@ -85,9 +84,12 @@ public class ServerSidePagingHandler { nextlink += nextlink.contains("?") ? '&' : '?'; // Append the new skiptoken. + nextlink += SystemQueryOptionKind.SKIPTOKEN.toString().replace("$", "%24") // poor man's percent encoding + + '=' + + page + "%2A" + pageSize; // "%2A" is a percent-encoded asterisk + try { - return new URI(nextlink + Encoder.encode(SystemQueryOptionKind.SKIPTOKEN.toString()) + '=' - + Encoder.encode(page.toString() + '*' + pageSize)); + return new URI(nextlink); } catch (final URISyntaxException e) { throw new ODataApplicationException("Exception while constructing next link", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e); From 5e2c60dbfdfa9cbfb080b7b55eaeb731ccce9181 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Wed, 17 Jun 2015 15:36:48 +0200 Subject: [PATCH 10/16] [OLINGO-694] Added 'samples' profile --- samples/pom.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/samples/pom.xml b/samples/pom.xml index a4c1e143a..765bd953e 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -23,7 +23,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.apache.olingo odata-samples pom ${project.artifactId} @@ -38,4 +37,13 @@ server + + + + samples + + client + + + From 7c557f25bd47b90aa75ed684b22db79b519b4e74 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Wed, 17 Jun 2015 15:48:14 +0200 Subject: [PATCH 11/16] [OLINGO-694] Added read tutorial (part 1) --- samples/pom.xml | 6 + samples/tutorials/p1_read/pom.xml | 75 +++++++++ .../mynamespace/service/DemoEdmProvider.java | 153 ++++++++++++++++++ .../DemoEntityCollectionProcessor.java | 129 +++++++++++++++ .../mynamespace/web/DemoServlet.java | 67 ++++++++ .../p1_read/src/main/webapp/WEB-INF/web.xml | 40 +++++ .../p1_read/src/main/webapp/index.jsp | 6 + samples/tutorials/pom.xml | 52 ++++++ 8 files changed, 528 insertions(+) create mode 100755 samples/tutorials/p1_read/pom.xml create mode 100755 samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java create mode 100755 samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java create mode 100755 samples/tutorials/p1_read/src/main/java/myservice/mynamespace/web/DemoServlet.java create mode 100755 samples/tutorials/p1_read/src/main/webapp/WEB-INF/web.xml create mode 100755 samples/tutorials/p1_read/src/main/webapp/index.jsp create mode 100644 samples/tutorials/pom.xml diff --git a/samples/pom.xml b/samples/pom.xml index 765bd953e..95e3ddbed 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -45,5 +45,11 @@ client + + tutorials + + tutorials + + diff --git a/samples/tutorials/p1_read/pom.xml b/samples/tutorials/p1_read/pom.xml new file mode 100755 index 000000000..c815f8d88 --- /dev/null +++ b/samples/tutorials/p1_read/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + myservice.mynamespace + DemoService + war + 0.0.1 + + DemoService Maven Webapp + + + 2.5 + 4.0.0-beta-03 + 1.7.7 + + + + + javax.servlet + servlet-api + ${javax.version} + provided + + + + org.apache.olingo + odata-server-api + ${odata.version} + + + org.apache.olingo + odata-server-core + ${odata.version} + + + + org.apache.olingo + odata-commons-api + ${odata.version} + + + org.apache.olingo + odata-commons-core + ${odata.version} + + + + org.slf4j + slf4j-simple + ${slf4j.version} + runtime + + + diff --git a/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java new file mode 100755 index 000000000..dd46e864e --- /dev/null +++ b/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java @@ -0,0 +1,153 @@ +/* + * 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 myservice.mynamespace.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.olingo.commons.api.ODataException; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; +import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; +import org.apache.olingo.commons.api.edm.provider.CsdlProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; + +/** + * this class is supposed to declare the metadata of the OData service + * it is invoked by the Olingo framework e.g. when the metadata document of the service is invoked + * e.g. http://localhost:8080/ExampleService1/ExampleService1.svc/$metadata + */ +public class DemoEdmProvider extends CsdlAbstractEdmProvider { + + // Service Namespace + public static final String NAMESPACE = "OData.Demo"; + + // EDM Container + public static final String CONTAINER_NAME = "Container"; + public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); + + // Entity Types Names + public static final String ET_PRODUCT_NAME = "Product"; + public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME); + + // Entity Set Names + public static final String ES_PRODUCTS_NAME = "Products"; + + + @Override + public List getSchemas() throws ODataException { + + // create Schema + CsdlSchema schema = new CsdlSchema(); + schema.setNamespace(NAMESPACE); + + // add EntityTypes + List entityTypes = new ArrayList(); + entityTypes.add(getEntityType(ET_PRODUCT_FQN)); + schema.setEntityTypes(entityTypes); + + // add EntityContainer + schema.setEntityContainer(getEntityContainer()); + + // finally + List schemas = new ArrayList(); + schemas.add(schema); + + return schemas; + } + + + @Override + public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException { + + // this method is called for one of the EntityTypes that are configured in the Schema + if(entityTypeName.equals(ET_PRODUCT_FQN)){ + + //create EntityType properties + CsdlProperty id = new CsdlProperty().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName()); + CsdlProperty name = new CsdlProperty().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + CsdlProperty description = new CsdlProperty().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + + // create CsdlPropertyRef for Key element + CsdlPropertyRef propertyRef = new CsdlPropertyRef(); + propertyRef.setName("ID"); + + // configure EntityType + CsdlEntityType entityType = new CsdlEntityType(); + entityType.setName(ET_PRODUCT_NAME); + entityType.setProperties(Arrays.asList(id, name , description)); + entityType.setKey(Collections.singletonList(propertyRef)); + + return entityType; + } + + return null; + } + + @Override + public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException { + + if(entityContainer.equals(CONTAINER)){ + if(entitySetName.equals(ES_PRODUCTS_NAME)){ + CsdlEntitySet entitySet = new CsdlEntitySet(); + entitySet.setName(ES_PRODUCTS_NAME); + entitySet.setType(ET_PRODUCT_FQN); + + return entitySet; + } + } + + return null; + } + + @Override + public CsdlEntityContainer getEntityContainer() throws ODataException { + + // create EntitySets + List entitySets = new ArrayList(); + entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME)); + + // create EntityContainer + CsdlEntityContainer entityContainer = new CsdlEntityContainer(); + entityContainer.setName(CONTAINER_NAME); + entityContainer.setEntitySets(entitySets); + + return entityContainer; + } + + @Override + public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException { + + // This method is invoked when displaying the service document at e.g. http://localhost:8080/DemoService/DemoService.svc + if(entityContainerName == null || entityContainerName.equals(CONTAINER)){ + CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo(); + entityContainerInfo.setContainerName(CONTAINER); + return entityContainerInfo; + } + + return null; + } +} diff --git a/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java new file mode 100755 index 000000000..e82a3caa6 --- /dev/null +++ b/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java @@ -0,0 +1,129 @@ +/* + * 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 myservice.mynamespace.service; + +import java.util.List; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.processor.EntityCollectionProcessor; +import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; +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.UriResourceEntitySet; + +/** + * This class is invoked by the Olingo framework when the the OData service is invoked order to display a list/collection of data (entities). + * This is the case if an EntitySet is requested by the user. + * Such an example URL would be: + * http://localhost:8080/ExampleService1/ExampleService1.svc/Products + */ +public class DemoEntityCollectionProcessor implements EntityCollectionProcessor { + + private OData odata; + private ServiceMetadata serviceMetadata; + + // our processor is initialized with the OData context object + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + } + + + // the only method that is declared in the EntityCollectionProcessor interface + // this method is called, when the user fires a request to an EntitySet + // in our example, the URL would be: + // http://localhost:8080/ExampleService1/ExampleServlet1.svc/Products + public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, SerializerException { + + // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) + List resourcePaths = uriInfo.getUriResourceParts(); + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2nd: fetch the data from backend for this requested EntitySetName // it has to be delivered as EntitySet object + EntityCollection entitySet = getData(edmEntitySet); + + // 3rd: create a serializer based on the requested format (json) + ODataFormat format = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = odata.createSerializer(format); + + // 4th: Now serialize the content: transform from the EntitySet object to InputStream + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build(); + + EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build(); + SerializerResult serializedContent = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts); + + // Finally: configure the response object: set the body, headers and status code + response.setContent(serializedContent.getContent()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + + /** + * Helper method for providing some sample data + * @param edmEntitySet for which the data is requested + * @return data of requested entity set + */ + private EntityCollection getData(EdmEntitySet edmEntitySet){ + + EntityCollection entityCollection = new EntityCollection(); + // check for which EdmEntitySet the data is requested + if(DemoEdmProvider.ES_PRODUCTS_NAME.equals(edmEntitySet.getName())) { + List entityList = entityCollection.getEntities(); + + // add some sample product entities + entityList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"))); + + entityList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"))); + + entityList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"))); + } + + return entityCollection; + } +} diff --git a/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/web/DemoServlet.java new file mode 100755 index 000000000..486770c45 --- /dev/null +++ b/samples/tutorials/p1_read/src/main/java/myservice/mynamespace/web/DemoServlet.java @@ -0,0 +1,67 @@ +/* + * 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 myservice.mynamespace.web; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import myservice.mynamespace.service.DemoEdmProvider; +import myservice.mynamespace.service.DemoEntityCollectionProcessor; + +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataHttpHandler; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.edmx.EdmxReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class represents a standard HttpServlet implementation. + * It is used as main entry point for the web application that carries the OData service. + * The implementation of this HttpServlet simply delegates the user requests to the ODataHttpHandler + */ +public class DemoServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class); + + @Override + protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + + try { + // create odata handler and configure it with EdmProvider and Processor + OData odata = OData.newInstance(); + ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList()); + ODataHttpHandler handler = odata.createHandler(edm); + handler.register(new DemoEntityCollectionProcessor()); + + // let the handler do the work + handler.process(req, resp); + + } catch (RuntimeException e) { + LOG.error("Server Error occurred in ExampleServlet", e); + throw new ServletException(e); + } + } +} diff --git a/samples/tutorials/p1_read/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p1_read/src/main/webapp/WEB-INF/web.xml new file mode 100755 index 000000000..21de52a8f --- /dev/null +++ b/samples/tutorials/p1_read/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,40 @@ + + + + + + + DemoServlet + myservice.mynamespace.web.DemoServlet + 1 + + + + + DemoServlet + /DemoService.svc/* + + \ No newline at end of file diff --git a/samples/tutorials/p1_read/src/main/webapp/index.jsp b/samples/tutorials/p1_read/src/main/webapp/index.jsp new file mode 100755 index 000000000..2baf543ea --- /dev/null +++ b/samples/tutorials/p1_read/src/main/webapp/index.jsp @@ -0,0 +1,6 @@ + + +

Hello World!

+OData Olingo V4 Demo Service + + diff --git a/samples/tutorials/pom.xml b/samples/tutorials/pom.xml new file mode 100644 index 000000000..ba862332c --- /dev/null +++ b/samples/tutorials/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + odata-tutorials + pom + ${project.artifactId} + + + org.apache.olingo + odata-samples + 4.0.0-SNAPSHOT + .. + + + + p1_read + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + From bff2ecf0a8a60b5a457663780404a7e5d25f0ed8 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Wed, 17 Jun 2015 15:51:57 +0200 Subject: [PATCH 12/16] [OLINGO-694] Fixed missing apache header in jsp file --- .../p1_read/src/main/webapp/index.jsp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/samples/tutorials/p1_read/src/main/webapp/index.jsp b/samples/tutorials/p1_read/src/main/webapp/index.jsp index 2baf543ea..7ffb4ba6f 100755 --- a/samples/tutorials/p1_read/src/main/webapp/index.jsp +++ b/samples/tutorials/p1_read/src/main/webapp/index.jsp @@ -1,3 +1,23 @@ +

Hello World!

From f24c3874e0686c6fd2d110f42778f8bff8535900 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Thu, 18 Jun 2015 12:15:03 +0200 Subject: [PATCH 13/16] [OLINGO-694] Added read property and write tutorial (part 2 and 3) --- samples/tutorials/p1_read/pom.xml | 6 +- samples/tutorials/p2_readep/pom.xml | 75 +++++ .../myservice/mynamespace/data/Storage.java | 107 +++++++ .../mynamespace/service/DemoEdmProvider.java | 135 +++++++++ .../DemoEntityCollectionProcessor.java | 72 +++++ .../service/DemoEntityProcessor.java | 108 +++++++ .../service/DemoPrimitiveProcessor.java | 129 +++++++++ .../java/myservice/mynamespace/util/Util.java | 120 ++++++++ .../mynamespace/web/DemoServlet.java | 76 +++++ .../p2_readep/src/main/webapp/WEB-INF/web.xml | 40 +++ .../p2_readep/src/main/webapp/index.jsp | 26 ++ samples/tutorials/p3_write/pom.xml | 75 +++++ .../myservice/mynamespace/data/Storage.java | 272 ++++++++++++++++++ .../mynamespace/service/DemoEdmProvider.java | 155 ++++++++++ .../DemoEntityCollectionProcessor.java | 93 ++++++ .../service/DemoEntityProcessor.java | 189 ++++++++++++ .../service/DemoPrimitiveProcessor.java | 143 +++++++++ .../java/myservice/mynamespace/util/Util.java | 122 ++++++++ .../mynamespace/web/DemoServlet.java | 73 +++++ .../p3_write/src/main/webapp/WEB-INF/web.xml | 40 +++ .../p3_write/src/main/webapp/index.jsp | 26 ++ samples/tutorials/pom.xml | 2 + 22 files changed, 2081 insertions(+), 3 deletions(-) create mode 100755 samples/tutorials/p2_readep/pom.xml create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java create mode 100755 samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/web/DemoServlet.java create mode 100755 samples/tutorials/p2_readep/src/main/webapp/WEB-INF/web.xml create mode 100755 samples/tutorials/p2_readep/src/main/webapp/index.jsp create mode 100755 samples/tutorials/p3_write/pom.xml create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java create mode 100755 samples/tutorials/p3_write/src/main/java/myservice/mynamespace/web/DemoServlet.java create mode 100755 samples/tutorials/p3_write/src/main/webapp/WEB-INF/web.xml create mode 100755 samples/tutorials/p3_write/src/main/webapp/index.jsp diff --git a/samples/tutorials/p1_read/pom.xml b/samples/tutorials/p1_read/pom.xml index c815f8d88..bcae4ef35 100755 --- a/samples/tutorials/p1_read/pom.xml +++ b/samples/tutorials/p1_read/pom.xml @@ -22,12 +22,12 @@ 4.0.0 - myservice.mynamespace - DemoService + my.group.id + DemoService-Read war 0.0.1 - DemoService Maven Webapp + ${project.artifactId}-Webapp 2.5 diff --git a/samples/tutorials/p2_readep/pom.xml b/samples/tutorials/p2_readep/pom.xml new file mode 100755 index 000000000..abe0601cf --- /dev/null +++ b/samples/tutorials/p2_readep/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + my.group.id + DemoService-ReadEp + war + 0.0.1 + + ${project.artifactId}-Webapp + + + 2.5 + 4.0.0-beta-03 + 1.7.7 + + + + + javax.servlet + servlet-api + ${javax.version} + provided + + + + org.apache.olingo + odata-server-api + ${odata.version} + + + org.apache.olingo + odata-server-core + ${odata.version} + + + + org.apache.olingo + odata-commons-api + ${odata.version} + + + org.apache.olingo + odata-commons-core + ${odata.version} + + + + org.slf4j + slf4j-simple + ${slf4j.version} + runtime + + + diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java new file mode 100755 index 000000000..be985f519 --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java @@ -0,0 +1,107 @@ +package myservice.mynamespace.data; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import myservice.mynamespace.service.DemoEdmProvider; +import myservice.mynamespace.util.Util; + +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.uri.UriParameter; + +public class Storage { + + private List productList; + + public Storage() { + productList = new ArrayList(); + initSampleData(); + } + + /* PUBLIC FACADE */ + + public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{ + + // actually, this is only required if we have more than one Entity Sets + if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){ + return getProducts(); + } + + return null; + } + + public Entity readEntityData(EdmEntitySet edmEntitySet, List keyParams) throws ODataApplicationException{ + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ + return getProduct(edmEntityType, keyParams); + } + + return null; + } + + + + /* INTERNAL */ + + private EntityCollection getProducts(){ + EntityCollection retEntitySet = new EntityCollection(); + + for(Entity productEntity : this.productList){ + retEntitySet.getEntities().add(productEntity); + } + + return retEntitySet; + } + + + private Entity getProduct(EdmEntityType edmEntityType, List keyParams) throws ODataApplicationException{ + + // the list of entities at runtime + EntityCollection entitySet = getProducts(); + + /* generic approach to find the requested entity */ + Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams); + + if(requestedEntity == null){ + // this variable is null if our data doesn't contain an entity for the requested key + // Throw suitable exception + throw new ODataApplicationException("Entity for requested key doesn't exist", + HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + return requestedEntity; + } + + /* HELPER */ + + private void initSampleData(){ + + // add some sample product entities + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"))); + + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"))); + + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"))); + + } +} diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java new file mode 100755 index 000000000..0b091ffc8 --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java @@ -0,0 +1,135 @@ +package myservice.mynamespace.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.olingo.commons.api.ODataException; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; +import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; +import org.apache.olingo.commons.api.edm.provider.CsdlProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; + +public class DemoEdmProvider extends CsdlAbstractEdmProvider { + + // Service Namespace + public static final String NAMESPACE = "OData.Demo"; + + // EDM Container + public static final String CONTAINER_NAME = "Container"; + public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); + + // Entity Types Names + public static final String ET_PRODUCT_NAME = "Product"; + public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME); + + // Entity Set Names + public static final String ES_PRODUCTS_NAME = "Products"; + + + @Override + public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) + throws ODataException { + // this method is called for one of the EntityTypes that are configured in the Schema + if(ET_PRODUCT_FQN.equals(entityTypeName)){ + + //create EntityType properties + CsdlProperty id = new CsdlProperty().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName()); + CsdlProperty name = new CsdlProperty().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + CsdlProperty description = new CsdlProperty().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + + // create PropertyRef for Key element + CsdlPropertyRef propertyRef = new CsdlPropertyRef(); + propertyRef.setName("ID"); + + // configure EntityType + CsdlEntityType entityType = new CsdlEntityType(); + entityType.setName(ET_PRODUCT_NAME); + entityType.setProperties(Arrays.asList(id, name, description)); + entityType.setKey(Collections.singletonList(propertyRef)); + + return entityType; + } + + return null; + + } + + @Override + public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, + String entitySetName) throws ODataException { + if(entityContainer.equals(CONTAINER)){ + if(entitySetName.equals(ES_PRODUCTS_NAME)){ + CsdlEntitySet entitySet = new CsdlEntitySet(); + entitySet.setName(ES_PRODUCTS_NAME); + entitySet.setType(ET_PRODUCT_FQN); + + return entitySet; + } + } + + return null; + + } + + @Override + public CsdlEntityContainerInfo getEntityContainerInfo( + FullQualifiedName entityContainerName) throws ODataException { + // This method is invoked when displaying the service document at e.g. http://localhost:8080/DemoService/DemoService.svc + if(entityContainerName == null || entityContainerName.equals(CONTAINER)){ + CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo(); + entityContainerInfo.setContainerName(CONTAINER); + return entityContainerInfo; + } + + return null; + + } + + @Override + public List getSchemas() throws ODataException { + // create Schema + CsdlSchema schema = new CsdlSchema(); + schema.setNamespace(NAMESPACE); + + // add EntityTypes + List entityTypes = new ArrayList(); + entityTypes.add(getEntityType(ET_PRODUCT_FQN)); + schema.setEntityTypes(entityTypes); + + // add EntityContainer + schema.setEntityContainer(getEntityContainer()); + + // finally + List schemas = new ArrayList(); + schemas.add(schema); + + return schemas; + + } + + @Override + public CsdlEntityContainer getEntityContainer() throws ODataException { + // create EntitySets + List entitySets = new ArrayList(); + entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME)); + + // create EntityContainer + CsdlEntityContainer entityContainer = new CsdlEntityContainer(); + entityContainer.setName(CONTAINER_NAME); + entityContainer.setEntitySets(entitySets); + + return entityContainer; + + } + + + +} diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java new file mode 100755 index 000000000..0835a4116 --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java @@ -0,0 +1,72 @@ +package myservice.mynamespace.service; + +import java.io.InputStream; +import java.util.List; + +import myservice.mynamespace.data.Storage; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.processor.EntityCollectionProcessor; +import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; +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.UriResourceEntitySet; + +public class DemoEntityCollectionProcessor implements EntityCollectionProcessor { + + private OData odata; + private ServiceMetadata serviceMetadata; + private Storage storage; + + public DemoEntityCollectionProcessor(Storage storage) { + this.storage = storage; + } + + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + } + + public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, SerializerException { + + // 1st retrieve the requested EntitySet from the uriInfo (representation of the parsed URI) + List resourcePaths = uriInfo.getUriResourceParts(); + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet + EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet); + + // 3rd: create a serializer based on the requested format (json) + ODataFormat format = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = odata.createSerializer(format); + + // and serialize the content: transform from the EntitySet object to InputStream + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build(); + + EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build(); + SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entityCollection, opts); + InputStream serializedContent = serializerResult.getContent(); + + // 4th: configure the response object: set the body, headers and status code + response.setContent(serializedContent); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } +} diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java new file mode 100755 index 000000000..dc633b1ae --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java @@ -0,0 +1,108 @@ +package myservice.mynamespace.service; + +import java.io.InputStream; +import java.util.List; +import java.util.Locale; + +import myservice.mynamespace.data.Storage; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.DeserializerException; +import org.apache.olingo.server.api.processor.EntityProcessor; +import org.apache.olingo.server.api.serializer.EntitySerializerOptions; +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.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; + +public class DemoEntityProcessor implements EntityProcessor { + + + private OData odata; + private ServiceMetadata serviceMetadata; + private Storage storage; + + + + public DemoEntityProcessor(Storage storage) { + this.storage = storage; + } + + + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + } + + + public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) + throws ODataApplicationException, SerializerException { + + // 1. retrieve the Entity Type + List resourcePaths = uriInfo.getUriResourceParts(); + // Note: only in our example we can assume that the first segment is the EntitySet + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2. retrieve the data from backend + List keyPredicates = uriResourceEntitySet.getKeyPredicates(); + Entity entity = storage.readEntityData(edmEntitySet, keyPredicates); + + // 3. serialize + EdmEntityType entityType = edmEntitySet.getEntityType(); + + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build(); + // expand and select currently not supported + EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); + + ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = this.odata.createSerializer(oDataFormat); + SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options); + InputStream entityStream = serializerResult.getContent(); + + //4. configure the response object + response.setContent(entityStream); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + + + + /* + * These processor methods are not handled in this tutorial + * */ + + + public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + + public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + + public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + +} diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java new file mode 100755 index 000000000..7c5b3155e --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java @@ -0,0 +1,129 @@ +package myservice.mynamespace.service; + +import java.io.InputStream; +import java.util.List; +import java.util.Locale; + +import myservice.mynamespace.data.Storage; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmProperty; +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.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.DeserializerException; +import org.apache.olingo.server.api.processor.PrimitiveProcessor; +import org.apache.olingo.server.api.serializer.ODataSerializer; +import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; +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.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; +import org.apache.olingo.server.api.uri.UriResourceProperty; + +public class DemoPrimitiveProcessor implements PrimitiveProcessor { + + private OData odata; + private Storage storage; + + public DemoPrimitiveProcessor(Storage storage) { + this.storage = storage; + } + + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + + } + + /* + * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name + * and the response: + * { + * @odata.context: "$metadata#Products/Name", + * value: "Notebook Basic 15" + * } + * */ + public void readPrimitive(ODataRequest request, ODataResponse response, + UriInfo uriInfo, ContentType responseFormat) + throws ODataApplicationException, SerializerException { + + // 1. Retrieve info from URI + // 1.1. retrieve the info about the requested entity set + List resourceParts = uriInfo.getUriResourceParts(); + // Note: only in our example we can rely that the first segment is the EntitySet + UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0); + EdmEntitySet edmEntitySet = uriEntityset.getEntitySet(); + // the key for the entity + List keyPredicates = uriEntityset.getKeyPredicates(); + + // 1.2. retrieve the requested (Edm) property + UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1); // the last segment is the Property + EdmProperty edmProperty = uriProperty.getProperty(); + String edmPropertyName = edmProperty.getName(); + // in our example, we know we have only primitive types in our model + EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType(); + + + // 2. retrieve data from backend + // 2.1. retrieve the entity data, for which the property has to be read + Entity entity = storage.readEntityData(edmEntitySet, keyPredicates); + if (entity == null) { // Bad request + throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + // 2.2. retrieve the property data from the entity + Property property = entity.getProperty(edmPropertyName); + if (property == null) { + throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + // 3. serialize + Object value = property.getValue(); + if (value != null) { + // 3.1. configure the serializer + ODataFormat format = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = odata.createSerializer(format); + + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build(); + PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build(); + // 3.2. serialize + SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options); + InputStream propertyStream = serializerResult.getContent(); + + //4. configure the response object + response.setContent(propertyStream); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } else { + // in case there's no value for the property, we can skip the serialization + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + } + + + + /* + * These processor methods are not handled in this tutorial + * */ + + public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } +} diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java new file mode 100755 index 000000000..16c774564 --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java @@ -0,0 +1,120 @@ +/* + * 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 myservice.mynamespace.util; + +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.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.uri.UriInfoResource; +import org.apache.olingo.server.api.uri.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; + +public class Util { + + public static EdmEntitySet getEdmEntitySet(UriInfoResource uriInfo) throws ODataApplicationException { + List resourcePaths = uriInfo.getUriResourceParts(); + // To get the entity set we have to interpret all URI segments + if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) { + // Here we should interpret the whole URI but in this example we do not support navigation so we throw an exception + throw new ODataApplicationException("Invalid resource type for first segment.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ENGLISH); + } + + UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0); + + return uriResource.getEntitySet(); + } + + + public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet, List keyParams) throws ODataApplicationException { + + List entityList = entitySet.getEntities(); + + // loop over all entities in order to find that one that matches all keys in request e.g. contacts(ContactID=1, CompanyID=1) + for(Entity entity : entityList){ + boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams); + if(foundEntity) { + return entity; + } + } + + return null; + } + + + public static boolean + entityMatchesAllKeys(EdmEntityType edmEntityType, Entity rt_entity, List keyParams) + throws ODataApplicationException { + + // loop over all keys + for (final UriParameter key : keyParams) { + // key + String keyName = key.getName(); + String keyText = key.getText(); + + // Edm: we need this info for the comparison below + EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName); + Boolean isNullable = edmKeyProperty.isNullable(); + Integer maxLength = edmKeyProperty.getMaxLength(); + Integer precision = edmKeyProperty.getPrecision(); + Boolean isUnicode = edmKeyProperty.isUnicode(); + Integer scale = edmKeyProperty.getScale(); + // get the EdmType in order to compare + EdmType edmType = edmKeyProperty.getType(); + // if(EdmType instanceof EdmPrimitiveType) // do we need this? + EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType; + + // Runtime data: the value of the current entity + // don't need to check for null, this is done in olingo library + Object valueObject = rt_entity.getProperty(keyName).getValue(); + + // now need to compare the valueObject with the keyText String + // this is done using type.valueToString + String valueAsString = null; + try { + valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode); + } catch (EdmPrimitiveTypeException e) { + throw new ODataApplicationException("Failed to retrieve String value", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH, e); + } + + if (valueAsString == null) { + return false; + } + + boolean matches = valueAsString.equals(keyText); + if (!matches) { + // if any of the key properties is not found in the entity, we don't need to search further + return false; + } + } + + return true; + } +} diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/web/DemoServlet.java new file mode 100755 index 000000000..fe5cdbb38 --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/web/DemoServlet.java @@ -0,0 +1,76 @@ +/* + * 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 myservice.mynamespace.web; + +import java.io.IOException; +import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import myservice.mynamespace.data.Storage; +import myservice.mynamespace.service.DemoEdmProvider; +import myservice.mynamespace.service.DemoEntityCollectionProcessor; +import myservice.mynamespace.service.DemoEntityProcessor; +import myservice.mynamespace.service.DemoPrimitiveProcessor; + +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataHttpHandler; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.edmx.EdmxReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DemoServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class); + + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + try { + HttpSession session = req.getSession(true); + Storage storage = (Storage) session.getAttribute(Storage.class.getName()); + if (storage == null) { + storage = new Storage(); + session.setAttribute(Storage.class.getName(), storage); + } + + // create odata handler and configure it with EdmProvider and Processor + OData odata = OData.newInstance(); + ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList()); + ODataHttpHandler handler = odata.createHandler(edm); + handler.register(new DemoEntityCollectionProcessor(storage)); + handler.register(new DemoEntityProcessor(storage)); + handler.register(new DemoPrimitiveProcessor(storage)); + + // let the handler do the work + handler.process(req, resp); + } catch (RuntimeException e) { + LOG.error("Server Error occurred in ExampleServlet", e); + throw new ServletException(e); + } + + } + +} diff --git a/samples/tutorials/p2_readep/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p2_readep/src/main/webapp/WEB-INF/web.xml new file mode 100755 index 000000000..21de52a8f --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,40 @@ + + + + + + + DemoServlet + myservice.mynamespace.web.DemoServlet + 1 + + + + + DemoServlet + /DemoService.svc/* + + \ No newline at end of file diff --git a/samples/tutorials/p2_readep/src/main/webapp/index.jsp b/samples/tutorials/p2_readep/src/main/webapp/index.jsp new file mode 100755 index 000000000..7ffb4ba6f --- /dev/null +++ b/samples/tutorials/p2_readep/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ + + + +

Hello World!

+OData Olingo V4 Demo Service + + diff --git a/samples/tutorials/p3_write/pom.xml b/samples/tutorials/p3_write/pom.xml new file mode 100755 index 000000000..4511a6f5c --- /dev/null +++ b/samples/tutorials/p3_write/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + my.group.id + DemoService-Write + war + 0.0.1 + + ${project.artifactId}-Webapp + + + 2.5 + 4.0.0-beta-03 + 1.7.7 + + + + + javax.servlet + servlet-api + ${javax.version} + provided + + + + org.apache.olingo + odata-server-api + ${odata.version} + + + org.apache.olingo + odata-server-core + ${odata.version} + + + + org.apache.olingo + odata-commons-api + ${odata.version} + + + org.apache.olingo + odata-commons-core + ${odata.version} + + + + org.slf4j + slf4j-simple + ${slf4j.version} + runtime + + + diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java new file mode 100755 index 000000000..3af32600d --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java @@ -0,0 +1,272 @@ +/* + * 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 myservice.mynamespace.data; + +import myservice.mynamespace.service.DemoEdmProvider; +import myservice.mynamespace.util.Util; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef; +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.uri.UriParameter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class Storage { + + + private List productList; + + + public Storage() { + + productList = new ArrayList(); + initSampleData(); + } + + + + /* PUBLIC FACADE */ + + + public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{ + + // actually, this is only required if we have more than one Entity Sets + if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){ + return getProducts(); + } + + return null; + } + + + public Entity readEntityData(EdmEntitySet edmEntitySet, List keyParams) throws ODataApplicationException{ + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ + return getProduct(edmEntityType, keyParams); + } + + return null; + } + + + public Entity createEntityData(EdmEntitySet edmEntitySet, Entity entityToCreate) { + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ + return createProduct(edmEntityType, entityToCreate); + } + + return null; + } + + + /** + * This method is invoked for PATCH or PUT requests + * */ + public void updateEntityData(EdmEntitySet edmEntitySet, List keyParams, Entity updateEntity, HttpMethod httpMethod) throws ODataApplicationException{ + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ + updateProduct(edmEntityType, keyParams, updateEntity, httpMethod); + } + } + + + public void deleteEntityData(EdmEntitySet edmEntitySet, List keyParams) throws ODataApplicationException{ + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ + deleteProduct(edmEntityType, keyParams); + } + } + + + + /* INTERNAL */ + + private EntityCollection getProducts(){ + EntityCollection retEntitySet = new EntityCollection(); + + for(Entity productEntity : this.productList){ + retEntitySet.getEntities().add(productEntity); + } + + return retEntitySet; + } + + + private Entity getProduct(EdmEntityType edmEntityType, List keyParams) throws ODataApplicationException{ + + // the list of entities at runtime + EntityCollection entitySet = getProducts(); + + /* generic approach to find the requested entity */ + Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams); + + + if(requestedEntity == null){ + // this variable is null if our data doesn't contain an entity for the requested key + // Throw suitable exception + throw new ODataApplicationException("Entity for requested key doesn't exist", + HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + return requestedEntity; + } + + + private Entity createProduct(EdmEntityType edmEntityType, Entity entity) { + + // the ID of the newly created product entity is generated automatically + int newId = 1; + while (productIdExists(newId)){ + newId++; + } + + Property idProperty = entity.getProperty("ID"); + if(idProperty != null){ + idProperty.setValue(ValueType.PRIMITIVE, new Integer(newId)); + }else{ + // as of OData v4 spec, the key property can be omitted from the POST request body + entity.getProperties().add(new Property(null, "ID", ValueType.PRIMITIVE, newId)); + } + + this.productList.add(entity); + + return entity; + + } + + + private boolean productIdExists(int id){ + + for(Entity entity : this.productList){ + Integer existingID = (Integer) entity.getProperty("ID").getValue(); + if(existingID.intValue() == id){ + return true; + } + } + + return false; + } + + + private void updateProduct(EdmEntityType edmEntityType, List keyParams, Entity entity, HttpMethod httpMethod) throws ODataApplicationException{ + + Entity productEntity = getProduct(edmEntityType, keyParams); + if(productEntity == null){ + throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + // loop over all properties and replace the values with the values of the given payload + // Note: ignoring ComplexType, as we don't have it in our odata model + List existingProperties = productEntity.getProperties(); + for(Property existingProp : existingProperties){ + String propName = existingProp.getName(); + + // ignore the key properties, they aren't updateable + if(isKey(edmEntityType, propName)){ + continue; + } + + Property updateProperty = entity.getProperty(propName); + // the request payload might not consider ALL properties, so it can be null + if(updateProperty == null){ + // if a property has NOT been added to the request payload + // depending on the HttpMethod, our behavior is different + if(httpMethod.equals(HttpMethod.PATCH)){ + // as of the OData spec, in case of PATCH, the existing property is not touched + continue; // do nothing + }else if(httpMethod.equals(HttpMethod.PUT)){ + // as of the OData spec, in case of PUT, the existing property is set to null (or to default value) + existingProp.setValue(existingProp.getValueType(), null); + continue; + } + } + + // change the value of the properties + existingProp.setValue(existingProp.getValueType(), updateProperty.getValue()); + } + } + + private void deleteProduct(EdmEntityType edmEntityType, List keyParams) throws ODataApplicationException{ + + Entity productEntity = getProduct(edmEntityType, keyParams); + if(productEntity == null){ + throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + this.productList.remove(productEntity); + } + + + + /* HELPER */ + + + private boolean isKey(EdmEntityType edmEntityType, String propertyName){ + List keyPropertyRefs = edmEntityType.getKeyPropertyRefs(); + for(EdmKeyPropertyRef propRef : keyPropertyRefs){ + String keyPropertyName = propRef.getName(); + if(keyPropertyName.equals(propertyName)){ + return true; + } + } + return false; + } + + + private void initSampleData(){ + + // add some sample product entities + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"))); + + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"))); + + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen")) + .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"))); + + } +} diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java new file mode 100755 index 000000000..6a64b319c --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package myservice.mynamespace.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.olingo.commons.api.ODataException; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; +import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; +import org.apache.olingo.commons.api.edm.provider.CsdlProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; + +/* + * this class is supposed to declare the metadata of the OData service + * it is invoked by the Olingo framework e.g. when the metadata document of the service is invoked + * e.g. http://localhost:8080/ExampleService1/ExampleService1.svc/$metadata + */ +public class DemoEdmProvider extends CsdlAbstractEdmProvider { + + + // Service Namespace + public static final String NAMESPACE = "OData.Demo"; + + // EDM Container + public static final String CONTAINER_NAME = "Container"; + public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); + + // Entity Types Names + public static final String ET_PRODUCT_NAME = "Product"; + public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME); + + // Entity Set Names + public static final String ES_PRODUCTS_NAME = "Products"; + + + @Override + public List getSchemas() throws ODataException { + + // create Schema + CsdlSchema schema = new CsdlSchema(); + schema.setNamespace(NAMESPACE); + + // add EntityTypes + List entityTypes = new ArrayList(); + entityTypes.add(getEntityType(ET_PRODUCT_FQN)); + schema.setEntityTypes(entityTypes); + + // add EntityContainer + schema.setEntityContainer(getEntityContainer()); + + // finally + List schemas = new ArrayList(); + schemas.add(schema); + + return schemas; + } + + + @Override + public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException { + // this method is called for one of the EntityTypes that are configured in the Schema + if(entityTypeName.equals(ET_PRODUCT_FQN)){ + + //create EntityType properties + CsdlProperty id = new CsdlProperty().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName()); + CsdlProperty name = new CsdlProperty().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + CsdlProperty description = new CsdlProperty().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + + // create CsdlPropertyRef for Key element + CsdlPropertyRef propertyRef = new CsdlPropertyRef(); + propertyRef.setName("ID"); + + // configure EntityType + CsdlEntityType entityType = new CsdlEntityType(); + entityType.setName(ET_PRODUCT_NAME); + entityType.setProperties(Arrays.asList(id, name, description)); + entityType.setKey(Collections.singletonList(propertyRef)); + + return entityType; + } + + return null; + + } + + @Override + public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException { + + if(entityContainer.equals(CONTAINER)){ + if(entitySetName.equals(ES_PRODUCTS_NAME)){ + CsdlEntitySet entitySet = new CsdlEntitySet(); + entitySet.setName(ES_PRODUCTS_NAME); + entitySet.setType(ET_PRODUCT_FQN); + + return entitySet; + } + } + + return null; + + } + + + public CsdlEntityContainer getEntityContainer() throws ODataException { + // create EntitySets + List entitySets = new ArrayList(); + entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME)); + + // create EntityContainer + CsdlEntityContainer entityContainer = new CsdlEntityContainer(); + entityContainer.setName(CONTAINER_NAME); + entityContainer.setEntitySets(entitySets); + + return entityContainer; + + } + + @Override + public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException { + + // This method is invoked when displaying the service document at + // e.g. http://localhost:8080/DemoService/DemoService.svc + if (entityContainerName == null || entityContainerName.equals(CONTAINER)) { + CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo(); + entityContainerInfo.setContainerName(CONTAINER); + return entityContainerInfo; + } + return null; + } +} diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java new file mode 100755 index 000000000..53470cb8b --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java @@ -0,0 +1,93 @@ +/* + * 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 myservice.mynamespace.service; + +import java.util.List; + +import myservice.mynamespace.data.Storage; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.processor.EntityCollectionProcessor; +import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; +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.UriResourceEntitySet; + +public class DemoEntityCollectionProcessor implements EntityCollectionProcessor { + + private OData odata; + private Storage storage; + private ServiceMetadata serviceMetadata; + + + public DemoEntityCollectionProcessor(Storage storage) { + this.storage = storage; + } + + + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + } + + public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, + ContentType responseFormat) throws ODataApplicationException, SerializerException { + + // 1st retrieve the requested EntitySet from the uriInfo (representation of the parsed URI) + List resourcePaths = uriInfo.getUriResourceParts(); + // in our example, the first segment is the EntitySet + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2nd: fetch the data from backend for this requested EntitySetName + // it has to be delivered as EntitySet object + EntityCollection entitySet = storage.readEntitySetData(edmEntitySet); + + // 3rd: create a serializer based on the requested format (json) + ODataFormat format = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = odata.createSerializer(format); + + // and serialize the content: transform from the EntitySet object to InputStream + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build(); + + EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build(); + SerializerResult serializedContent = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts); + + // Finally: configure the response object: set the body, headers and status code + response.setContent(serializedContent.getContent()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } +} diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java new file mode 100755 index 000000000..10d5023db --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java @@ -0,0 +1,189 @@ +/* + * 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 myservice.mynamespace.service; + +import java.io.InputStream; +import java.util.List; + +import myservice.mynamespace.data.Storage; +import myservice.mynamespace.util.Util; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.DeserializerException; +import org.apache.olingo.server.api.deserializer.DeserializerResult; +import org.apache.olingo.server.api.deserializer.ODataDeserializer; +import org.apache.olingo.server.api.processor.EntityProcessor; +import org.apache.olingo.server.api.serializer.EntitySerializerOptions; +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.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; + +public class DemoEntityProcessor implements EntityProcessor { + + private OData odata; + private Storage storage; + private ServiceMetadata serviceMetadata; + + + public DemoEntityProcessor(Storage storage) { + this.storage = storage; + } + + + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + } + + + public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) + throws ODataApplicationException, SerializerException { + + // 1. retrieve the Entity Type + List resourcePaths = uriInfo.getUriResourceParts(); + // Note: only in our example we can assume that the first segment is the EntitySet + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2. retrieve the data from backend + List keyPredicates = uriResourceEntitySet.getKeyPredicates(); + Entity entity = storage.readEntityData(edmEntitySet, keyPredicates); + + // 3. serialize + EdmEntityType entityType = edmEntitySet.getEntityType(); + + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build(); + // expand and select currently not supported + EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); + + ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = this.odata.createSerializer(oDataFormat); + SerializerResult result = serializer.entity(serviceMetadata, entityType, entity, options); + + //4. configure the response object + response.setContent(result.getContent()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + /* + * Example request: + * + * POST URL: http://localhost:8080/DemoService/DemoService.svc/Products + * Header: Content-Type: application/json; odata.metadata=minimal + * Request body: + { + "ID":3, + "Name":"Ergo Screen", + "Description":"17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960" + } + * */ + public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + + // 1. Retrieve the entity type from the URI + EdmEntitySet edmEntitySet = Util.getEdmEntitySet(uriInfo); + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // 2. create the data in backend + // 2.1. retrieve the payload from the POST request for the entity to create and deserialize it + InputStream requestInputStream = request.getBody(); + ODataFormat requestODataFormat = ODataFormat.fromContentType(requestFormat); + ODataDeserializer deserializer = this.odata.createDeserializer(requestODataFormat); + DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType); + Entity requestEntity = result.getEntity(); + // 2.2 do the creation in backend, which returns the newly created entity + Entity createdEntity = storage.createEntityData(edmEntitySet, requestEntity); + + // 3. serialize the response (we have to return the created entity) + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build(); + EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); // expand and select currently not supported + + ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = this.odata.createSerializer(oDataFormat); + SerializerResult serializedResponse = serializer.entity(serviceMetadata, edmEntityType, createdEntity, options); + + //4. configure the response object + response.setContent(serializedResponse.getContent()); + response.setStatusCode(HttpStatusCode.CREATED.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + + public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + + // 1. Retrieve the entity set which belongs to the requested entity + List resourcePaths = uriInfo.getUriResourceParts(); + // Note: only in our example we can assume that the first segment is the EntitySet + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // 2. update the data in backend + // 2.1. retrieve the payload from the PUT request for the entity to be updated + InputStream requestInputStream = request.getBody(); + ODataFormat requestODataFormat = ODataFormat.fromContentType(requestFormat); + ODataDeserializer deserializer = this.odata.createDeserializer(requestODataFormat); + DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType); + Entity requestEntity = result.getEntity(); + // 2.2 do the modification in backend + List keyPredicates = uriResourceEntitySet.getKeyPredicates(); + // Note that this updateEntity()-method is invoked for both PUT or PATCH operations + HttpMethod httpMethod = request.getMethod(); + storage.updateEntityData(edmEntitySet, keyPredicates, requestEntity, httpMethod); + + //3. configure the response object + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + + + public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { + + // 1. Retrieve the entity set which belongs to the requested entity + List resourcePaths = uriInfo.getUriResourceParts(); + // Note: only in our example we can assume that the first segment is the EntitySet + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2. delete the data in backend + List keyPredicates = uriResourceEntitySet.getKeyPredicates(); + storage.deleteEntityData(edmEntitySet, keyPredicates); + + //3. configure the response object + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } +} diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java new file mode 100755 index 000000000..ec4ba3a23 --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java @@ -0,0 +1,143 @@ +/* + * 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 myservice.mynamespace.service; + +import java.util.List; +import java.util.Locale; + +import myservice.mynamespace.data.Storage; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmProperty; +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.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +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.DeserializerException; +import org.apache.olingo.server.api.processor.PrimitiveProcessor; +import org.apache.olingo.server.api.serializer.ODataSerializer; +import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; +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.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; +import org.apache.olingo.server.api.uri.UriResourceProperty; + +public class DemoPrimitiveProcessor implements PrimitiveProcessor { + + private OData odata; + private Storage storage; + + public DemoPrimitiveProcessor(Storage storage) { + this.storage = storage; + } + + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + } + + + /* + * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name + * and the response: + * { + * @odata.context: "$metadata#Products/Name", + * value: "Notebook Basic 15" + * } + * */ + public void readPrimitive(ODataRequest request, ODataResponse response, + UriInfo uriInfo, ContentType responseFormat) + throws ODataApplicationException, SerializerException { + + // 1. Retrieve info from URI + // 1.1. retrieve the info about the requested entity set + List resourceParts = uriInfo.getUriResourceParts(); + // Note: only in our example we can rely that the first segment is the EntitySet + UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0); + EdmEntitySet edmEntitySet = uriEntityset.getEntitySet(); + // the key for the entity + List keyPredicates = uriEntityset.getKeyPredicates(); + + // 1.2. retrieve the requested (Edm) property + UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1); // the last segment is the Property + EdmProperty edmProperty = uriProperty.getProperty(); + String edmPropertyName = edmProperty.getName(); + // in our example, we know we have only primitive types in our model + EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType(); + + + // 2. retrieve data from backend + // 2.1. retrieve the entity data, for which the property has to be read + Entity entity = storage.readEntityData(edmEntitySet, keyPredicates); + if (entity == null) { // Bad request + throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + // 2.2. retrieve the property data from the entity + Property property = entity.getProperty(edmPropertyName); + if (property == null) { + throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + // 3. serialize + Object value = property.getValue(); + if (value != null) { + // 3.1. configure the serializer + ODataFormat format = ODataFormat.fromContentType(responseFormat); + ODataSerializer serializer = odata.createSerializer(format); + + ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build(); + PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build(); + // 3.2. serialize + SerializerResult result = serializer.primitive(edmPropertyType, property, options); + + //4. configure the response object + response.setContent(result.getContent()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + }else{ + // in case there's no value for the property, we can skip the serialization + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + } + + /* + * These processor methods are not handled in this tutorial + * + * */ + public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { + throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } +} diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java new file mode 100755 index 000000000..8ad19a02f --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java @@ -0,0 +1,122 @@ +/* + * 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 myservice.mynamespace.util; + +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.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +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.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.uri.UriInfoResource; +import org.apache.olingo.server.api.uri.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; + +public class Util { + + public static EdmEntitySet getEdmEntitySet(UriInfoResource uriInfo) throws ODataApplicationException { + + List resourcePaths = uriInfo.getUriResourceParts(); + // To get the entity set we have to interpret all URI segments + if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) { + // Here we should interpret the whole URI but in this example we do not support navigation so we throw an + // exception + throw new ODataApplicationException("Invalid resource type for first segment.", HttpStatusCode.NOT_IMPLEMENTED + .getStatusCode(), Locale.ENGLISH); + } + + UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0); + + return uriResource.getEntitySet(); + } + + public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet, + List keyParams) throws ODataApplicationException { + + List entityList = entitySet.getEntities(); + + // loop over all entities in order to find that one that matches all keys in request + // e.g. contacts(ContactID=1, CompanyID=1) + for (Entity entity: entityList) { + boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams); + if (foundEntity) { + return entity; + } + } + + return null; + } + + public static boolean + entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List keyParams) + throws ODataApplicationException { + + // loop over all keys + for (final UriParameter key : keyParams) { + // key + String keyName = key.getName(); + String keyText = key.getText(); + + // Edm: we need this info for the comparison below + EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName); + Boolean isNullable = edmKeyProperty.isNullable(); + Integer maxLength = edmKeyProperty.getMaxLength(); + Integer precision = edmKeyProperty.getPrecision(); + Boolean isUnicode = edmKeyProperty.isUnicode(); + Integer scale = edmKeyProperty.getScale(); + // get the EdmType in order to compare + EdmType edmType = edmKeyProperty.getType(); + EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType; + + // Runtime data: the value of the current entity + // don't need to check for null, this is done in olingo library + Object valueObject = entity.getProperty(keyName).getValue(); + + // now need to compare the valueObject with the keyText String + // this is done using the type.valueToString // + String valueAsString = null; + try { + valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode); + } catch (EdmPrimitiveTypeException e) { + throw new ODataApplicationException("Failed to retrieve String value", HttpStatusCode.INTERNAL_SERVER_ERROR + .getStatusCode(), Locale.ENGLISH, e); + } + + if (valueAsString == null) { + return false; + } + + boolean matches = valueAsString.equals(keyText); + if (!matches) { + // if any of the key properties is not found in the entity, we don't need to search further + return false; + } + } + + return true; + } +} diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/web/DemoServlet.java new file mode 100755 index 000000000..2e7b65ff2 --- /dev/null +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/web/DemoServlet.java @@ -0,0 +1,73 @@ +/* + * 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 myservice.mynamespace.web; + +import java.io.IOException; +import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import myservice.mynamespace.data.Storage; +import myservice.mynamespace.service.DemoEdmProvider; +import myservice.mynamespace.service.DemoEntityCollectionProcessor; +import myservice.mynamespace.service.DemoEntityProcessor; +import myservice.mynamespace.service.DemoPrimitiveProcessor; + +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataHttpHandler; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.edmx.EdmxReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DemoServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class); + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + try { + HttpSession session = req.getSession(true); + Storage storage = (Storage) session.getAttribute(Storage.class.getName()); + if (storage == null) { + storage = new Storage(); + session.setAttribute(Storage.class.getName(), storage); + } + + // create odata handler and configure it with EdmProvider and Processor + OData odata = OData.newInstance(); + ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList()); + ODataHttpHandler handler = odata.createHandler(edm); + handler.register(new DemoEntityCollectionProcessor(storage)); + handler.register(new DemoEntityProcessor(storage)); + handler.register(new DemoPrimitiveProcessor(storage)); + + // let the handler do the work + handler.process(req, resp); + } catch (RuntimeException e) { + LOG.error("Server Error occurred in ExampleServlet", e); + throw new ServletException(e); + } + } +} diff --git a/samples/tutorials/p3_write/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p3_write/src/main/webapp/WEB-INF/web.xml new file mode 100755 index 000000000..21de52a8f --- /dev/null +++ b/samples/tutorials/p3_write/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,40 @@ + + + + + + + DemoServlet + myservice.mynamespace.web.DemoServlet + 1 + + + + + DemoServlet + /DemoService.svc/* + + \ No newline at end of file diff --git a/samples/tutorials/p3_write/src/main/webapp/index.jsp b/samples/tutorials/p3_write/src/main/webapp/index.jsp new file mode 100755 index 000000000..7ffb4ba6f --- /dev/null +++ b/samples/tutorials/p3_write/src/main/webapp/index.jsp @@ -0,0 +1,26 @@ + + + +

Hello World!

+OData Olingo V4 Demo Service + + diff --git a/samples/tutorials/pom.xml b/samples/tutorials/pom.xml index ba862332c..e64da0a1d 100644 --- a/samples/tutorials/pom.xml +++ b/samples/tutorials/pom.xml @@ -36,6 +36,8 @@ p1_read + p2_readep + p3_write From 89d134e62f4cbdc3728de34ae04a9bd4eba8ff38 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Thu, 18 Jun 2015 16:27:11 +0200 Subject: [PATCH 14/16] [OLINGO-694] Adapted RAT plugin and fixed missing headers --- pom.xml | 1 + .../myservice/mynamespace/data/Storage.java | 18 ++++++++++++++++++ .../mynamespace/service/DemoEdmProvider.java | 18 ++++++++++++++++++ .../service/DemoEntityCollectionProcessor.java | 18 ++++++++++++++++++ .../service/DemoEntityProcessor.java | 18 ++++++++++++++++++ .../service/DemoPrimitiveProcessor.java | 18 ++++++++++++++++++ 6 files changed, 91 insertions(+) diff --git a/pom.xml b/pom.xml index 84ae71857..144f56ac7 100644 --- a/pom.xml +++ b/pom.xml @@ -552,6 +552,7 @@ + **/target/** **/META-INF/** **/*.txt **/*.ini diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java index be985f519..d5d16c299 100755 --- a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/data/Storage.java @@ -1,3 +1,21 @@ +/* + * 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 myservice.mynamespace.data; import java.util.ArrayList; diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java index 0b091ffc8..15140e19a 100755 --- a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java @@ -1,3 +1,21 @@ +/* + * 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 myservice.mynamespace.service; import java.util.ArrayList; diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java index 0835a4116..d69d5291f 100755 --- a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java @@ -1,3 +1,21 @@ +/* + * 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 myservice.mynamespace.service; import java.io.InputStream; diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java index dc633b1ae..e3c876787 100755 --- a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java @@ -1,3 +1,21 @@ +/* + * 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 myservice.mynamespace.service; import java.io.InputStream; diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java index 7c5b3155e..1ba0c750c 100755 --- a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java @@ -1,3 +1,21 @@ +/* + * 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 myservice.mynamespace.service; import java.io.InputStream; From 93999d510ea8fac1bd4d7d94ad2be1d2e7175592 Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Fri, 19 Jun 2015 06:46:01 +0200 Subject: [PATCH 15/16] [OLINGO-694] Changed final build name --- samples/tutorials/p1_read/pom.xml | 4 ++++ samples/tutorials/p2_readep/pom.xml | 4 ++++ samples/tutorials/p3_write/pom.xml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/samples/tutorials/p1_read/pom.xml b/samples/tutorials/p1_read/pom.xml index bcae4ef35..7f212c5f7 100755 --- a/samples/tutorials/p1_read/pom.xml +++ b/samples/tutorials/p1_read/pom.xml @@ -29,6 +29,10 @@ ${project.artifactId}-Webapp + + DemoService + + 2.5 4.0.0-beta-03 diff --git a/samples/tutorials/p2_readep/pom.xml b/samples/tutorials/p2_readep/pom.xml index abe0601cf..9a47d1c95 100755 --- a/samples/tutorials/p2_readep/pom.xml +++ b/samples/tutorials/p2_readep/pom.xml @@ -29,6 +29,10 @@ ${project.artifactId}-Webapp + + DemoService + + 2.5 4.0.0-beta-03 diff --git a/samples/tutorials/p3_write/pom.xml b/samples/tutorials/p3_write/pom.xml index 4511a6f5c..dc9ba693c 100755 --- a/samples/tutorials/p3_write/pom.xml +++ b/samples/tutorials/p3_write/pom.xml @@ -29,6 +29,10 @@ ${project.artifactId}-Webapp + + DemoService + + 2.5 4.0.0-beta-03 From 431938c1e6f513912fe0131ee4a220e20d9a474e Mon Sep 17 00:00:00 2001 From: Michael Bolz Date: Fri, 19 Jun 2015 06:56:44 +0200 Subject: [PATCH 16/16] [OLINGO-694] Minor code clean up in tutorials --- .../java/myservice/mynamespace/util/Util.java | 63 +-- .../myservice/mynamespace/data/Storage.java | 423 +++++++++--------- .../mynamespace/service/DemoEdmProvider.java | 10 +- .../service/DemoEntityProcessor.java | 13 +- .../service/DemoPrimitiveProcessor.java | 13 +- .../java/myservice/mynamespace/util/Util.java | 3 +- 6 files changed, 253 insertions(+), 272 deletions(-) diff --git a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java index 16c774564..c21d352c3 100755 --- a/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java +++ b/samples/tutorials/p2_readep/src/main/java/myservice/mynamespace/util/Util.java @@ -6,9 +6,9 @@ * 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 @@ -37,39 +37,25 @@ import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceEntitySet; public class Util { + + public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet, + List keyParams) throws ODataApplicationException { - public static EdmEntitySet getEdmEntitySet(UriInfoResource uriInfo) throws ODataApplicationException { - List resourcePaths = uriInfo.getUriResourceParts(); - // To get the entity set we have to interpret all URI segments - if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) { - // Here we should interpret the whole URI but in this example we do not support navigation so we throw an exception - throw new ODataApplicationException("Invalid resource type for first segment.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ENGLISH); - } - - UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0); - - return uriResource.getEntitySet(); - } + List entityList = entitySet.getEntities(); - - public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet, List keyParams) throws ODataApplicationException { - - List entityList = entitySet.getEntities(); - - // loop over all entities in order to find that one that matches all keys in request e.g. contacts(ContactID=1, CompanyID=1) - for(Entity entity : entityList){ - boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams); - if(foundEntity) { - return entity; - } - } - - return null; - } - - - public static boolean - entityMatchesAllKeys(EdmEntityType edmEntityType, Entity rt_entity, List keyParams) + // loop over all entities in order to find that one that matches all keys in request + // e.g. contacts(ContactID=1, CompanyID=1) + for (Entity entity: entityList) { + boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams); + if (foundEntity) { + return entity; + } + } + + return null; + } + + public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List keyParams) throws ODataApplicationException { // loop over all keys @@ -87,21 +73,20 @@ public class Util { Integer scale = edmKeyProperty.getScale(); // get the EdmType in order to compare EdmType edmType = edmKeyProperty.getType(); - // if(EdmType instanceof EdmPrimitiveType) // do we need this? EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType; // Runtime data: the value of the current entity // don't need to check for null, this is done in olingo library - Object valueObject = rt_entity.getProperty(keyName).getValue(); + Object valueObject = entity.getProperty(keyName).getValue(); // now need to compare the valueObject with the keyText String - // this is done using type.valueToString - String valueAsString = null; + // this is done using the type.valueToString + String valueAsString; try { valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode); } catch (EdmPrimitiveTypeException e) { - throw new ODataApplicationException("Failed to retrieve String value", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH, e); + throw new ODataApplicationException("Failed to retrieve String value", HttpStatusCode.INTERNAL_SERVER_ERROR + .getStatusCode(), Locale.ENGLISH, e); } if (valueAsString == null) { diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java index 3af32600d..ad5dd71c4 100755 --- a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/data/Storage.java @@ -6,9 +6,9 @@ * 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 @@ -38,235 +38,226 @@ import java.util.Locale; public class Storage { - - private List productList; - - - public Storage() { - - productList = new ArrayList(); - initSampleData(); - } + private List productList; - - - /* PUBLIC FACADE */ - - - public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{ - - // actually, this is only required if we have more than one Entity Sets - if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){ - return getProducts(); - } - - return null; - } - - - public Entity readEntityData(EdmEntitySet edmEntitySet, List keyParams) throws ODataApplicationException{ - - EdmEntityType edmEntityType = edmEntitySet.getEntityType(); - - // actually, this is only required if we have more than one Entity Type - if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ - return getProduct(edmEntityType, keyParams); - } - - return null; - } + public Storage() { + productList = new ArrayList(); + initSampleData(); + } - - public Entity createEntityData(EdmEntitySet edmEntitySet, Entity entityToCreate) { - - EdmEntityType edmEntityType = edmEntitySet.getEntityType(); - - // actually, this is only required if we have more than one Entity Type - if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ - return createProduct(edmEntityType, entityToCreate); - } - - return null; - } + /* PUBLIC FACADE */ + public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet) throws ODataApplicationException { - /** - * This method is invoked for PATCH or PUT requests - * */ - public void updateEntityData(EdmEntitySet edmEntitySet, List keyParams, Entity updateEntity, HttpMethod httpMethod) throws ODataApplicationException{ - - EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + // actually, this is only required if we have more than one Entity Sets + if (edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)) { + return getProducts(); + } - // actually, this is only required if we have more than one Entity Type - if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ - updateProduct(edmEntityType, keyParams, updateEntity, httpMethod); - } - } - + return null; + } - public void deleteEntityData(EdmEntitySet edmEntitySet, List keyParams) throws ODataApplicationException{ - - EdmEntityType edmEntityType = edmEntitySet.getEntityType(); - - // actually, this is only required if we have more than one Entity Type - if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){ - deleteProduct(edmEntityType, keyParams); - } - } + public Entity readEntityData(EdmEntitySet edmEntitySet, List keyParams) + throws ODataApplicationException { - - - /* INTERNAL */ - - private EntityCollection getProducts(){ - EntityCollection retEntitySet = new EntityCollection(); - - for(Entity productEntity : this.productList){ - retEntitySet.getEntities().add(productEntity); - } - - return retEntitySet; - } - - - private Entity getProduct(EdmEntityType edmEntityType, List keyParams) throws ODataApplicationException{ - - // the list of entities at runtime - EntityCollection entitySet = getProducts(); - - /* generic approach to find the requested entity */ - Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams); - - - if(requestedEntity == null){ - // this variable is null if our data doesn't contain an entity for the requested key - // Throw suitable exception - throw new ODataApplicationException("Entity for requested key doesn't exist", + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) { + return getProduct(edmEntityType, keyParams); + } + + return null; + } + + public Entity createEntityData(EdmEntitySet edmEntitySet, Entity entityToCreate) { + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) { + return createProduct(edmEntityType, entityToCreate); + } + + return null; + } + + /** + * This method is invoked for PATCH or PUT requests + * */ + public void updateEntityData(EdmEntitySet edmEntitySet, List keyParams, Entity updateEntity, + HttpMethod httpMethod) throws ODataApplicationException { + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) { + updateProduct(edmEntityType, keyParams, updateEntity, httpMethod); + } + } + + public void deleteEntityData(EdmEntitySet edmEntitySet, List keyParams) + throws ODataApplicationException { + + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + + // actually, this is only required if we have more than one Entity Type + if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) { + deleteProduct(edmEntityType, keyParams); + } + } + + /* INTERNAL */ + + private EntityCollection getProducts() { + EntityCollection retEntitySet = new EntityCollection(); + + for (Entity productEntity : this.productList) { + retEntitySet.getEntities().add(productEntity); + } + + return retEntitySet; + } + + private Entity getProduct(EdmEntityType edmEntityType, List keyParams) + throws ODataApplicationException { + + // the list of entities at runtime + EntityCollection entitySet = getProducts(); + + /* generic approach to find the requested entity */ + Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams); + + if (requestedEntity == null) { + // this variable is null if our data doesn't contain an entity for the requested key + // Throw suitable exception + throw new ODataApplicationException("Entity for requested key doesn't exist", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); - } - - return requestedEntity; - } - - - private Entity createProduct(EdmEntityType edmEntityType, Entity entity) { - - // the ID of the newly created product entity is generated automatically - int newId = 1; - while (productIdExists(newId)){ - newId++; - } - - Property idProperty = entity.getProperty("ID"); - if(idProperty != null){ - idProperty.setValue(ValueType.PRIMITIVE, new Integer(newId)); - }else{ - // as of OData v4 spec, the key property can be omitted from the POST request body - entity.getProperties().add(new Property(null, "ID", ValueType.PRIMITIVE, newId)); - } - - this.productList.add(entity); + } - return entity; - - } + return requestedEntity; + } + private Entity createProduct(EdmEntityType edmEntityType, Entity entity) { - private boolean productIdExists(int id){ - - for(Entity entity : this.productList){ - Integer existingID = (Integer) entity.getProperty("ID").getValue(); - if(existingID.intValue() == id){ - return true; - } - } - - return false; - } - - - private void updateProduct(EdmEntityType edmEntityType, List keyParams, Entity entity, HttpMethod httpMethod) throws ODataApplicationException{ - - Entity productEntity = getProduct(edmEntityType, keyParams); - if(productEntity == null){ - throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); - } - - // loop over all properties and replace the values with the values of the given payload - // Note: ignoring ComplexType, as we don't have it in our odata model - List existingProperties = productEntity.getProperties(); - for(Property existingProp : existingProperties){ - String propName = existingProp.getName(); - - // ignore the key properties, they aren't updateable - if(isKey(edmEntityType, propName)){ - continue; - } - - Property updateProperty = entity.getProperty(propName); - // the request payload might not consider ALL properties, so it can be null - if(updateProperty == null){ - // if a property has NOT been added to the request payload - // depending on the HttpMethod, our behavior is different - if(httpMethod.equals(HttpMethod.PATCH)){ - // as of the OData spec, in case of PATCH, the existing property is not touched - continue; // do nothing - }else if(httpMethod.equals(HttpMethod.PUT)){ - // as of the OData spec, in case of PUT, the existing property is set to null (or to default value) - existingProp.setValue(existingProp.getValueType(), null); - continue; - } - } - - // change the value of the properties - existingProp.setValue(existingProp.getValueType(), updateProperty.getValue()); - } - } + // the ID of the newly created product entity is generated automatically + int newId = 1; + while (productIdExists(newId)) { + newId++; + } - private void deleteProduct(EdmEntityType edmEntityType, List keyParams) throws ODataApplicationException{ - - Entity productEntity = getProduct(edmEntityType, keyParams); - if(productEntity == null){ - throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); - } - - this.productList.remove(productEntity); - } - - - - /* HELPER */ - - - private boolean isKey(EdmEntityType edmEntityType, String propertyName){ - List keyPropertyRefs = edmEntityType.getKeyPropertyRefs(); - for(EdmKeyPropertyRef propRef : keyPropertyRefs){ - String keyPropertyName = propRef.getName(); - if(keyPropertyName.equals(propertyName)){ - return true; - } - } - return false; - } + Property idProperty = entity.getProperty("ID"); + if (idProperty != null) { + idProperty.setValue(ValueType.PRIMITIVE, new Integer(newId)); + } else { + // as of OData v4 spec, the key property can be omitted from the POST request body + entity.getProperties().add(new Property(null, "ID", ValueType.PRIMITIVE, newId)); + } - - private void initSampleData(){ + this.productList.add(entity); - // add some sample product entities - productList.add(new Entity() - .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1)) - .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15")) - .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"))); + return entity; - productList.add(new Entity() - .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2)) - .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA")) - .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"))); + } - productList.add(new Entity() - .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3)) - .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen")) - .addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"))); + private boolean productIdExists(int id) { - } + for (Entity entity : this.productList) { + Integer existingID = (Integer) entity.getProperty("ID").getValue(); + if (existingID.intValue() == id) { + return true; + } + } + + return false; + } + + private void updateProduct(EdmEntityType edmEntityType, List keyParams, Entity entity, + HttpMethod httpMethod) throws ODataApplicationException { + + Entity productEntity = getProduct(edmEntityType, keyParams); + if (productEntity == null) { + throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + // loop over all properties and replace the values with the values of the given payload + // Note: ignoring ComplexType, as we don't have it in our odata model + List existingProperties = productEntity.getProperties(); + for (Property existingProp : existingProperties) { + String propName = existingProp.getName(); + + // ignore the key properties, they aren't updateable + if (isKey(edmEntityType, propName)) { + continue; + } + + Property updateProperty = entity.getProperty(propName); + // the request payload might not consider ALL properties, so it can be null + if (updateProperty == null) { + // if a property has NOT been added to the request payload + // depending on the HttpMethod, our behavior is different + if (httpMethod.equals(HttpMethod.PATCH)) { + // as of the OData spec, in case of PATCH, the existing property is not touched + continue; // do nothing + } else if (httpMethod.equals(HttpMethod.PUT)) { + // as of the OData spec, in case of PUT, the existing property is set to null (or to default value) + existingProp.setValue(existingProp.getValueType(), null); + continue; + } + } + + // change the value of the properties + existingProp.setValue(existingProp.getValueType(), updateProperty.getValue()); + } + } + + private void deleteProduct(EdmEntityType edmEntityType, List keyParams) + throws ODataApplicationException { + + Entity productEntity = getProduct(edmEntityType, keyParams); + if (productEntity == null) { + throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + } + + this.productList.remove(productEntity); + } + + /* HELPER */ + + private boolean isKey(EdmEntityType edmEntityType, String propertyName) { + List keyPropertyRefs = edmEntityType.getKeyPropertyRefs(); + for (EdmKeyPropertyRef propRef : keyPropertyRefs) { + String keyPropertyName = propRef.getName(); + if (keyPropertyName.equals(propertyName)) { + return true; + } + } + return false; + } + + private void initSampleData() { + + // add some sample product entities + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15")) + .addProperty( + new Property(null, "Description", ValueType.PRIMITIVE, + "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"))); + + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA")) + .addProperty( + new Property(null, "Description", ValueType.PRIMITIVE, + "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"))); + + productList.add(new Entity() + .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3)) + .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen")) + .addProperty( + new Property(null, "Description", ValueType.PRIMITIVE, + "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"))); + + } } diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java index 6a64b319c..f842af8ad 100755 --- a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java @@ -42,7 +42,6 @@ import org.apache.olingo.commons.api.edm.provider.CsdlSchema; */ public class DemoEdmProvider extends CsdlAbstractEdmProvider { - // Service Namespace public static final String NAMESPACE = "OData.Demo"; @@ -87,9 +86,12 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider { if(entityTypeName.equals(ET_PRODUCT_FQN)){ //create EntityType properties - CsdlProperty id = new CsdlProperty().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName()); - CsdlProperty name = new CsdlProperty().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); - CsdlProperty description = new CsdlProperty().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + CsdlProperty id = new CsdlProperty().setName("ID") + .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName()); + CsdlProperty name = new CsdlProperty().setName("Name") + .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); + CsdlProperty description = new CsdlProperty().setName("Description") + .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()); // create CsdlPropertyRef for Key element CsdlPropertyRef propertyRef = new CsdlPropertyRef(); diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java index 10d5023db..35d42033e 100755 --- a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java @@ -56,13 +56,11 @@ public class DemoEntityProcessor implements EntityProcessor { private OData odata; private Storage storage; private ServiceMetadata serviceMetadata; - - + public DemoEntityProcessor(Storage storage) { this.storage = storage; } - public void init(OData odata, ServiceMetadata serviceMetadata) { this.odata = odata; this.serviceMetadata = serviceMetadata; @@ -111,7 +109,8 @@ public class DemoEntityProcessor implements EntityProcessor { "Description":"17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960" } * */ - public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, + ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException { // 1. Retrieve the entity type from the URI @@ -143,7 +142,8 @@ public class DemoEntityProcessor implements EntityProcessor { } - public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, + ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException { // 1. Retrieve the entity set which belongs to the requested entity @@ -171,7 +171,8 @@ public class DemoEntityProcessor implements EntityProcessor { } - public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { + public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) + throws ODataApplicationException { // 1. Retrieve the entity set which belongs to the requested entity List resourcePaths = uriInfo.getUriResourceParts(); diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java index ec4ba3a23..ccf6d2b85 100755 --- a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java @@ -63,7 +63,6 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor { this.odata = odata; } - /* * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name * and the response: @@ -97,13 +96,15 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor { // 2.1. retrieve the entity data, for which the property has to be read Entity entity = storage.readEntityData(edmEntitySet, keyPredicates); if (entity == null) { // Bad request - throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + throw new ODataApplicationException("Entity not found", + HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } // 2.2. retrieve the property data from the entity Property property = entity.getProperty(edmPropertyName); if (property == null) { - throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); + throw new ODataApplicationException("Property not found", + HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH); } // 3. serialize @@ -132,12 +133,14 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor { * These processor methods are not handled in this tutorial * * */ - public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) + public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, + ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException { throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } - public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException { + public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo) + throws ODataApplicationException { throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } } diff --git a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java index 8ad19a02f..035cc7b95 100755 --- a/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java +++ b/samples/tutorials/p3_write/src/main/java/myservice/mynamespace/util/Util.java @@ -71,8 +71,7 @@ public class Util { return null; } - public static boolean - entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List keyParams) + public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List keyParams) throws ODataApplicationException { // loop over all keys