You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/01/19 15:48:21 UTC
olingo-odata4 git commit: [OLINGO-530] Tests and JsonType Validation
Repository: olingo-odata4
Updated Branches:
refs/heads/master af64cb1fa -> b6c1e347c
[OLINGO-530] Tests and JsonType Validation
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b6c1e347
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b6c1e347
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b6c1e347
Branch: refs/heads/master
Commit: b6c1e347c7b8b16d4184dd3d39b9ad0594d65e10
Parents: af64cb1
Author: Christian Amend <ch...@apache.org>
Authored: Mon Jan 19 15:47:19 2015 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Mon Jan 19 15:47:19 2015 +0100
----------------------------------------------------------------------
.../api/deserializer/DeserializerException.java | 4 +-
.../json/ODataJsonDeserializer.java | 236 ++++++++-----------
.../server-core-exceptions-i18n.properties | 13 +
.../json/ODataDeserializerDeepInsertTest.java | 38 +++
.../ODataDeserializerEntityCollectionTest.java | 32 +++
.../json/ODataJsonDeserializerEntityTest.java | 218 ++++++++++++++++-
.../ESAllPrimWithCustomAnnotations.json | 57 +++++
.../test/resources/ESAllPrimWithDoubleKey.json | 57 +++++
.../ESAllPrimWithODataAnnotations.json | 59 +++++
...pertyETTwoPrimManyWithCustomAnnotations.json | 25 ++
...opertyETTwoPrimManyWithODataAnnotations.json | 27 +++
...opertyETTwoPrimOneWithCustomAnnotations.json | 24 ++
...ropertyETTwoPrimOneWithODataAnnotations.json | 26 ++
13 files changed, 672 insertions(+), 144 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
index 6ecc2c8..5a9128f 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/DeserializerException.java
@@ -40,7 +40,9 @@ public class DeserializerException extends ODataTranslatedException {
VALUE_TAG_MUST_BE_AN_ARRAY,
INVALID_ENTITY,
/** parameter: navigationPropertyName */INVALID_VALUE_FOR_NAVIGATION_PROPERTY,
- DUPLICATE_PROPERTY;
+ DUPLICATE_PROPERTY,
+ DUPLICATE_JSON_PROPERTY,
+ /** parameters: primitiveTypeName, propertyName */ UNKNOWN_PRIMITIVE_TYPE;
@Override
public String getKey() {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/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 13c32ff..711b3db 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
@@ -20,14 +20,12 @@ package org.apache.olingo.server.core.deserializer.json;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
@@ -40,13 +38,14 @@ import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
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.PropertyImpl;
-import org.apache.olingo.commons.core.edm.EdmTypeInfo;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
@@ -61,6 +60,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class ODataJsonDeserializer implements ODataDeserializer {
+ private static final String ODATA_ANNOTATION_MARKER = "@";
+ private static final String ODATA_CONTROL_INFORMATION_PREFIX = "@odata.";
+
@Override
public EntitySet entityCollection(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException {
try {
@@ -74,8 +76,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
throw new DeserializerException("An JsonParseException occourred", e,
DeserializerException.MessageKeys.JSON_SYNTAX_EXCEPTION);
} catch (JsonMappingException e) {
- throw new DeserializerException("Duplicate property detected", e,
- DeserializerException.MessageKeys.DUPLICATE_PROPERTY);
+ throw new DeserializerException("Duplicate json property detected", e,
+ DeserializerException.MessageKeys.DUPLICATE_JSON_PROPERTY);
} catch (IOException e) {
throw new DeserializerException("An IOException occourred", e, DeserializerException.MessageKeys.IO_EXCEPTION);
}
@@ -84,8 +86,6 @@ public class ODataJsonDeserializer implements ODataDeserializer {
private EntitySet consumeEntitySetNode(EdmEntityType edmEntityType, final ObjectNode tree)
throws DeserializerException {
EntitySetImpl entitySet = new EntitySetImpl();
- // Consume entitySet annotations
- consumeODataEntitySetAnnotations(tree, entitySet);
// Consume entities
JsonNode jsonNode = tree.get(Constants.VALUE);
@@ -102,6 +102,22 @@ public class ODataJsonDeserializer implements ODataDeserializer {
DeserializerException.MessageKeys.VALUE_ARRAY_NOT_PRESENT);
}
+ final List<String> toRemove = new ArrayList<String>();
+ Iterator<Entry<String, JsonNode>> fieldsIterator = tree.fields();
+ while (fieldsIterator.hasNext()) {
+ Map.Entry<String, JsonNode> field = fieldsIterator.next();
+
+ if (field.getKey().contains(ODATA_CONTROL_INFORMATION_PREFIX)) {
+ // Control Information is ignored for requests as per specification chapter "4.5 Control Information"
+ toRemove.add(field.getKey());
+ } else if (field.getKey().contains(ODATA_ANNOTATION_MARKER)) {
+ throw new DeserializerException("Custom annotation with field name: " + field.getKey() + " not supported",
+ DeserializerException.MessageKeys.NOT_IMPLEMENTED);
+ }
+ }
+ // remove here to avoid iterator issues.
+ tree.remove(toRemove);
+
if (tree.size() != 0) {
throw new DeserializerException("Tree should be empty but still has content left.",
DeserializerException.MessageKeys.UNKOWN_CONTENT);
@@ -123,35 +139,6 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
}
- private void consumeODataEntitySetAnnotations(final ObjectNode tree, EntitySetImpl entitySet) {
- URI contextURL;
- if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
- contextURL = URI.create(tree.get(Constants.JSON_CONTEXT).textValue());
- tree.remove(Constants.JSON_CONTEXT);
- } else if (tree.hasNonNull(Constants.JSON_METADATA)) {
- contextURL = URI.create(tree.get(Constants.JSON_METADATA).textValue());
- tree.remove(Constants.JSON_METADATA);
- } else {
- contextURL = null;
- }
- if (contextURL != null) {
- entitySet.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA));
- }
-
- if (tree.hasNonNull(Constants.JSON_COUNT)) {
- entitySet.setCount(tree.get(Constants.JSON_COUNT).asInt());
- tree.remove(Constants.JSON_COUNT);
- }
- if (tree.hasNonNull(Constants.JSON_NEXT_LINK)) {
- entitySet.setNext(URI.create(tree.get(Constants.JSON_NEXT_LINK).textValue()));
- tree.remove(Constants.JSON_NEXT_LINK);
- }
- if (tree.hasNonNull(Constants.JSON_DELTA_LINK)) {
- entitySet.setDeltaLink(URI.create(tree.get(Constants.JSON_DELTA_LINK).textValue()));
- tree.remove(Constants.JSON_DELTA_LINK);
- }
- }
-
@Override
public Entity entity(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException {
try {
@@ -231,19 +218,17 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
}
- // Check and consume all Annotations
- consumeODataEntityAnnotations(tree, entity, edmEntityType);
-
final List<String> toRemove = new ArrayList<String>();
Iterator<Entry<String, JsonNode>> fieldsIterator = tree.fields();
- // TODO: Add custom annotation support
while (fieldsIterator.hasNext()) {
- Map.Entry<String, JsonNode> field = (Map.Entry<String, JsonNode>) fieldsIterator.next();
+ Map.Entry<String, JsonNode> field = fieldsIterator.next();
- if (field.getKey().endsWith(Constants.JSON_NAVIGATION_LINK)
- || field.getKey().endsWith(Constants.JSON_ASSOCIATION_LINK) || field.getKey().endsWith(Constants.JSON_TYPE)) {
- // navigation links, association links and type information have to be ignored in requests.
+ if (field.getKey().contains(ODATA_CONTROL_INFORMATION_PREFIX)) {
+ // Control Information is ignored for requests as per specification chapter "4.5 Control Information"
toRemove.add(field.getKey());
+ } else if (field.getKey().contains(ODATA_ANNOTATION_MARKER)) {
+ throw new DeserializerException("Custom annotation with field name: " + field.getKey() + " not supported",
+ DeserializerException.MessageKeys.NOT_IMPLEMENTED);
}
}
@@ -259,75 +244,6 @@ public class ODataJsonDeserializer implements ODataDeserializer {
return entity;
}
- private void consumeODataEntityAnnotations(ObjectNode tree, EntityImpl entity, EdmEntityType edmEntityType) {
- final URI contextURL;
- if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
- contextURL = URI.create(tree.get(Constants.JSON_CONTEXT).textValue());
- tree.remove(Constants.JSON_CONTEXT);
- } else if (tree.hasNonNull(Constants.JSON_METADATA)) {
- contextURL = URI.create(tree.get(Constants.JSON_METADATA).textValue());
- tree.remove(Constants.JSON_METADATA);
- } else {
- contextURL = null;
- }
- if (contextURL != null) {
- entity.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA));
- }
-
- if (tree.hasNonNull(Constants.JSON_ETAG)) {
- entity.setETag(tree.get(Constants.JSON_ETAG).textValue());
- tree.remove(Constants.JSON_ETAG);
- }
-
- if (tree.hasNonNull(Constants.JSON_TYPE)) {
- entity.setType(new EdmTypeInfo.Builder().setTypeExpression(tree.get(Constants.JSON_TYPE).textValue()).build()
- .internal());
- tree.remove(Constants.JSON_TYPE);
- }
-
- if (tree.hasNonNull(Constants.JSON_ID)) {
- entity.setId(URI.create(tree.get(Constants.JSON_ID).textValue()));
- tree.remove(Constants.JSON_ID);
- }
-
- if (tree.hasNonNull(Constants.JSON_READ_LINK)) {
- final LinkImpl link = new LinkImpl();
- link.setRel(Constants.SELF_LINK_REL);
- link.setHref(tree.get(Constants.JSON_READ_LINK).textValue());
- entity.setSelfLink(link);
-
- tree.remove(Constants.JSON_READ_LINK);
- }
-
- if (tree.hasNonNull(Constants.JSON_EDIT_LINK)) {
- final LinkImpl link = new LinkImpl();
- link.setRel(Constants.EDIT_LINK_REL);
- link.setHref(tree.get(Constants.JSON_EDIT_LINK).textValue());
- entity.setEditLink(link);
-
- tree.remove(Constants.JSON_EDIT_LINK);
- }
-
- // TODO: Should we check if this is a media resource?
- if (tree.hasNonNull(Constants.JSON_MEDIA_READ_LINK)) {
- entity.setMediaContentSource(URI.create(tree.get(Constants.JSON_MEDIA_READ_LINK).textValue()));
- tree.remove(Constants.JSON_MEDIA_READ_LINK);
- }
- if (tree.hasNonNull(Constants.JSON_MEDIA_EDIT_LINK)) {
- entity.setMediaContentSource(URI.create(tree.get(Constants.JSON_MEDIA_EDIT_LINK).textValue()));
- tree.remove(Constants.JSON_MEDIA_EDIT_LINK);
- }
- if (tree.hasNonNull(Constants.JSON_MEDIA_CONTENT_TYPE)) {
- entity.setMediaContentType(tree.get(Constants.JSON_MEDIA_CONTENT_TYPE).textValue());
- tree.remove(Constants.JSON_MEDIA_CONTENT_TYPE);
- }
- if (tree.hasNonNull(Constants.JSON_MEDIA_ETAG)) {
- entity.setMediaETag(tree.get(Constants.JSON_MEDIA_ETAG).textValue());
- tree.remove(Constants.JSON_MEDIA_ETAG);
- }
-
- }
-
private Property consumePropertyNode(EdmProperty edmProperty, JsonNode jsonNode) throws DeserializerException {
Property property = new PropertyImpl();
property.setName(edmProperty.getName());
@@ -356,6 +272,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
valueArray.add(value);
}
property.setValue(ValueType.COLLECTION_PRIMITIVE, valueArray);
+ break;
case ENUM:
while (iterator.hasNext()) {
JsonNode arrayElement = iterator.next();
@@ -370,19 +287,19 @@ public class ODataJsonDeserializer implements ODataDeserializer {
// read and add all complex properties
Object value = readComplexValue(edmProperty, arrayElement);
valueArray.add(value);
- // If navigationProperties are present we have to consume them and create a LinkedComplexValue Object
- // TODO: Complex Type Navigation Deserialization
+
final List<String> toRemove = new ArrayList<String>();
Iterator<Entry<String, JsonNode>> fieldsIterator = arrayElement.fields();
- // TODO: Add custom annotation support
while (fieldsIterator.hasNext()) {
- Map.Entry<String, JsonNode> field = (Map.Entry<String, JsonNode>) fieldsIterator.next();
+ Map.Entry<String, JsonNode> field = fieldsIterator.next();
- if (field.getKey().endsWith(Constants.JSON_NAVIGATION_LINK)
- || field.getKey().endsWith(Constants.JSON_ASSOCIATION_LINK)
- || field.getKey().endsWith(Constants.JSON_TYPE)) {
- // navigation links, association links and type information have to be ignored in requests.
+ if (field.getKey().contains(ODATA_CONTROL_INFORMATION_PREFIX)) {
+ // Control Information is ignored for requests as per specification chapter "4.5 Control Information"
toRemove.add(field.getKey());
+ } else if (field.getKey().contains(ODATA_ANNOTATION_MARKER)) {
+ throw new DeserializerException(
+ "Custom annotation with field name: " + field.getKey() + " not supported",
+ DeserializerException.MessageKeys.NOT_IMPLEMENTED);
}
}
// remove here to avoid iterator issues.
@@ -410,6 +327,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
case DEFINITION:
value = readTypeDefinitionValue(edmProperty, jsonNode);
property.setValue(ValueType.PRIMITIVE, value);
+ break;
case ENUM:
value = readEnumValue(edmProperty, jsonNode);
property.setValue(ValueType.PRIMITIVE, value);
@@ -419,19 +337,17 @@ public class ODataJsonDeserializer implements ODataDeserializer {
value = readComplexValue(edmProperty, jsonNode);
property.setValue(ValueType.COMPLEX, value);
- // read and add all navigation properties
- // TODO: Complex Type Navigation Deserialization
final List<String> toRemove = new ArrayList<String>();
Iterator<Entry<String, JsonNode>> fieldsIterator = jsonNode.fields();
- // TODO: Add custom annotation support
while (fieldsIterator.hasNext()) {
- Map.Entry<String, JsonNode> field = (Map.Entry<String, JsonNode>) fieldsIterator.next();
+ Map.Entry<String, JsonNode> field = fieldsIterator.next();
- if (field.getKey().endsWith(Constants.JSON_NAVIGATION_LINK)
- || field.getKey().endsWith(Constants.JSON_ASSOCIATION_LINK)
- || field.getKey().endsWith(Constants.JSON_TYPE)) {
- // navigation links, association links and type information have to be ignored in requests.
+ if (field.getKey().contains(ODATA_CONTROL_INFORMATION_PREFIX)) {
+ // Control Information is ignored for requests as per specification chapter "4.5 Control Information"
toRemove.add(field.getKey());
+ } else if (field.getKey().contains(ODATA_ANNOTATION_MARKER)) {
+ throw new DeserializerException("Custom annotation with field name: " + field.getKey() + " not supported",
+ DeserializerException.MessageKeys.NOT_IMPLEMENTED);
}
}
// remove here to avoid iterator issues.
@@ -485,6 +401,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
try {
EdmTypeDefinition edmTypeDefinition = (EdmTypeDefinition) edmProperty.getType();
+ checkJsonTypeBasedOnPrimitiveType(edmProperty.getName(), edmTypeDefinition.getUnderlyingType().getName(),
+ jsonNode);
Object value =
edmTypeDefinition.valueOfString(jsonNode.asText(), edmProperty.isNullable(),
edmTypeDefinition.getMaxLength(),
@@ -506,6 +424,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
try {
EdmEnumType edmEnumType = (EdmEnumType) edmProperty.getType();
+ checkJsonTypeBasedOnPrimitiveType(edmProperty.getName(), edmEnumType.getUnderlyingType().getName(), jsonNode);
Object value =
edmEnumType
.valueOfString(jsonNode.asText(), edmProperty.isNullable(), edmProperty.getMaxLength(), edmProperty
@@ -526,6 +445,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
try {
EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmProperty.getType();
+ checkJsonTypeBasedOnPrimitiveType(edmProperty.getName(), edmPrimitiveType.getName(), jsonNode);
Object value =
edmPrimitiveType.valueOfString(jsonNode.asText(), edmProperty.isNullable(),
edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(),
@@ -538,13 +458,53 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
}
-// @Override
-// public Entity entity(InputStream stream, EdmEntityType edmEntityType)
-// throws DeserializerException {
-// try {
-// return new JsonDeserializer(ODataServiceVersion.V40, true).toEntity(stream).getPayload();
-// } catch (Exception e) {
-// throw new DeserializerException("", e, DeserializerException.MessageKeys.JSON_SYNTAX_EXCEPTION);
-// }
-// }
+ private void checkJsonTypeBasedOnPrimitiveType(String propertyName, String edmPrimitiveTypeName, JsonNode jsonNode)
+ throws DeserializerException {
+ EdmPrimitiveTypeKind primKind = null;
+ try {
+ primKind = EdmPrimitiveTypeKind.valueOf(ODataServiceVersion.V40, edmPrimitiveTypeName);
+ } catch (IllegalArgumentException e) {
+ throw new DeserializerException("Unkown Primitive Type: " + edmPrimitiveTypeName, e,
+ DeserializerException.MessageKeys.UNKNOWN_PRIMITIVE_TYPE, edmPrimitiveTypeName, propertyName);
+ }
+ switch (primKind) {
+ // Booleans
+ case Boolean:
+ if (!jsonNode.isBoolean()) {
+ throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
+ + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+ }
+ break;
+ // Numbers
+ case Int16:
+ case Int32:
+ case Int64:
+ case Byte:
+ case SByte:
+ case Single:
+ case Double:
+ case Decimal:
+ if (!jsonNode.isNumber()) {
+ throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
+ + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+ }
+ break;
+//Strings
+ case String:
+ case Binary:
+ case Date:
+ case DateTimeOffset:
+ case Duration:
+ case Guid:
+ case TimeOfDay:
+ if (!jsonNode.isTextual()) {
+ throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
+ + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+ }
+ break;
+ default:
+ throw new DeserializerException("Unsupported Edm Primitive Type: " + primKind,
+ DeserializerException.MessageKeys.NOT_IMPLEMENTED);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index 034a6bd..eb31dd1 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -99,6 +99,19 @@ SerializerException.WRONG_PRIMITIVE_VALUE=The value '%2$s' is not valid for the
DeserializerException.NOT_IMPLEMENTED=The requested deserialization method has not been implemented yet.
DeserializerException.IO_EXCEPTION=An I/O exception occurred.
+DeserializerException.UNSUPPORTED_FORMAT=The format '%1$s' is not supported.
+DeserializerException.JSON_SYNTAX_EXCEPTION=The syntax of the JSON document is not valid.
+DeserializerException.INVALID_NULL_PROPERTY=The property '%1$s' must not be null.
+DeserializerException.UNKOWN_CONTENT='%1$s' can not be mapped as a property or an annotation.
+DeserializerException.INVALID_VALUE_FOR_PROPERTY=Invalid value for property '%1$s'.
+DeserializerException.INVALID_TYPE_FOR_PROPERTY=Invalid JSON type for property '%1$s'.
+DeserializerException.VALUE_ARRAY_NOT_PRESENT=Cannot find the value array. A collection needs at least an empty array.
+DeserializerException.VALUE_TAG_MUST_BE_AN_ARRAY=Invalid JSON type for the value tag. Must be an Array.
+DeserializerException.INVALID_ENTITY=Invalid JSON type for an entity. Must be a JSON object.
+DeserializerException.INVALID_VALUE_FOR_NAVIGATION_PROPERTY=Invalid value for navigation property '%1$s'. Must be an array for collections or for an entity either null or an object.
+DeserializerException.DUPLICATE_PROPERTY="Edm Properties must not appear twice within the same object."
+DeserializerException.DUPLICATE_JSON_PROPERTY="JSON properties must not appear twice within the same object."
+DeserializerException.UNKNOWN_PRIMITIVE_TYPE=Unknown primitive type '%1$s' for property '%2$s';
BatchDeserializerException.INVALID_BOUNDARY=Invalid boundary at line '%1$s'.
BatchDeserializerException.INVALID_CHANGESET_METHOD=Invalid method: a ChangeSet cannot contain retrieve requests at line '%1$s'.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
index 3b90277..a2f61a9 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
@@ -31,6 +31,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.junit.Test;
public class ODataDeserializerDeepInsertTest extends AbstractODataDeserializerTest {
@@ -51,6 +52,13 @@ public class ODataDeserializerDeepInsertTest extends AbstractODataDeserializerTe
}
@Test
+ public void esAllPrimExpandedToOneWithODataAnnotations() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithODataAnnotations.json");
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entity(stream, edmEntityType);
+ }
+
+ @Test
public void esAllPrimExpandedToMany() throws Exception {
EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimMany.json");
@@ -66,4 +74,34 @@ public class ODataDeserializerDeepInsertTest extends AbstractODataDeserializerTe
assertEquals(1, navigationLink.getInlineEntitySet().getEntities().size());
}
+ @Test
+ public void esAllPrimExpandedToManyWithODataAnnotations() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithODataAnnotations.json");
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entity(stream, edmEntityType);
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void esAllPrimExpandedToOneWithCustomAnnotations() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithCustomAnnotations.json");
+ try {
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entity(stream, edmEntityType);
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.NOT_IMPLEMENTED, e.getMessageKey());
+ throw e;
+ }
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void esAllPrimExpandedToManyWithCustomAnnotations() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithCustomAnnotations.json");
+ try {
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entity(stream, edmEntityType);
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.NOT_IMPLEMENTED, e.getMessageKey());
+ throw e;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
index 888722e..e9ebbde 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
@@ -32,6 +32,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.junit.Test;
public class ODataDeserializerEntityCollectionTest extends AbstractODataDeserializerTest {
@@ -82,4 +83,35 @@ public class ODataDeserializerEntityCollectionTest extends AbstractODataDeserial
// Since entity deserialization is called we do not check all entities here excplicitly
}
+
+ @Test
+ public void esAllPrimODataAnnotationsAreIgnored() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("ESAllPrimWithODataAnnotations.json");
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entityCollection(stream, edmEntityType);
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void esAllPrimCustomAnnotationsLeadToNotImplemented() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("ESAllPrimWithCustomAnnotations.json");
+ try {
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entityCollection(stream, edmEntityType);
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.NOT_IMPLEMENTED, e.getMessageKey());
+ throw e;
+ }
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void esAllPrimDoubleKeysLeadToException() throws Exception {
+ EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
+ InputStream stream = getFileAsStream("ESAllPrimWithDoubleKey.json");
+ try {
+ OData.newInstance().createDeserializer(ODataFormat.JSON).entityCollection(stream, edmEntityType);
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.DUPLICATE_JSON_PROPERTY, e.getMessageKey());
+ throw e;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/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 a446825..dce010c 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
@@ -21,6 +21,7 @@ package org.apache.olingo.server.core.deserializer.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@@ -35,7 +36,6 @@ import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
-import org.junit.Ignore;
import org.junit.Test;
public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTest {
@@ -265,7 +265,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
}
@Test
- public void ingoreSomeAnnotationsInEntityTypes() throws Exception {
+ public void ignoreSomeAnnotationsInEntityTypes() throws Exception {
// We have to ignore @odata.navigation, @odata.association and @odata.type annotations on server side
String entityString =
"{\"PropertyInt16\":32767,"
@@ -280,7 +280,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
}
@Test
- public void ingoreSomeAnnotationsInComplexTypes() throws Exception {
+ public void ignoreSomeAnnotationsInComplexTypes() throws Exception {
final String entityString = "{"
+ "\"PropertyInt16\":32767,"
+ "\"CollPropertyString\":"
@@ -298,6 +298,32 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp")));
}
+ @Test
+ public void odataControlInformationIsIgnoredForRequests() throws Exception {
+ String entityString =
+ "{"
+ + "\"@odata.context\":\"http://localhost:8080\","
+ + "\"@odata.metadataEtag\":\"metadataEtag\","
+ + "\"@odata.id\":\"value\","
+ + "\"@odata.editLink\":\"value\","
+ + "\"@odata.readLink\":\"value\","
+ + "\"@odata.etag\":\"value\","
+ + "\"@odata.mediaEtag\":\"value\","
+ + "\"@odata.mediaReadLink\":\"value\","
+ + "\"@odata.mediaEditLink\":\"value\","
+ + "\"PropertyInt16\":32767,"
+ + "\"PropertyString\":\"First Resource - positive values\""
+ + "}";
+ InputStream stream = new ByteArrayInputStream(entityString.getBytes());
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
+ Entity entity =
+ deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim")));
+ assertNotNull(entity);
+ List<Property> properties = entity.getProperties();
+ assertNotNull(properties);
+ assertEquals(2, properties.size());
+ }
+
// ---------------------------------- Negative Tests -----------------------------------------------------------
@Test(expected = DeserializerException.class)
@@ -452,9 +478,8 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
}
}
- @Ignore
@Test(expected = DeserializerException.class)
- public void customAnnotationsLeadToNotImplemented() throws Exception {
+ public void customAnnotationInEntityLeadToNotImplemented() throws Exception {
final String entityString = "{"
+ "\"PropertyInt16\":32767,"
+ "\"CollPropertyString@custom.annotation\": 12,"
@@ -477,6 +502,51 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
}
@Test(expected = DeserializerException.class)
+ public void customAnnotationInComplexValueLeadToNotImplemented() throws Exception {
+ final String entityString = "{"
+ + "\"PropertyInt16\":32767,"
+ + "\"CollPropertyString\":"
+ + "[\"Employee1@company.example\",\"Employee2@company.example\",\"Employee3@company.example\"],"
+ + "\"PropertyComp\":{\"PropertyInt16\":111," +
+ "\"CollPropertyString@custom.annotation\": 12,\"PropertyString\":\"TEST A\"},"
+ + "\"CollPropertyComp\":["
+ + "{\"PropertyInt16\":123,\"PropertyString\":\"TEST 1\"},"
+ + "{\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"},"
+ + "{\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"}]}";
+
+ InputStream stream = new ByteArrayInputStream(entityString.getBytes());
+ try {
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
+ deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp")));
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.NOT_IMPLEMENTED, e.getMessageKey());
+ throw e;
+ }
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void customAnnotationInComplexCollectionValueLeadToNotImplemented() throws Exception {
+ final String entityString = "{"
+ + "\"PropertyInt16\":32767,"
+ + "\"CollPropertyString\":"
+ + "[\"Employee1@company.example\",\"Employee2@company.example\",\"Employee3@company.example\"],"
+ + "\"PropertyComp\":{\"PropertyInt16\":111,\"PropertyString\":\"TEST A\"},"
+ + "\"CollPropertyComp\":["
+ + "{\"PropertyInt16\":123,\"CollPropertyString@custom.annotation\": 12,\"PropertyString\":\"TEST 1\"},"
+ + "{\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"},"
+ + "{\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"}]}";
+
+ InputStream stream = new ByteArrayInputStream(entityString.getBytes());
+ try {
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
+ deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp")));
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.NOT_IMPLEMENTED, e.getMessageKey());
+ throw e;
+ }
+ }
+
+ @Test(expected = DeserializerException.class)
public void unkownContentInEntity() throws Exception {
final String entityString = "{"
+ "\"PropertyInt16\":32767,"
@@ -543,4 +613,142 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
}
}
+ @Test
+ public void propertyInt16JsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyInt16\":\"32767\"}");
+ checkPropertyJsonType("{\"PropertyInt16\":true}");
+ checkPropertyJsonType("{\"PropertyInt16\":[]}");
+ checkPropertyJsonType("{\"PropertyInt16\":{}}");
+ }
+
+ @Test
+ public void propertyInt32JsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyInt32\":\"2147483647\"}");
+ checkPropertyJsonType("{\"PropertyInt32\":true}");
+ checkPropertyJsonType("{\"PropertyInt32\":[]}");
+ checkPropertyJsonType("{\"PropertyInt32\":{}}");
+ }
+
+ @Test
+ public void propertyInt64JsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyInt64\":\"9223372036854775807\"}");
+ checkPropertyJsonType("{\"PropertyInt64\":true}");
+ checkPropertyJsonType("{\"PropertyInt64\":[]}");
+ checkPropertyJsonType("{\"PropertyInt64\":{}}");
+ }
+
+ @Test
+ public void propertyStringJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyString\":32767}");
+ checkPropertyJsonType("{\"PropertyString\":true}");
+ checkPropertyJsonType("{\"PropertyString\":[]}");
+ checkPropertyJsonType("{\"PropertyString\":{}}");
+ }
+
+ @Test
+ public void propertyBooleanJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyBoolean\":\"true\"}");
+ checkPropertyJsonType("{\"PropertyBoolean\":123}");
+ checkPropertyJsonType("{\"PropertyBoolean\":[]}");
+ checkPropertyJsonType("{\"PropertyBoolean\":{}}");
+ }
+
+ @Test
+ public void propertyByteJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyByte\":\"255\"}");
+ checkPropertyJsonType("{\"PropertyByte\":true}");
+ checkPropertyJsonType("{\"PropertyByte\":[]}");
+ checkPropertyJsonType("{\"PropertyByte\":{}}");
+ }
+
+ @Test
+ public void propertySByteJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertySByte\":\"127\"}");
+ checkPropertyJsonType("{\"PropertySByte\":true}");
+ checkPropertyJsonType("{\"PropertySByte\":[]}");
+ checkPropertyJsonType("{\"PropertySByte\":{}}");
+ }
+
+ @Test
+ public void propertySingleJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertySingle\":\"1.79E20\"}");
+ checkPropertyJsonType("{\"PropertySingle\":true}");
+ checkPropertyJsonType("{\"PropertySingle\":[]}");
+ checkPropertyJsonType("{\"PropertySingle\":{}}");
+ }
+
+ @Test
+ public void propertyDoubleJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyDouble\":\"-1.79E19\"}");
+ checkPropertyJsonType("{\"PropertyDouble\":true}");
+ checkPropertyJsonType("{\"PropertyDouble\":[]}");
+ checkPropertyJsonType("{\"PropertyDouble\":{}}");
+ }
+
+ @Test
+ public void propertyDecimalJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyDecimal\":\"34\"}");
+ checkPropertyJsonType("{\"PropertyDecimal\":true}");
+ checkPropertyJsonType("{\"PropertyDecimal\":[]}");
+ checkPropertyJsonType("{\"PropertyDecimal\":{}}");
+ }
+
+ @Test
+ public void propertyBinaryJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyBinary\":32767}");
+ checkPropertyJsonType("{\"PropertyBinary\":true}");
+ checkPropertyJsonType("{\"PropertyBinary\":[]}");
+ checkPropertyJsonType("{\"PropertyBinary\":{}}");
+ }
+
+ @Test
+ public void propertyDateJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyDate\":32767}");
+ checkPropertyJsonType("{\"PropertyDate\":true}");
+ checkPropertyJsonType("{\"PropertyDate\":[]}");
+ checkPropertyJsonType("{\"PropertyDate\":{}}");
+ }
+
+ @Test
+ public void propertyDateTimeOffsetJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyDateTimeOffset\":32767}");
+ checkPropertyJsonType("{\"PropertyDateTimeOffset\":true}");
+ checkPropertyJsonType("{\"PropertyDateTimeOffset\":[]}");
+ checkPropertyJsonType("{\"PropertyDateTimeOffset\":{}}");
+ }
+
+ @Test
+ public void propertyDurationJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyDuration\":32767}");
+ checkPropertyJsonType("{\"PropertyDuration\":true}");
+ checkPropertyJsonType("{\"PropertyDuration\":[]}");
+ checkPropertyJsonType("{\"PropertyDuration\":{}}");
+ }
+
+ @Test
+ public void propertyGuidTimeOffsetJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyGuid\":32767}");
+ checkPropertyJsonType("{\"PropertyGuid\":true}");
+ checkPropertyJsonType("{\"PropertyGuid\":[]}");
+ checkPropertyJsonType("{\"PropertyGuid\":{}}");
+ }
+
+ @Test
+ public void propertyTimeOfDayJsonTypesNegativeCheck() throws Exception {
+ checkPropertyJsonType("{\"PropertyTimeOfDay\":32767}");
+ checkPropertyJsonType("{\"PropertyTimeOfDay\":true}");
+ checkPropertyJsonType("{\"PropertyTimeOfDay\":[]}");
+ checkPropertyJsonType("{\"PropertyTimeOfDay\":{}}");
+ }
+
+ private void checkPropertyJsonType(String entityString) throws DeserializerException {
+ InputStream stream = new ByteArrayInputStream(entityString.getBytes());
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
+ try {
+ deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim")));
+ fail("Expected an exception but was not thrown: " + this.getClass().getName());
+ } catch (DeserializerException e) {
+ assertEquals(DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, e.getMessageKey());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/ESAllPrimWithCustomAnnotations.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/ESAllPrimWithCustomAnnotations.json b/lib/server-test/src/test/resources/ESAllPrimWithCustomAnnotations.json
new file mode 100644
index 0000000..915a3f0
--- /dev/null
+++ b/lib/server-test/src/test/resources/ESAllPrimWithCustomAnnotations.json
@@ -0,0 +1,57 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim",
+ "@custom.annotation" : "customValue",
+ "value" : [{
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05"
+ }, {
+ "PropertyInt16" : -32768,
+ "PropertyString" : "Second Resource - negative values",
+ "PropertyBoolean" : false,
+ "PropertyByte" : 0,
+ "PropertySByte" : -128,
+ "PropertyInt32" : -2147483648,
+ "PropertyInt64" : -9223372036854775808,
+ "PropertySingle" : -1.79000000E+08,
+ "PropertyDouble" : -1.7900000000000000E+05,
+ "PropertyDecimal" : -34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2015-11-05",
+ "PropertyDateTimeOffset" : "2005-12-03T07:17:08Z",
+ "PropertyDuration" : "P0DT0H0M9S",
+ "PropertyGuid" : "76543201-23ab-cdef-0123-456789dddfff",
+ "PropertyTimeOfDay" : "23:49:14"
+ }, {
+ "PropertyInt16" : 0,
+ "PropertyString" : "",
+ "PropertyBoolean" : false,
+ "PropertyByte" : 0,
+ "PropertySByte" : 0,
+ "PropertyInt32" : 0,
+ "PropertyInt64" : 0,
+ "PropertySingle" : 0.00000000E+00,
+ "PropertyDouble" : 0.0000000000000000E+00,
+ "PropertyDecimal" : 0,
+ "PropertyBinary" : "",
+ "PropertyDate" : "1970-01-01",
+ "PropertyDateTimeOffset" : "2005-12-03T00:00:00Z",
+ "PropertyDuration" : "P0DT0H0M0S",
+ "PropertyGuid" : "76543201-23ab-cdef-0123-456789cccddd",
+ "PropertyTimeOfDay" : "00:01:01"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/ESAllPrimWithDoubleKey.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/ESAllPrimWithDoubleKey.json b/lib/server-test/src/test/resources/ESAllPrimWithDoubleKey.json
new file mode 100644
index 0000000..6c12ca1
--- /dev/null
+++ b/lib/server-test/src/test/resources/ESAllPrimWithDoubleKey.json
@@ -0,0 +1,57 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim",
+ "value" : [],
+ "value" : [{
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05"
+ }, {
+ "PropertyInt16" : -32768,
+ "PropertyString" : "Second Resource - negative values",
+ "PropertyBoolean" : false,
+ "PropertyByte" : 0,
+ "PropertySByte" : -128,
+ "PropertyInt32" : -2147483648,
+ "PropertyInt64" : -9223372036854775808,
+ "PropertySingle" : -1.79000000E+08,
+ "PropertyDouble" : -1.7900000000000000E+05,
+ "PropertyDecimal" : -34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2015-11-05",
+ "PropertyDateTimeOffset" : "2005-12-03T07:17:08Z",
+ "PropertyDuration" : "P0DT0H0M9S",
+ "PropertyGuid" : "76543201-23ab-cdef-0123-456789dddfff",
+ "PropertyTimeOfDay" : "23:49:14"
+ }, {
+ "PropertyInt16" : 0,
+ "PropertyString" : "",
+ "PropertyBoolean" : false,
+ "PropertyByte" : 0,
+ "PropertySByte" : 0,
+ "PropertyInt32" : 0,
+ "PropertyInt64" : 0,
+ "PropertySingle" : 0.00000000E+00,
+ "PropertyDouble" : 0.0000000000000000E+00,
+ "PropertyDecimal" : 0,
+ "PropertyBinary" : "",
+ "PropertyDate" : "1970-01-01",
+ "PropertyDateTimeOffset" : "2005-12-03T00:00:00Z",
+ "PropertyDuration" : "P0DT0H0M0S",
+ "PropertyGuid" : "76543201-23ab-cdef-0123-456789cccddd",
+ "PropertyTimeOfDay" : "00:01:01"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/ESAllPrimWithODataAnnotations.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/ESAllPrimWithODataAnnotations.json b/lib/server-test/src/test/resources/ESAllPrimWithODataAnnotations.json
new file mode 100644
index 0000000..ce3ae40
--- /dev/null
+++ b/lib/server-test/src/test/resources/ESAllPrimWithODataAnnotations.json
@@ -0,0 +1,59 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim",
+ "@odata.count" : 3,
+ "@odata.nextLink" : "http://localhost:8080/nextLink",
+ "@odata.deltaLink" : "http://localhost:8080/deltaLink",
+ "value" : [{
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05"
+ }, {
+ "PropertyInt16" : -32768,
+ "PropertyString" : "Second Resource - negative values",
+ "PropertyBoolean" : false,
+ "PropertyByte" : 0,
+ "PropertySByte" : -128,
+ "PropertyInt32" : -2147483648,
+ "PropertyInt64" : -9223372036854775808,
+ "PropertySingle" : -1.79000000E+08,
+ "PropertyDouble" : -1.7900000000000000E+05,
+ "PropertyDecimal" : -34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2015-11-05",
+ "PropertyDateTimeOffset" : "2005-12-03T07:17:08Z",
+ "PropertyDuration" : "P0DT0H0M9S",
+ "PropertyGuid" : "76543201-23ab-cdef-0123-456789dddfff",
+ "PropertyTimeOfDay" : "23:49:14"
+ }, {
+ "PropertyInt16" : 0,
+ "PropertyString" : "",
+ "PropertyBoolean" : false,
+ "PropertyByte" : 0,
+ "PropertySByte" : 0,
+ "PropertyInt32" : 0,
+ "PropertyInt64" : 0,
+ "PropertySingle" : 0.00000000E+00,
+ "PropertyDouble" : 0.0000000000000000E+00,
+ "PropertyDecimal" : 0,
+ "PropertyBinary" : "",
+ "PropertyDate" : "1970-01-01",
+ "PropertyDateTimeOffset" : "2005-12-03T00:00:00Z",
+ "PropertyDuration" : "P0DT0H0M0S",
+ "PropertyGuid" : "76543201-23ab-cdef-0123-456789cccddd",
+ "PropertyTimeOfDay" : "00:01:01"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithCustomAnnotations.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithCustomAnnotations.json b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithCustomAnnotations.json
new file mode 100644
index 0000000..edcc3ad
--- /dev/null
+++ b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithCustomAnnotations.json
@@ -0,0 +1,25 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim/$entity",
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05",
+ "NavPropertyETTwoPrimMany@custom.annotation" : "customValue",
+ "NavPropertyETTwoPrimMany" : [{
+ "PropertyInt16" : -365,
+ "PropertyString" : "Test String2"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithODataAnnotations.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithODataAnnotations.json b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithODataAnnotations.json
new file mode 100644
index 0000000..4cbf650
--- /dev/null
+++ b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimManyWithODataAnnotations.json
@@ -0,0 +1,27 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim/$entity",
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05",
+ "NavPropertyETTwoPrimMany@odata.context" : "http://localhost:8080/context",
+ "NavPropertyETTwoPrimMany@odata.count" : 12,
+ "NavPropertyETTwoPrimMany@odata.nextLink" : "http://localhost:8080/nextLink",
+ "NavPropertyETTwoPrimMany" : [{
+ "PropertyInt16" : -365,
+ "PropertyString" : "Test String2"
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithCustomAnnotations.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithCustomAnnotations.json b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithCustomAnnotations.json
new file mode 100644
index 0000000..85c55e7
--- /dev/null
+++ b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithCustomAnnotations.json
@@ -0,0 +1,24 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim/$entity",
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05",
+ "NavPropertyETTwoPrimOne@custom.annotation" : "customValue",
+ "NavPropertyETTwoPrimOne" : {
+ "PropertyInt16" : 32767,
+ "PropertyString" : "Test String4"
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b6c1e347/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithODataAnnotations.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithODataAnnotations.json b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithODataAnnotations.json
new file mode 100644
index 0000000..e778f58
--- /dev/null
+++ b/lib/server-test/src/test/resources/EntityESAllPrimExpandedNavPropertyETTwoPrimOneWithODataAnnotations.json
@@ -0,0 +1,26 @@
+{
+ "@odata.context" : "$metadata#ESAllPrim/$entity",
+ "PropertyInt16" : 32767,
+ "PropertyString" : "First Resource - positive values",
+ "PropertyBoolean" : true,
+ "PropertyByte" : 255,
+ "PropertySByte" : 127,
+ "PropertyInt32" : 2147483647,
+ "PropertyInt64" : 9223372036854775807,
+ "PropertySingle" : 1.79000000E+20,
+ "PropertyDouble" : -1.7900000000000000E+19,
+ "PropertyDecimal" : 34,
+ "PropertyBinary" : "ASNFZ4mrze8=",
+ "PropertyDate" : "2012-12-03",
+ "PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
+ "PropertyDuration" : "P0DT0H0M6S",
+ "PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay" : "03:26:05",
+ "NavPropertyETTwoPrimOne@odata.context" : "http://localhost:8080/context",
+ "NavPropertyETTwoPrimOne@odata.count" : 12,
+ "NavPropertyETTwoPrimOne@odata.nextLink" : "http://localhost:8080/nextLink",
+ "NavPropertyETTwoPrimOne" : {
+ "PropertyInt16" : 32767,
+ "PropertyString" : "Test String4"
+ }
+}