You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2015/09/11 22:53:53 UTC
[1/2] olingo-odata4 git commit: OLINGO-700: added action parameter
parsing rountines for atom and json payloads
Repository: olingo-odata4
Updated Branches:
refs/heads/master ba88c43b5 -> fcec0c349
OLINGO-700: added action parameter parsing rountines for atom and json payloads
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/e99b0700
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/e99b0700
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/e99b0700
Branch: refs/heads/master
Commit: e99b07008ef021da592efd2c1f42662da4588abb
Parents: 11ebbb5
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Fri Sep 11 15:50:32 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Fri Sep 11 15:50:32 2015 -0500
----------------------------------------------------------------------
.../server/core/requests/ActionRequest.java | 13 +-
.../json/ODataJsonDeserializer.java | 6 +-
.../deserializer/xml/ODataXmlDeserializer.java | 183 +++++++++--
...ataJsonDeserializerActionParametersTest.java | 140 +++++++++
...DataXMLDeserializerActionParametersTest.java | 303 +++++++++++++++++++
5 files changed, 614 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e99b0700/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
index bef9da0..9ff4cde 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
@@ -20,15 +20,20 @@
package org.apache.olingo.server.core.requests;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Parameter;
import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.uri.UriResourceAction;
import org.apache.olingo.server.core.ContentNegotiatorException;
@@ -138,4 +143,10 @@ public class ActionRequest extends OperationRequest {
public InputStream getPayload() {
return getODataRequest().getBody();
}
+
+ public List<Parameter> getParameters() throws DeserializerException {
+ ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+ return new ArrayList<Parameter>(deserializer.actionParameters(getPayload(), getAction()).getActionParameters()
+ .values());
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e99b0700/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 759cf66..e2ea7cf 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
@@ -261,14 +261,14 @@ public class ODataJsonDeserializer implements ODataDeserializer {
case PRIMITIVE:
case DEFINITION:
case ENUM:
+ case COMPLEX:
Parameter parameter = createParameter(node.get(paramName), paramName, edmParameter);
parameters.put(paramName, parameter);
node.remove(paramName);
break;
- case COMPLEX:
case ENTITY:
- throw new DeserializerException("Entity and complex parameters currently not Implemented",
- DeserializerException.MessageKeys.NOT_IMPLEMENTED);
+ throw new DeserializerException("Entity parameters are not allowed",
+ DeserializerException.MessageKeys.INVALID_ACTION_PARAMETER_TYPE);
default:
throw new DeserializerException("Invalid type kind " + edmParameter.getType().getKind().toString()
+ " for action parameter: " + paramName, DeserializerException.MessageKeys.INVALID_ACTION_PARAMETER_TYPE,
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e99b0700/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
index 29c29e7..a762f5c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
@@ -21,7 +21,9 @@ package org.apache.olingo.server.core.deserializer.xml;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
@@ -38,6 +40,7 @@ import org.apache.olingo.commons.api.data.ComplexValue;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.data.Parameter;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.Valuable;
import org.apache.olingo.commons.api.data.ValueType;
@@ -46,6 +49,7 @@ import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmParameter;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
@@ -67,7 +71,8 @@ public class ODataXmlDeserializer implements ODataDeserializer {
private static final String ATOM = "a";
private static final String NS_ATOM = "http://www.w3.org/2005/Atom";
private static final QName REF_ELEMENT = new QName("http://docs.oasis-open.org/odata/ns/metadata", "ref");
-// private static final QName FEED_ELEMENT = new QName("http://www.w3.org/2005/Atom", "feed");
+ private static final QName PARAMETERS_ELEMENT =
+ new QName("http://docs.oasis-open.org/odata/ns/metadata", "parameters");
private static final QName ID_ATTR = new QName(NS_ATOM, ATOM);
private final QName propertiesQName = new QName(Constants.NS_METADATA, Constants.PROPERTIES);
@@ -93,7 +98,8 @@ public class ODataXmlDeserializer implements ODataDeserializer {
}
private Object primitive(final XMLEventReader reader, final StartElement start,
- final EdmProperty edmProperty) throws XMLStreamException, EdmPrimitiveTypeException,
+ final EdmType type, final boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final boolean isUnicode) throws XMLStreamException, EdmPrimitiveTypeException,
DeserializerException {
Object value = null;
@@ -103,18 +109,18 @@ public class ODataXmlDeserializer implements ODataDeserializer {
final XMLEvent event = reader.nextEvent();
if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
- if (edmProperty.getType() instanceof AbstractGeospatialType<?>) {
+ if (type instanceof AbstractGeospatialType<?>) {
throw new DeserializerException("geo types support not implemented",
DeserializerException.MessageKeys.NOT_IMPLEMENTED);
}
final String stringValue = event.asCharacters().getData();
- value = ((EdmPrimitiveType)edmProperty.getType()).valueOfString(stringValue,
- edmProperty.isNullable(),
- edmProperty.getMaxLength(),
- edmProperty.getPrecision(),
- edmProperty.getScale(),
- edmProperty.isUnicode(),
- ((EdmPrimitiveType)edmProperty.getType()).getDefaultType());
+ value = ((EdmPrimitiveType)type).valueOfString(stringValue,
+ isNullable,
+ maxLength,
+ precision,
+ scale,
+ isUnicode,
+ ((EdmPrimitiveType)type).getDefaultType());
}
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
@@ -132,7 +138,9 @@ public class ODataXmlDeserializer implements ODataDeserializer {
final XMLEvent event = reader.nextEvent();
if (event.isStartElement()) {
StartElement se = event.asStartElement();
- value.getValue().add(property(reader, se, (EdmProperty)edmComplex.getProperty(se.getName().getLocalPart())));
+ EdmProperty p = (EdmProperty)edmComplex.getProperty(se.getName().getLocalPart());
+ value.getValue().add(property(reader, se, p.getType(), p.isNullable(), p.getMaxLength(),
+ p.getPrecision(), p.getScale(), p.isUnicode(), p.isCollection()));
}
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
foundEndProperty = true;
@@ -142,10 +150,12 @@ public class ODataXmlDeserializer implements ODataDeserializer {
}
private void collection(final Valuable valuable, final XMLEventReader reader, final StartElement start,
- final EdmProperty edmProperty) throws XMLStreamException, EdmPrimitiveTypeException, DeserializerException {
+ final EdmType type, final boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final boolean isUnicode) throws XMLStreamException, EdmPrimitiveTypeException,
+ DeserializerException {
List<Object> values = new ArrayList<Object>();
- EdmType edmType = edmProperty.getType();
+ EdmType edmType = type;
boolean foundEndProperty = false;
while (reader.hasNext() && !foundEndProperty) {
@@ -153,7 +163,8 @@ public class ODataXmlDeserializer implements ODataDeserializer {
if (event.isStartElement()) {
if (edmType instanceof SingletonPrimitiveType) {
- values.add(primitive(reader, event.asStartElement(), edmProperty));
+ values.add(primitive(reader, event.asStartElement(), type, isNullable,
+ maxLength, precision, scale, isUnicode));
} else if (edmType instanceof EdmComplexType) {
values.add(complex(reader, event.asStartElement(), (EdmComplexType) edmType));
} else if (edmType instanceof EdmEnumType) {
@@ -184,7 +195,9 @@ public class ODataXmlDeserializer implements ODataDeserializer {
return value;
}
- private Property property(final XMLEventReader reader, final StartElement start, final EdmProperty edmProperty)
+ private Property property(final XMLEventReader reader, final StartElement start, final EdmType edmType,
+ final boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final boolean isUnicode, final boolean isCollection)
throws XMLStreamException, EdmPrimitiveTypeException, DeserializerException {
final Property property = new Property();
@@ -198,7 +211,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
} else {
property.setName(start.getName().getLocalPart());
}
- valuable(property, reader, start, edmProperty);
+ valuable(property, reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode, isCollection);
return property;
}
@@ -215,8 +228,9 @@ public class ODataXmlDeserializer implements ODataDeserializer {
}
private void valuable(final Valuable valuable, final XMLEventReader reader, final StartElement start,
- EdmProperty edmProperty) throws XMLStreamException, EdmPrimitiveTypeException,
- DeserializerException {
+ final EdmType edmType, final boolean isNullable, final Integer maxLength, final Integer precision,
+ final Integer scale, final boolean isUnicode, final boolean isCollection) throws XMLStreamException,
+ EdmPrimitiveTypeException, DeserializerException {
final Attribute nullAttr = start.getAttributeByName(nullQName);
if (nullAttr != null) {
@@ -228,23 +242,26 @@ public class ODataXmlDeserializer implements ODataDeserializer {
foundEndProperty = true;
}
}
- valuable.setValue(getValueType(edmProperty.getType(), false), null);
+ valuable.setValue(getValueType(edmType, false), null);
return;
}
- EdmType edmType = edmProperty.getType();
- if (edmProperty.isCollection()) {
- collection(valuable, reader, start, edmProperty);
+ if (isCollection) {
+ collection(valuable, reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode);
valuable.setType("Collection("+edmType.getFullQualifiedName().getFullQualifiedNameAsString()+")");
} else if (edmType instanceof SingletonPrimitiveType) {
valuable.setType(edmType.getFullQualifiedName().getFullQualifiedNameAsString());
- valuable.setValue(ValueType.PRIMITIVE, primitive(reader, start, edmProperty));
+ valuable.setValue(ValueType.PRIMITIVE,
+ primitive(reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode));
} else if (edmType instanceof EdmComplexType) {
valuable.setValue(ValueType.COMPLEX, complex(reader, start, (EdmComplexType) edmType));
valuable.setType(edmType.getFullQualifiedName().getFullQualifiedNameAsString());
} else if (edmType instanceof EdmEnumType) {
valuable.setValue(ValueType.ENUM, readEnum(reader, start));
valuable.setType(edmType.getFullQualifiedName().getFullQualifiedNameAsString());
+ } else if (edmType instanceof EdmEntityType) {
+ valuable.setValue(ValueType.ENTITY, entity(reader, start, (EdmEntityType)edmType));
+ valuable.setType(edmType.getFullQualifiedName().getFullQualifiedNameAsString());
}
// do not add null or empty values
}
@@ -255,7 +272,14 @@ public class ODataXmlDeserializer implements ODataDeserializer {
try {
final XMLEventReader reader = getReader(input);
final StartElement start = skipBeforeFirstStartElement(reader);
- Property property = property(reader, start, edmProperty);
+ Property property = property(reader, start,
+ edmProperty.getType(),
+ edmProperty.isNullable(),
+ edmProperty.getMaxLength(),
+ edmProperty.getPrecision(),
+ edmProperty.getScale(),
+ edmProperty.isUnicode(),
+ edmProperty.isCollection());
return DeserializerResultImpl.with().property(property)
.build();
} catch (XMLStreamException e) {
@@ -409,7 +433,14 @@ public class ODataXmlDeserializer implements ODataDeserializer {
if (event.isStartElement()) {
EdmProperty edmProperty = (EdmProperty)edmEntityType
.getProperty(event.asStartElement().getName().getLocalPart());
- entity.getProperties().add(property(reader, event.asStartElement(), edmProperty));
+ entity.getProperties().add(property(reader, event.asStartElement(),
+ edmProperty.getType(),
+ edmProperty.isNullable(),
+ edmProperty.getMaxLength(),
+ edmProperty.getPrecision(),
+ edmProperty.getScale(),
+ edmProperty.isUnicode(),
+ edmProperty.isCollection()));
}
if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
@@ -683,6 +714,104 @@ public class ODataXmlDeserializer implements ODataDeserializer {
@Override
public DeserializerResult actionParameters(InputStream stream, EdmAction edmAction)
throws DeserializerException {
- throw new DeserializerException("Not implemented", DeserializerException.MessageKeys.NOT_IMPLEMENTED);
- }
+ Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
+ if(edmAction.getParameterNames() == null || edmAction.getParameterNames().isEmpty()
+ || (edmAction.isBound() && edmAction.getParameterNames().size() == 1)) {
+ return DeserializerResultImpl.with().actionParameters(parameters)
+ .build();
+ }
+
+ try {
+ final XMLEventReader reader = getReader(stream);
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement() && PARAMETERS_ELEMENT.equals(event.asStartElement().getName())) {
+ consumeParameters(edmAction, reader, event.asStartElement(), parameters);
+ }
+ }
+ // NULL fill for missing parameters
+ Parameter nullParameter = new Parameter();
+ nullParameter.setValue(ValueType.PRIMITIVE, null);
+ for (String param:edmAction.getParameterNames()) {
+ if (parameters.get(param) == null) {
+ parameters.put(param, nullParameter);
+ }
+ }
+ return DeserializerResultImpl.with().actionParameters(parameters)
+ .build();
+ } catch (XMLStreamException e) {
+ throw new DeserializerException(e.getMessage(), e, DeserializerException.MessageKeys.IO_EXCEPTION);
+ } catch (final EdmPrimitiveTypeException e) {
+ throw new DeserializerException(e.getMessage(), e,
+ DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY);
+ }
+ }
+
+ private void consumeParameters(EdmAction edmAction, XMLEventReader reader,
+ StartElement start, Map<String, Parameter> parameters) throws DeserializerException,
+ EdmPrimitiveTypeException, XMLStreamException {
+
+ List<String> parameterNames = edmAction.getParameterNames();
+ if (edmAction.isBound()) {
+ // The binding parameter must not occur in the payload.
+ parameterNames = parameterNames.subList(1, parameterNames.size());
+ }
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement()) {
+ boolean found = false;
+ for(String paramName:parameterNames) {
+ if(paramName.equals(event.asStartElement().getName().getLocalPart())) {
+ found = true;
+ Parameter parameter = createParameter(reader, event.asStartElement(), paramName,
+ edmAction.getParameter(paramName));
+ Parameter previous = parameters.put(paramName, parameter);
+ if (previous != null) {
+ throw new DeserializerException("Duplicate property detected",
+ DeserializerException.MessageKeys.DUPLICATE_PROPERTY);
+ }
+ break; //for
+ }
+ }
+ if (!found) {
+ throw new DeserializerException("failed to read "+event.asStartElement().getName().getLocalPart(),
+ DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+ }
+ }
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private Parameter createParameter(XMLEventReader reader, StartElement start, String paramName,
+ EdmParameter edmParameter) throws DeserializerException, EdmPrimitiveTypeException, XMLStreamException {
+
+ switch (edmParameter.getType().getKind()) {
+ case PRIMITIVE:
+ case ENUM:
+ case COMPLEX:
+ Parameter parameter = new Parameter();
+ parameter.setName(paramName);
+ Property property = property(reader, start,
+ edmParameter.getType(),
+ edmParameter.isNullable(),
+ edmParameter.getMaxLength(),
+ edmParameter.getPrecision(),
+ edmParameter.getScale(),
+ true,
+ edmParameter.isCollection());
+ parameter.setValue(property.getValueType(), property.getValue());
+ return parameter;
+ case ENTITY:
+ throw new DeserializerException("Entity parameters are not allowed",
+ DeserializerException.MessageKeys.INVALID_ACTION_PARAMETER_TYPE);
+ default:
+ throw new DeserializerException("Invalid type kind " + edmParameter.getType().getKind().toString()
+ + " for action parameter: " + paramName, DeserializerException.MessageKeys.INVALID_ACTION_PARAMETER_TYPE,
+ paramName);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e99b0700/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
index 3ed9f89..ab82684 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
@@ -20,17 +20,35 @@ 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.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Parameter;
+import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.CsdlAction;
+import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
+import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
+import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
+import org.apache.olingo.commons.core.edm.EdmActionImpl;
+import org.apache.olingo.commons.core.edm.EdmComplexTypeImpl;
+import org.apache.olingo.commons.core.edm.EdmEntityTypeImpl;
+import org.apache.olingo.commons.core.edm.EdmProviderImpl;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.junit.Test;
+import org.mockito.Mockito;
public class ODataJsonDeserializerActionParametersTest extends AbstractODataDeserializerTest {
@@ -55,7 +73,129 @@ public class ODataJsonDeserializerActionParametersTest extends AbstractODataDese
assertNotNull(parameter);
assertEquals(BigDecimal.valueOf(3669753), parameter.getValue());
}
+
+ @Test
+ public void complex() throws Exception {
+ EdmProviderImpl provider = mock(EdmProviderImpl.class);
+ CsdlComplexType address = new CsdlComplexType();
+ address.setProperties(Arrays.asList(createProperty("Street", "Edm.String"),
+ createProperty("Zip", "Edm.Int32")));
+ address.setName("Address");
+ EdmComplexTypeImpl edmAddress = new EdmComplexTypeImpl(provider,
+ new FullQualifiedName("namespace.Address"), address);
+ Mockito.stub(provider.getComplexType(Mockito.any(FullQualifiedName.class))).toReturn(edmAddress);
+
+ List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
+ parameters.add(createParam("param1", "Edm.Int16"));
+ parameters.add(createParam("param2", "namespace.Address"));
+ parameters.add(createParam("param3", "Edm.Int32").setCollection(true));
+ parameters.add(createParam("param4", "Edm.String").setNullable(true));
+
+ FullQualifiedName actionName = new FullQualifiedName("namespace", "action");
+ CsdlAction csdlAction = new CsdlAction().setName("action1").setParameters(parameters);
+ EdmAction action = new EdmActionImpl(provider, actionName, csdlAction);
+
+ final String input = "{\n" +
+ " \"param1\": 42,\n" +
+ " \"param2\": {\n" +
+ " \"Street\": \"One Microsoft Way\",\n" +
+ " \"Zip\": 98052\n" +
+ " },\n" +
+ " \"param3\": [ 1, 42, 99 ],\n" +
+ " \"param4\": null\n" +
+ "}";
+ final Map<String, Parameter> response = OData.newInstance().createDeserializer(CONTENT_TYPE_JSON)
+ .actionParameters(new ByteArrayInputStream(input.getBytes()), action).getActionParameters();
+
+ assertNotNull(response);
+ assertEquals(4, response.size());
+ Parameter parameter = response.get("param1");
+ assertNotNull(response);
+ assertEquals((short) 42, parameter.getValue());
+ parameter = response.get("param2");
+ assertNotNull(parameter);
+ ComplexValue addressValue = (ComplexValue)parameter.getValue();
+ assertEquals("Street", addressValue.getValue().get(0).getName());
+ assertEquals("One Microsoft Way", addressValue.getValue().get(0).getValue());
+ assertEquals("Zip", addressValue.getValue().get(1).getName());
+ assertEquals(98052, addressValue.getValue().get(1).getValue());
+
+ parameter = response.get("param3");
+ assertNotNull(parameter);
+ assertEquals(Arrays.asList(1, 42, 99), parameter.getValue());
+
+ parameter = response.get("param4");
+ assertNull(parameter.getValue());
+ }
+
+ @Test
+ public void complexCollection() throws Exception {
+ EdmProviderImpl provider = mock(EdmProviderImpl.class);
+ CsdlComplexType address = new CsdlComplexType();
+ address.setProperties(Arrays.asList(createProperty("Street", "Edm.String"),
+ createProperty("Zip", "Edm.Int32")));
+ address.setName("Address");
+ EdmComplexTypeImpl edmAddress = new EdmComplexTypeImpl(provider,
+ new FullQualifiedName("namespace.Address"), address);
+ Mockito.stub(provider.getComplexType(Mockito.any(FullQualifiedName.class))).toReturn(edmAddress);
+
+ List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
+ parameters.add(createParam("param1", "Edm.Int16"));
+ parameters.add(createParam("param2", "namespace.Address").setCollection(true));
+ parameters.add(createParam("param3", "Edm.Int32").setCollection(true));
+ parameters.add(createParam("param4", "Edm.String").setNullable(true));
+
+ FullQualifiedName actionName = new FullQualifiedName("namespace", "action");
+ CsdlAction csdlAction = new CsdlAction().setName("action1").setParameters(parameters);
+ EdmAction action = new EdmActionImpl(provider, actionName, csdlAction);
+
+ final String input = "{\n" +
+ " \"param1\": 42,\n" +
+ " \"param2\": [{\n" +
+ " \"Street\": \"One Microsoft Way\",\n" +
+ " \"Zip\": 98052\n" +
+ " },\n" +
+ " {\n" +
+ " \"Street\": \"Two Microsoft Way\",\n" +
+ " \"Zip\": 98052\n" +
+ " }],\n" +
+ " \"param3\": [ 1, 42, 99 ],\n" +
+ " \"param4\": null\n" +
+ "}";
+ final Map<String, Parameter> response = OData.newInstance().createDeserializer(CONTENT_TYPE_JSON)
+ .actionParameters(new ByteArrayInputStream(input.getBytes()), action).getActionParameters();
+
+ assertNotNull(response);
+ assertEquals(4, response.size());
+ Parameter parameter = response.get("param1");
+ assertNotNull(response);
+ assertEquals((short) 42, parameter.getValue());
+ parameter = response.get("param2");
+ assertNotNull(parameter);
+ ComplexValue addressValue = (ComplexValue)((List<?>)parameter.getValue()).get(0);
+ assertEquals("One Microsoft Way", addressValue.getValue().get(0).getValue());
+ assertEquals(98052, addressValue.getValue().get(1).getValue());
+
+ addressValue = (ComplexValue)((List<?>)parameter.getValue()).get(1);
+ assertEquals("Two Microsoft Way", addressValue.getValue().get(0).getValue());
+ assertEquals(98052, addressValue.getValue().get(1).getValue());
+
+ parameter = response.get("param3");
+ assertNotNull(parameter);
+ assertEquals(Arrays.asList(1, 42, 99), parameter.getValue());
+
+ parameter = response.get("param4");
+ assertNull(parameter.getValue());
+ }
+ private CsdlParameter createParam(String name, String type) {
+ return new CsdlParameter().setName(name).setType(new FullQualifiedName(type));
+ }
+
+ private CsdlProperty createProperty(String name, String type) {
+ return new CsdlProperty().setName(name).setType(type);
+ }
+
@Test
public void boundEmpty() throws Exception {
final String input = "{}";
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e99b0700/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXMLDeserializerActionParametersTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXMLDeserializerActionParametersTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXMLDeserializerActionParametersTest.java
new file mode 100644
index 0000000..c63d036
--- /dev/null
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXMLDeserializerActionParametersTest.java
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.serializer.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.Parameter;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmAction;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.CsdlAction;
+import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
+import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
+import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.core.edm.EdmActionImpl;
+import org.apache.olingo.commons.core.edm.EdmComplexTypeImpl;
+import org.apache.olingo.commons.core.edm.EdmProviderImpl;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class ODataXMLDeserializerActionParametersTest {
+
+ @Test
+ public void empty() throws Exception {
+ final String input = "";
+ final Map<String, Parameter> parameters = deserialize(input, "UART");
+ assertNotNull(parameters);
+ assertTrue(parameters.isEmpty());
+ }
+
+ @Test
+ public void primitive() throws Exception {
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>"
+ +"<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">"
+ +"<ParameterInt16>42</ParameterInt16>"
+ +"<ParameterDuration>P42DT11H22M33S</ParameterDuration>"
+ +"</metadata:parameters>";
+
+ final Map<String, Parameter> parameters = deserialize(input, "UARTTwoParam");
+ assertNotNull(parameters);
+ assertEquals(2, parameters.size());
+ Parameter parameter = parameters.get("ParameterInt16");
+ assertNotNull(parameter);
+ assertEquals((short) 42, parameter.getValue());
+ parameter = parameters.get("ParameterDuration");
+ assertNotNull(parameter);
+ assertEquals(BigDecimal.valueOf(3669753), parameter.getValue());
+ }
+
+ @Test
+ public void complex() throws Exception {
+ EdmProviderImpl provider = mock(EdmProviderImpl.class);
+ CsdlComplexType address = new CsdlComplexType();
+ address.setProperties(Arrays.asList(createProperty("Street", "Edm.String"),
+ createProperty("Zip", "Edm.Int32")));
+ address.setName("Address");
+ EdmComplexTypeImpl edmAddress = new EdmComplexTypeImpl(provider,
+ new FullQualifiedName("namespace.Address"), address);
+ Mockito.stub(provider.getComplexType(Mockito.any(FullQualifiedName.class))).toReturn(edmAddress);
+
+ List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
+ parameters.add(createParam("param1", "Edm.Int16"));
+ parameters.add(createParam("param2", "namespace.Address"));
+ parameters.add(createParam("param3", "Edm.Int32").setCollection(true));
+ parameters.add(createParam("param4", "Edm.String").setNullable(true));
+
+ FullQualifiedName actionName = new FullQualifiedName("namespace", "action");
+ CsdlAction csdlAction = new CsdlAction().setName("action1").setParameters(parameters);
+ EdmAction action = new EdmActionImpl(provider, actionName, csdlAction);
+
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">\n" +
+ " <param1>42</param1>\n" +
+ " <param2 metadata:type=\"#namespace.Address\">\n" +
+ " <Street>One Microsoft Way</Street>\n" +
+ " <Zip>98052</Zip>\n" +
+ " </param2>\n" +
+ " <param3>\n" +
+ " <element>1</element>\n" +
+ " <element>42</element>\n" +
+ " <element>99</element>\n" +
+ " </param3>\n" +
+ " <param4 metadata:null=\"true\"/>\n" +
+ "</metadata:parameters>";
+ final Map<String, Parameter> response = OData.newInstance().createDeserializer(ContentType.APPLICATION_XML)
+ .actionParameters(new ByteArrayInputStream(input.getBytes()), action).getActionParameters();
+
+ assertNotNull(response);
+ assertEquals(4, response.size());
+ Parameter parameter = response.get("param1");
+ assertNotNull(response);
+ assertEquals((short) 42, parameter.getValue());
+ parameter = response.get("param2");
+ assertNotNull(parameter);
+ ComplexValue addressValue = (ComplexValue)parameter.getValue();
+ assertEquals("Street", addressValue.getValue().get(0).getName());
+ assertEquals("One Microsoft Way", addressValue.getValue().get(0).getValue());
+ assertEquals("Zip", addressValue.getValue().get(1).getName());
+ assertEquals(98052, addressValue.getValue().get(1).getValue());
+
+ parameter = response.get("param3");
+ assertNotNull(parameter);
+ assertEquals(Arrays.asList(1, 42, 99), parameter.getValue());
+
+ parameter = response.get("param4");
+ assertNull(parameter.getValue());
+ }
+
+ @Test
+ public void complexCollection() throws Exception {
+ EdmProviderImpl provider = mock(EdmProviderImpl.class);
+ CsdlComplexType address = new CsdlComplexType();
+ address.setProperties(Arrays.asList(createProperty("Street", "Edm.String"),
+ createProperty("Zip", "Edm.Int32")));
+ address.setName("Address");
+ EdmComplexTypeImpl edmAddress = new EdmComplexTypeImpl(provider,
+ new FullQualifiedName("namespace.Address"), address);
+ Mockito.stub(provider.getComplexType(Mockito.any(FullQualifiedName.class))).toReturn(edmAddress);
+
+ List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
+ parameters.add(createParam("param1", "Edm.Int16"));
+ parameters.add(createParam("param2", "namespace.Address").setCollection(true));
+ parameters.add(createParam("param3", "Edm.Int32").setCollection(true));
+ parameters.add(createParam("param4", "Edm.String").setNullable(true));
+
+ FullQualifiedName actionName = new FullQualifiedName("namespace", "action");
+ CsdlAction csdlAction = new CsdlAction().setName("action1").setParameters(parameters);
+ EdmAction action = new EdmActionImpl(provider, actionName, csdlAction);
+
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">\n" +
+ " <param1>42</param1>\n" +
+ " <param2 metadata:type=\"#namespace.Address\">\n" +
+ " <element>" +
+ " <Street>One Microsoft Way</Street>\n" +
+ " <Zip>98052</Zip>\n" +
+ " </element>" +
+ " <element>" +
+ " <Street>Two Microsoft Way</Street>\n" +
+ " <Zip>98052</Zip>\n" +
+ " </element>" +
+ " </param2>\n" +
+ " <param3>\n" +
+ " <element>1</element>\n" +
+ " <element>42</element>\n" +
+ " <element>99</element>\n" +
+ " </param3>\n" +
+ " <param4 metadata:null=\"true\"/>\n" +
+ "</metadata:parameters>";
+ final Map<String, Parameter> response = OData.newInstance().createDeserializer(ContentType.APPLICATION_XML)
+ .actionParameters(new ByteArrayInputStream(input.getBytes()), action).getActionParameters();
+
+ assertNotNull(response);
+ assertEquals(4, response.size());
+ Parameter parameter = response.get("param1");
+ assertNotNull(response);
+ assertEquals((short) 42, parameter.getValue());
+ parameter = response.get("param2");
+ assertNotNull(parameter);
+ ComplexValue addressValue = (ComplexValue)((List<?>)parameter.getValue()).get(0);
+ assertEquals("One Microsoft Way", addressValue.getValue().get(0).getValue());
+ assertEquals(98052, addressValue.getValue().get(1).getValue());
+
+ addressValue = (ComplexValue)((List<?>)parameter.getValue()).get(1);
+ assertEquals("Two Microsoft Way", addressValue.getValue().get(0).getValue());
+ assertEquals(98052, addressValue.getValue().get(1).getValue());
+
+ parameter = response.get("param3");
+ assertNotNull(parameter);
+ assertEquals(Arrays.asList(1, 42, 99), parameter.getValue());
+
+ parameter = response.get("param4");
+ assertNull(parameter.getValue());
+ }
+
+ private CsdlParameter createParam(String name, String type) {
+ return new CsdlParameter().setName(name).setType(new FullQualifiedName(type));
+ }
+
+ private CsdlProperty createProperty(String name, String type) {
+ return new CsdlProperty().setName(name).setType(type);
+ }
+
+ @Test
+ public void boundEmpty() throws Exception {
+ final String input = "";
+ final Map<String, Parameter> parameters = deserialize(input, "BAETAllPrimRT", "ETAllPrim");
+ assertNotNull(parameters);
+ assertTrue(parameters.isEmpty());
+ }
+
+ @Test
+ public void testParameterWithNullLiteral() throws Exception {
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>"
+ +"<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">"
+ +"<ParameterInt16>1</ParameterInt16>"
+ +"</metadata:parameters>";
+
+ final Map<String, Parameter> parameters = deserialize(input,
+ "UARTCollStringTwoParam");
+ assertNotNull(parameters);
+ assertEquals(2, parameters.size());
+ Parameter parameter = parameters.get("ParameterInt16");
+ assertNotNull(parameter);
+ assertEquals((short) 1, parameter.getValue());
+ parameter = parameters.get("ParameterDuration");
+ assertNotNull(parameter);
+ assertEquals(null, parameter.getValue());
+ }
+
+ @Test
+ public void bindingParameter() throws Exception {
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>"
+ +"<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">"
+ +"<ParameterETAllPrim>1</ParameterETAllPrim>"
+ +"</metadata:parameters>";
+ deserialize(input, "BAETAllPrimRT", "ETAllPrim");
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void wrongName() throws Exception {
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>"
+ +"<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">"
+ +"<ParameterWrong>1</ParameterWrong>"
+ +"</metadata:parameters>";
+ deserialize(input, "UARTParam");
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void nullNotNullable() throws Exception {
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>"
+ +"<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">"
+ +"<ParameterInt16>null</ParameterInt16>"
+ +"</metadata:parameters>";
+ deserialize(input, "UARTCTTwoPrimParam");
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void missingParameter() throws Exception {
+ deserialize("", "UARTCTTwoPrimParam");
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void parameterTwice() throws Exception {
+ final String input = "<?xml version='1.0' encoding='UTF-8'?>"
+ +"<metadata:parameters xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\">"
+ +"<ParameterInt16>1</ParameterInt16>"
+ +"<ParameterInt16>2</ParameterInt16>"
+ +"</metadata:parameters>";
+ deserialize(input, "UARTParam");
+ }
+
+ protected static final Edm edm = OData.newInstance().createServiceMetadata(
+ new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
+
+ private Map<String, Parameter> deserialize(final String input, final String actionName) throws DeserializerException {
+ return OData.newInstance().createDeserializer(ContentType.APPLICATION_XML)
+ .actionParameters(new ByteArrayInputStream(input.getBytes()),
+ edm.getUnboundAction(new FullQualifiedName("Namespace1_Alias", actionName))).getActionParameters();
+ }
+
+ private Map<String, Parameter> deserialize(final String input, final String actionName, final String typeName)
+ throws DeserializerException {
+ return OData.newInstance().createDeserializer(ContentType.APPLICATION_XML)
+ .actionParameters(new ByteArrayInputStream(input.getBytes()),
+ edm.getBoundAction(new FullQualifiedName("Namespace1_Alias", actionName),
+ new FullQualifiedName("Namespace1_Alias", typeName), false)).getActionParameters();
+ }
+}
[2/2] olingo-odata4 git commit: Merge branch 'OLINGO-700'
Posted by ra...@apache.org.
Merge branch 'OLINGO-700'
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/fcec0c34
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/fcec0c34
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/fcec0c34
Branch: refs/heads/master
Commit: fcec0c349b9f64cf2db3d94aabcc2b4f8d4020f2
Parents: ba88c43 e99b070
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Fri Sep 11 15:51:17 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Fri Sep 11 15:51:17 2015 -0500
----------------------------------------------------------------------
.../server/core/requests/ActionRequest.java | 13 +-
.../json/ODataJsonDeserializer.java | 6 +-
.../deserializer/xml/ODataXmlDeserializer.java | 183 +++++++++--
...ataJsonDeserializerActionParametersTest.java | 140 +++++++++
...DataXMLDeserializerActionParametersTest.java | 303 +++++++++++++++++++
5 files changed, 614 insertions(+), 31 deletions(-)
----------------------------------------------------------------------