[ODATAJAVA-1123]OData V4.0: Support of derived types and mixed
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/ecf7f56e Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/ecf7f56e Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/ecf7f56e Branch: refs/heads/master Commit: ecf7f56ec8e8a92164fe31dce66a9b42a59d4333 Parents: d808142 Author: Archana Rai <[email protected]> Authored: Sun Jul 23 15:29:00 2017 +0530 Committer: Archana Rai <[email protected]> Committed: Sun Jul 23 15:29:00 2017 +0530 ---------------------------------------------------------------------- .../fit/tecsvc/http/DerivedTypeTestITCase.java | 176 +++++++++ .../json/ODataJsonDeserializer.java | 5 + .../deserializer/xml/ODataXmlDeserializer.java | 20 +- .../serializer/json/ODataJsonSerializer.java | 9 +- .../core/serializer/xml/ODataXmlSerializer.java | 14 +- .../olingo/server/tecsvc/data/DataCreator.java | 187 +++++++++ .../olingo/server/tecsvc/data/DataProvider.java | 19 +- .../processor/TechnicalEntityProcessor.java | 4 +- .../tecsvc/provider/ComplexTypeProvider.java | 24 ++ .../tecsvc/provider/ContainerProvider.java | 42 +- .../tecsvc/provider/EntityTypeProvider.java | 11 + .../tecsvc/provider/PropertyProvider.java | 9 + .../server/tecsvc/provider/SchemaProvider.java | 7 +- .../json/ODataJsonDeserializerEntityTest.java | 223 +++++++++++ .../xml/ODataXmlDeserializerTest.java | 352 +++++++++++++++++ .../json/ODataJsonSerializerTest.java | 112 ++++++ .../serializer/xml/ODataXmlSerializerTest.java | 390 +++++++++++++++++++ 17 files changed, 1585 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedTypeTestITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedTypeTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedTypeTestITCase.java new file mode 100644 index 0000000..e7d4a80 --- /dev/null +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedTypeTestITCase.java @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.fit.tecsvc.http; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.commons.io.IOUtils; +import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.commons.api.format.ContentType; +import org.apache.olingo.commons.api.http.HttpHeader; +import org.apache.olingo.commons.api.http.HttpMethod; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.fit.AbstractBaseTestITCase; +import org.apache.olingo.fit.tecsvc.TecSvcConst; +import org.junit.Test; + +public class DerivedTypeTestITCase extends AbstractBaseTestITCase { + + private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/"; + + @Test + public void queryESCompCollDerivedJson() throws Exception { + URL url = new URL(SERVICE_URI + "ESCompCollDerived?$format=json"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + + assertTrue(content.contains( + "[{\"PropertyInt16\":32767,\"PropertyCompAno\":null,\"CollPropertyCompAno\":[{\"PropertyString\":" + + "\"TEST9876\"}]},{\"PropertyInt16\":12345,\"PropertyCompAno\":{\"@odata.type\":" + + "\"#olingo.odata.test1.CTBaseAno\",\"PropertyString\":\"Num111\",\"AdditionalPropString\":" + + "\"Test123\"},\"CollPropertyCompAno\":[{\"@odata.type\":\"#olingo.odata.test1.CTBaseAno\"," + + "\"PropertyString\":\"TEST12345\",\"AdditionalPropString\":\"Additional12345\"}," + + "{\"PropertyString\":\"TESTabcd\"}]}]}" )); + } + + @Test + public void queryESCompCollDerivedXml() throws Exception { + URL url = new URL(SERVICE_URI + "ESCompCollDerived?$format=xml"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.APPLICATION_XML, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("<d:PropertyCompAno m:type=\"#olingo.odata.test1.CTBaseAno\">" + + "<d:PropertyString>Num111</d:PropertyString>" + + "<d:AdditionalPropString>Test123</d:AdditionalPropString>" + + "</d:PropertyCompAno>" + + "<d:CollPropertyCompAno m:type=\"#Collection(olingo.odata.test1.CTTwoPrimAno)\">" + + "<m:element m:type=\"olingo.odata.test1.CTBaseAno\">" + + "<d:PropertyString>TEST12345</d:PropertyString>" + + "<d:AdditionalPropString>Additional12345</d:AdditionalPropString>" )); + } + + @Test + public void queryESAllPrimDerivedJson() throws Exception { + URL url = new URL(SERVICE_URI + "ESAllPrimDerived(0)?$expand=NavPropertyETTwoPrimMany&$format=json"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("\"@odata.type\":\"#olingo.odata.test1.ETBase\"," + + "\"PropertyInt16\":32766," + + "\"PropertyString\":\"Test String1\"," + + "\"AdditionalPropertyString_5\":\"Additional String1\"" )); + } + + @Test + public void queryESAllPrimDerivedXml() throws Exception { + URL url = new URL(SERVICE_URI + "ESAllPrimDerived(0)?$expand=NavPropertyETTwoPrimMany&$format=xml"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("term=\"#olingo.odata.test1.ETBase\"/>")); + assertTrue(content.contains( + "<d:PropertyInt16 m:type=\"Int16\">32766</d:PropertyInt16>" + + "<d:PropertyString>Test String1</d:PropertyString>" + + "<d:AdditionalPropertyString_5>Additional String1</d:AdditionalPropertyString_5>")); + } + + @Test + public void queryESCompCollDerivedJsonNone() throws Exception { + URL url = new URL(SERVICE_URI + "ESCompCollDerived"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=none"); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON_NO_METADATA, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + + assertTrue(content.contains( + "[{\"PropertyInt16\":32767,\"PropertyCompAno\":null,\"CollPropertyCompAno\":[{\"PropertyString\":" + + "\"TEST9876\"}]},{\"PropertyInt16\":12345,\"PropertyCompAno\":{"+ + "\"PropertyString\":\"Num111\",\"AdditionalPropString\":" + + "\"Test123\"},\"CollPropertyCompAno\":[{" + + "\"PropertyString\":\"TEST12345\",\"AdditionalPropString\":\"Additional12345\"}," + + "{\"PropertyString\":\"TESTabcd\"}]}]}" )); + } + @Test + public void queryESCompCollDerivedJsonFull() throws Exception { + URL url = new URL(SERVICE_URI + "ESCompCollDerived"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full"); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON_FULL_METADATA, + ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + + assertTrue(content.contains("\"PropertyInt16\":32767,\"PropertyCompAno\":null," + + "\"[email protected]\":\"#Collection(olingo.odata.test1.CTTwoPrimAno)\"," + + "\"CollPropertyCompAno\":[{\"@odata.type\":" + + "\"#olingo.odata.test1.CTTwoPrimAno\",\"PropertyString\":\"TEST9876\"}]}," + + "{\"@odata.type\":\"#olingo.odata.test1.ETDeriveCollComp\",\"@odata.id\":\"ESCompCollDerived(12345)\"," + + "\"[email protected]\":\"#Int16\",\"PropertyInt16\":12345,\"PropertyCompAno\":" + + "{\"@odata.type\":\"#olingo.odata.test1.CTBaseAno\"," + + "\"PropertyString\":\"Num111\",\"AdditionalPropString\":\"Test123\"}," + + "\"[email protected]\":\"#Collection(olingo.odata.test1.CTTwoPrimAno)\",\"CollPropertyCompAno\":" + + "[{\"@odata.type\":\"#olingo.odata.test1.CTBaseAno\"," + + "\"PropertyString\":\"TEST12345\",\"AdditionalPropString\":\"Additional12345\"}," + + "{\"@odata.type\":\"#olingo.odata.test1.CTTwoPrimAno\",\"PropertyString\":\"TESTabcd\"}]}]}" )); + } + + @Override + protected ODataClient getClient() { + return null; + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java index 9106613..71aee42 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 @@ -594,6 +594,10 @@ public class ODataJsonDeserializer implements ODataDeserializer { // Even if there are no properties defined we have to give back an empty list ComplexValue complexValue = new ComplexValue(); EdmComplexType edmType = (EdmComplexType) type; + + //Check if the properties are from derived type + edmType = (EdmComplexType) getDerivedType(edmType, jsonNode); + // Check and consume all Properties for (String propertyName : edmType.getPropertyNames()) { JsonNode subNode = jsonNode.get(propertyName); @@ -612,6 +616,7 @@ public class ODataJsonDeserializer implements ODataDeserializer { ((ObjectNode) jsonNode).remove(propertyName); } } + complexValue.setTypeName(edmType.getFullQualifiedName().getFullQualifiedNameAsString()); return complexValue; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java index 21c9b37..c8a1fcb 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java @@ -134,14 +134,28 @@ public class ODataXmlDeserializer implements ODataDeserializer { private Object complex(final XMLEventReader reader, final StartElement start, final EdmComplexType edmComplex) throws XMLStreamException, EdmPrimitiveTypeException, DeserializerException { ComplexValue value = new ComplexValue(); + EdmType resolvedType = edmComplex; boolean foundEndProperty = false; while (reader.hasNext() && !foundEndProperty) { final XMLEvent event = reader.nextEvent(); - if (event.isStartElement()) { + + if (event.isStartElement()) { + //Get the derived type from the element tag + final Attribute attrType = start.getAttributeByName(typeQName); + if (attrType != null ) { + String type = new EdmTypeInfo.Builder().setTypeExpression(attrType.getValue()).build().internal(); + if (type.startsWith("Collection(") && type.endsWith(")")) { + type = type.substring(11, type.length()-1); + } + resolvedType = getDerivedType(edmComplex, type); + } + + StartElement se = event.asStartElement(); - EdmProperty p = (EdmProperty) edmComplex.getProperty(se.getName().getLocalPart()); + EdmProperty p = (EdmProperty) ((EdmComplexType)resolvedType).getProperty(se.getName().getLocalPart()); value.getValue().add(property(reader, se, p.getType(), p.isNullable(), p.getMaxLength(), p.getPrecision(), p.getScale(), p.isUnicode(), p.isCollection())); + value.setTypeName(resolvedType.getFullQualifiedName().getFullQualifiedNameAsString()); } if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) { foundEndProperty = true; @@ -156,11 +170,9 @@ public class ODataXmlDeserializer implements ODataDeserializer { DeserializerException { List<Object> values = new ArrayList<Object>(); - boolean foundEndProperty = false; while (reader.hasNext() && !foundEndProperty) { final XMLEvent event = reader.nextEvent(); - if (event.isStartElement()) { if (edmType instanceof EdmPrimitiveType) { values.add(primitive(reader, event.asStartElement(), edmType, isNullable, http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java index d48c413..9cce970 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java @@ -757,15 +757,18 @@ public class ODataJsonSerializer extends AbstractODataSerializer { final Set<List<String>> selectedPaths, final JsonGenerator json) throws IOException, SerializerException { json.writeStartArray(); + EdmComplexType derivedType = type; for (Object value : property.asCollection()) { + derivedType = ((ComplexValue) value).getTypeName()!=null ? metadata.getEdm().getComplexType + (new FullQualifiedName(((ComplexValue) value).getTypeName())): type; switch (property.getValueType()) { case COLLECTION_COMPLEX: json.writeStartObject(); - if (isODataMetadataFull) { + if (isODataMetadataFull || (!isODataMetadataNone && !derivedType.equals(type))) { json.writeStringField(Constants.JSON_TYPE, "#" + - type.getFullQualifiedName().getFullQualifiedNameAsString()); + derivedType.getFullQualifiedName().getFullQualifiedNameAsString()); } - writeComplexValue(metadata, type, ((ComplexValue) value).getValue(), selectedPaths, json); + writeComplexValue(metadata, derivedType, ((ComplexValue) value).getValue(), selectedPaths, json); json.writeEndObject(); break; default: http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java index 0555285..80ba2b7 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java @@ -891,14 +891,22 @@ public class ODataXmlSerializer extends AbstractODataSerializer { final EdmComplexType type, final Property property, final Set<List<String>> selectedPaths, final String xml10InvalidCharReplacement, final XMLStreamWriter writer) throws XMLStreamException, SerializerException { + EdmComplexType complexType = type; for (Object value : property.asCollection()) { writer.writeStartElement(METADATA, Constants.ELEM_ELEMENT, NS_METADATA); - if (derivedComplexType(type, property.getType()) != null) { - writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, property.getType()); + String typeName = ((ComplexValue)value).getTypeName(); + String propertyType = typeName != null ? typeName :property.getType(); + if (derivedComplexType(type, propertyType ) != null) { + writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, propertyType); + } + if(typeName!=null && !propertyType.equals(type.getFullQualifiedName().getFullQualifiedNameAsString())){ + complexType = (EdmComplexType) (metadata.getEdm().getComplexType(new FullQualifiedName(propertyType))); + }else{ + complexType = type; } switch (property.getValueType()) { case COLLECTION_COMPLEX: - writeComplexValue(metadata, type, + writeComplexValue(metadata, complexType, ((ComplexValue) value).getValue(), selectedPaths, xml10InvalidCharReplacement, writer); break; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java ---------------------------------------------------------------------- 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 index 1533dbd..e3d932f 100644 --- 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 @@ -91,10 +91,14 @@ public class DataCreator { data.put("ESPeople", createESPeople(edm, odata)); data.put("SINav", createSINav(edm, odata)); data.put("SI", createESTwoPrim(edm, odata)); + data.put("ESCompCollDerived", createESCompCollDerived(edm, odata)); + data.put("ESTwoPrimDerived", createESTwoPrimDerived(edm, odata)); + data.put("ESAllPrimDerived", createESAllPrimDerived(edm, odata)); linkSINav(data); linkESTwoPrim(data); linkESAllPrim(data); + linkESAllPrimDerived(data); linkESKeyNav(data); linkESTwoKeyNav(data); linkESPeople(data); @@ -110,6 +114,79 @@ public class DataCreator { createOperations("ESTwoKeyNav", entityCollection, EntityTypeProvider.nameETTwoKeyNav); return entityCollection; } + + + @SuppressWarnings("unchecked") + private EntityCollection createESCompCollDerived(final Edm edm, final OData odata) { + final EntityCollection entityCollection = new EntityCollection(); + Property derivedComplexProperty = + createComplex("PropertyCompAno", + ComplexTypeProvider.nameCTBaseAno.getFullQualifiedNameAsString(), + createPrimitive("PropertyString", "Num111"), + createPrimitive("AdditionalPropString", "Test123") + ); + ((ComplexValue)derivedComplexProperty.getValue()).setTypeName( + ComplexTypeProvider.nameCTBaseAno.getFullQualifiedNameAsString()); + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) + .addProperty( + createComplexCollection("CollPropertyCompAno", + ComplexTypeProvider.nameCTTwoPrimAno.getFullQualifiedNameAsString(), + Arrays.asList(new Property[] { + createDerived("PropertyString", + ComplexTypeProvider.nameCTTwoPrimAno.getFullQualifiedNameAsString(), + "TEST9876") + })) + ) + ); + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", 12345)) + .addProperty(derivedComplexProperty) + .addProperty(createComplexDerievedCollection("CollPropertyCompAno", + ComplexTypeProvider.nameCTTwoPrimAno.getFullQualifiedNameAsString(), + Arrays.asList(new ComplexValue[] { + createComplexValue(ComplexTypeProvider.nameCTBaseAno.getFullQualifiedNameAsString(), + Arrays.asList(new Property[] { + createDerived("AdditionalPropString", + ComplexTypeProvider.nameCTBaseAno.getFullQualifiedNameAsString(), + "Additional12345"), + createDerived("PropertyString", + ComplexTypeProvider.nameCTBaseAno.getFullQualifiedNameAsString(), + "TEST12345") + } + )), + createComplexValue(ComplexTypeProvider.nameCTTwoPrimAno.getFullQualifiedNameAsString(), + Arrays.asList(new Property[] { + createDerived("PropertyString", + ComplexTypeProvider.nameCTTwoPrimAno.getFullQualifiedNameAsString(), + "TESTabcd") + } + ))} + + )))); + + setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETDeriveCollComp)); + createEntityId(edm, odata, "ESCompCollDerived", entityCollection); + createOperations("ESCompCollDerived", entityCollection, EntityTypeProvider.nameETDeriveCollComp); + return entityCollection; + } + + private ComplexValue createComplexValue(String type, List<Property> properties) { + ComplexValue complexValue = new ComplexValue(); + complexValue.getValue().addAll(properties); + complexValue.setTypeName(type); + return complexValue; + } + + private Property createComplexDerievedCollection(final String name, + String type, final List<ComplexValue> list) { + List<ComplexValue> complexCollection = new ArrayList<ComplexValue>(); + complexCollection.addAll(list); + Property property = new Property(type, name, ValueType.COLLECTION_COMPLEX, complexCollection); + createOperations(name, type, property); + return property; + + } private EntityCollection createESMixEnumDefCollComp(Edm edm, OData odata) { final EntityCollection entityCollection = new EntityCollection(); @@ -726,6 +803,35 @@ public class DataCreator { createOperations("ESTwoPrim", entityCollection, EntityTypeProvider.nameETTwoPrim); return entityCollection; } + + private EntityCollection createESTwoPrimDerived(final Edm edm, final OData odata) { + EntityCollection entityCollection = new EntityCollection(); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", (short) -365)) + .addProperty(createPrimitive("PropertyString", "Test String2"))); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", (short) -32766)) + .addProperty(createPrimitive("PropertyString", null))); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) + .addProperty(createPrimitive("PropertyString", "Test String4"))); + + setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETTwoPrim)); + + Entity derivedEntity = new Entity() + .addProperty(createPrimitive("PropertyInt16", (short) 32766)) + .addProperty(createPrimitive("PropertyString", "Test String1")) + .addProperty(createPrimitive("AdditionalPropertyString_5", "Additional String1")); + derivedEntity.setType(EntityTypeProvider.nameETBase.getFullQualifiedNameAsString()); + entityCollection.getEntities().add(derivedEntity); + + createEntityId(edm, odata, "ESTwoPrimDerived", entityCollection); + createOperations("ESTwoPrimDerived", entityCollection, EntityTypeProvider.nameETTwoPrim); + return entityCollection; + } private void setEntityType(EntityCollection entityCollection, final EdmEntityType type) { for (Entity entity : entityCollection.getEntities()) { @@ -797,6 +903,71 @@ public class DataCreator { createOperations("ESAllPrim", entityCollection, EntityTypeProvider.nameETAllPrim); return entityCollection; } + + private EntityCollection createESAllPrimDerived(final Edm edm, final OData odata) { + EntityCollection entityCollection = new EntityCollection(); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE)) + .addProperty(createPrimitive("PropertyString", "First Resource - positive values")) + .addProperty(createPrimitive("PropertyBoolean", true)) + .addProperty(createPrimitive("PropertyByte", (short) 255)) + .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE)) + .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE)) + .addProperty(createPrimitive("PropertySingle", (float) 1.79000000E+20)) + .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+19)) + .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(34))) + .addProperty(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })) + .addProperty(createPrimitive("PropertyDate", getDate(2012, 12, 3))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23))) + .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(6))) + .addProperty(createPrimitive("PropertyGuid", GUID)) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(3, 26, 5)))); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", Short.MIN_VALUE)) + .addProperty(createPrimitive("PropertyString", "Second Resource - negative values")) + .addProperty(createPrimitive("PropertyBoolean", false)) + .addProperty(createPrimitive("PropertyByte", (short) 0)) + .addProperty(createPrimitive("PropertySByte", Byte.MIN_VALUE)) + .addProperty(createPrimitive("PropertyInt32", Integer.MIN_VALUE)) + .addProperty(createPrimitive("PropertyInt64", Long.MIN_VALUE)) + .addProperty(createPrimitive("PropertySingle", (float) -1.79000000E+08)) + .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+05)) + .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(-34))) + .addProperty(createPrimitive("PropertyBinary", + new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF })) + .addProperty(createPrimitive("PropertyDate", getDate(2015, 11, 5))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 7, 17, 8))) + .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(9))) + .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff"))) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14)))); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", (short) 0)) + .addProperty(createPrimitive("PropertyString", "")) + .addProperty(createPrimitive("PropertyBoolean", false)) + .addProperty(createPrimitive("PropertyByte", (short) 0)) + .addProperty(createPrimitive("PropertySByte", 0)) + .addProperty(createPrimitive("PropertyInt32", 0)) + .addProperty(createPrimitive("PropertyInt64", 0L)) + .addProperty(createPrimitive("PropertySingle", (float) 0)) + .addProperty(createPrimitive("PropertyDouble", 0D)) + .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(0))) + .addProperty(createPrimitive("PropertyBinary", new byte[] {})) + .addProperty(createPrimitive("PropertyDate", getDate(1970, 1, 1))) + .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0))) + .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(0))) + .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd"))) + .addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1)))); + + setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETAllPrim)); + createEntityId(edm, odata, "ESAllPrim", entityCollection); + createOperations("ESAllPrim", entityCollection, EntityTypeProvider.nameETAllPrim); + return entityCollection; + } private void createOperations(String entitySetName, EntityCollection entityCollection, FullQualifiedName entityTypeName) { @@ -1363,6 +1534,18 @@ public class DataCreator { targetEntities.get(2), targetEntities.get(3)); } + + private void linkESAllPrimDerived(final Map<String, EntityCollection> data) { + final EntityCollection entityCollection = data.get("ESAllPrimDerived"); + final List<Entity> targetEntities = data.get("ESTwoPrimDerived").getEntities(); + + setLinks(entityCollection.getEntities().get(0), "NavPropertyETTwoPrimMany", targetEntities.get(1)); + setLink(entityCollection.getEntities().get(0), "NavPropertyETTwoPrimOne", targetEntities.get(3)); + + setLinks(entityCollection.getEntities().get(2), "NavPropertyETTwoPrimMany", targetEntities.get(0), + targetEntities.get(2), + targetEntities.get(3)); + } private void linkESKeyNav(final Map<String, EntityCollection> data) { final EntityCollection entityCollection = data.get("ESKeyNav"); @@ -1469,6 +1652,10 @@ public class DataCreator { return new Property(null, name, ValueType.COLLECTION_PRIMITIVE, propertyValues); } + protected static Property createDerived(final String name, final String type, final Object value) { + return new Property(type, name, ValueType.PRIMITIVE, value); + } + protected static Property createComplex(final String name, final String type, final Property... properties) { ComplexValue complexValue = new ComplexValue(); for (final Property property : properties) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java ---------------------------------------------------------------------- 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 b526887..dd806c2 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 @@ -312,7 +312,8 @@ public class DataProvider { public void update(final String rawBaseUri, final EdmEntitySet edmEntitySet, Entity entity, final Entity changedEntity, final boolean patch, final boolean isInsert) throws DataProviderException { - final EdmEntityType entityType = edmEntitySet.getEntityType(); + final EdmEntityType entityType = changedEntity.getType()!=null ? + edm.getEntityType(new FullQualifiedName(changedEntity.getType())):edmEntitySet.getEntityType(); final List<String> keyNames = entityType.getKeyPredicateNames(); // Update Properties @@ -468,6 +469,10 @@ public class DataProvider { @SuppressWarnings("unchecked") public void updateProperty(final EdmProperty edmProperty, Property property, final Property newProperty, final boolean patch) throws DataProviderException { + if(property == null){ + throw new DataProviderException("Cannot update type of the entity", + HttpStatusCode.BAD_REQUEST); + } final EdmType type = edmProperty.getType(); if (edmProperty.isCollection()) { // Updating collection properties means replacing all entries with the given ones. @@ -508,9 +513,15 @@ public class DataProvider { private ComplexValue createComplexValue(final EdmProperty edmProperty, final ComplexValue complexValue, final boolean patch) throws DataProviderException { final ComplexValue result = new ComplexValue(); - final EdmComplexType edmType = (EdmComplexType) edmProperty.getType(); + EdmComplexType edmType = (EdmComplexType) edmProperty.getType(); final List<Property> givenProperties = complexValue.getValue(); - + if(complexValue.getTypeName()!=null){ + EdmComplexType derivedType = edm.getComplexType(new FullQualifiedName(complexValue.getTypeName())); + if(derivedType.getBaseType()!=null && edmType.getFullQualifiedName().getFullQualifiedNameAsString() + .equals(derivedType.getBaseType().getFullQualifiedName().getFullQualifiedNameAsString())){ + edmType = derivedType; + } + } // Create ALL properties, even if no value is given. Check if null is allowed for (final String propertyName : edmType.getPropertyNames()) { final EdmProperty innerEdmProperty = (EdmProperty) edmType.getProperty(propertyName); @@ -529,7 +540,7 @@ public class DataProvider { } } } - + result.setTypeName(edmType.getFullQualifiedName().getFullQualifiedNameAsString()); return result; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index d7830be..98817a1 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 @@ -181,7 +181,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor requestFormat.toContentTypeString()); } else { final DeserializerResult deserializerResult = - odata.createDeserializer(requestFormat).entity(request.getBody(), edmEntityType); + odata.createDeserializer(requestFormat,serviceMetadata).entity(request.getBody(), edmEntityType); new RequestValidator(dataProvider, request.getRawBaseUri()) .validate(edmEntitySet, deserializerResult.getEntity()); @@ -235,7 +235,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor odata.createETagHelper().checkChangePreconditions(entity.getETag(), request.getHeaders(HttpHeader.IF_MATCH), request.getHeaders(HttpHeader.IF_NONE_MATCH)); - final ODataDeserializer deserializer = odata.createDeserializer(requestFormat); + final ODataDeserializer deserializer = odata.createDeserializer(requestFormat, serviceMetadata); final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity(); new RequestValidator(dataProvider, http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java index e93d9b9..114acef 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java @@ -31,6 +31,11 @@ public class ComplexTypeProvider { public static final FullQualifiedName nameCTAllPrim = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTAllPrim"); public static final FullQualifiedName nameCTBase = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTBase"); + public static final FullQualifiedName nameCTBaseAno = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTBaseAno"); + public static final FullQualifiedName nameCTCompCollCompAno = new FullQualifiedName(SchemaProvider.NAMESPACE, + "CTCompCollCompAno"); + public static final FullQualifiedName nameCTTwoPrimAno = new FullQualifiedName(SchemaProvider.NAMESPACE, + "CTTwoPrimAno"); public static final FullQualifiedName nameCTBasePrimCompNav = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTBasePrimCompNav"); public static final FullQualifiedName nameCTCollAllPrim = new FullQualifiedName(SchemaProvider.NAMESPACE, @@ -87,6 +92,25 @@ public class ComplexTypeProvider { PropertyProvider.collPropertyGuid, PropertyProvider.collPropertyTimeOfDay )); + } else if (complexTypeName.equals(nameCTTwoPrimAno)) { + return new CsdlComplexType() + .setName("CTTwoPrimAno") + .setProperties(Arrays.asList(PropertyProvider.propertyString)) + .setAbstract(true); + + } else if (complexTypeName.equals(nameCTBaseAno)) { + return new CsdlComplexType() + .setName("CTBaseAno") + .setBaseType(nameCTTwoPrimAno) + .setProperties(Arrays.asList( + new CsdlProperty() + .setName("AdditionalPropString") + .setType(PropertyProvider.nameString))); + }else if (complexTypeName.equals(nameCTCompCollCompAno)) { + return new CsdlComplexType() + .setName("CTCompCollCompAno") + .setProperties(Arrays.asList(PropertyProvider.collPropertyComp_CTTwoPrim_Ano)); + } else if (complexTypeName.equals(nameCTTwoPrim)) { return new CsdlComplexType() .setName("CTTwoPrim") http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java index 9cbd5e8..0d28c37 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java @@ -93,6 +93,7 @@ public class ContainerProvider { entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESInvisible")); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESServerSidePaging")); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, ES_STREAM_SERVER_PAGINATION)); + entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESCompCollDerived")); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESAllNullable")); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESKeyNav")); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESTwoKeyNav")); @@ -106,6 +107,8 @@ public class ContainerProvider { entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESWithStream")); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, ES_STREAM)); entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESPeople")); + entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESTwoPrimDerived")); + entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESAllPrimDerived")); // Singletons List<CsdlSingleton> singletons = new ArrayList<CsdlSingleton>(); @@ -327,6 +330,10 @@ public class ContainerProvider { new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression( new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true")))); + } else if (name.equals("ESCompCollDerived")) { + return new CsdlEntitySet() + .setName("ESCompCollDerived") + .setType(EntityTypeProvider.nameETDeriveCollComp); } else if (name.equals("ESMedia")) { return new CsdlEntitySet() .setName("ESMedia") @@ -653,7 +660,40 @@ public class ContainerProvider { .setType(EntityTypeProvider.nameETPeople) .setNavigationPropertyBindings(Arrays.asList(new CsdlNavigationPropertyBinding().setPath("friends") .setTarget("ESPeople"))); - } + } else if (name.equals("ESTwoPrimDerived")) { + return new CsdlEntitySet() + .setName("ESTwoPrimDerived") + .setType(EntityTypeProvider.nameETTwoPrim) + .setNavigationPropertyBindings(Arrays.asList( + new CsdlNavigationPropertyBinding() + .setPath("NavPropertyETAllPrimOne") + .setTarget("ESAllPrimDerived"), + new CsdlNavigationPropertyBinding() + .setPath("NavPropertyETAllPrimMany") + .setTarget("ESAllPrimDerived"))) + .setAnnotations(Arrays.asList( + new CsdlAnnotation().setTerm("Core.Description") + .setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String) + .setValue("Contains entities with two primitive types")), + new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression( + new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true")))); + + }else if (name.equals("ESAllPrimDerived")) { + return new CsdlEntitySet() + .setName("ESAllPrimDerived") + .setType(EntityTypeProvider.nameETAllPrim) + .setTitle("All PropertyTypes EntitySet") + .setNavigationPropertyBindings(Arrays.asList( + new CsdlNavigationPropertyBinding().setPath("NavPropertyETTwoPrimOne").setTarget("ESTwoPrimDerived"), + new CsdlNavigationPropertyBinding().setPath("NavPropertyETTwoPrimMany").setTarget("ESTwoPrimDerived"))) + .setAnnotations(Arrays.asList(new CsdlAnnotation().setTerm("Core.Description").setExpression( + new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String, + "Contains entities with all primitive types")), + new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression( + new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true")) + )); + + } } return null; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java index 26c6f19..22f56a8 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java @@ -33,6 +33,8 @@ public class EntityTypeProvider { public static final FullQualifiedName nameETAllKey = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETAllKey"); public static final FullQualifiedName nameETAllNullable = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETAllNullable"); + public static final FullQualifiedName nameETDeriveCollComp = new FullQualifiedName(SchemaProvider.NAMESPACE, + "ETDeriveCollComp"); public static final FullQualifiedName nameETAllPrim = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETAllPrim"); public static final FullQualifiedName nameETAllPrimDefaultValues = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETAllPrimDefaultValues"); @@ -170,6 +172,15 @@ public class EntityTypeProvider { PropertyProvider.propertyInt16_NotNullable, PropertyProvider.collPropertyString, PropertyProvider.propertyComp_CTTwoPrim, PropertyProvider.collPropertyComp_CTTwoPrim)); + } else if (entityTypeName.equals(nameETDeriveCollComp)) { + return new CsdlEntityType() + .setName("ETDeriveCollComp") + .setKey(Arrays.asList(new CsdlPropertyRef().setName("PropertyInt16"))) + .setProperties(Arrays.asList( + PropertyProvider.propertyInt16_NotNullable, + PropertyProvider.propertyComp_CTTwoPrim_Ano, + PropertyProvider.collPropertyComp_CTTwoPrim_Ano)); + } else if (entityTypeName.equals(nameETTwoKeyTwoPrim)) { return new CsdlEntityType() .setName("ETTwoKeyTwoPrim") http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java index c19e99f..f991d7f 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java @@ -673,6 +673,15 @@ public class PropertyProvider { .setType(ComplexTypeProvider.nameCTPrimComp) .setCollection(true); + public static final CsdlProperty collPropertyComp_CTTwoPrim_Ano = new CsdlProperty() + .setName("CollPropertyCompAno") + .setType(ComplexTypeProvider.nameCTTwoPrimAno) + .setCollection(true); + + public static final CsdlProperty propertyComp_CTTwoPrim_Ano = new CsdlProperty() + .setName("PropertyCompAno") + .setType(ComplexTypeProvider.nameCTTwoPrimAno); + public static final CsdlProperty collPropertyComp_CTTwoPrim = new CsdlProperty() .setName("CollPropertyComp") .setType(ComplexTypeProvider.nameCTTwoPrim) http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java index b8c525a..507c217 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java @@ -57,7 +57,7 @@ public class SchemaProvider { // EntityTypes List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>(); schema.setEntityTypes(entityTypes); - + entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETDeriveCollComp)); entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETAllPrim)); entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETAllPrimDefaultValues)); entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETCollAllPrim)); @@ -106,7 +106,10 @@ public class SchemaProvider { complexTypes.add(prov.getComplexType(ComplexTypeProvider.nameCTTwoBasePrimCompNav)); complexTypes.add(prov.getComplexType(ComplexTypeProvider.nameCTCompNav)); complexTypes.add(prov.getComplexType(ComplexTypeProvider.nameCTNavCont)); - + complexTypes.add(prov.getComplexType(ComplexTypeProvider.nameCTCompCollCompAno)); + complexTypes.add(prov.getComplexType(ComplexTypeProvider.nameCTTwoPrimAno)); + complexTypes.add(prov.getComplexType(ComplexTypeProvider.nameCTBaseAno)); + // Actions List<CsdlAction> actions = new ArrayList<CsdlAction>(); schema.setActions(actions); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java index 2f18594..34ccb55 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 @@ -123,6 +123,33 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe assertNotNull(entity.getProperty("PropertyGuid").getValue()); assertNotNull(entity.getProperty("PropertyTimeOfDay").getValue()); } + + @Test + public void derivedEntityETTwoPrim() throws Exception { + String entityString = + "{\"@odata.type\":\"#olingo.odata.test1.ETBase\","+ + "\"PropertyInt16\":32767," + + "\"PropertyString\":\"First Resource - positive values\"," + + "\"AdditionalPropertyString_5\":\"Additional\"}"; + final Entity entity = deserialize(entityString, "ETTwoPrim"); + assertNotNull(entity); + assertEquals("olingo.odata.test1.ETBase", entity.getType()); + List<Property> properties = entity.getProperties(); + assertNotNull(properties); + assertEquals(3, properties.size()); + assertEquals(new Short((short) 32767), entity.getProperty("PropertyInt16").getValue()); + assertEquals("First Resource - positive values", entity.getProperty("PropertyString").getValue()); + assertNotNull(entity.getProperty("AdditionalPropertyString_5").getValue()); + } + + @Test(expected=DeserializerException.class) + public void derivedEntityETTwoPrimError() throws Exception { + String entityString = + "{ \"PropertyInt16\":32767," + + "\"PropertyString\":\"First Resource - positive values\"," + + "\"AdditionalPropertyString_5\":\"Additional\"}"; + deserialize(entityString, "ETTwoPrim"); + } @Test public void simpleEntityETAllPrimWithDefaultNullValue() throws Exception { @@ -298,7 +325,132 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe Assert.assertEquals("First Resource - first", e.getProperty("PropertyString").getValue()); Assert.assertEquals(true, e.getProperty("PropertyBoolean").getValue()); } + + @Test + public void derivedEntityESCompCollDerived() throws Exception { + final String payload = "{\n" + + " \"@odata.context\": \"$metadata#ESCompCollDerived/$entity\",\n" + + " \"@odata.metadataEtag\":\"W/metadataETag\",\n" + + " \"@odata.etag\":\"W/32767\",\n" + + " \"PropertyInt16\":32767,\n" + + " \"[email protected]\": \"#Collection(olingo.odata.test1.CTTwoPrimAno)\",\n" + + " \"CollPropertyCompAno\": [\n" + + " {\n" + + " \"@odata.type\": \"#olingo.odata.test1.CTBaseAno\",\n" + + " \"PropertyString\": \"TEST9876\",\n" + + " \"AdditionalPropString\": \"Additional9876\"\n" + + " },\n" + + " {\n" + + " \"@odata.type\": \"#olingo.odata.test1.CTTwoPrimAno\",\n" + + " \"PropertyString\": \"TEST1234\"\n" + + " }\n" + + " ]\n" + + " \n" + + "}"; + final Entity entity = deserialize(payload, "ETDeriveCollComp"); + Assert.assertNotNull(entity); + List<Property> properties = entity.getProperties(); + assertNotNull(properties); + assertEquals(2, properties.size()); + assertEquals("PropertyInt16=32767", properties.get(0).toString()); + for (Property prop : properties) { + assertNotNull(prop); + if (prop.isCollection()) { + Property property = entity.getProperty("CollPropertyCompAno"); + assertEquals(ValueType.COLLECTION_COMPLEX, property.getValueType()); + + assertTrue(property.getValue() instanceof List); + List<? extends Object> asCollection = property.asCollection(); + assertEquals(2, asCollection.size()); + + for (Object arrayElement : asCollection) { + assertTrue(arrayElement instanceof ComplexValue); + List<Property> castedArrayElement = ((ComplexValue) arrayElement).getValue(); + if(castedArrayElement.size() == 1){ + assertEquals("PropertyString=TEST1234", castedArrayElement.get(0).toString()); + assertEquals("olingo.odata.test1.CTTwoPrimAno", ((ComplexValue) arrayElement).getTypeName()); + }else{ + assertEquals(2, castedArrayElement.size()); + assertEquals("AdditionalPropString=Additional9876", castedArrayElement.get(1).toString()); + assertEquals("olingo.odata.test1.CTBaseAno", ((ComplexValue) arrayElement).getTypeName()); + } + } + } + } + } + + @Test + public void derivedEntityESCompCollDerivedEmptyNull() throws Exception { + final String payload = "{\n" + + " \"@odata.context\": \"$metadata#ESCompCollDerived/$entity\",\n" + + " \"@odata.metadataEtag\":\"W/metadataETag\",\n" + + " \"@odata.etag\":\"W/32767\",\n" + + " \"PropertyInt16\":32767,\n" + + " \"PropertyCompAno\":null,\n"+ + " \"[email protected]\": \"#Collection(olingo.odata.test1.CTTwoPrimAno)\",\n" + + " \"CollPropertyCompAno\": [\n" + + " {\n" + + " \"@odata.type\": \"#olingo.odata.test1.CTBaseAno\",\n" + + " \"PropertyString\": null,\n" + + " \"AdditionalPropString\": null\n" + + " },\n" + + " {\n" + + " }\n" + + " ]\n" + + " \n" + + "}"; + final Entity entity = deserialize(payload, "ETDeriveCollComp"); + Assert.assertNotNull(entity); + List<Property> properties = entity.getProperties(); + assertNotNull(properties); + assertEquals(3, properties.size()); + assertEquals("PropertyInt16=32767", properties.get(0).toString()); + assertEquals("PropertyCompAno=null", properties.get(1).toString()); + for (Property prop : properties) { + assertNotNull(prop); + if (prop.isCollection()) { + Property property = entity.getProperty("CollPropertyCompAno"); + assertEquals(ValueType.COLLECTION_COMPLEX, property.getValueType()); + + assertTrue(property.getValue() instanceof List); + List<? extends Object> asCollection = property.asCollection(); + assertEquals(2, asCollection.size()); + + for (Object arrayElement : asCollection) { + assertTrue(arrayElement instanceof ComplexValue); + List<Property> castedArrayElement = ((ComplexValue) arrayElement).getValue(); + if(castedArrayElement.size() == 2){ + assertEquals(2, castedArrayElement.size()); + assertEquals("AdditionalPropString=null", castedArrayElement.get(1).toString()); + }else{ + assertEquals(0, castedArrayElement.size()); + } + } + } + } + } + @Test(expected = DeserializerException.class) + public void derivedEntityESCompCollDerivedError() throws Exception { + final String payload = "{\n" + + " \"@odata.context\": \"$metadata#ESCompCollDerived/$entity\",\n" + + " \"@odata.metadataEtag\":\"W/metadataETag\",\n" + + " \"@odata.etag\":\"W/32767\",\n" + + " \"PropertyInt16\":32767,\n" + + " \"[email protected]\": \"#Collection(olingo.odata.test1.CTTwoPrimAno)\",\n" + + " \"CollPropertyCompAno\": [\n" + + " {\n" + + " \"PropertyString\": \"TEST9876\",\n" + + " \"AdditionalPropString\": \"Additional9876\"\n" + + " },\n" + + " {\n" + + " \"PropertyString\": \"TEST1234\"\n" + + " }\n" + + " ]\n" + + " \n" + + "}"; + deserialize(payload, "ETDeriveCollComp"); + } private Property getCVProperty(ComplexValue cv, String name) { for (Property p : cv.getValue()) { if (p.getName().equals(name)) { @@ -386,6 +538,77 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe } @Test + public void deriveEntityETMixPrimCollComp() throws Exception { + final String entityString = "{" + + "\"PropertyInt16\":32767," + + "\"CollPropertyString\":" + + "[\"[email protected]\",\"[email protected]\",\"[email protected]\"]," + + "\"PropertyComp\":{\"@odata.type\": \"#olingo.odata.test1.CTBase\"," + + "\"PropertyInt16\":111,\"PropertyString\":\"TEST A\",\"AdditionalPropString\":\"Additional\"}," + + "\"CollPropertyComp\":[" + + "{\"@odata.type\": \"#olingo.odata.test1.CTBase\",\n" + + "\"PropertyInt16\":123,\"PropertyString\":\"TEST 1\",\"AdditionalPropString\":\"Additional\"}," + + "{\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"}," + + "{\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"}]}"; + final Entity entity = deserialize(entityString, "ETMixPrimCollComp"); + assertNotNull(entity); + List<Property> properties = entity.getProperties(); + assertNotNull(properties); + assertEquals(4, properties.size()); + Property prop = entity.getProperty("PropertyComp"); + ComplexValue asComp = prop.asComplex(); + assertEquals(3,asComp.getValue().size()); + assertEquals("olingo.odata.test1.CTBase",prop.getType()); + Property property = entity.getProperty("CollPropertyComp"); + assertEquals(ValueType.COLLECTION_COMPLEX, property.getValueType()); + + assertTrue(property.getValue() instanceof List); + List<? extends Object> asCollection = property.asCollection(); + assertEquals(3, asCollection.size()); + assertEquals(3,((ComplexValue)asCollection.get(0)).getValue().size()); + assertEquals(2,((ComplexValue)asCollection.get(1)).getValue().size()); + assertEquals(2,((ComplexValue)asCollection.get(2)).getValue().size()); + } + + @Test + public void deriveEntityESAllPrimDeepInsert() throws Exception { + final String entityString = "{\"PropertyInt16\": 32767," + + "\"PropertyString\": \"First Resource - positive values\"," + + "\"PropertyBoolean\": true," + + "\"PropertyByte\": 255," + + "\"PropertySByte\": 127," + + "\"PropertyInt32\": 2147483647," + + "\"PropertyInt64\": 9223372036854775807," + + "\"PropertyDecimal\": 34," + + "\"PropertyBinary\": \"ASNFZ4mrze8=\"," + + "\"PropertyDate\": \"2012-12-03\"," + + "\"PropertyDateTimeOffset\": \"2012-12-03T07:16:23Z\"," + + "\"PropertyDuration\": \"PT6S\"," + + "\"PropertyGuid\": \"01234567-89ab-cdef-0123-456789abcdef\"," + + "\"PropertyTimeOfDay\": \"03:26:05\"," + + "\"NavPropertyETTwoPrimMany\": [{\"@odata.type\": \"#olingo.odata.test1.ETBase\"," + + "\"PropertyInt16\": -365,\"PropertyString\": \"Test String2\"," + + "\"AdditionalPropertyString_5\": \"Test String2\"}," + + "{\"PropertyInt16\": -365,\"PropertyString\": \"Test String2\"}]," + + "\"NavPropertyETTwoPrimOne\":" + + "{\"@odata.type\": \"#olingo.odata.test1.ETBase\",\"PropertyInt16\": 32767," + + "\"PropertyString\": \"Test String4\"," + + "\"AdditionalPropertyString_5\": \"Test String2\"}}"; + final Entity entity = deserialize(entityString, "ETAllPrim"); + assertNotNull(entity); + List<Property> properties = entity.getProperties(); + assertNotNull(properties); + assertEquals(14, properties.size()); + List<Link> navProperties = entity.getNavigationLinks(); + assertNotNull(navProperties); + assertEquals(2, navProperties.size()); + assertNotNull(navProperties.get(1).getInlineEntitySet() + .getEntities().get(0).getProperty("AdditionalPropertyString_5")); + assertNotNull(navProperties.get(0).getInlineEntity().getProperty("AdditionalPropertyString_5")); + } + + + @Test public void eTMixPrimCollCompMissingPropertyInComplexType() throws Exception { final String entityString = "{" + "\"PropertyComp\":{\"PropertyInt16\":111}," http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ecf7f56e/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java index 0c83e40..06e5df4 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java @@ -18,6 +18,11 @@ */ package org.apache.olingo.server.core.deserializer.xml; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayInputStream; import java.math.BigDecimal; import java.net.URI; @@ -131,7 +136,68 @@ public class ODataXmlDeserializerTest extends AbstractODataDeserializerTest { Assert.assertEquals(valueOf("03:26:05", EdmPrimitiveTypeKind.TimeOfDay), result.getProperty("PropertyTimeOfDay").asPrimitive()); } + + @Test + public void derivedEntityETTwoPrim() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim"); + + String payload = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\"\n" + + " xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + + " xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\"> " + + " <atom:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETBase\" />\n" + + " <atom:content type=\"application/xml\">\n" + + " <metadata:properties>\n" + + " <data:PropertyInt16>32767</data:PropertyInt16>\n" + + " <data:PropertyString>First Resource - positive values</data:PropertyString>\n" + + " <data:AdditionalPropertyString_5>Additional</data:AdditionalPropertyString_5>\n" + + " </metadata:properties>\n" + + " </atom:content>\n" + + "</atom:entry>\n"; + + Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), + edmEntitySet.getEntityType()).getEntity(); + Assert.assertEquals("olingo.odata.test1.ETBase", result.getType()); + Assert.assertEquals(3, result.getProperties().size()); + Assert.assertEquals((short) 32767, result.getProperty("PropertyInt16").asPrimitive()); + Assert.assertEquals("First Resource - positive values", result.getProperty("PropertyString").asPrimitive()); + Assert.assertNotNull( + result.getProperty("AdditionalPropertyString_5").asPrimitive()); + } + + @Test + public void derivedEntityETTwoPrimNull() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim"); + + String payload = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\"\n" + + " xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + + " xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\"> " + + " <atom:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETBase\" />\n" + + " <atom:content type=\"application/xml\">\n" + + " <metadata:properties>\n" + + " <data:PropertyInt16/>\n" + + " <data:PropertyString/>\n" + + " <data:AdditionalPropertyString_5/>\n" + + " </metadata:properties>\n" + + " </atom:content>\n" + + "</atom:entry>\n"; + + Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), + edmEntitySet.getEntityType()).getEntity(); + + Assert.assertEquals(3, result.getProperties().size()); + + Assert.assertNull(result.getProperty("PropertyInt16").asPrimitive()); + Assert.assertNull(result.getProperty("PropertyString").asPrimitive()); + Assert.assertNull( + result.getProperty("AdditionalPropertyString_5").asPrimitive()); + } + + @Test public void entitySimpleWithTypes() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); @@ -341,8 +407,294 @@ public class ODataXmlDeserializerTest extends AbstractODataDeserializerTest { Assert.assertEquals((short) 789, getCVProperty((ComplexValue) properties.get(2), "PropertyInt16").asPrimitive()); Assert.assertEquals("TEST 3", getCVProperty((ComplexValue) properties.get(2), "PropertyString").asPrimitive()); } + + + @Test + public void derivedEntityMixPrimCollComp() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp"); + final String payload = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\"\n" + + " xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + + " xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" \n" + + " metadata:metadata-etag=\"WmetadataETag\">\n" + + " <atom:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETMixPrimCollComp\" />\n" + + " <atom:content type=\"application/xml\">\n" + + " <metadata:properties>\n" + + " <data:PropertyInt16>32767</data:PropertyInt16>\n" + + " <data:CollPropertyString type=\"#Collection(String)\">\n" + + " <metadata:element>[email protected]</metadata:element>\n" + + " <metadata:element>[email protected]</metadata:element>\n" + + " <metadata:element>[email protected]</metadata:element>\n" + + " </data:CollPropertyString>\n" + + " <data:PropertyComp metadata:type=\"#olingo.odata.test1.CTBase\">\n" + + " <data:PropertyInt16>111</data:PropertyInt16>\n" + + " <data:PropertyString>TEST A</data:PropertyString>\n" + + " <data:AdditionalPropString>Additional</data:AdditionalPropString>\n" + + " </data:PropertyComp>\n" + + " <data:CollPropertyComp metadata:type=\"#Collection(olingo.odata.test1.CTTwoPrim)\">\n" + + " <metadata:element metadata:type=\"olingo.odata.test1.CTBase\">\n" + + " <data:PropertyInt16>123</data:PropertyInt16>\n" + + " <data:PropertyString>TEST 1</data:PropertyString>\n" + + " <data:AdditionalPropString>Additional test</data:AdditionalPropString>\n" + + " </metadata:element>\n" + + " <metadata:element>\n" + + " <data:PropertyInt16>456</data:PropertyInt16>\n" + + " <data:PropertyString>TEST 2</data:PropertyString>\n" + + " </metadata:element>\n" + + " <metadata:element>\n" + + " <data:PropertyInt16>789</data:PropertyInt16>\n" + + " <data:PropertyString>TEST 3</data:PropertyString>\n" + + " </metadata:element>\n" + + " </data:CollPropertyComp>\n" + + " </metadata:properties>\n" + + " </atom:content>\n" + + "</atom:entry>\n"; + + Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), + edmEntitySet.getEntityType()).getEntity(); + + Assert.assertEquals(4, result.getProperties().size()); + Assert.assertEquals(0, result.getNavigationLinks().size()); + + Assert.assertEquals(Arrays.asList("[email protected]", "[email protected]", + "[email protected]"), result.getProperty("CollPropertyString").getValue()); + + Property comp = result.getProperty("PropertyComp"); + Assert.assertEquals("olingo.odata.test1.CTBase", comp.getType()); + ComplexValue cv = comp.asComplex(); + + Assert.assertEquals(3, cv.getValue().size()); + Assert.assertEquals((short) 111, getCVProperty(cv, "PropertyInt16").asPrimitive()); + Assert.assertEquals("TEST A", getCVProperty(cv, "PropertyString").asPrimitive()); + Assert.assertEquals("Additional", getCVProperty(cv, "AdditionalPropString").asPrimitive()); + + comp = result.getProperty("CollPropertyComp"); + Assert.assertEquals("Collection(olingo.odata.test1.CTTwoPrim)", comp.getType()); + + List<?> properties = comp.asCollection(); + Assert.assertEquals(3, properties.size()); + + Assert.assertEquals((short) 123, getCVProperty((ComplexValue) properties.get(0), "PropertyInt16").asPrimitive()); + Assert.assertEquals("TEST 1", getCVProperty((ComplexValue) properties.get(0), "PropertyString").asPrimitive()); + Assert.assertEquals("Additional test", getCVProperty((ComplexValue) properties.get(0), "AdditionalPropString") + .asPrimitive()); + + Assert.assertEquals((short) 789, getCVProperty((ComplexValue) properties.get(2), "PropertyInt16").asPrimitive()); + Assert.assertEquals("TEST 3", getCVProperty((ComplexValue) properties.get(2), "PropertyString").asPrimitive()); + } + + @Test + public void deriveEntityESAllPrimDeepInsert() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + final String payload = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" \n" + + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" \n" + + "xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" m:context=\"$metadata#ESAllPrim/$entity\" \n" + + "m:metadata-etag=\"W/"f67e7bc4-37c8-46a8-bcd5-d77875906099"\">\n" + + " <a:id>ESAllPrim(32767)</a:id>\n" + + + " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\"/>\n" + + " <a:link rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\" \n" + + " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\" \n" + + " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\">\n" + + " <m:inline>\n" + + " <a:feed>\n" + + " <a:entry>\n" + + " <a:id>ESTwoPrim(-365)</a:id> \n" + + " <a:link rel=\"edit\" href=\"ESTwoPrim(-365)\"/>\n" + + " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETTwoPrim\"/>\n" + + " <a:content type=\"application/xml\">\n" + + " <m:properties>\n" + + " <d:PropertyInt16 m:type=\"Int16\">-365</d:PropertyInt16>\n" + + " <d:PropertyString>Test String2</d:PropertyString>\n" + + " </m:properties>\n" + + " </a:content>\n" + + " </a:entry>\n" + + " <a:entry>\n" + + " <a:id>ESTwoPrim(-365)</a:id> \n" + + " <a:link rel=\"edit\" href=\"ESTwoPrim(-365)\"/>\n" + + " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" \n" + + " term=\"#olingo.odata.test1.ETBase\"/>\n" + + " <a:content type=\"application/xml\">\n" + + " <m:properties>\n" + + " <d:PropertyInt16 m:type=\"Int16\">-365</d:PropertyInt16>\n" + + " <d:PropertyString>Test String2</d:PropertyString>\n" + + " <d:AdditionalPropertyString_5>Test String2</d:AdditionalPropertyString_5>\n" + + " </m:properties>\n" + + " </a:content>\n" + + " </a:entry>\n" + + " </a:feed>\n" + + " </m:inline>\n" + + " </a:link>\n" + + " <a:link rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\" \n" + + " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\" href=\"ESTwoPrim(32767)\">\n" + + " <m:inline>\n" + + " <a:entry>\n" + + " <a:id>ESTwoPrim(32767)</a:id>\n" + + " <a:link rel=\"edit\" href=\"ESTwoPrim(32767)\"/>\n" + + " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" \n" + + " term=\"#olingo.odata.test1.ETBase\"/>\n" + + " <a:content type=\"application/xml\">\n" + + " <m:properties>\n" + + " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" + + " <d:PropertyString>Test String4</d:PropertyString>\n" + + " <d:AdditionalPropertyString_5>Test String2</d:AdditionalPropertyString_5>\n" + + " </m:properties>\n" + + " </a:content>\n" + + " </a:entry>\n" + + " </m:inline>\n" + + " </a:link>\n" + + " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETAllPrim\"/>\n" + + " <a:content type=\"application/xml\">\n" + + " <m:properties>\n" + + " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" + + " <d:PropertyString>First Resource - positive values</d:PropertyString>\n" + + " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" + + " <d:PropertyByte m:type=\"Byte\">255</d:PropertyByte>\n" + + " <d:PropertySByte m:type=\"SByte\">127</d:PropertySByte>\n" + + " <d:PropertyInt32 m:type=\"Int32\">2147483647</d:PropertyInt32>\n" + + " <d:PropertyInt64 m:type=\"Int64\">9223372036854775807</d:PropertyInt64>\n" + + " <d:PropertySingle m:type=\"Single\">1.79E20</d:PropertySingle>\n" + + " <d:PropertyDouble m:type=\"Double\">-1.79E19</d:PropertyDouble>\n" + + " <d:PropertyDecimal m:type=\"Decimal\">34</d:PropertyDecimal>\n" + + " <d:PropertyBinary m:type=\"Binary\">ASNFZ4mrze8=</d:PropertyBinary>\n" + + " <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n"+ + " <d:PropertyDuration m:type=\"Duration\">PT6S</d:PropertyDuration>\n" + + " <d:PropertyGuid m:type=\"Guid\">01234567-89ab-cdef-0123-456789abcdef</d:PropertyGuid>\n" + + " <d:PropertyTimeOfDay m:type=\"TimeOfDay\">03:26:05</d:PropertyTimeOfDay>\n" + + " </m:properties>\n" + + " </a:content>\n" + + "</a:entry>\n" ; + + Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), + edmEntitySet.getEntityType()).getEntity(); + Assert.assertEquals(15, result.getProperties().size()); + Assert.assertEquals(2, result.getNavigationLinks().size()); + assertNotNull(result.getNavigationLinks().get(0).getInlineEntitySet() + .getEntities().get(1).getProperty("AdditionalPropertyString_5")); + assertNotNull(result.getNavigationLinks().get(1).getInlineEntity().getProperty("AdditionalPropertyString_5")); + } @Test + public void derivedEntityESCompCollDerived() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompCollDerived"); + final String payload = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + + "xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" m:context=\"$metadata#ESCompCollDerived/$entity\"\n" + + "m:metadata-etag=\"W/"1c2796fd-da13-4741-9da2-99cac365f296"\">\n" + + " <a:id>ESCompCollDerived(32767)</a:id>\n" + + " <a:title/>\n" + + " <a:summary/>\n" + + " <a:updated>2017-07-18T13:18:13Z</a:updated>\n" + + " <a:author>\n" + + " <a:name/>\n" + + " </a:author>\n" + + " <a:link rel=\"edit\" href=\"ESCompCollDerived(32767)\"/>\n" + + " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETDeriveCollComp\"/>\n" + + " <a:content type=\"application/xml\">\n" + + " <m:properties>\n" + + " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" + + " <d:CollPropertyCompAno>\n" + + " <m:element m:type=\"#olingo.odata.test1.CTTwoPrimAno\">\n" + + " <d:PropertyString>TEST9876</d:PropertyString>\n" + + " </m:element>\n" + + " <m:element m:type=\"#olingo.odata.test1.CTBaseAno\">\n" + + " <d:AdditionalPropString>TEST9889</d:AdditionalPropString>\n" + + " <d:PropertyString>TEST9889</d:PropertyString>\n" + + " </m:element>\n" + + " </d:CollPropertyCompAno>\n" + + " </m:properties>\n" + + " </a:content>\n" + + "</a:entry>\n" ; + + Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), + edmEntitySet.getEntityType()).getEntity(); + + Assert.assertEquals(2, result.getProperties().size()); + Assert.assertEquals(0, result.getNavigationLinks().size()); + + Assert.assertEquals(("[[PropertyString=TEST9876], [AdditionalPropString=TEST9889, PropertyString=TEST9889]]"), + result.getProperty("CollPropertyCompAno").getValue().toString()); + + Property comp = result.getProperty("CollPropertyCompAno"); + Assert.assertEquals("Collection(olingo.odata.test1.CTTwoPrimAno)", comp.getType()); + List<? extends Object> cv = comp.asCollection(); + + Assert.assertEquals(2, cv.size()); + for (Object arrayElement : cv) { + + assertTrue(arrayElement instanceof ComplexValue); + List<Property> castedArrayElement = ((ComplexValue) arrayElement).getValue(); + if(castedArrayElement.size() == 1){ + assertEquals("PropertyString=TEST9876", castedArrayElement.get(0).toString()); + }else{ + assertEquals(2, castedArrayElement.size()); + assertEquals("AdditionalPropString=TEST9889", castedArrayElement.get(0).toString()); + } + + } + } + + @Test + public void derivedEntityESCompCollDerivedNullEmpty() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompCollDerived"); + final String payload = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + + "xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" m:context=\"$metadata#ESCompCollDerived/$entity\"\n" + + "m:metadata-etag=\"W/"1c2796fd-da13-4741-9da2-99cac365f296"\">\n" + + " <a:id>ESCompCollDerived(32767)</a:id>\n" + + " <a:title/>\n" + + " <a:summary/>\n" + + " <a:updated>2017-07-18T13:18:13Z</a:updated>\n" + + " <a:author>\n" + + " <a:name/>\n" + + " </a:author>\n" + + " <a:link rel=\"edit\" href=\"ESCompCollDerived(32767)\"/>\n" + + " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" + + " term=\"#olingo.odata.test1.ETDeriveCollComp\"/>\n" + + " <a:content type=\"application/xml\">\n" + + " <m:properties>\n" + + " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" + + " <d:CollPropertyCompAno>\n" + + " <m:element m:type=\"#olingo.odata.test1.CTBaseAno\">\n" + + " <d:PropertyString/>\n" + + " <d:AdditionalPropString/>\n" + + " </m:element>\n" + + " <m:element m:type=\"#olingo.odata.test1.CTBaseAno\">\n" + + " </m:element>\n" + + " </d:CollPropertyCompAno>\n" + + " </m:properties>\n" + + " </a:content>\n" + + "</a:entry>\n" ; + + Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), + edmEntitySet.getEntityType()).getEntity(); + + Assert.assertEquals(2, result.getProperties().size()); + Assert.assertEquals(0, result.getNavigationLinks().size()); + + + Property comp = result.getProperty("CollPropertyCompAno"); + Assert.assertEquals("Collection(olingo.odata.test1.CTTwoPrimAno)", comp.getType()); + List<? extends Object> cv = comp.asCollection(); + + Assert.assertEquals(2, cv.size()); + for (Object arrayElement : cv) { + + assertTrue(arrayElement instanceof ComplexValue); + List<Property> castedArrayElement = ((ComplexValue) arrayElement).getValue(); + if(castedArrayElement.size()>0){ + assertEquals(2, castedArrayElement.size()); + assertNull(castedArrayElement.get(0).getValue()); + } + } + } + + @Test public void entityMixEnumDefCollComp() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixEnumDefCollComp"); final String payload = "<?xml version='1.0' encoding='UTF-8'?>\n"
