From 4cd8752e15ab0f3240980ff274d8fcd2942bb095 Mon Sep 17 00:00:00 2001 From: Christian Holzer Date: Wed, 3 Jun 2015 17:19:39 +0200 Subject: [PATCH] [OLINGO-685] Fix: ODataDeserializer respects missing annotations --- .../json/ODataJsonDeserializer.java | 13 +- .../json/ODataJsonDeserializerBasicTest.java | 114 ++++++++++++++++++ 2 files changed, 124 insertions(+), 3 deletions(-) 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 ed27725ed..2d8b05766 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 @@ -816,16 +816,23 @@ public class ODataJsonDeserializer implements ODataDeserializer { ArrayNode arrayNode = (ArrayNode) jsonNode; Iterator it = arrayNode.iterator(); while (it.hasNext()) { - parsedValues.add(new URI(it.next().get(key).asText())); + final JsonNode next = it.next(); + if(next.has(key)) { + parsedValues.add(new URI(next.get(key).asText())); + } } } else { - parsedValues.add(new URI(jsonNode.asText())); + throw new DeserializerException("Value must be an array", DeserializerException.MessageKeys.UNKOWN_CONTENT); } tree.remove(Constants.VALUE); // if this is value there can be only one property return DeserializerResultImpl.with().entityReferences(parsedValues).build(); } - parsedValues.add(new URI(tree.get(key).asText())); + if(tree.get(key) != null) { + parsedValues.add(new URI(tree.get(key).asText())); + } else { + throw new DeserializerException("Missing entity reference", DeserializerException.MessageKeys.UNKOWN_CONTENT); + } return DeserializerResultImpl.with().entityReferences(parsedValues).build(); } catch (JsonParseException e) { throw new DeserializerException("An JsonParseException occurred", e, diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerBasicTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerBasicTest.java index 720029cd5..053dd074d 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerBasicTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerBasicTest.java @@ -22,11 +22,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.net.URI; import java.util.List; 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.Test; @@ -76,4 +78,116 @@ public class ODataJsonDeserializerBasicTest { assertEquals(1, values.size()); assertEquals("Orders(10643)", values.get(0).toASCIIString()); } + + @Test + public void reference() throws Exception { + String entityString = "{" + + "\"@odata.context\": \"$metadata#$ref\"," + + "\"@odata.id\": \"ESAllPrim(0)\"" + + "}"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + final List entityReferences = deserializer.entityReferences(stream).getEntityReferences(); + + assertEquals(1, entityReferences.size()); + assertEquals("ESAllPrim(0)", entityReferences.get(0).toASCIIString()); + } + + @Test + public void references() throws Exception { + String entityString = "{" + + " \"@odata.context\": \"$metadata#Collection($ref)\"," + + " \"value\": [" + + " { \"@odata.id\": \"ESAllPrim(0)\" }," + + " { \"@odata.id\": \"ESAllPrim(1)\" }" + + " ]" + + "}"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + final List entityReferences = deserializer.entityReferences(stream).getEntityReferences(); + + assertEquals(2, entityReferences.size()); + assertEquals("ESAllPrim(0)", entityReferences.get(0).toASCIIString()); + assertEquals("ESAllPrim(1)", entityReferences.get(1).toASCIIString()); + } + + @Test + public void referencesWithOtherAnnotations() throws Exception { + String entityString = "{" + + " \"@odata.context\": \"$metadata#Collection($ref)\"," + + " \"value\": [" + + " { \"@odata.id\": \"ESAllPrim(0)\" }," + + " { \"@odata.nonExistingODataAnnotation\": \"ESAllPrim(1)\" }" + + " ]" + + "}"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + final List entityReferences = deserializer.entityReferences(stream).getEntityReferences(); + + assertEquals(1, entityReferences.size()); + assertEquals("ESAllPrim(0)", entityReferences.get(0).toASCIIString()); + } + + @Test + public void referencesWithCustomAnnotation() throws Exception { + String entityString = "{" + + " \"@odata.context\": \"$metadata#Collection($ref)\"," + + " \"value\": [" + + " { \"@odata.id\": \"ESAllPrim(0)\" }," + + " { \"@invalid\": \"ESAllPrim(1)\" }" + + " ]" + + "}"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + final List entityReferences = deserializer.entityReferences(stream).getEntityReferences(); + + assertEquals(1, entityReferences.size()); + assertEquals("ESAllPrim(0)", entityReferences.get(0).toASCIIString()); + } + + @Test + public void referenceEmpty() throws Exception { + String entityString = "{" + + " \"@odata.context\": \"$metadata#Collection($ref)\"," + + " \"value\": [" + + " ]" + + "}"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + final List entityReferences = deserializer.entityReferences(stream).getEntityReferences(); + + assertEquals(0, entityReferences.size()); + } + + @Test(expected=DeserializerException.class) + public void referencesEmpty() throws Exception { + /* + * See OData JSON Format chaper 13 + * ... the object that MUST contain the id of the referenced entity + */ + String entityString = "{ }"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + final List entityReferences = deserializer.entityReferences(stream).getEntityReferences(); + + assertEquals(0, entityReferences.size()); + } + + @Test(expected=DeserializerException.class) + public void referenceValueIsNotAnArray() throws Exception { + String entityString = "{" + + " \"@odata.context\": \"$metadata#Collection($ref)\"," + + " \"value\": \"ESAllPrim(0)\"" + // This is not allowed. Value must be followed by an array + "}"; + + InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + deserializer.entityReferences(stream); + } }