diff --git a/dist/android-lib/pom.xml b/dist/android-lib/pom.xml index 11c2ca673..1b648deaf 100644 --- a/dist/android-lib/pom.xml +++ b/dist/android-lib/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-dist - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/dist/client-lib/pom.xml b/dist/client-lib/pom.xml index 8203cf757..cc5885323 100644 --- a/dist/client-lib/pom.xml +++ b/dist/client-lib/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-dist - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/dist/javadoc/pom.xml b/dist/javadoc/pom.xml index 8ce097cbf..4c956ce94 100644 --- a/dist/javadoc/pom.xml +++ b/dist/javadoc/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-dist - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/dist/pom.xml b/dist/pom.xml index e0c2699ef..bce1e195f 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-parent - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/dist/server-lib/pom.xml b/dist/server-lib/pom.xml index 3a57bc667..bbc6bd256 100644 --- a/dist/server-lib/pom.xml +++ b/dist/server-lib/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-dist - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/ext/client-android/pom.xml b/ext/client-android/pom.xml index 3b928966c..c15e6036c 100644 --- a/ext/client-android/pom.xml +++ b/ext/client-android/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-ext - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/ext/client-proxy/pom.xml b/ext/client-proxy/pom.xml index 321715c42..9396a4486 100644 --- a/ext/client-proxy/pom.xml +++ b/ext/client-proxy/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-ext - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/ext/pojogen-maven-plugin/pom.xml b/ext/pojogen-maven-plugin/pom.xml index ad2e80d74..3a975c192 100644 --- a/ext/pojogen-maven-plugin/pom.xml +++ b/ext/pojogen-maven-plugin/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-ext - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/ext/pom.xml b/ext/pom.xml index d8fc4732f..a36be45f6 100644 --- a/ext/pom.xml +++ b/ext/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-parent - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/fit/pom.xml b/fit/pom.xml index 39a87510c..565916d1c 100644 --- a/fit/pom.xml +++ b/fit/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-parent - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. 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 39ed4cede..9c3c9e25a 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 @@ -28,20 +28,23 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; +import java.net.URI; import java.util.Collections; import java.util.Iterator; import java.util.List; -import org.apache.olingo.client.api.CommonODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.ODataServerErrorException; import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest; +import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest; +import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType; import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest; 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.XMLMetadataRequest; import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse; +import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.edm.xml.XMLMetadata; import org.apache.olingo.client.api.edm.xml.v4.Reference; @@ -52,14 +55,19 @@ import org.apache.olingo.commons.api.domain.ODataServiceDocument; import org.apache.olingo.commons.api.domain.v4.ODataAnnotation; import org.apache.olingo.commons.api.domain.v4.ODataEntity; import org.apache.olingo.commons.api.domain.v4.ODataEntitySet; +import org.apache.olingo.commons.api.domain.v4.ODataLinkedComplexValue; +import org.apache.olingo.commons.api.domain.v4.ODataObjectFactory; import org.apache.olingo.commons.api.domain.v4.ODataProperty; import org.apache.olingo.commons.api.domain.v4.ODataValue; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.FullQualifiedName; 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.fit.AbstractBaseTestITCase; import org.apache.olingo.fit.tecsvc.TecSvcConst; +import org.junit.Ignore; import org.junit.Test; public class BasicITCase extends AbstractBaseTestITCase { @@ -169,7 +177,7 @@ public class BasicITCase extends AbstractBaseTestITCase { } @Test - public void readEntity() throws IOException { + public void readEntity() throws Exception { final ODataEntityRequest request = getClient().getRetrieveRequestFactory() .getEntityRequest(getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment("ESCollAllPrim").appendKeySegment(1).build()); @@ -191,15 +199,150 @@ public class BasicITCase extends AbstractBaseTestITCase { assertEquals(30112, iterator.next().asPrimitive().toValue()); } + @Test + public void patchEntity() throws Exception { + final ODataClient client = getClient(); + final ODataObjectFactory factory = client.getObjectFactory(); + ODataEntity patchEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim")); + patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyString", + factory.newPrimitiveValueBuilder().buildString("new"))); + patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyDecimal", + factory.newPrimitiveValueBuilder().buildDouble(42.875))); + patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyInt64", + factory.newPrimitiveValueBuilder().buildInt64(null))); + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(32767) + .build(); + final ODataEntityUpdateRequest request = client.getCUDRequestFactory().getEntityUpdateRequest( + uri, UpdateType.PATCH, patchEntity); + final ODataEntityUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + + // Check that the patched properties have changed and the other properties not. + // This check has to be in the same session in order to access the same data provider. + ODataEntityRequest entityRequest = client.getRetrieveRequestFactory().getEntityRequest(uri); + entityRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next()); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + final ODataEntity entity = entityResponse.getBody(); + assertNotNull(entity); + final ODataProperty property1 = entity.getProperty("PropertyString"); + assertNotNull(property1); + assertEquals("new", property1.getPrimitiveValue().toValue()); + final ODataProperty property2 = entity.getProperty("PropertyDecimal"); + assertNotNull(property2); + assertEquals(42.875, property2.getPrimitiveValue().toValue()); + final ODataProperty property3 = entity.getProperty("PropertyInt64"); + assertNotNull(property3); + assertNull(property3.getPrimitiveValue()); + final ODataProperty property4 = entity.getProperty("PropertyDuration"); + assertNotNull(property4); + assertEquals("PT6S", property4.getPrimitiveValue().toValue()); + } + + @Test + public void updateEntity() throws Exception { + final ODataClient client = getClient(); + final ODataObjectFactory factory = client.getObjectFactory(); + ODataEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim")); + newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyInt64", + factory.newPrimitiveValueBuilder().buildInt32(42))); + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(32767) + .build(); + final ODataEntityUpdateRequest request = client.getCUDRequestFactory().getEntityUpdateRequest( + uri, UpdateType.REPLACE, newEntity); + final ODataEntityUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + + // Check that the updated properties have changed and that other properties have their default values. + // This check has to be in the same session in order to access the same data provider. + ODataEntityRequest entityRequest = client.getRetrieveRequestFactory().getEntityRequest(uri); + entityRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next()); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + final ODataEntity entity = entityResponse.getBody(); + assertNotNull(entity); + final ODataProperty property1 = entity.getProperty("PropertyInt64"); + assertNotNull(property1); + assertEquals(42, property1.getPrimitiveValue().toValue()); + final ODataProperty property2 = entity.getProperty("PropertyDecimal"); + assertNotNull(property2); + assertNull(property2.getPrimitiveValue()); + } + + @Test + public void patchEntityWithComplex() throws Exception { + final ODataClient client = getClient(); + final ODataObjectFactory factory = client.getObjectFactory(); + ODataEntity patchEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETCompComp")); + patchEntity.getProperties().add(factory.newComplexProperty("PropertyComp", + factory.newLinkedComplexValue("olingo.odata.test1.CTCompComp").add( + factory.newComplexProperty("PropertyComp", + factory.newLinkedComplexValue("olingo.odata.test1.CTTwoPrim").add( + factory.newPrimitiveProperty("PropertyInt16", + factory.newPrimitiveValueBuilder().buildInt32(42))))))); + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESCompComp").appendKeySegment(1).build(); + final ODataEntityUpdateRequest request = client.getCUDRequestFactory().getEntityUpdateRequest( + uri, UpdateType.PATCH, patchEntity); + final ODataEntityUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + + // Check that the patched properties have changed and the other properties not. + // This check has to be in the same session in order to access the same data provider. + ODataEntityRequest entityRequest = client.getRetrieveRequestFactory().getEntityRequest(uri); + entityRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next()); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + final ODataEntity entity = entityResponse.getBody(); + assertNotNull(entity); + final ODataLinkedComplexValue complex = entity.getProperty("PropertyComp").getLinkedComplexValue() + .get("PropertyComp").getLinkedComplexValue(); + assertNotNull(complex); + final ODataProperty property1 = complex.get("PropertyInt16"); + assertNotNull(property1); + assertEquals(42, property1.getPrimitiveValue().toValue()); + final ODataProperty property2 = complex.get("PropertyString"); + assertNotNull(property2); + assertEquals("String 1", property2.getPrimitiveValue().toValue()); + } + + @Test + @Ignore("Actual leads to an unexpected exception") + public void updateEntityWithComplex() throws Exception { + final ODataClient client = getClient(); + final ODataObjectFactory factory = client.getObjectFactory(); + ODataEntity newEntity = factory.newEntity(new FullQualifiedName("olingo.odata.test1", "ETCompComp")); + newEntity.getProperties().add(factory.newComplexProperty("PropertyComp", null)); + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESCompComp").appendKeySegment(1).build(); + final ODataEntityUpdateRequest request = client.getCUDRequestFactory().getEntityUpdateRequest( + uri, UpdateType.REPLACE, newEntity); + final ODataEntityUpdateResponse response = request.execute(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + + // Check that the complex-property hierarchy is still there and that all primitive values are now null. + // This check has to be in the same session in order to access the same data provider. + ODataEntityRequest entityRequest = client.getRetrieveRequestFactory().getEntityRequest(uri); + entityRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next()); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + final ODataEntity entity = entityResponse.getBody(); + assertNotNull(entity); + final ODataLinkedComplexValue complex = entity.getProperty("PropertyComp").getLinkedComplexValue() + .get("PropertyComp").getLinkedComplexValue(); + assertNotNull(complex); + final ODataProperty property = complex.get("PropertyInt16"); + assertNotNull(property); + assertNull(property.getPrimitiveValue()); + } + /** - * Actual an create request for an entity will lead to an "501 - Not Implemented" response - * and hence to an ODataServerErrorException + * Currently a create request for an entity will lead to a "501 - Not Implemented" response + * and hence to an ODataServerErrorException. */ @Test(expected = ODataServerErrorException.class) public void createEntity() throws IOException { final ODataEntityRequest request = getClient().getRetrieveRequestFactory() - .getEntityRequest(getClient().newURIBuilder(SERVICE_URI) - .appendEntitySetSegment("ESCollAllPrim").appendKeySegment(1).build()); + .getEntityRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESCollAllPrim").appendKeySegment(1).build()); assertNotNull(request); final ODataRetrieveResponse response = request.execute(); @@ -210,8 +353,8 @@ public class BasicITCase extends AbstractBaseTestITCase { assertNotNull(entity); final ODataEntityCreateRequest createRequest = getClient().getCUDRequestFactory() - .getEntityCreateRequest(getClient().newURIBuilder(SERVICE_URI) - .appendEntitySetSegment("ESCollAllPrim").build(), entity); + .getEntityCreateRequest(getClient().newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESCollAllPrim").build(), entity); assertNotNull(createRequest); ODataEntityCreateResponse createResponse = createRequest.execute(); @@ -228,7 +371,7 @@ public class BasicITCase extends AbstractBaseTestITCase { } @Override - protected CommonODataClient getClient() { + protected ODataClient getClient() { ODataClient odata = ODataClientFactory.getV4(); odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON); return odata; diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java index 18fa834a8..2e8269990 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/MediaITCase.java @@ -104,13 +104,7 @@ public final class MediaITCase extends AbstractBaseTestITCase { assertNotNull(request); final ODataMediaEntityUpdateResponse response = request.payloadManager().getResponse(); - assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); - final CommonODataEntity entity = response.getBody(); - assertNotNull(entity); - final CommonODataProperty property = entity.getProperty("PropertyInt16"); - assertNotNull(property); - assertNotNull(property.getPrimitiveValue()); - assertEquals(4, property.getPrimitiveValue().toValue()); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); // Check that the media stream has changed. // This check has to be in the same session in order to access the same data provider. diff --git a/lib/client-api/pom.xml b/lib/client-api/pom.xml index c284848d6..3ed98f622 100644 --- a/lib/client-api/pom.xml +++ b/lib/client-api/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml index ef3fc2e81..3218de814 100644 --- a/lib/client-core/pom.xml +++ b/lib/client-core/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/commons-api/pom.xml b/lib/commons-api/pom.xml index f4eb2a68b..4de91f0fa 100644 --- a/lib/commons-api/pom.xml +++ b/lib/commons-api/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/commons-core/pom.xml b/lib/commons-core/pom.xml index 8f510f0ce..10ad95182 100644 --- a/lib/commons-core/pom.xml +++ b/lib/commons-core/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/pom.xml b/lib/pom.xml index 775a6f88c..6843ff376 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-parent - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/server-api/pom.xml b/lib/server-api/pom.xml index 1b27d3fa4..e8c29e8b6 100644 --- a/lib/server-api/pom.xml +++ b/lib/server-api/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/server-core/pom.xml b/lib/server-core/pom.xml index c63505c98..1895b86c8 100644 --- a/lib/server-core/pom.xml +++ b/lib/server-core/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/server-tecsvc/pom.xml b/lib/server-tecsvc/pom.xml index dde3f12e4..f74f78cc8 100644 --- a/lib/server-tecsvc/pom.xml +++ b/lib/server-tecsvc/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java new file mode 100644 index 000000000..3e964eefe --- /dev/null +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java @@ -0,0 +1,506 @@ +/* + * 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.data; + +import java.nio.charset.Charset; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; + +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntitySet; +import org.apache.olingo.commons.api.data.Link; +import org.apache.olingo.commons.api.data.LinkedComplexValue; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.core.data.EntityImpl; +import org.apache.olingo.commons.core.data.EntitySetImpl; +import org.apache.olingo.commons.core.data.LinkImpl; +import org.apache.olingo.commons.core.data.LinkedComplexValueImpl; +import org.apache.olingo.commons.core.data.PropertyImpl; + +public class DataCreator { + + private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef"); + + private final Map data; + + public DataCreator() { + data = new HashMap(); + data.put("ESTwoPrim", createESTwoPrim()); + data.put("ESAllPrim", createESAllPrim()); + data.put("ESCompAllPrim", createESCompAllPrim()); + data.put("ESCollAllPrim", createESCollAllPrim()); + data.put("ESMixPrimCollComp", createESMixPrimCollComp()); + data.put("ESAllKey", createESAllKey()); + data.put("ESCompComp", createESCompComp()); + data.put("ESMedia", createESMedia()); + + linkESTwoPrim(data); + linkESAllPrim(data); + } + + Map getData() { + return data; + } + + private EntitySet createESTwoPrim() { + EntitySet entitySet = new EntitySetImpl(); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", 32766)) + .addProperty(createPrimitive("PropertyString", "Test String1"))); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", -365)) + .addProperty(createPrimitive("PropertyString", "Test String2"))); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", -32766)) + .addProperty(createPrimitive("PropertyString", null))); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) + .addProperty(createPrimitive("PropertyString", "Test String4"))); + + return entitySet; + } + + private EntitySet createESAllPrim() { + EntitySet entitySet = new EntitySetImpl(); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) + .addProperty(createPrimitive("PropertyString", "First Resource - positive values")) + .addProperty(createPrimitive("PropertyBoolean", true)) + .addProperty(createPrimitive("PropertyByte", 255)) + .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE)) + .addProperty(createPrimitive("PropertySingle", 1.79000000E+20)) + .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+19)) + .addProperty(createPrimitive("PropertyDecimal", 34)) + .addProperty(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })) + .addProperty(createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) + .addProperty(createPrimitive("PropertyDuration", 6)) + .addProperty(createPrimitive("PropertyGuid", GUID)) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(3, 26, 5)))); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", Short.MIN_VALUE)) + .addProperty(createPrimitive("PropertyString", "Second Resource - negative values")) + .addProperty(createPrimitive("PropertyBoolean", false)) + .addProperty(createPrimitive("PropertyByte", 0)) + .addProperty(createPrimitive("PropertySByte", Byte.MIN_VALUE)) + .addProperty(createPrimitive("PropertyInt32", Integer.MIN_VALUE)) + .addProperty(createPrimitive("PropertyInt64", Long.MIN_VALUE)) + .addProperty(createPrimitive("PropertySingle", -1.79000000E+08)) + .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+05)) + .addProperty(createPrimitive("PropertyDecimal", -34)) + .addProperty(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })) + .addProperty(createPrimitive("PropertyDate", getDateTime(2015, 11, 5, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 7, 17, 8))) + .addProperty(createPrimitive("PropertyDuration", 9)) + .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff"))) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14)))); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", 0)) + .addProperty(createPrimitive("PropertyString", "")) + .addProperty(createPrimitive("PropertyBoolean", false)) + .addProperty(createPrimitive("PropertyByte", 0)) + .addProperty(createPrimitive("PropertySByte", 0)) + .addProperty(createPrimitive("PropertyInt32", 0)) + .addProperty(createPrimitive("PropertyInt64", 0)) + .addProperty(createPrimitive("PropertySingle", 0)) + .addProperty(createPrimitive("PropertyDouble", 0)) + .addProperty(createPrimitive("PropertyDecimal", 0)) + .addProperty(createPrimitive("PropertyBinary", new byte[] {})) + .addProperty(createPrimitive("PropertyDate", getDateTime(1970, 1, 1, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDuration", 0)) + .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd"))) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1)))); + + return entitySet; + } + + private EntitySet createESCompAllPrim() { + EntitySet entitySet = new EntitySetImpl(); + + Entity entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)); + LinkedComplexValue complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyString", "First Resource - first")); + complexValue.getValue().add(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })); + complexValue.getValue().add(createPrimitive("PropertyBoolean", true)); + complexValue.getValue().add(createPrimitive("PropertyByte", 255)); + complexValue.getValue().add(createPrimitive("PropertyDate", getDateTime(2012, 10, 3, 0, 0, 0))); + complexValue.getValue().add(createPrimitive("PropertyDateTimeOffset", + getTimestamp(2012, 10, 3, 7, 16, 23, 123456700))); + complexValue.getValue().add(createPrimitive("PropertyDecimal", 34.27)); + complexValue.getValue().add(createPrimitive("PropertySingle", 1.79000000E+20)); + complexValue.getValue().add(createPrimitive("PropertyDouble", -1.7900000000000000E+19)); + complexValue.getValue().add(createPrimitive("PropertyDuration", 6)); + complexValue.getValue().add(createPrimitive("PropertyGuid", GUID)); + complexValue.getValue().add(createPrimitive("PropertyInt16", Short.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyInt32", Integer.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyInt64", Long.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertySByte", Byte.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyTimeOfDay", getTime(1, 0, 1))); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 7)); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyString", "Second Resource - second")); + complexValue.getValue().add(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })); + complexValue.getValue().add(createPrimitive("PropertyBoolean", true)); + complexValue.getValue().add(createPrimitive("PropertyByte", 255)); + complexValue.getValue().add(createPrimitive("PropertyDate", getDateTime(2013, 11, 4, 0, 0, 0))); + complexValue.getValue().add(createPrimitive("PropertyDateTimeOffset", + getDateTime(2013, 11, 4, 7, 16, 23))); + complexValue.getValue().add(createPrimitive("PropertyDecimal", 34.27)); + complexValue.getValue().add(createPrimitive("PropertySingle", 1.79000000E+20)); + complexValue.getValue().add(createPrimitive("PropertyDouble", -1.7900000000000000E+02)); + complexValue.getValue().add(createPrimitive("PropertyDuration", 6)); + complexValue.getValue().add(createPrimitive("PropertyGuid", GUID)); + complexValue.getValue().add(createPrimitive("PropertyInt16", 25)); + complexValue.getValue().add(createPrimitive("PropertyInt32", Integer.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyInt64", Long.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertySByte", Byte.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyTimeOfDay", getTimestamp(1, 1, 1, 7, 45, 12, 765432100))); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 0)); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyString", "Third Resource - third")); + complexValue.getValue().add(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })); + complexValue.getValue().add(createPrimitive("PropertyBoolean", true)); + complexValue.getValue().add(createPrimitive("PropertyByte", 255)); + complexValue.getValue().add(createPrimitive("PropertyDate", getDateTime(2014, 12, 5, 0, 0, 0))); + complexValue.getValue().add(createPrimitive("PropertyDateTimeOffset", + getTimestamp(2014, 12, 5, 8, 17, 45, 123456700))); + complexValue.getValue().add(createPrimitive("PropertyDecimal", 17.98)); + complexValue.getValue().add(createPrimitive("PropertySingle", 1.79000000E+20)); + complexValue.getValue().add(createPrimitive("PropertyDouble", -1.7900000000000000E+02)); + complexValue.getValue().add(createPrimitive("PropertyDuration", 6)); + complexValue.getValue().add(createPrimitive("PropertyGuid", GUID)); + complexValue.getValue().add(createPrimitive("PropertyInt16", -25)); + complexValue.getValue().add(createPrimitive("PropertyInt32", Integer.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyInt64", Long.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertySByte", Byte.MAX_VALUE)); + complexValue.getValue().add(createPrimitive("PropertyTimeOfDay", getTime(13, 27, 45))); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); + entitySet.getEntities().add(entity); + + return entitySet; + } + + private EntitySet createESCollAllPrim() { + EntitySet entitySet = new EntitySetImpl(); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyInt16", 1)) + .addProperty(createCollection("CollPropertyString", + "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")) + .addProperty(createCollection("CollPropertyBoolean", true, false, true)) + .addProperty(createCollection("CollPropertyByte", 50, 200, 249)) + .addProperty(createCollection("CollPropertySByte", -120, 120, 126)) + .addProperty(createCollection("CollPropertyInt16", 1000, 2000, 30112)) + .addProperty(createCollection("CollPropertyInt32", 23232323, 11223355, 10000001)) + .addProperty(createCollection("CollPropertyInt64", 929292929292L, 333333333333L, 444444444444L)) + .addProperty(createCollection("CollPropertySingle", 1.79000000E+03, 2.66000000E+04, 3.21000000E+03)) + .addProperty(createCollection("CollPropertyDouble", + -1.7900000000000000E+04, -2.7800000000000000E+07, 3.2100000000000000E+03)) + .addProperty(createCollection("CollPropertyDecimal", 12, -2, 1234)) + .addProperty(createCollection("CollPropertyBinary", + new byte[] { (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }, + new byte[] { 0x01, 0x23, 0x45 }, + new byte[] { 0x54, 0x67, (byte) 0x89 })) + .addProperty(createCollection("CollPropertyDate", + getDateTime(1958, 12, 3, 0, 0, 0), + getDateTime(1999, 8, 5, 0, 0, 0), + getDateTime(2013, 6, 25, 0, 0, 0))) + .addProperty(createCollection("CollPropertyDateTimeOffset", + getDateTime(2015, 8, 12, 3, 8, 34), + getDateTime(1970, 3, 28, 12, 11, 10), + getDateTime(1948, 2, 17, 9, 9, 9))) + .addProperty(createCollection("CollPropertyDuration", 13, 19680, 3600)) + .addProperty(createCollection("CollPropertyGuid", + UUID.fromString("ffffff67-89ab-cdef-0123-456789aaaaaa"), + UUID.fromString("eeeeee67-89ab-cdef-0123-456789bbbbbb"), + UUID.fromString("cccccc67-89ab-cdef-0123-456789cccccc"))) + .addProperty(createCollection("CollPropertyTimeOfDay", + getTime(4, 14, 13), getTime(23, 59, 59), getTime(1, 12, 33)))); + + Entity entity = new EntityImpl(); + entity.getProperties().addAll(entitySet.getEntities().get(0).getProperties()); + entity.getProperties().set(0, createPrimitive("PropertyInt16", 2)); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.getProperties().addAll(entitySet.getEntities().get(0).getProperties()); + entity.getProperties().set(0, createPrimitive("PropertyInt16", 3)); + entitySet.getEntities().add(entity); + + return entitySet; + } + + private EntitySet createESMixPrimCollComp() { + EntitySet entitySet = new EntitySetImpl(); + + Entity entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)); + entity.addProperty(createCollection("CollPropertyString", + "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")); + LinkedComplexValue complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyInt16", 111)); + complexValue.getValue().add(createPrimitive("PropertyString", "TEST A")); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); + List complexCollection = new ArrayList(); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyInt16", 123)); + complexValue.getValue().add(createPrimitive("PropertyString", "TEST 1")); + complexCollection.add(complexValue); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyInt16", 456)); + complexValue.getValue().add(createPrimitive("PropertyString", "TEST 2")); + complexCollection.add(complexValue); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyInt16", 789)); + complexValue.getValue().add(createPrimitive("PropertyString", "TEST 3")); + complexCollection.add(complexValue); + entity.addProperty(new PropertyImpl(null, "CollPropertyComp", ValueType.COLLECTION_LINKED_COMPLEX, + complexCollection)); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 7)); + entity.addProperty(createCollection("CollPropertyString", + "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyInt16", 222)); + complexValue.getValue().add(createPrimitive("PropertyString", "TEST B")); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); + entity.addProperty(new PropertyImpl(null, "CollPropertyComp", ValueType.COLLECTION_LINKED_COMPLEX, + complexCollection)); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 0)); + entity.addProperty(createCollection("CollPropertyString", + "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")); + complexValue = new LinkedComplexValueImpl(); + complexValue.getValue().add(createPrimitive("PropertyInt16", 333)); + complexValue.getValue().add(createPrimitive("PropertyString", "TEST C")); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); + entity.addProperty(new PropertyImpl(null, "CollPropertyComp", ValueType.COLLECTION_LINKED_COMPLEX, + complexCollection)); + entitySet.getEntities().add(entity); + + return entitySet; + } + + private EntitySet createESAllKey() { + EntitySet entitySet = new EntitySetImpl(); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyString", "First")) + .addProperty(createPrimitive("PropertyBoolean", true)) + .addProperty(createPrimitive("PropertyByte", 255)) + .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE)) + .addProperty(createPrimitive("PropertyDecimal", 34)) + .addProperty(createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) + .addProperty(createPrimitive("PropertyDuration", 6)) + .addProperty(createPrimitive("PropertyGuid", GUID)) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(2, 48, 21)))); + + entitySet.getEntities().add(new EntityImpl() + .addProperty(createPrimitive("PropertyString", "Second")) + .addProperty(createPrimitive("PropertyBoolean", true)) + .addProperty(createPrimitive("PropertyByte", 254)) + .addProperty(createPrimitive("PropertySByte", 124)) + .addProperty(createPrimitive("PropertyInt16", 32764)) + .addProperty(createPrimitive("PropertyInt32", 2147483644)) + .addProperty(createPrimitive("PropertyInt64", 9223372036854775804L)) + .addProperty(createPrimitive("PropertyDecimal", 34)) + .addProperty(createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) + .addProperty(createPrimitive("PropertyDuration", 6)) + .addProperty(createPrimitive("PropertyGuid", GUID)) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(2, 48, 21)))); + + return entitySet; + } + + private EntitySet createESCompComp() { + EntitySet entitySet = new EntitySetImpl(); + + Entity entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 1)); + LinkedComplexValue complexValueInner = new LinkedComplexValueImpl(); + complexValueInner.getValue().add(createPrimitive("PropertyInt16", 123)); + complexValueInner.getValue().add(createPrimitive("PropertyString", "String 1")); + LinkedComplexValue complexValueOuter = new LinkedComplexValueImpl(); + complexValueOuter.getValue().add( + new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueInner)); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueOuter)); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 2)); + complexValueInner = new LinkedComplexValueImpl(); + complexValueInner.getValue().add(createPrimitive("PropertyInt16", 987)); + complexValueInner.getValue().add(createPrimitive("PropertyString", "String 2")); + complexValueOuter = new LinkedComplexValueImpl(); + complexValueOuter.getValue().add( + new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueInner)); + entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueOuter)); + entitySet.getEntities().add(entity); + + return entitySet; + } + + private EntitySet createESMedia() { + EntitySet entitySet = new EntitySetImpl(); + + Entity entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 1)); + entity.addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("darkturquoise"))); + entity.setMediaContentType("image/svg+xml"); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 2)); + entity.addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("royalblue"))); + entity.setMediaContentType("image/svg+xml"); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 3)); + entity.addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("crimson"))); + entity.setMediaContentType("image/svg+xml"); + entitySet.getEntities().add(entity); + + entity = new EntityImpl(); + entity.addProperty(createPrimitive("PropertyInt16", 4)); + entity.addProperty(createPrimitive(DataProvider.MEDIA_PROPERTY_NAME, createImage("black"))); + entity.setMediaContentType("image/svg+xml"); + entitySet.getEntities().add(entity); + + return entitySet; + } + + private byte[] createImage(final String color) { + return ("\n" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n").getBytes(Charset.forName("UTF-8")); + } + + private void linkESTwoPrim(Map data) { + EntitySet entitySet = data.get("ESTwoPrim"); + final List targetEntities = data.get("ESAllPrim").getEntities(); + + setLinks(entitySet.getEntities().get(1), "NavPropertyETAllPrimMany", targetEntities.subList(1, 3)); + + setLink(entitySet.getEntities().get(3), "NavPropertyETAllPrimOne", targetEntities.get(0)); + } + + private void linkESAllPrim(Map data) { + EntitySet entitySet = data.get("ESAllPrim"); + final List targetEntities = data.get("ESTwoPrim").getEntities(); + + setLinks(entitySet.getEntities().get(0), "NavPropertyETTwoPrimMany", targetEntities.subList(1, 2)); + setLink(entitySet.getEntities().get(0), "NavPropertyETTwoPrimOne", targetEntities.get(3)); + + setLinks(entitySet.getEntities().get(2), "NavPropertyETTwoPrimMany", + Arrays.asList(targetEntities.get(0), targetEntities.get(2), targetEntities.get(3))); + } + + protected static Property createPrimitive(final String name, final Object value) { + return new PropertyImpl(null, name, ValueType.PRIMITIVE, value); + } + + protected static Property createCollection(final String name, final Object... values) { + return new PropertyImpl(null, name, ValueType.COLLECTION_PRIMITIVE, Arrays.asList(values)); + } + + private Calendar getDateTime(final int year, final int month, final int day, + final int hour, final int minute, final int second) { + Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + dateTime.clear(); + dateTime.set(year, month - 1, day, hour, minute, second); + return dateTime; + } + + private Calendar getTime(final int hour, final int minute, final int second) { + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + time.clear(); + time.set(Calendar.HOUR_OF_DAY, hour); + time.set(Calendar.MINUTE, minute); + time.set(Calendar.SECOND, second); + return time; + } + + private Timestamp getTimestamp(final int year, final int month, final int day, + final int hour, final int minute, final int second, final int nanosecond) { + Timestamp timestamp = new Timestamp(getDateTime(year, month, day, hour, minute, second).getTimeInMillis()); + timestamp.setNanos(nanosecond); + return timestamp; + } + + protected static void setLink(Entity entity, final String navigationPropertyName, final Entity target) { + Link link = new LinkImpl(); + link.setTitle(navigationPropertyName); + link.setInlineEntity(target); + entity.getNavigationLinks().add(link); + } + + protected static void setLinks(Entity entity, final String navigationPropertyName, final List targets) { + Link link = new LinkImpl(); + link.setTitle(navigationPropertyName); + EntitySet target = new EntitySetImpl(); + target.getEntities().addAll(targets); + link.setInlineEntitySet(target); + entity.getNavigationLinks().add(link); + } +} diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index 07b748d22..925dbf8ed 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@ -18,25 +18,17 @@ */ package org.apache.olingo.server.tecsvc.data; -import java.nio.charset.Charset; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; -import java.util.UUID; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.Link; -import org.apache.olingo.commons.api.data.LinkedComplexValue; import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; @@ -44,33 +36,17 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.commons.core.data.EntityImpl; -import org.apache.olingo.commons.core.data.EntitySetImpl; -import org.apache.olingo.commons.core.data.LinkImpl; -import org.apache.olingo.commons.core.data.LinkedComplexValueImpl; -import org.apache.olingo.commons.core.data.PropertyImpl; import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.uri.UriParameter; public class DataProvider { - private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef"); - private static final String MEDIA_PROPERTY_NAME = "$value"; + protected static final String MEDIA_PROPERTY_NAME = "$value"; private Map data; public DataProvider() { - data = new HashMap(); - data.put("ESTwoPrim", createESTwoPrim()); - data.put("ESAllPrim", createESAllPrim()); - data.put("ESCompAllPrim", createESCompAllPrim()); - data.put("ESCollAllPrim", createESCollAllPrim()); - data.put("ESMixPrimCollComp", createESMixPrimCollComp()); - data.put("ESAllKey", createESAllKey()); - data.put("ESCompComp", createESCompComp()); - data.put("ESMedia", createESMedia()); - - linkESTwoPrim(); - linkESAllPrim(); + data = new DataCreator().getData(); } public EntitySet readAll(final EdmEntitySet edmEntitySet) throws DataProviderException { @@ -142,7 +118,7 @@ public class DataProvider { Entity entity = new EntityImpl(); final List keyNames = edmEntitySet.getEntityType().getKeyPredicateNames(); if (keyNames.size() == 1 && keyNames.get(0).equals("PropertyInt16")) { - entity.addProperty(createPrimitive("PropertyInt16", + entity.addProperty(DataCreator.createPrimitive("PropertyInt16", entities.isEmpty() ? 1 : (Integer) entities.get(entities.size() - 1).getProperty("PropertyInt16").getValue() + 1)); } else { @@ -152,13 +128,64 @@ public class DataProvider { return entity; } + public void update(final EdmEntitySet edmEntitySet, Entity entity, final Entity changedEntity, final boolean patch) + throws DataProviderException { + final EdmEntityType entityType = edmEntitySet.getEntityType(); + final List keyNames = entityType.getKeyPredicateNames(); + for (final String propertyName : entityType.getPropertyNames()) { + if (!keyNames.contains(propertyName)) { + updateProperty(entityType.getStructuralProperty(propertyName), + entity.getProperty(propertyName), + changedEntity.getProperty(propertyName), + patch); + } + } + if (!changedEntity.getNavigationBindings().isEmpty()) { + throw new DataProviderException("Binding operations are not yet supported."); + } + } + + public void updateProperty(final EdmProperty edmProperty, Property property, final Property newProperty, + final boolean patch) throws DataProviderException { + if (edmProperty.isCollection() && !edmProperty.isPrimitive()) { + throw new DataProviderException("Complex-collection properties are not yet supported."); + } else if (property.isPrimitive()) { + if (newProperty != null || !patch) { + final Object value = newProperty == null ? null : newProperty.getValue(); + if (value == null && edmProperty.isNullable() != null && !edmProperty.isNullable()) { + throw new DataProviderException("Cannot null non-nullable property!"); + } + property.setValue(property.getValueType(), value); + } + } else { + final EdmComplexType type = (EdmComplexType) edmProperty.getType(); + for (final String propertyName : type.getPropertyNames()) { + final List newProperties = newProperty == null ? null : + newProperty.isComplex() ? newProperty.asComplex() : newProperty.asLinkedComplex().getValue(); + updateProperty(type.getStructuralProperty(propertyName), + findProperty(propertyName, property.asLinkedComplex().getValue()), + newProperties == null ? null : findProperty(propertyName, newProperties), + patch); + } + } + } + + private Property findProperty(final String propertyName, final List properties) { + for (final Property property : properties) { + if (propertyName.equals(property.getName())) { + return property; + } + } + return null; + } + public byte[] readMedia(final Entity entity) { return (byte[]) entity.getProperty(MEDIA_PROPERTY_NAME).asPrimitive(); } public void setMedia(Entity entity, byte[] media, String type) { entity.getProperties().remove(entity.getProperty(MEDIA_PROPERTY_NAME)); - entity.addProperty(createPrimitive(MEDIA_PROPERTY_NAME, media)); + entity.addProperty(DataCreator.createPrimitive(MEDIA_PROPERTY_NAME, media)); entity.setMediaContentType(type); } @@ -173,438 +200,4 @@ public class DataProvider { super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); } } - - private EntitySet createESTwoPrim() { - EntitySet entitySet = new EntitySetImpl(); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", 32766)) - .addProperty(createPrimitive("PropertyString", "Test String1"))); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", -365)) - .addProperty(createPrimitive("PropertyString", "Test String2"))); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", -32766)) - .addProperty(createPrimitive("PropertyString", null))); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) - .addProperty(createPrimitive("PropertyString", "Test String4"))); - - return entitySet; - } - - private EntitySet createESAllPrim() { - EntitySet entitySet = new EntitySetImpl(); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) - .addProperty(createPrimitive("PropertyString", "First Resource - positive values")) - .addProperty(createPrimitive("PropertyBoolean", true)) - .addProperty(createPrimitive("PropertyByte", 255)) - .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE)) - .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE)) - .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE)) - .addProperty(createPrimitive("PropertySingle", 1.79000000E+20)) - .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+19)) - .addProperty(createPrimitive("PropertyDecimal", 34)) - .addProperty(createPrimitive("PropertyBinary", - new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })) - .addProperty(createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))) - .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) - .addProperty(createPrimitive("PropertyDuration", 6)) - .addProperty(createPrimitive("PropertyGuid", GUID)) - .addProperty(createPrimitive("PropertyTimeOfDay", getTime(3, 26, 5)))); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", Short.MIN_VALUE)) - .addProperty(createPrimitive("PropertyString", "Second Resource - negative values")) - .addProperty(createPrimitive("PropertyBoolean", false)) - .addProperty(createPrimitive("PropertyByte", 0)) - .addProperty(createPrimitive("PropertySByte", Byte.MIN_VALUE)) - .addProperty(createPrimitive("PropertyInt32", Integer.MIN_VALUE)) - .addProperty(createPrimitive("PropertyInt64", Long.MIN_VALUE)) - .addProperty(createPrimitive("PropertySingle", -1.79000000E+08)) - .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+05)) - .addProperty(createPrimitive("PropertyDecimal", -34)) - .addProperty(createPrimitive("PropertyBinary", - new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })) - .addProperty(createPrimitive("PropertyDate", getDateTime(2015, 11, 5, 0, 0, 0))) - .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 7, 17, 8))) - .addProperty(createPrimitive("PropertyDuration", 9)) - .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff"))) - .addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14)))); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", 0)) - .addProperty(createPrimitive("PropertyString", "")) - .addProperty(createPrimitive("PropertyBoolean", false)) - .addProperty(createPrimitive("PropertyByte", 0)) - .addProperty(createPrimitive("PropertySByte", 0)) - .addProperty(createPrimitive("PropertyInt32", 0)) - .addProperty(createPrimitive("PropertyInt64", 0)) - .addProperty(createPrimitive("PropertySingle", 0)) - .addProperty(createPrimitive("PropertyDouble", 0)) - .addProperty(createPrimitive("PropertyDecimal", 0)) - .addProperty(createPrimitive("PropertyBinary", new byte[] {})) - .addProperty(createPrimitive("PropertyDate", getDateTime(1970, 1, 1, 0, 0, 0))) - .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0))) - .addProperty(createPrimitive("PropertyDuration", 0)) - .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd"))) - .addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1)))); - - return entitySet; - } - - private EntitySet createESCompAllPrim() { - EntitySet entitySet = new EntitySetImpl(); - - Entity entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)); - LinkedComplexValue complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyString", "First Resource - first")); - complexValue.getValue().add(createPrimitive("PropertyBinary", - new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })); - complexValue.getValue().add(createPrimitive("PropertyBoolean", true)); - complexValue.getValue().add(createPrimitive("PropertyByte", 255)); - complexValue.getValue().add(createPrimitive("PropertyDate", getDateTime(2012, 10, 3, 0, 0, 0))); - complexValue.getValue().add(createPrimitive("PropertyDateTimeOffset", - getTimestamp(2012, 10, 3, 7, 16, 23, 123456700))); - complexValue.getValue().add(createPrimitive("PropertyDecimal", 34.27)); - complexValue.getValue().add(createPrimitive("PropertySingle", 1.79000000E+20)); - complexValue.getValue().add(createPrimitive("PropertyDouble", -1.7900000000000000E+19)); - complexValue.getValue().add(createPrimitive("PropertyDuration", 6)); - complexValue.getValue().add(createPrimitive("PropertyGuid", GUID)); - complexValue.getValue().add(createPrimitive("PropertyInt16", Short.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyInt32", Integer.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyInt64", Long.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertySByte", Byte.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyTimeOfDay", getTime(1, 0, 1))); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 7)); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyString", "Second Resource - second")); - complexValue.getValue().add(createPrimitive("PropertyBinary", - new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })); - complexValue.getValue().add(createPrimitive("PropertyBoolean", true)); - complexValue.getValue().add(createPrimitive("PropertyByte", 255)); - complexValue.getValue().add(createPrimitive("PropertyDate", getDateTime(2013, 11, 4, 0, 0, 0))); - complexValue.getValue().add(createPrimitive("PropertyDateTimeOffset", - getDateTime(2013, 11, 4, 7, 16, 23))); - complexValue.getValue().add(createPrimitive("PropertyDecimal", 34.27)); - complexValue.getValue().add(createPrimitive("PropertySingle", 1.79000000E+20)); - complexValue.getValue().add(createPrimitive("PropertyDouble", -1.7900000000000000E+02)); - complexValue.getValue().add(createPrimitive("PropertyDuration", 6)); - complexValue.getValue().add(createPrimitive("PropertyGuid", GUID)); - complexValue.getValue().add(createPrimitive("PropertyInt16", 25)); - complexValue.getValue().add(createPrimitive("PropertyInt32", Integer.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyInt64", Long.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertySByte", Byte.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyTimeOfDay", getTimestamp(1, 1, 1, 7, 45, 12, 765432100))); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 0)); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyString", "Third Resource - third")); - complexValue.getValue().add(createPrimitive("PropertyBinary", - new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })); - complexValue.getValue().add(createPrimitive("PropertyBoolean", true)); - complexValue.getValue().add(createPrimitive("PropertyByte", 255)); - complexValue.getValue().add(createPrimitive("PropertyDate", getDateTime(2014, 12, 5, 0, 0, 0))); - complexValue.getValue().add(createPrimitive("PropertyDateTimeOffset", - getTimestamp(2014, 12, 5, 8, 17, 45, 123456700))); - complexValue.getValue().add(createPrimitive("PropertyDecimal", 17.98)); - complexValue.getValue().add(createPrimitive("PropertySingle", 1.79000000E+20)); - complexValue.getValue().add(createPrimitive("PropertyDouble", -1.7900000000000000E+02)); - complexValue.getValue().add(createPrimitive("PropertyDuration", 6)); - complexValue.getValue().add(createPrimitive("PropertyGuid", GUID)); - complexValue.getValue().add(createPrimitive("PropertyInt16", -25)); - complexValue.getValue().add(createPrimitive("PropertyInt32", Integer.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyInt64", Long.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertySByte", Byte.MAX_VALUE)); - complexValue.getValue().add(createPrimitive("PropertyTimeOfDay", getTime(13, 27, 45))); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); - entitySet.getEntities().add(entity); - - return entitySet; - } - - private EntitySet createESCollAllPrim() { - EntitySet entitySet = new EntitySetImpl(); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyInt16", 1)) - .addProperty(createCollection("CollPropertyString", - "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")) - .addProperty(createCollection("CollPropertyBoolean", true, false, true)) - .addProperty(createCollection("CollPropertyByte", 50, 200, 249)) - .addProperty(createCollection("CollPropertySByte", -120, 120, 126)) - .addProperty(createCollection("CollPropertyInt16", 1000, 2000, 30112)) - .addProperty(createCollection("CollPropertyInt32", 23232323, 11223355, 10000001)) - .addProperty(createCollection("CollPropertyInt64", 929292929292L, 333333333333L, 444444444444L)) - .addProperty(createCollection("CollPropertySingle", 1.79000000E+03, 2.66000000E+04, 3.21000000E+03)) - .addProperty(createCollection("CollPropertyDouble", - -1.7900000000000000E+04, -2.7800000000000000E+07, 3.2100000000000000E+03)) - .addProperty(createCollection("CollPropertyDecimal", 12, -2, 1234)) - .addProperty(createCollection("CollPropertyBinary", - new byte[] { (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }, - new byte[] { 0x01, 0x23, 0x45 }, - new byte[] { 0x54, 0x67, (byte) 0x89 })) - .addProperty(createCollection("CollPropertyDate", - getDateTime(1958, 12, 3, 0, 0, 0), - getDateTime(1999, 8, 5, 0, 0, 0), - getDateTime(2013, 6, 25, 0, 0, 0))) - .addProperty(createCollection("CollPropertyDateTimeOffset", - getDateTime(2015, 8, 12, 3, 8, 34), - getDateTime(1970, 3, 28, 12, 11, 10), - getDateTime(1948, 2, 17, 9, 9, 9))) - .addProperty(createCollection("CollPropertyDuration", 13, 19680, 3600)) - .addProperty(createCollection("CollPropertyGuid", - UUID.fromString("ffffff67-89ab-cdef-0123-456789aaaaaa"), - UUID.fromString("eeeeee67-89ab-cdef-0123-456789bbbbbb"), - UUID.fromString("cccccc67-89ab-cdef-0123-456789cccccc"))) - .addProperty(createCollection("CollPropertyTimeOfDay", - getTime(4, 14, 13), getTime(23, 59, 59), getTime(1, 12, 33)))); - - Entity entity = new EntityImpl(); - entity.getProperties().addAll(entitySet.getEntities().get(0).getProperties()); - entity.getProperties().set(0, createPrimitive("PropertyInt16", 2)); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.getProperties().addAll(entitySet.getEntities().get(0).getProperties()); - entity.getProperties().set(0, createPrimitive("PropertyInt16", 3)); - entitySet.getEntities().add(entity); - - return entitySet; - } - - private EntitySet createESMixPrimCollComp() { - EntitySet entitySet = new EntitySetImpl(); - - Entity entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)); - entity.addProperty(createCollection("CollPropertyString", - "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")); - LinkedComplexValue complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyInt16", 111)); - complexValue.getValue().add(createPrimitive("PropertyString", "TEST A")); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); - List complexCollection = new ArrayList(); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyInt16", 123)); - complexValue.getValue().add(createPrimitive("PropertyString", "TEST 1")); - complexCollection.add(complexValue); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyInt16", 456)); - complexValue.getValue().add(createPrimitive("PropertyString", "TEST 2")); - complexCollection.add(complexValue); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyInt16", 789)); - complexValue.getValue().add(createPrimitive("PropertyString", "TEST 3")); - complexCollection.add(complexValue); - entity.addProperty(new PropertyImpl(null, "CollPropertyComp", ValueType.COLLECTION_LINKED_COMPLEX, - complexCollection)); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 7)); - entity.addProperty(createCollection("CollPropertyString", - "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyInt16", 222)); - complexValue.getValue().add(createPrimitive("PropertyString", "TEST B")); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); - entity.addProperty(new PropertyImpl(null, "CollPropertyComp", ValueType.COLLECTION_LINKED_COMPLEX, - complexCollection)); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 0)); - entity.addProperty(createCollection("CollPropertyString", - "Employee1@company.example", "Employee2@company.example", "Employee3@company.example")); - complexValue = new LinkedComplexValueImpl(); - complexValue.getValue().add(createPrimitive("PropertyInt16", 333)); - complexValue.getValue().add(createPrimitive("PropertyString", "TEST C")); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValue)); - entity.addProperty(new PropertyImpl(null, "CollPropertyComp", ValueType.COLLECTION_LINKED_COMPLEX, - complexCollection)); - entitySet.getEntities().add(entity); - - return entitySet; - } - - private EntitySet createESAllKey() { - EntitySet entitySet = new EntitySetImpl(); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyString", "First")) - .addProperty(createPrimitive("PropertyBoolean", true)) - .addProperty(createPrimitive("PropertyByte", 255)) - .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE)) - .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) - .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE)) - .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE)) - .addProperty(createPrimitive("PropertyDecimal", 34)) - .addProperty(createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))) - .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) - .addProperty(createPrimitive("PropertyDuration", 6)) - .addProperty(createPrimitive("PropertyGuid", GUID)) - .addProperty(createPrimitive("PropertyTimeOfDay", getTime(2, 48, 21)))); - - entitySet.getEntities().add(new EntityImpl() - .addProperty(createPrimitive("PropertyString", "Second")) - .addProperty(createPrimitive("PropertyBoolean", true)) - .addProperty(createPrimitive("PropertyByte", 254)) - .addProperty(createPrimitive("PropertySByte", 124)) - .addProperty(createPrimitive("PropertyInt16", 32764)) - .addProperty(createPrimitive("PropertyInt32", 2147483644)) - .addProperty(createPrimitive("PropertyInt64", 9223372036854775804L)) - .addProperty(createPrimitive("PropertyDecimal", 34)) - .addProperty(createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))) - .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) - .addProperty(createPrimitive("PropertyDuration", 6)) - .addProperty(createPrimitive("PropertyGuid", GUID)) - .addProperty(createPrimitive("PropertyTimeOfDay", getTime(2, 48, 21)))); - - return entitySet; - } - - private EntitySet createESCompComp() { - EntitySet entitySet = new EntitySetImpl(); - - Entity entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 1)); - LinkedComplexValue complexValueInner = new LinkedComplexValueImpl(); - complexValueInner.getValue().add(createPrimitive("PropertyInt16", 123)); - complexValueInner.getValue().add(createPrimitive("PropertyString", "String 1")); - LinkedComplexValue complexValueOuter = new LinkedComplexValueImpl(); - complexValueOuter.getValue().add( - new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueInner)); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueOuter)); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 2)); - complexValueInner = new LinkedComplexValueImpl(); - complexValueInner.getValue().add(createPrimitive("PropertyInt16", 987)); - complexValueInner.getValue().add(createPrimitive("PropertyString", "String 2")); - complexValueOuter = new LinkedComplexValueImpl(); - complexValueOuter.getValue().add( - new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueInner)); - entity.addProperty(new PropertyImpl(null, "PropertyComp", ValueType.LINKED_COMPLEX, complexValueOuter)); - entitySet.getEntities().add(entity); - - return entitySet; - } - - private EntitySet createESMedia() { - EntitySet entitySet = new EntitySetImpl(); - - Entity entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 1)); - setMedia(entity, createImage("darkturquoise"), "image/svg+xml"); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 2)); - setMedia(entity, createImage("royalblue"), "image/svg+xml"); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 3)); - setMedia(entity, createImage("crimson"), "image/svg+xml"); - entitySet.getEntities().add(entity); - - entity = new EntityImpl(); - entity.addProperty(createPrimitive("PropertyInt16", 4)); - setMedia(entity, createImage("black"), "image/svg+xml"); - entitySet.getEntities().add(entity); - - return entitySet; - } - - private static byte[] createImage(final String color) { - return ("\n" - + "\n" - + " \n" - + " \n" - + " \n" - + "\n").getBytes(Charset.forName("UTF-8")); - } - - private void linkESTwoPrim() { - EntitySet entitySet = data.get("ESTwoPrim"); - final List targetEntities = data.get("ESAllPrim").getEntities(); - - setLinks(entitySet.getEntities().get(1), "NavPropertyETAllPrimMany", targetEntities.subList(1, 3)); - - setLink(entitySet.getEntities().get(3), "NavPropertyETAllPrimOne", targetEntities.get(0)); - } - - private void linkESAllPrim() { - EntitySet entitySet = data.get("ESAllPrim"); - final List targetEntities = data.get("ESTwoPrim").getEntities(); - - setLinks(entitySet.getEntities().get(0), "NavPropertyETTwoPrimMany", targetEntities.subList(1, 2)); - setLink(entitySet.getEntities().get(0), "NavPropertyETTwoPrimOne", targetEntities.get(3)); - - setLinks(entitySet.getEntities().get(2), "NavPropertyETTwoPrimMany", - Arrays.asList(targetEntities.get(0), targetEntities.get(2), targetEntities.get(3))); - } - - private Property createPrimitive(final String name, final Object value) { - return new PropertyImpl(null, name, ValueType.PRIMITIVE, value); - } - - private Property createCollection(final String name, final Object... values) { - return new PropertyImpl(null, name, ValueType.COLLECTION_PRIMITIVE, Arrays.asList(values)); - } - - private Calendar getDateTime(final int year, final int month, final int day, - final int hour, final int minute, final int second) { - Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - dateTime.clear(); - dateTime.set(year, month - 1, day, hour, minute, second); - return dateTime; - } - - private Calendar getTime(final int hour, final int minute, final int second) { - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - time.clear(); - time.set(Calendar.HOUR_OF_DAY, hour); - time.set(Calendar.MINUTE, minute); - time.set(Calendar.SECOND, second); - return time; - } - - private Timestamp getTimestamp(final int year, final int month, final int day, - final int hour, final int minute, final int second, final int nanosecond) { - Timestamp timestamp = new Timestamp(getDateTime(year, month, day, hour, minute, second).getTimeInMillis()); - timestamp.setNanos(nanosecond); - return timestamp; - } - - private void setLink(Entity entity, final String navigationPropertyName, final Entity target) { - Link link = new LinkImpl(); - link.setTitle(navigationPropertyName); - link.setInlineEntity(target); - entity.getNavigationLinks().add(link); - } - - private void setLinks(Entity entity, final String navigationPropertyName, final List targets) { - Link link = new LinkImpl(); - link.setTitle(navigationPropertyName); - EntitySet target = new EntitySetImpl(); - target.getEntities().addAll(targets); - link.setInlineEntitySet(target); - entity.getNavigationLinks().add(link); - } } 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 f86a64c1d..3400b0dac 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 @@ -30,11 +30,13 @@ import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpContentType; import org.apache.olingo.commons.api.http.HttpHeader; +import org.apache.olingo.commons.api.http.HttpMethod; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.deserializer.DeserializerException; +import org.apache.olingo.server.api.deserializer.ODataDeserializer; import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor; import org.apache.olingo.server.api.processor.ActionEntityProcessor; import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor; @@ -94,16 +96,15 @@ public class TechnicalEntityProcessor extends TechnicalProcessor @Override public void processActionEntityCollection(final ODataRequest request, final ODataResponse response, - final UriInfo uriInfo, - final ContentType requestFormat, final ContentType responseFormat) + final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException { throw new ODataApplicationException("Process entity collection is not supported yet.", - HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } @Override public void countEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) - throws ODataApplicationException, SerializerException { + throws ODataApplicationException, SerializerException { validateOptions(uriInfo.asUriInfoResource()); blockNavigation(uriInfo); @@ -129,43 +130,37 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates()); + checkEntity(entity); - if (entity == null) { - throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); - } else { - final ODataFormat format = ODataFormat.fromContentType(requestedContentType); - ODataSerializer serializer = odata.createSerializer(format); - final ExpandOption expand = uriInfo.getExpandOption(); - final SelectOption select = uriInfo.getSelectOption(); - response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity, - EntitySerializerOptions.with() - .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : - getContextUrl(edmEntitySet, true, expand, select)) - .expand(expand).select(select) - .build())); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); - } + final ODataFormat format = ODataFormat.fromContentType(requestedContentType); + ODataSerializer serializer = odata.createSerializer(format); + final ExpandOption expand = uriInfo.getExpandOption(); + final SelectOption select = uriInfo.getSelectOption(); + response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity, + EntitySerializerOptions.with() + .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : + getContextUrl(edmEntitySet, true, expand, select)) + .expand(expand).select(select) + .build())); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); } @Override public void readMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, - final ContentType responseFormat) throws ODataApplicationException, SerializerException { + final ContentType responseFormat) throws ODataApplicationException, SerializerException { blockNavigation(uriInfo); final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates()); - if (entity == null) { - throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); - } else { - response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readMedia(entity))); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, entity.getMediaContentType()); - } + checkEntity(entity); + response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readMedia(entity))); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, entity.getMediaContentType()); } @Override public void createMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, - final ContentType requestFormat, final ContentType responseFormat) + final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException { blockNavigation(uriInfo); @@ -173,66 +168,14 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet(); Entity entity = null; if (edmEntitySet.getEntityType().hasStream()) { - if (requestFormat == null) { - throw new ODataApplicationException("The content type has not been set in the request.", - HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT); - } + checkRequestFormat(requestFormat); entity = dataProvider.create(edmEntitySet); dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), requestFormat.toContentTypeString()); } else { throw new ODataApplicationException("Requested Entity is not a media resource.", - HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT); - } - - final ODataFormat format = ODataFormat.fromContentType(responseFormat); - ODataSerializer serializer = odata.createSerializer(format); - response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity, - EntitySerializerOptions.with() - .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : - getContextUrl(edmEntitySet, true, null, null)) - .build())); - response.setStatusCode(HttpStatusCode.CREATED.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - response.setHeader(HttpHeader.LOCATION, - request.getRawBaseUri() + '/' + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity)); - } - - @Override - public void createEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, - final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - - throw new ODataApplicationException("Entity creation is not supported yet.", - HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); - } - - @Override - public void updateEntity(final ODataRequest request, final ODataResponse response, - final UriInfo uriInfo, final ContentType requestFormat, - final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - throw new ODataApplicationException("Entity update is not supported yet.", - HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); - } - - @Override - public void updateMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, - final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockNavigation(uriInfo); - final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); - final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet(); - final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates()); - if (entity == null) { - throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); - } - if (requestFormat == null) { - throw new ODataApplicationException("The content type has not been set in the request.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT); } - dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), - requestFormat.toContentTypeString()); final ODataFormat format = ODataFormat.fromContentType(responseFormat); ODataSerializer serializer = odata.createSerializer(format); @@ -241,8 +184,49 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, true, null, null)) .build())); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setStatusCode(HttpStatusCode.CREATED.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + response.setHeader(HttpHeader.LOCATION, + request.getRawBaseUri() + '/' + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity)); + } + + @Override + public void createEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + throw new ODataApplicationException("Entity creation is not supported yet.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + @Override + public void updateEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockNavigation(uriInfo); + final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); + final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet(); + Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates()); + checkEntity(entity); + checkRequestFormat(requestFormat); + ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat)); + final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()); + dataProvider.update(edmEntitySet, entity, changedEntity, request.getMethod() == HttpMethod.PATCH); + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + + @Override + public void updateMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockNavigation(uriInfo); + final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); + final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet(); + final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates()); + checkEntity(entity); + checkRequestFormat(requestFormat); + dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), + requestFormat.toContentTypeString()); + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); } @Override @@ -251,21 +235,17 @@ public class TechnicalEntityProcessor extends TechnicalProcessor blockNavigation(uriInfo); final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0); final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates()); - if (entity == null) { - throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); - } else { - dataProvider.delete(resourceEntitySet.getEntitySet(), entity); - response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); - } + checkEntity(entity); + dataProvider.delete(resourceEntitySet.getEntitySet(), entity); + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); } @Override - public void processActionEntity(final ODataRequest request, final ODataResponse response, - final UriInfo uriInfo, final ContentType requestFormat, - final ContentType responseFormat) + public void processActionEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException { throw new ODataApplicationException("Process entity is not supported yet.", - HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } private void blockNavigation(final UriInfo uriInfo) throws ODataApplicationException { @@ -289,6 +269,19 @@ public class TechnicalEntityProcessor extends TechnicalProcessor return entitySet; } + private void checkEntity(final Entity entity) throws ODataApplicationException { + if (entity == null) { + throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); + } + } + + private void checkRequestFormat(final ContentType requestFormat) throws ODataApplicationException { + if (requestFormat == null) { + throw new ODataApplicationException("The content type has not been set in the request.", + HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT); + } + } + private ContextURL getContextUrl(final EdmEntitySet entitySet, final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws SerializerException { return ContextURL.with().entitySet(entitySet) diff --git a/lib/server-test/pom.xml b/lib/server-test/pom.xml index dd986b167..490f5111c 100644 --- a/lib/server-test/pom.xml +++ b/lib/server-test/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 4fd025a19..e12deed08 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ org.apache.olingo odata-parent - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT pom Olingo-OData diff --git a/samples/client/pom.xml b/samples/client/pom.xml index 4e5e6e4f9..eba21d032 100644 --- a/samples/client/pom.xml +++ b/samples/client/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-samples - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/samples/pom.xml b/samples/pom.xml index fc7f4b666..8166c1de0 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -31,7 +31,7 @@ org.apache.olingo odata-parent - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT .. diff --git a/samples/server/pom.xml b/samples/server/pom.xml index 31ad7a194..900142c73 100644 --- a/samples/server/pom.xml +++ b/samples/server/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-samples - 4.0.0-beta-02-RC01 + 4.0.0-beta-03-SNAPSHOT ..