[OLINGO-603] Refactor action parameter deserialization part 1
This commit is contained in:
parent
d94edf568c
commit
3e8c50646e
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.commons.api.data;
|
||||
|
||||
public interface Parameter extends Valuable {
|
||||
|
||||
/**
|
||||
* @return name of the parameter
|
||||
*/
|
||||
String getName();
|
||||
|
||||
boolean isEntity();
|
||||
|
||||
Entity asEntity();
|
||||
|
||||
}
|
|
@ -19,11 +19,12 @@
|
|||
package org.apache.olingo.commons.api.data;
|
||||
|
||||
public enum ValueType {
|
||||
PRIMITIVE, GEOSPATIAL, ENUM, COMPLEX,
|
||||
PRIMITIVE, GEOSPATIAL, ENUM, COMPLEX, ENTITY,
|
||||
COLLECTION_PRIMITIVE(PRIMITIVE),
|
||||
COLLECTION_GEOSPATIAL(GEOSPATIAL),
|
||||
COLLECTION_ENUM(ENUM),
|
||||
COLLECTION_COMPLEX(COMPLEX);
|
||||
COLLECTION_COMPLEX(COMPLEX),
|
||||
COLLECTION_ENTITY(ENTITY);
|
||||
|
||||
private final ValueType baseType;
|
||||
|
||||
|
|
|
@ -37,12 +37,23 @@ public abstract class AbstractValuable implements Valuable, Annotatable {
|
|||
private ValueType valueType = null;
|
||||
private Object value = null;
|
||||
private final List<Annotation> annotations = new ArrayList<Annotation>();
|
||||
private String type;
|
||||
|
||||
@Override
|
||||
public boolean isNull() {
|
||||
return value == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrimitive() {
|
||||
return valueType == ValueType.PRIMITIVE;
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.apache.olingo.commons.api.data.Annotation;
|
|||
public class AnnotationImpl extends AbstractValuable implements Annotation {
|
||||
|
||||
private String term;
|
||||
private String type;
|
||||
|
||||
@Override
|
||||
public String getTerm() {
|
||||
|
@ -34,14 +33,4 @@ public class AnnotationImpl extends AbstractValuable implements Annotation {
|
|||
public void setTerm(final String term) {
|
||||
this.term = term;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.commons.core.data;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Parameter;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
|
||||
public class ParameterImpl extends AbstractValuable implements Parameter {
|
||||
|
||||
String name;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntity() {
|
||||
return getValueType() == ValueType.ENTITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity asEntity() {
|
||||
return isEntity() ? (Entity) getValue() : null;
|
||||
}
|
||||
}
|
|
@ -24,13 +24,12 @@ import org.apache.olingo.commons.api.data.ValueType;
|
|||
public class PropertyImpl extends AbstractValuable implements Property {
|
||||
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public PropertyImpl() {}
|
||||
|
||||
public PropertyImpl(final String type, final String name) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
super.setType(type);
|
||||
}
|
||||
|
||||
public PropertyImpl(String type, String name, ValueType valueType, Object value) {
|
||||
|
@ -48,18 +47,8 @@ public class PropertyImpl extends AbstractValuable implements Property {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNull() {
|
||||
return getValue() == null || "Edm.Null".equals(type);
|
||||
return getValue() == null || "Edm.Null".equals(getType());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import javax.xml.stream.XMLStreamWriter;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.data.Annotation;
|
||||
import org.apache.olingo.commons.api.data.ComplexValue;
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
|
@ -113,6 +114,9 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
|
|||
property(writer, property, false);
|
||||
}
|
||||
break;
|
||||
case ENTITY:
|
||||
case COLLECTION_ENTITY:
|
||||
throw new ODataRuntimeException("Entities cannot appear in this payload");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
package org.apache.olingo.server.api.deserializer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Parameter;
|
||||
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
|
||||
|
@ -54,8 +56,8 @@ public interface ODataDeserializer {
|
|||
* Validates: parameter types, no double parameters, correct json types.
|
||||
* @param stream
|
||||
* @param edmAction
|
||||
* @return deserialized {@link Entity} object
|
||||
* @return deserialized list of {@link Parameter} objects
|
||||
* @throws DeserializerException
|
||||
*/
|
||||
Entity actionParameters(InputStream stream, EdmAction edmAction) throws DeserializerException;
|
||||
List<Parameter> actionParameters(InputStream stream, EdmAction edmAction) throws DeserializerException;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.olingo.commons.api.data.ComplexValue;
|
|||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
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.ValueType;
|
||||
import org.apache.olingo.commons.api.domain.ODataLinkType;
|
||||
|
@ -51,6 +52,7 @@ import org.apache.olingo.commons.core.data.ComplexValueImpl;
|
|||
import org.apache.olingo.commons.core.data.EntityImpl;
|
||||
import org.apache.olingo.commons.core.data.EntitySetImpl;
|
||||
import org.apache.olingo.commons.core.data.LinkImpl;
|
||||
import org.apache.olingo.commons.core.data.ParameterImpl;
|
||||
import org.apache.olingo.commons.core.data.PropertyImpl;
|
||||
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
||||
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
|
||||
|
@ -58,6 +60,7 @@ import org.apache.olingo.server.api.deserializer.ODataDeserializer;
|
|||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
@ -72,10 +75,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
|||
@Override
|
||||
public EntitySet entityCollection(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
|
||||
JsonParser parser = new JsonFactory(objectMapper).createParser(stream);
|
||||
final ObjectNode tree = parser.getCodec().readTree(parser);
|
||||
final ObjectNode tree = parseJsonTree(stream);
|
||||
|
||||
return consumeEntitySetNode(edmEntityType, tree);
|
||||
} catch (JsonParseException e) {
|
||||
|
@ -145,10 +145,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
|||
@Override
|
||||
public Entity entity(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
|
||||
JsonParser parser = new JsonFactory(objectMapper).createParser(stream);
|
||||
final ObjectNode tree = parser.getCodec().readTree(parser);
|
||||
final ObjectNode tree = parseJsonTree(stream);
|
||||
|
||||
return consumeEntityNode(edmEntityType, tree);
|
||||
|
||||
|
@ -183,16 +180,13 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Entity actionParameters(InputStream stream, final EdmAction edmAction) throws DeserializerException {
|
||||
public List<Parameter> actionParameters(InputStream stream, final EdmAction edmAction) throws DeserializerException {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
|
||||
JsonParser parser = new JsonFactory(objectMapper).createParser(stream);
|
||||
ObjectNode tree = parser.getCodec().readTree(parser);
|
||||
EntityImpl entity = new EntityImpl();
|
||||
consumeParameters(edmAction, tree, entity);
|
||||
ObjectNode tree = parseJsonTree(stream);
|
||||
ArrayList<Parameter> parameters = new ArrayList<Parameter>();
|
||||
consumeParameters(edmAction, tree, parameters);
|
||||
assertJsonNodeIsEmpty(tree);
|
||||
return entity;
|
||||
return parameters;
|
||||
|
||||
} catch (final JsonParseException e) {
|
||||
throw new DeserializerException("An JsonParseException occurred", e,
|
||||
|
@ -206,22 +200,36 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
}
|
||||
|
||||
private void consumeParameters(final EdmAction edmAction, ObjectNode node, EntityImpl entity)
|
||||
private ObjectNode parseJsonTree(InputStream stream) throws IOException, JsonParseException, JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
|
||||
JsonParser parser = new JsonFactory(objectMapper).createParser(stream);
|
||||
ObjectNode tree = parser.getCodec().readTree(parser);
|
||||
return tree;
|
||||
}
|
||||
|
||||
private void consumeParameters(final EdmAction edmAction, ObjectNode node, ArrayList<Parameter> parameters)
|
||||
throws DeserializerException {
|
||||
for (final String name : edmAction.getParameterNames()) {
|
||||
final EdmParameter parameter = edmAction.getParameter(name);
|
||||
final EdmParameter edmParameter = edmAction.getParameter(name);
|
||||
ParameterImpl parameter = new ParameterImpl();
|
||||
parameter.setName(name);
|
||||
JsonNode jsonNode = node.get(name);
|
||||
if (jsonNode == null) {
|
||||
if (!parameter.isNullable()) {
|
||||
if (!edmParameter.isNullable()) {
|
||||
// TODO: new message key.
|
||||
throw new DeserializerException("Non-nullable parameter not present or null",
|
||||
DeserializerException.MessageKeys.INVALID_NULL_PROPERTY, name);
|
||||
}
|
||||
} else {
|
||||
entity.addProperty(consumePropertyNode(parameter.getName(), parameter.getType(), parameter.isCollection(),
|
||||
parameter.isNullable(), parameter.getMaxLength(), parameter.getPrecision(), parameter.getScale(),
|
||||
true, parameter.getMapping(),
|
||||
jsonNode));
|
||||
Property consumePropertyNode =
|
||||
consumePropertyNode(edmParameter.getName(), edmParameter.getType(), edmParameter.isCollection(),
|
||||
edmParameter.isNullable(), edmParameter.getMaxLength(), edmParameter.getPrecision(), edmParameter
|
||||
.getScale(),
|
||||
true, edmParameter.getMapping(),
|
||||
jsonNode);
|
||||
parameter.setValue(consumePropertyNode.getValueType(), consumePropertyNode.getValue());
|
||||
parameters.add(parameter);
|
||||
node.remove(name);
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +310,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
|||
EntitySetImpl inlineEntitySet = new EntitySetImpl();
|
||||
inlineEntitySet.getEntities().addAll(consumeEntitySetArray(edmNavigationProperty.getType(), jsonNode));
|
||||
link.setInlineEntitySet(inlineEntitySet);
|
||||
} else if (!jsonNode.isArray() && (!jsonNode.isValueNode() || jsonNode.isNull())
|
||||
} else if (!jsonNode.isArray() && (!jsonNode.isValueNode() || jsonNode.isNull())
|
||||
&& !edmNavigationProperty.isCollection()) {
|
||||
link.setType(ODataLinkType.ENTITY_NAVIGATION.toString());
|
||||
if (!jsonNode.isNull()) {
|
||||
|
@ -623,7 +631,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
|
|||
/**
|
||||
* Check if JsonNode is a value node (<code>jsonNode.isValueNode()</code>) and if not throw
|
||||
* an DeserializerException.
|
||||
* @param name name of property which is checked
|
||||
* @param name name of property which is checked
|
||||
* @param jsonNode node which is checked
|
||||
* @throws DeserializerException is thrown if json node is not a value node
|
||||
*/
|
||||
|
|
|
@ -26,8 +26,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.Parameter;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
|
@ -39,27 +38,23 @@ public class ODataJsonDeserializerActionParametersTest extends AbstractODataDese
|
|||
@Test
|
||||
public void empty() throws Exception {
|
||||
final String input = "{}";
|
||||
final Entity entity = deserialize(input, "UART");
|
||||
assertNotNull(entity);
|
||||
final List<Property> properties = entity.getProperties();
|
||||
assertNotNull(properties);
|
||||
assertTrue(properties.isEmpty());
|
||||
final List<Parameter> parameters = deserialize(input, "UART");
|
||||
assertNotNull(parameters);
|
||||
assertTrue(parameters.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void primitive() throws Exception {
|
||||
final String input = "{\"ParameterDuration\":\"P42DT11H22M33S\",\"ParameterInt16\":42}";
|
||||
final Entity entity = deserialize(input, "UARTTwoParam");
|
||||
assertNotNull(entity);
|
||||
final List<Property> properties = entity.getProperties();
|
||||
assertNotNull(properties);
|
||||
assertEquals(2, properties.size());
|
||||
Property property = properties.get(0);
|
||||
assertNotNull(property);
|
||||
assertEquals((short) 42, property.getValue());
|
||||
property = properties.get(1);
|
||||
assertNotNull(property);
|
||||
assertEquals(BigDecimal.valueOf(3669753), property.getValue());
|
||||
final List<Parameter> parameters = deserialize(input, "UARTTwoParam");
|
||||
assertNotNull(parameters);
|
||||
assertEquals(2, parameters.size());
|
||||
Parameter parameter = parameters.get(0);
|
||||
assertNotNull(parameter);
|
||||
assertEquals((short) 42, parameter.getValue());
|
||||
parameter = parameters.get(1);
|
||||
assertNotNull(parameter);
|
||||
assertEquals(BigDecimal.valueOf(3669753), parameter.getValue());
|
||||
}
|
||||
|
||||
@Test(expected = DeserializerException.class)
|
||||
|
@ -77,7 +72,7 @@ public class ODataJsonDeserializerActionParametersTest extends AbstractODataDese
|
|||
deserialize("{\"ParameterInt16\":\"42\"}", "UARTParam");
|
||||
}
|
||||
|
||||
private Entity deserialize(final String input, final String actionName) throws DeserializerException {
|
||||
private List<Parameter> deserialize(final String input, final String actionName) throws DeserializerException {
|
||||
return OData.newInstance().createDeserializer(ODataFormat.JSON)
|
||||
.actionParameters(new ByteArrayInputStream(input.getBytes()),
|
||||
edm.getUnboundAction(new FullQualifiedName("Namespace1_Alias", actionName)));
|
||||
|
|
Loading…
Reference in New Issue