Repository: olingo-odata2 Updated Branches: refs/heads/master f414699f0 -> 6fd6f064d
[OLINGO-354] Deserialization of all types of FunctionImports Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/6fd6f064 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/6fd6f064 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/6fd6f064 Branch: refs/heads/master Commit: 6fd6f064d5d8ed97cd914b1378e988655270533a Parents: f414699 Author: Michael Bolz <[email protected]> Authored: Tue Aug 5 15:14:09 2014 +0200 Committer: Michael Bolz <[email protected]> Committed: Tue Aug 5 19:41:00 2014 +0200 ---------------------------------------------------------------------- .../olingo/odata2/api/ep/EntityProvider.java | 34 +++++ .../odata2/core/ep/AtomEntityProvider.java | 18 +++ .../core/ep/ContentTypeBasedEntityProvider.java | 3 + .../odata2/core/ep/JsonEntityProvider.java | 18 +++ .../odata2/core/ep/ProviderFacadeImpl.java | 6 + .../core/ep/consumer/JsonEntityConsumer.java | 39 ++++- .../core/ep/consumer/JsonPropertyConsumer.java | 126 +++++++++++---- .../core/ep/consumer/XmlEntityConsumer.java | 39 ++++- .../core/ep/consumer/XmlEntryConsumer.java | 2 +- .../core/ep/consumer/XmlPropertyConsumer.java | 63 ++++++-- .../odata2/core/ep/ProviderFacadeImplTest.java | 10 ++ .../ep/consumer/JsonPropertyConsumerTest.java | 120 ++++++++++++++- .../ep/consumer/XmlPropertyConsumerTest.java | 153 ++++++++++++++----- .../odata2/core/uri/expression/TestParser.java | 1 - .../odata2/fit/ref/FunctionImportJsonTest.java | 106 +++++++++++-- .../odata2/fit/ref/FunctionImportXmlTest.java | 34 ++++- 16 files changed, 664 insertions(+), 108 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java index f989d4a..361a94e 100644 --- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java +++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java @@ -313,6 +313,22 @@ public final class EntityProvider { throws EntityProviderException; /** + * Reads (de-serializes) function-import data from <code>content</code> (as {@link InputStream}) in specified format + * (given as <code>contentType</code>) based on <code>entity data model</code> (given as {@link EdmFunctionImport}) + * and provide this data as {@link Object}. + * + * @param contentType format of content in the given input stream. + * @param functionImport entity data model for Function Import to be read + * @param content data in form of an {@link InputStream} which contains the data in specified format + * @param properties additional properties necessary for reading content from {@link InputStream} into {@link Map}. + * Must not be null. + * @return data as {@link Object} + * @throws EntityProviderException if reading of data (de-serialization) fails + */ + Object readFunctionImport(final String contentType, final EdmFunctionImport functionImport, + final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException; + + /** * Read (de-serialize) a link from <code>content</code> (as {@link InputStream}) in specified format (given as * <code>contentType</code>) * based on <code>entity data model</code> (given as {@link EdmEntitySet}) and provide the link as {@link String}. @@ -754,6 +770,24 @@ public final class EntityProvider { } /** + * Reads (de-serializes) function-import data from <code>content</code> (as {@link InputStream}) in specified format + * (given as <code>contentType</code>) based on <code>entity data model</code> (given as {@link EdmFunctionImport}) + * and provide this data as {@link Object}. + * + * @param contentType format of content in the given input stream. + * @param functionImport entity data model for Function Import to be read + * @param content data in form of an {@link InputStream} which contains the data in specified format + * @param properties additional properties necessary for reading content from {@link InputStream} into {@link Map}. + * Must not be null. + * @return data as {@link Object} + * @throws EntityProviderException if reading of data (de-serialization) fails + */ + public static Object readFunctionImport(final String contentType, final EdmFunctionImport functionImport, + final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException { + return createEntityProvider().readFunctionImport(contentType, functionImport, content, properties); + } + + /** * Read (de-serialize) a link from <code>content</code> (as {@link InputStream}) in specified format (given as * <code>contentType</code>) * based on <code>entity data model</code> (given as {@link EdmEntitySet}) and provide the link as {@link String}. http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java index 441dace..e788403 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java @@ -409,4 +409,22 @@ public class AtomEntityProvider implements ContentTypeBasedEntityProvider { XmlErrorDocumentConsumer xmlErrorDocumentConsumer = new XmlErrorDocumentConsumer(); return xmlErrorDocumentConsumer.readError(errorDocument); } + + @Override + public Object readFunctionImport(final EdmFunctionImport functionImport, InputStream content, + final EntityProviderReadProperties properties) throws EntityProviderException { + try { + if (functionImport.getReturnType().getType().getKind() == EdmTypeKind.ENTITY) { + return new XmlEntityConsumer().readEntry(functionImport.getEntitySet(), content, properties); + } else { + final EntityPropertyInfo info = EntityInfoAggregator.create(functionImport); + return functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY ? + new XmlEntityConsumer().readCollection(info, content, properties) : + new XmlEntityConsumer().readProperty(info, content, properties).get(info.getName()); + } + } catch (final EdmException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java index b988039..249931d 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java @@ -87,4 +87,7 @@ public interface ContentTypeBasedEntityProvider { throws EntityProviderException; ODataErrorContext readErrorDocument(InputStream errorDocument) throws EntityProviderException; + + Object readFunctionImport(EdmFunctionImport functionImport, InputStream content, + EntityProviderReadProperties properties) throws EntityProviderException; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java index def8c6a..bbece4f 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java @@ -322,6 +322,24 @@ public class JsonEntityProvider implements ContentTypeBasedEntityProvider { } @Override + public Object readFunctionImport(final EdmFunctionImport functionImport, final InputStream content, + final EntityProviderReadProperties properties) throws EntityProviderException { + try { + if (functionImport.getReturnType().getType().getKind() == EdmTypeKind.ENTITY) { + return new JsonEntityConsumer().readEntry(functionImport.getEntitySet(), content, properties); + } else { + final EntityPropertyInfo info = EntityInfoAggregator.create(functionImport); + return functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY ? + new JsonEntityConsumer().readCollection(info, content, properties) : + new JsonEntityConsumer().readProperty(info, content, properties).get(info.getName()); + } + } catch (final EdmException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } + } + + @Override public String readLink(final EdmEntitySet entitySet, final InputStream content) throws EntityProviderException { return new JsonEntityConsumer().readLink(entitySet, content); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java index 803c97c..c76109b 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java @@ -192,6 +192,12 @@ public class ProviderFacadeImpl implements EntityProviderInterface { } @Override + public Object readFunctionImport(final String contentType, final EdmFunctionImport functionImport, + final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException { + return create(contentType).readFunctionImport(functionImport, content, properties); + } + + @Override public List<String> readLinks(final String contentType, final EdmEntitySet entitySet, final InputStream content) throws EntityProviderException { return create(contentType).readLinks(entitySet, content); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java index efbcbb9..2faa530 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java @@ -33,6 +33,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry; import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed; import org.apache.olingo.odata2.api.ep.feed.ODataFeed; import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator; +import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo; import com.google.gson.stream.JsonReader; @@ -115,14 +116,20 @@ public class JsonEntityConsumer { } } - public Map<String, Object> readProperty(final EdmProperty property, final InputStream content, + + public Map<String, Object> readProperty(final EdmProperty edmProperty, InputStream content, + final EntityProviderReadProperties properties) throws EntityProviderException { + return readProperty(EntityInfoAggregator.create(edmProperty), content, properties); + } + + public Map<String, Object> readProperty(final EntityPropertyInfo propertyInfo, final InputStream content, final EntityProviderReadProperties readProperties) throws EntityProviderException { JsonReader reader = null; EntityProviderException cachedException = null; try { reader = createJsonReader(content); - return new JsonPropertyConsumer().readPropertyStandalone(reader, property, readProperties); + return new JsonPropertyConsumer().readPropertyStandalone(reader, propertyInfo, readProperties); } catch (final UnsupportedEncodingException e) { cachedException = new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass() @@ -144,6 +151,34 @@ public class JsonEntityConsumer { } } + public List<?> readCollection(final EntityPropertyInfo info, InputStream content, + final EntityProviderReadProperties properties) throws EntityProviderException { + JsonReader reader = null; + EntityProviderException cachedException = null; + + try { + reader = createJsonReader(content); + return new JsonPropertyConsumer().readCollection(reader, info, properties); + } catch (final UnsupportedEncodingException e) { + cachedException = new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + throw cachedException; + } finally {// NOPMD (suppress DoNotThrowExceptionInFinally) + if (reader != null) { + try { + reader.close(); + } catch (final IOException e) { + if (cachedException != null) { + throw cachedException; + } else { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } + } + } + } + } + public String readLink(final EdmEntitySet entitySet, final Object content) throws EntityProviderException { JsonReader reader = null; EntityProviderException cachedException = null; http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java index 1d0cd96..7589aa5 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java @@ -19,7 +19,9 @@ package org.apache.olingo.odata2.core.ep.consumer; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.olingo.odata2.api.edm.Edm; @@ -44,22 +46,26 @@ import com.google.gson.stream.JsonToken; */ public class JsonPropertyConsumer { - public Map<String, Object> readPropertyStandalone(final JsonReader reader, final EdmProperty property, + public Map<String, Object> readPropertyStandalone(JsonReader reader, final EdmProperty edmProperty, final EntityProviderReadProperties readProperties) throws EntityProviderException { - try { - EntityPropertyInfo entityPropertyInfo = EntityInfoAggregator.create(property); - Map<String, Object> typeMappings = readProperties == null ? null : readProperties.getTypeMappings(); - Map<String, Object> result = new HashMap<String, Object>(); + return readPropertyStandalone(reader, EntityInfoAggregator.create(edmProperty), readProperties); + } + public Map<String, Object> readPropertyStandalone(final JsonReader reader, final EntityPropertyInfo propertyInfo, + final EntityProviderReadProperties readProperties) throws EntityProviderException { + Map<String, Object> typeMappings = readProperties == null ? null : readProperties.getTypeMappings(); + Map<String, Object> result = new HashMap<String, Object>(); + + try { reader.beginObject(); String nextName = reader.nextName(); if (FormatJson.D.equals(nextName)) { reader.beginObject(); nextName = reader.nextName(); - handleName(reader, typeMappings, entityPropertyInfo, readProperties, result, nextName); + handleName(reader, typeMappings, propertyInfo, readProperties, result, nextName); reader.endObject(); } else { - handleName(reader, typeMappings, entityPropertyInfo, readProperties, result, nextName); + handleName(reader, typeMappings, propertyInfo, readProperties, result, nextName); } reader.endObject(); @@ -78,17 +84,80 @@ public class JsonPropertyConsumer { } } + public List<?> readCollection(JsonReader reader, final EntityPropertyInfo propertyInfo, + final EntityProviderReadProperties readProperties) throws EntityProviderException { + final Object typeMapping = readProperties == null ? null : + readProperties.getTypeMappings().get(propertyInfo.getName()); + List<Object> result = new ArrayList<Object>(); + String name = null; + boolean wrapped = false; + boolean version2 = false; + + try { + if (reader.peek() == JsonToken.BEGIN_OBJECT) { + reader.beginObject(); + name = reader.nextName(); + if (FormatJson.D.equals(name)) { + wrapped = true; + if (reader.peek() == JsonToken.BEGIN_OBJECT) { + reader.beginObject(); + name = reader.nextName(); + } else { + name = null; + } + } + } + if (name != null) { + version2 = true; + if (FormatJson.METADATA.equals(name)) { + readAndCheckTypeInfo(reader, + "Collection(" + propertyInfo.getType().getNamespace() + Edm.DELIMITER + + propertyInfo.getType().getName() + ")"); + name = reader.nextName(); + } + if (!FormatJson.RESULTS.equals(name)) { + throw new EntityProviderException(EntityProviderException.INVALID_PARENT_TAG + .addContent(FormatJson.RESULTS, name)); + } + } + reader.beginArray(); + while (reader.hasNext()) { + result.add(readPropertyValue(reader, propertyInfo, typeMapping, readProperties)); + } + reader.endArray(); + if (version2) { + reader.endObject(); + } + if (wrapped) { + reader.endObject(); + } + + if (reader.peek() != JsonToken.END_DOCUMENT) { + throw new EntityProviderException(EntityProviderException.END_DOCUMENT_EXPECTED + .addContent(reader.peek().toString())); + } + + return result; + } catch (final EdmException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } catch (final IOException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } catch (final IllegalStateException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } + } + private void handleName(final JsonReader reader, final Map<String, Object> typeMappings, final EntityPropertyInfo entityPropertyInfo, final EntityProviderReadProperties readProperties, final Map<String, Object> result, final String nextName) throws EntityProviderException { if (!entityPropertyInfo.getName().equals(nextName)) { throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent(nextName)); } - Object mapping = null; - if (typeMappings != null) { - mapping = typeMappings.get(nextName); - } - Object propertyValue = readPropertyValue(reader, entityPropertyInfo, mapping, readProperties); + final Object mapping = typeMappings == null ? null : typeMappings.get(nextName); + final Object propertyValue = readPropertyValue(reader, entityPropertyInfo, mapping, readProperties); result.put(nextName, propertyValue); } @@ -196,22 +265,10 @@ public class JsonPropertyConsumer { } while (reader.hasNext()) { - String childName = reader.nextName(); + final String childName = reader.nextName(); if (FormatJson.METADATA.equals(childName)) { - reader.beginObject(); - childName = reader.nextName(); - if (!FormatJson.TYPE.equals(childName)) { - throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.TYPE) - .addContent(FormatJson.METADATA)); - } - String actualTypeName = reader.nextString(); - String expectedTypeName = - complexPropertyInfo.getType().getNamespace() + Edm.DELIMITER + complexPropertyInfo.getType().getName(); - if (!expectedTypeName.equals(actualTypeName)) { - throw new EntityProviderException(EntityProviderException.INVALID_ENTITYTYPE.addContent(expectedTypeName) - .addContent(actualTypeName)); - } - reader.endObject(); + readAndCheckTypeInfo(reader, + complexPropertyInfo.getType().getNamespace() + Edm.DELIMITER + complexPropertyInfo.getType().getName()); } else { EntityPropertyInfo childPropertyInfo = complexPropertyInfo.getPropertyInfo(childName); if (childPropertyInfo == null) { @@ -227,4 +284,19 @@ public class JsonPropertyConsumer { reader.endObject(); return data; } + + protected void readAndCheckTypeInfo(final JsonReader reader, String expectedTypeName) + throws IOException, EntityProviderException { + reader.beginObject(); + if (!FormatJson.TYPE.equals(reader.nextName())) { + throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.TYPE) + .addContent(FormatJson.METADATA)); + } + final String actualTypeName = reader.nextString(); + if (!expectedTypeName.equals(actualTypeName)) { + throw new EntityProviderException(EntityProviderException.INVALID_ENTITYTYPE.addContent(expectedTypeName) + .addContent(actualTypeName)); + } + reader.endObject(); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java index acbc77f..378cf98 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java @@ -36,6 +36,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry; import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed; import org.apache.olingo.odata2.core.commons.XmlHelper; import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator; +import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo; /** * Xml entity (content type dependent) consumer for reading input (from <code>content</code>). @@ -109,14 +110,16 @@ public class XmlEntityConsumer { public Map<String, Object> readProperty(final EdmProperty edmProperty, final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException { + return readProperty(EntityInfoAggregator.create(edmProperty), content, properties); + } + + public Map<String, Object> readProperty(final EntityPropertyInfo propertyInfo, final InputStream content, + final EntityProviderReadProperties readProperties) throws EntityProviderException { XMLStreamReader reader = null; EntityProviderException cachedException = null; - XmlPropertyConsumer xec = new XmlPropertyConsumer(); - try { reader = XmlHelper.createStreamReader(content); - return xec.readProperty(reader, edmProperty, properties.getMergeSemantic(), properties.getTypeMappings(), - properties); + return new XmlPropertyConsumer().readProperty(reader, propertyInfo, readProperties); } catch (EntityProviderException e) { cachedException = e; throw cachedException; @@ -160,6 +163,33 @@ public class XmlEntityConsumer { } } + + public Object readCollection(final EntityPropertyInfo info, InputStream content, + final EntityProviderReadProperties properties) throws EntityProviderException { + XMLStreamReader reader = null; + EntityProviderException cachedException = null; + try { + reader = XmlHelper.createStreamReader(content); + return new XmlPropertyConsumer().readCollection(reader, info, properties); + } catch (final EntityProviderException e) { + cachedException = e; + throw cachedException; + } finally {// NOPMD (suppress DoNotThrowExceptionInFinally) + if (reader != null) { + try { + reader.close(); + } catch (final XMLStreamException e) { + if (cachedException != null) { + throw cachedException; + } else { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } + } + } + } + } + public String readLink(final EdmEntitySet entitySet, final Object content) throws EntityProviderException { XMLStreamReader reader = null; EntityProviderException cachedException = null; @@ -213,5 +243,4 @@ public class XmlEntityConsumer { } } } - } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java index 4bc9173..a9d8ae1 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java @@ -588,7 +588,7 @@ public class XmlEntryConsumer { throw new EntityProviderException(EntityProviderException.DOUBLE_PROPERTY.addContent(closeTag)); } property = getValidatedPropertyInfo(entitySet, closeTag); - final Object value = xpc.readStartedElement(reader, property, typeMappings, readProperties); + final Object value = xpc.readStartedElement(reader, closeTag, property, typeMappings, readProperties); properties.put(closeTag, value); closeTag = null; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java index 3887333..8a052cb 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java @@ -18,7 +18,10 @@ ******************************************************************************/ package org.apache.olingo.odata2.core.ep.consumer; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.xml.stream.XMLStreamConstants; @@ -49,26 +52,27 @@ public class XmlPropertyConsumer { protected static final String FALSE = "false"; public Map<String, Object> readProperty(final XMLStreamReader reader, final EdmProperty property, - final boolean merge, final EntityProviderReadProperties readProperties) throws EntityProviderException { - return readProperty(reader, property, merge, null, readProperties); + final EntityProviderReadProperties readProperties) throws EntityProviderException { + return readProperty(reader, EntityInfoAggregator.create(property), readProperties); } - public Map<String, Object> readProperty(final XMLStreamReader reader, final EdmProperty property, - final boolean merge, final Map<String, Object> typeMappings, final EntityProviderReadProperties readProperties) - throws EntityProviderException { - EntityPropertyInfo eia = EntityInfoAggregator.create(property); - + public Map<String, Object> readProperty(final XMLStreamReader reader, final EntityPropertyInfo propertyInfo, + final EntityProviderReadProperties readProperties) throws EntityProviderException { + final EntityTypeMapping typeMappings = + EntityTypeMapping.create(readProperties == null ? Collections.<String, Object> emptyMap() : + readProperties.getTypeMappings()); + final boolean merge = readProperties != null && readProperties.getMergeSemantic(); try { reader.next(); - Object value = readStartedElement(reader, eia, EntityTypeMapping.create(typeMappings), readProperties); + Object value = readStartedElement(reader, propertyInfo.getName(), propertyInfo, typeMappings, readProperties); - if (eia.isComplex() && merge) { - mergeWithDefaultValues(value, eia); + if (propertyInfo.isComplex() && merge) { + mergeWithDefaultValues(value, propertyInfo); } Map<String, Object> result = new HashMap<String, Object>(); - result.put(eia.getName(), value); + result.put(propertyInfo.getName(), value); return result; } catch (XMLStreamException e) { throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass() @@ -110,10 +114,39 @@ public class XmlPropertyConsumer { } } - protected Object readStartedElement(final XMLStreamReader reader, final EntityPropertyInfo propertyInfo, + public List<?> readCollection(XMLStreamReader reader, final EntityPropertyInfo info, + final EntityProviderReadProperties properties) throws EntityProviderException { + final String collectionName = info.getName(); + final EntityTypeMapping typeMappings = EntityTypeMapping.create( + properties == null || !properties.getTypeMappings().containsKey(collectionName) ? + Collections.<String, Object> emptyMap() : + Collections.<String, Object> singletonMap(FormatXml.D_ELEMENT, + properties.getTypeMappings().get(collectionName))); + List<Object> result = new ArrayList<Object>(); + try { + reader.nextTag(); + reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_D_2007_08, collectionName); + reader.nextTag(); + while (reader.isStartElement()) { + result.add(readStartedElement(reader, FormatXml.D_ELEMENT, info, typeMappings, properties)); + reader.nextTag(); + } + reader.require(XMLStreamConstants.END_ELEMENT, Edm.NAMESPACE_D_2007_08, collectionName); + reader.next(); + reader.require(XMLStreamConstants.END_DOCUMENT, null, null); + return result; + } catch (final XMLStreamException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } catch (final EdmException e) { + throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED + .addContent(e.getClass().getSimpleName()), e); + } + } + + protected Object readStartedElement(XMLStreamReader reader, final String name, final EntityPropertyInfo propertyInfo, final EntityTypeMapping typeMappings, final EntityProviderReadProperties readProperties) throws EntityProviderException, EdmException { - final String name = propertyInfo.getName(); Object result = null; try { @@ -149,8 +182,8 @@ public class XmlPropertyConsumer { if (childProperty == null) { throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY.addContent(childName)); } - final Object value = readStartedElement(reader, childProperty, typeMappings.getEntityTypeMapping(name), - readProperties); + final Object value = readStartedElement(reader, childName, childProperty, + typeMappings.getEntityTypeMapping(name), readProperties); name2Value.put(childName, value); reader.nextTag(); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java index e5236d4..40e5e0b 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java @@ -217,6 +217,16 @@ public class ProviderFacadeImplTest extends AbstractConsumerTest { } @Test + public void readFunctionImport() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("MaximalAge"); + InputStream content = new ByteArrayInputStream("{\"d\":{\"MaximalAge\":42}}".getBytes("UTF-8")); + final Object result = new ProviderFacadeImpl().readFunctionImport(HttpContentType.APPLICATION_JSON, + functionImport, content, EntityProviderReadProperties.init().build()); + assertEquals((short) 42, result); + } + + @Test public void readLink() throws Exception { final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); InputStream content = new ByteArrayInputStream("{\"d\":{\"uri\":\"http://somelink\"}}".getBytes("UTF-8")); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java index cc5ec25..36b1cca 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java @@ -32,7 +32,9 @@ import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -665,10 +667,6 @@ public class JsonPropertyConsumerTest extends BaseTest { return resultMap; } - private InputStream createContentAsStream(final String json) throws UnsupportedEncodingException { - return new ByteArrayInputStream(json.getBytes("UTF-8")); - } - @Test(expected = EntityProviderException.class) public void invalidDoubleClosingBrackets() throws Exception { String simplePropertyJson = "{\"d\":{\"Name\":\"Team 1\"}}}"; @@ -691,4 +689,118 @@ public class JsonPropertyConsumerTest extends BaseTest { new JsonPropertyConsumer().readPropertyStandalone(reader, edmProperty, null); } + @Test + public void collectionEmpty() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader("[]"), info, null); + assertNotNull(collection); + assertTrue(collection.isEmpty()); + + collection = new JsonPropertyConsumer().readCollection(prepareReader("{\"d\":[]}"), info, null); + assertNotNull(collection); + assertTrue(collection.isEmpty()); + + collection = new JsonPropertyConsumer().readCollection(prepareReader("{\"results\":[]}"), info, null); + assertNotNull(collection); + assertTrue(collection.isEmpty()); + + collection = new JsonPropertyConsumer().readCollection(prepareReader("{\"d\":{\"results\":[]}}"), info, null); + assertNotNull(collection); + assertTrue(collection.isEmpty()); + } + + @Test + public void collectionSimple() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader("[\"1\",\"42\"]"), info, null); + assertNotNull(collection); + assertEquals(Arrays.asList("1", "42"), collection); + } + + @Test + public void collectionSimpleWithMetadata() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader( + "{\"__metadata\":{\"type\":\"Collection(Edm.String)\"},\"results\":[\"1\",\"42\"]}"), + info, null); + assertNotNull(collection); + assertEquals(Arrays.asList("1", "42"), collection); + } + + @Test + public void collectionSimpleWithMapping() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + when(readProperties.getTypeMappings()).thenReturn( + Collections.<String, Object> singletonMap("AllUsedRoomIds", String.class)); + List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader("[\"1\",\"42\"]"), info, + readProperties); + assertNotNull(collection); + assertEquals(Arrays.asList("1", "42"), collection); + } + + @Test + public void collectionComplex() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllLocations")); + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + final Map<String, Object> mappings = Collections.<String, Object> singletonMap("Location", + Collections.<String, Object> singletonMap("City", + Collections.<String, Object> singletonMap("PostalCode", String.class))); + when(readProperties.getTypeMappings()).thenReturn(mappings); + List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader( + "{\"__metadata\":{\"type\":\"Collection(RefScenario.c_Location)\"}," + + "\"results\":[" + + "{\"City\":{\"PostalCode\":\"69124\",\"CityName\":\"Heidelberg\"},\"Country\":\"Germany\"}," + + "{\"City\":{\"PostalCode\":\"69190\",\"CityName\":\"Walldorf\"},\"Country\":\"Germany\"}]}"), + info, readProperties); + assertNotNull(collection); + assertEquals(2, collection.size()); + @SuppressWarnings("unchecked") + final Map<String, Object> secondLocation = (Map<String, Object>) collection.get(1); + assertEquals("Germany", secondLocation.get("Country")); + } + + @Test(expected = EntityProviderException.class) + public void collectionUnfinished() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + new JsonPropertyConsumer().readCollection(prepareReader("[\"1\""), info, null); + } + + @Test(expected = EntityProviderException.class) + public void collectionWithoutClosing() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + new JsonPropertyConsumer().readCollection(prepareReader("{\"results\":[]"), info, null); + } + + @Test(expected = EntityProviderException.class) + public void collectionWithWrongTag() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + new JsonPropertyConsumer().readCollection(prepareReader("{\"something\":[]}"), info, null); + } + + @Test(expected = EntityProviderException.class) + public void collectionWithWrongInnerTag() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + new JsonPropertyConsumer().readCollection(prepareReader("{\"d\":{\"something\":[]}}"), info, null); + } + + @Test(expected = EntityProviderException.class) + public void collectionWithTrailing() throws Exception { + final EntityPropertyInfo info = EntityInfoAggregator.create( + MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds")); + new JsonPropertyConsumer().readCollection(prepareReader("{\"results\":[],\"a\":0}"), info, null); + } + + private InputStream createContentAsStream(final String json) throws UnsupportedEncodingException { + return new ByteArrayInputStream(json.getBytes("UTF-8")); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java index c33b4ea..1b3bc8c 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java @@ -26,8 +26,11 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.xml.stream.XMLStreamReader; @@ -40,6 +43,7 @@ import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException; import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind; import org.apache.olingo.odata2.api.ep.EntityProviderException; import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties; +import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator; import org.apache.olingo.odata2.testutil.mock.MockFacade; import org.junit.Test; @@ -59,7 +63,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age"); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertEquals(Integer.valueOf(67), resultMap.get("Age")); } @@ -71,9 +75,9 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age"); - Map<String, Object> typeMappings = createTypeMappings("Age", Long.class); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings, - null); + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + when(readProperties.getTypeMappings()).thenReturn(createTypeMappings("Age", Long.class)); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties); assertEquals(Long.valueOf(67), resultMap.get("Age")); } @@ -85,9 +89,9 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age"); - Map<String, Object> typeMappings = null; - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings, - null); + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + when(readProperties.getTypeMappings()).thenReturn(null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties); assertEquals(Integer.valueOf(67), resultMap.get("Age")); } @@ -99,9 +103,9 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age"); - Map<String, Object> typeMappings = new HashMap<String, Object>(); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings, - null); + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + when(readProperties.getTypeMappings()).thenReturn(new HashMap<String, Object>()); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties); assertEquals(Integer.valueOf(67), resultMap.get("Age")); } @@ -113,7 +117,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EmployeeName"); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertEquals("Max Mustermann", resultMap.get("EmployeeName")); } @@ -125,7 +129,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EmployeeName"); - final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertTrue(resultMap.containsKey("EmployeeName")); assertEquals("", resultMap.get("EmployeeName")); @@ -139,7 +143,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate"); - final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertTrue(resultMap.containsKey("EntryDate")); assertNull(resultMap.get("EntryDate")); @@ -153,7 +157,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate"); - final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertEquals(86400000L, ((Calendar) resultMap.get("EntryDate")).getTimeInMillis()); } @@ -165,7 +169,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test(expected = EntityProviderException.class) @@ -176,7 +180,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test(expected = EntityProviderException.class) @@ -190,7 +194,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { when(facets.isNullable()).thenReturn(false); when(property.getFacets()).thenReturn(facets); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test(expected = EntityProviderException.class) @@ -202,7 +206,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { when(facets.getMaxLength()).thenReturn(10); when(property.getFacets()).thenReturn(facets); - new XmlPropertyConsumer().readProperty(createReaderForTest(xml, true), property, false, null); + new XmlPropertyConsumer().readProperty(createReaderForTest(xml, true), property, null); } @Test @@ -216,7 +220,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); final Map<String, Object> resultMap = new XmlPropertyConsumer() - .readProperty(createReaderForTest(xml, true), property, false, readProperties); + .readProperty(createReaderForTest(xml, true), property, readProperties); assertTrue(resultMap.containsKey("Name")); assertEquals("TooLongName", resultMap.get("Name")); } @@ -237,7 +241,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location"); assertEquals("Germany", locationMap.get("Country")); @@ -265,7 +269,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location"); assertEquals("Germany", locationMap.get("Country")); @@ -289,10 +293,13 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + when(readProperties.getTypeMappings()).thenReturn( + createTypeMappings("Location", + createTypeMappings("City", + createTypeMappings("PostalCode", Integer.class)))); try { - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, - createTypeMappings("Location", createTypeMappings("City", createTypeMappings("PostalCode", Integer.class))), - null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties); assertNotNull(resultMap); } catch (EntityProviderException e) { assertTrue(e.getCause() instanceof EdmSimpleTypeException); @@ -322,12 +329,13 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { when(postalCodeProperty.getType()).thenReturn(EdmSimpleTypeKind.Int32.getEdmSimpleTypeInstance()); // Execute test - Map<String, Object> typeMappings = + EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); + when(readProperties.getTypeMappings()).thenReturn( createTypeMappings("Location", createTypeMappings("City", - createTypeMappings("CityName", String.class, "PostalCode", Long.class))); + createTypeMappings("CityName", String.class, "PostalCode", Long.class)))); Map<String, Object> resultMap = - new XmlPropertyConsumer().readProperty(reader, locationComplexProperty, false, typeMappings, null); + new XmlPropertyConsumer().readProperty(reader, locationComplexProperty, readProperties); // verify Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location"); @@ -354,7 +362,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - Object prop = new XmlPropertyConsumer().readProperty(reader, property, false, null); + Object prop = new XmlPropertyConsumer().readProperty(reader, property, null); Map<String, Object> resultMap = (Map<String, Object>) prop; Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location"); @@ -379,7 +387,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test(expected = EntityProviderException.class) @@ -397,7 +405,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test(expected = EntityProviderException.class) @@ -415,7 +423,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test(expected = EntityProviderException.class) @@ -433,7 +441,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test @@ -452,7 +460,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location"); assertEquals("Germany", locationMap.get("Country")); @@ -469,7 +477,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertTrue(resultMap.containsKey("Location")); assertNull(resultMap.get("Location")); @@ -486,7 +494,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { when(facets.isNullable()).thenReturn(false); when(property.getFacets()).thenReturn(facets); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test @@ -501,7 +509,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class); final Map<String, Object> resultMap = new XmlPropertyConsumer() - .readProperty(createReaderForTest(xml, true), property, false, readProperties); + .readProperty(createReaderForTest(xml, true), property, readProperties); assertFalse(resultMap.isEmpty()); assertNull(resultMap.get("Location")); } @@ -516,7 +524,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - new XmlPropertyConsumer().readProperty(reader, property, false, null); + new XmlPropertyConsumer().readProperty(reader, property, null); } @Test @@ -526,11 +534,80 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest { final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location"); - final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null); + final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); assertNotNull(resultMap.get("Location")); @SuppressWarnings("unchecked") final Map<String, Object> innerMap = (Map<String, Object>) resultMap.get("Location"); assertTrue(innerMap.isEmpty()); } + + @Test + public void collectionSimpleType() throws Exception { + final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">" + + "<element>1</element>" + + "<element m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />" + + "<element></element>" + + "</AllUsedRoomIds>"; + @SuppressWarnings("unchecked") + final List<String> result = (List<String>) new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true), + EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllUsedRoomIds")), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + assertEquals(Arrays.asList("1", null, ""), result); + } + + @Test(expected = EntityProviderException.class) + public void collectionSimpleTypeWrong() throws Exception { + final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">" + + "<m:element xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />" + + "</AllUsedRoomIds>"; + new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true), + EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllUsedRoomIds")), null); + } + + @Test(expected = EntityProviderException.class) + public void collectionSimpleTypeWrongMapping() throws Exception { + final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">" + + "<element>1</element></AllUsedRoomIds>"; + new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true), + EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllUsedRoomIds")), + EntityProviderReadProperties.init().addTypeMappings( + Collections.<String, Object> singletonMap("AllUsedRoomIds", Integer.class)).build()); + } + + @Test(expected = EntityProviderException.class) + public void collectionSimpleTypeWrongXml() throws Exception { + final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\"><element>1</element>"; + new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true), + EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllUsedRoomIds")), null); + } + + @Test + public void collectionComplexType() throws Exception { + final String xml = "<d:AllLocations xmlns:d=\"" + Edm.NAMESPACE_D_2007_08 + "\">" + + "<d:element><d:City><d:PostalCode>69124</d:PostalCode><d:CityName>Heidelberg</d:CityName></d:City>" + + "<d:Country>Germany</d:Country></d:element>" + + "<d:element m:type=\"RefScenario.c_Location\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\">" + + "<d:City m:type=\"RefScenario.c_City\"><d:PostalCode>69190</d:PostalCode><d:CityName>Walldorf</d:CityName>" + + "</d:City><d:Country>Germany</d:Country></d:element>" + + "</d:AllLocations>"; + @SuppressWarnings("unchecked") + final List<?> result = (List<String>) new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true), + EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllLocations")), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + assertEquals(2, result.size()); + @SuppressWarnings("unchecked") + final Map<String, Object> secondLocation = (Map<String, Object>) result.get(1); + assertEquals("Germany", secondLocation.get("Country")); + @SuppressWarnings("unchecked") + final Map<String, Object> secondCity = (Map<String, Object>) secondLocation.get("City"); + assertEquals("Walldorf", secondCity.get("CityName")); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java index ef73dc8..229edeb 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java @@ -44,7 +44,6 @@ import org.apache.olingo.odata2.core.edm.EdmGuid; import org.apache.olingo.odata2.core.edm.EdmInt16; import org.apache.olingo.odata2.core.edm.EdmInt32; import org.apache.olingo.odata2.core.edm.EdmInt64; -import org.apache.olingo.odata2.core.edm.EdmNull; import org.apache.olingo.odata2.core.edm.EdmSByte; import org.apache.olingo.odata2.core.edm.EdmSingle; import org.apache.olingo.odata2.core.edm.EdmString; http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java index 937f64f..b17663e 100644 --- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java +++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java @@ -19,11 +19,22 @@ package org.apache.olingo.odata2.fit.ref; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import org.apache.http.HttpResponse; import org.apache.olingo.odata2.api.commons.HttpContentType; import org.apache.olingo.odata2.api.commons.HttpHeaders; +import org.apache.olingo.odata2.api.edm.EdmEntityContainer; +import org.apache.olingo.odata2.api.ep.EntityProvider; +import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.testutil.helper.StringHelper; import org.apache.olingo.odata2.testutil.server.ServletType; import org.junit.Test; @@ -37,15 +48,27 @@ public class FunctionImportJsonTest extends AbstractRefTest { super(servletType); } + private EdmEntityContainer getEntityContainer() throws Exception { + final HttpResponse response = callUri("$metadata"); + final EdmEntityContainer entityContainer = EntityProvider.readMetadata(response.getEntity().getContent(), false) + .getDefaultEntityContainer(); + getBody(response); + return entityContainer; + } + @Test - public void functionImports() throws Exception { - HttpResponse response = callUri("EmployeeSearch?q='nat'&$format=json"); + public void entityCollection() throws Exception { + final HttpResponse response = callUri("EmployeeSearch?q='nat'&$format=json"); checkMediaType(response, HttpContentType.APPLICATION_JSON); final String body = getBody(response); assertEquals(getBody(callUri("Employees?$filter=substringof('nat',EmployeeName)&$format=json")), body); + } - response = callUri("AllLocations?$format=json"); + @Test + public void complexTypeCollection() throws Exception { + final HttpResponse response = callUri("AllLocations?$format=json"); checkMediaType(response, HttpContentType.APPLICATION_JSON); + final String body = getBody(response); assertEquals("{\"d\":{\"__metadata\":{\"type\":\"Collection(RefScenario.c_Location)\"}," + "\"results\":[{\"__metadata\":{\"type\":\"RefScenario.c_Location\"}," + "\"City\":{\"__metadata\":{\"type\":\"RefScenario.c_City\"}," @@ -53,34 +76,91 @@ public class FunctionImportJsonTest extends AbstractRefTest { + "{\"__metadata\":{\"type\":\"RefScenario.c_Location\"}," + "\"City\":{\"__metadata\":{\"type\":\"RefScenario.c_City\"}," + "\"PostalCode\":\"69190\",\"CityName\":\"Walldorf\"},\"Country\":\"Germany\"}]}}", - getBody(response)); + body); + final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON, + getEntityContainer().getFunctionImport("AllLocations"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + final List<?> collection = (List<?>) result; + @SuppressWarnings("unchecked") + final Map<String, Object> secondLocation = (Map<String, Object>) collection.get(1); + @SuppressWarnings("unchecked") + final Map<String, Object> secondCity = (Map<String, Object>) secondLocation.get("City"); + assertEquals(CITY_2_NAME, secondCity.get("CityName")); + } - response = callUri("AllUsedRoomIds?$format=json"); + @Test + public void simpleTypeCollection() throws Exception { + final HttpResponse response = callUri("AllUsedRoomIds?$format=json"); checkMediaType(response, HttpContentType.APPLICATION_JSON); + final String body = getBody(response); assertEquals("{\"d\":{\"__metadata\":{\"type\":\"Collection(Edm.String)\"}," + "\"results\":[\"1\",\"2\",\"3\"]}}", - getBody(response)); + body); + final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON, + getEntityContainer().getFunctionImport("AllUsedRoomIds"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + assertEquals(Arrays.asList("1", "2", "3"), result); + } - response = callUri("MaximalAge?$format=json"); + @Test + public void simpleType() throws Exception { + final HttpResponse response = callUri("MaximalAge?$format=json"); checkMediaType(response, HttpContentType.APPLICATION_JSON); - assertEquals("{\"d\":{\"MaximalAge\":56}}", getBody(response)); + final String body = getBody(response); + assertEquals("{\"d\":{\"MaximalAge\":56}}", body); + final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON, + getEntityContainer().getFunctionImport("MaximalAge"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + assertEquals(Short.valueOf(EMPLOYEE_3_AGE), result); + } - response = callUri("MostCommonLocation?$format=json"); + @SuppressWarnings("unchecked") + @Test + public void complexType() throws Exception { + final HttpResponse response = callUri("MostCommonLocation?$format=json"); checkMediaType(response, HttpContentType.APPLICATION_JSON); + final String body = getBody(response); assertEquals("{\"d\":{\"MostCommonLocation\":" + "{\"__metadata\":{\"type\":\"RefScenario.c_Location\"}," + "\"City\":{\"__metadata\":{\"type\":\"RefScenario.c_City\"}," + "\"PostalCode\":\"69190\",\"CityName\":\"" + CITY_2_NAME + "\"}," + "\"Country\":\"Germany\"}}}", - getBody(response)); + body); + final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON, + getEntityContainer().getFunctionImport("MostCommonLocation"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + Map<String, Object> resultMap = (Map<String, Object>) result; + assertNotNull(resultMap); + assertFalse(resultMap.isEmpty()); + resultMap = (Map<String, Object>) resultMap.get("City"); + assertNotNull(resultMap); + assertFalse(resultMap.isEmpty()); + assertEquals(CITY_2_NAME, resultMap.get("CityName")); + } - response = callUri("ManagerPhoto?Id='1'&$format=json"); + @Test + public void binary() throws Exception { + final HttpResponse response = callUri("ManagerPhoto?Id='1'&$format=json"); checkMediaType(response, HttpContentType.APPLICATION_JSON); assertTrue(getBody(response).startsWith("{\"d\":{\"ManagerPhoto\":\"iVBORw0KGgoAAAAN")); + } + @Test + public void entity() throws Exception { final String expected = getBody(callUri("Employees('3')?$format=json")); - response = callUri("OldestEmployee", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_JSON); + final HttpResponse response = callUri("OldestEmployee", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_JSON); checkMediaType(response, HttpContentType.APPLICATION_JSON); - assertEquals(expected, getBody(response)); + final String body = getBody(response); + assertEquals(expected, body); + final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON, + getEntityContainer().getFunctionImport("OldestEmployee"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + final ODataEntry entry = (ODataEntry) result; + assertEquals("3", entry.getProperties().get("EmployeeId")); } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java index bdf62e5..fdf43e5 100644 --- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java +++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java @@ -25,12 +25,21 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import junit.framework.Assert; import org.apache.http.HttpResponse; import org.apache.olingo.odata2.api.commons.HttpContentType; import org.apache.olingo.odata2.api.commons.HttpHeaders; +import org.apache.olingo.odata2.api.edm.EdmEntityContainer; +import org.apache.olingo.odata2.api.ep.EntityProvider; +import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties; import org.apache.olingo.odata2.core.commons.ContentType; +import org.apache.olingo.odata2.testutil.helper.StringHelper; import org.apache.olingo.odata2.testutil.server.ServletType; import org.junit.Test; @@ -55,11 +64,32 @@ public class FunctionImportXmlTest extends AbstractRefXmlTest { response = callUri("AllLocations", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_XML); checkMediaType(response, HttpContentType.APPLICATION_XML_UTF8); - assertXpathExists("/d:AllLocations/d:element/d:City[d:CityName=\"" + CITY_2_NAME + "\"]", getBody(response)); + String body = getBody(response); + assertXpathExists("/d:AllLocations/d:element/d:City[d:CityName=\"" + CITY_2_NAME + "\"]", body); + final HttpResponse metadataResponse = callUri("$metadata"); + final EdmEntityContainer entityContainer = EntityProvider.readMetadata(metadataResponse.getEntity().getContent(), + false).getDefaultEntityContainer(); + getBody(metadataResponse); + Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_XML, + entityContainer.getFunctionImport("AllLocations"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + final List<?> collection = (List<?>) result; + @SuppressWarnings("unchecked") + final Map<String, Object> secondLocation = (Map<String, Object>) collection.get(1); + @SuppressWarnings("unchecked") + final Map<String, Object> secondCity = (Map<String, Object>) secondLocation.get("City"); + assertEquals(CITY_2_NAME, secondCity.get("CityName")); response = callUri("AllUsedRoomIds", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_XML); checkMediaType(response, HttpContentType.APPLICATION_XML_UTF8); - assertXpathExists("/d:AllUsedRoomIds[d:element=\"3\"]", getBody(response)); + body = getBody(response); + assertXpathExists("/d:AllUsedRoomIds[d:element=\"3\"]", body); + result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_XML, + entityContainer.getFunctionImport("AllUsedRoomIds"), StringHelper.encapsulate(body), + EntityProviderReadProperties.init().build()); + assertNotNull(result); + assertEquals(Arrays.asList("1", "2", "3"), result); response = callUri("MaximalAge", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_XML); checkMediaType(response, HttpContentType.APPLICATION_XML_UTF8);
