[OLINGO-530] Entity and EntitySet deserialization

This commit is contained in:
Christian Amend 2015-01-14 09:20:27 +01:00
parent ab39763f3e
commit 2ac6ba18bb
14 changed files with 1206 additions and 1 deletions

View File

@ -22,7 +22,9 @@ import java.util.List;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.edm.provider.EdmProvider;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
@ -96,4 +98,6 @@ public abstract class OData {
* It can be used in Processor implementations.
*/
public abstract UriHelper createUriHelper();
public abstract ODataDeserializer createDeserializer(ODataFormat format) throws DeserializerException;
}

View File

@ -28,7 +28,18 @@ public class DeserializerException extends ODataTranslatedException {
/** Keys for exception texts in the resource bundle. */
public static enum MessageKeys implements MessageKey {
NOT_IMPLEMENTED,
IO_EXCEPTION;
IO_EXCEPTION,
//TODO: create texts for the following message keys:
/** parameter: format */ UNSUPPORTED_FORMAT,
JSON_SYNTAX_EXCEPTION,
/** parameter: propertyName */ INVALID_NULL_PROPERTY,
TREE_NOT_EMPTY,
/** parameter: propertyName */ INVALID_VALUE_FOR_PROPERTY,
/** parameter: propertyName */ INVALID_TYPE_FOR_PROPERTY,
VALUE_ARRAY_NOT_PRESENT,
VALUE_TAG_MUST_BE_AN_ARRAY,
INVALID_ENTITY,
/** parameter: navigationPropertyName */INVALID_VALUE_FOR_NAVIGATION_PROPERTY;
@Override
public String getKey() {

View File

@ -0,0 +1,33 @@
/*
* 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.api.deserializer;
import java.io.InputStream;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
public interface ODataDeserializer {
Entity entity(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException;
EntitySet entitySet(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException;
}

View File

@ -25,7 +25,9 @@ import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.edm.provider.EdmProvider;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
@ -33,6 +35,7 @@ import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriHelper;
import org.apache.olingo.server.core.deserializer.FixedFormatDeserializerImpl;
import org.apache.olingo.server.core.deserializer.json.ODataJsonDeserializer;
import org.apache.olingo.server.core.serializer.FixedFormatSerializerImpl;
import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializerImpl;
@ -84,4 +87,23 @@ public class ODataImpl extends OData {
public UriHelper createUriHelper() {
return new UriHelperImpl();
}
@Override
public ODataDeserializer createDeserializer(ODataFormat format) throws DeserializerException{
ODataDeserializer serializer;
switch (format) {
case JSON:
case JSON_NO_METADATA:
case JSON_FULL_METADATA:
serializer = new ODataJsonDeserializer();
break;
case XML:
//We do not support xml deserialization right now so this mus lead to an error
default:
throw new DeserializerException("Unsupported format: " + format,
SerializerException.MessageKeys.UNSUPPORTED_FORMAT, format.toString());
}
return serializer;
}
}

View File

@ -0,0 +1,523 @@
/*
* 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.deserializer.json;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.domain.ODataLinkType;
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.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.core.data.EntityImpl;
import org.apache.olingo.commons.core.data.EntitySetImpl;
import org.apache.olingo.commons.core.data.LinkImpl;
import org.apache.olingo.commons.core.data.PropertyImpl;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class ODataJsonDeserializer implements ODataDeserializer {
@Override
public EntitySet entitySet(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException {
try {
JsonParser parser = new JsonFactory(new ObjectMapper()).createParser(stream);
final ObjectNode tree = parser.getCodec().readTree(parser);
return consumeEntitySetNode(edmEntityType, tree);
} catch (JsonParseException e) {
throw new DeserializerException("An JsonParseException occourred", e,
DeserializerException.MessageKeys.JSON_SYNTAX_EXCEPTION);
} catch (IOException e) {
throw new DeserializerException("An IOException occourred", e, DeserializerException.MessageKeys.IO_EXCEPTION);
}
}
private EntitySet consumeEntitySetNode(EdmEntityType edmEntityType, final ObjectNode tree)
throws DeserializerException {
EntitySetImpl entitySet = new EntitySetImpl();
// Consume entitySet annotations
consumeODataEntitySetAnnotations(tree, entitySet);
// Consume entities
JsonNode jsonNode = tree.get(Constants.VALUE);
if (jsonNode != null) {
if (jsonNode.isArray() == false) {
throw new DeserializerException("The content of the value tag must be an Array but is not. ",
DeserializerException.MessageKeys.VALUE_TAG_MUST_BE_AN_ARRAY);
}
consumeEntitySetArray(entitySet, edmEntityType, jsonNode);
tree.remove(Constants.VALUE);
} else {
throw new DeserializerException("Could not find value array.",
DeserializerException.MessageKeys.VALUE_ARRAY_NOT_PRESENT);
}
if (tree.size() != 0) {
throw new DeserializerException("Tree should be empty but still has content left.",
DeserializerException.MessageKeys.TREE_NOT_EMPTY);
}
return entitySet;
}
private void consumeEntitySetArray(EntitySetImpl entitySet, EdmEntityType edmEntityType, JsonNode jsonNode)
throws DeserializerException {
Iterator<JsonNode> arrayIterator = jsonNode.iterator();
while (arrayIterator.hasNext()) {
JsonNode arrayElement = (JsonNode) arrayIterator.next();
if (arrayElement.isContainerNode() && arrayElement.isArray()) {
throw new DeserializerException("Nested Arrays and primitive values are not allowed for an entity value.",
DeserializerException.MessageKeys.INVALID_ENTITY);
}
entitySet.getEntities().add(consumeEntityNode(edmEntityType, (ObjectNode) arrayElement));
}
}
private void consumeODataEntitySetAnnotations(final ObjectNode tree, EntitySetImpl entitySet) {
URI contextURL;
if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
contextURL = URI.create(tree.get(Constants.JSON_CONTEXT).textValue());
tree.remove(Constants.JSON_CONTEXT);
} else if (tree.hasNonNull(Constants.JSON_METADATA)) {
contextURL = URI.create(tree.get(Constants.JSON_METADATA).textValue());
tree.remove(Constants.JSON_METADATA);
} else {
contextURL = null;
}
if (contextURL != null) {
entitySet.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA));
}
if (tree.hasNonNull(Constants.JSON_COUNT)) {
entitySet.setCount(tree.get(Constants.JSON_COUNT).asInt());
tree.remove(Constants.JSON_COUNT);
}
if (tree.hasNonNull(Constants.JSON_NEXT_LINK)) {
entitySet.setNext(URI.create(tree.get(Constants.JSON_NEXT_LINK).textValue()));
tree.remove(Constants.JSON_NEXT_LINK);
}
if (tree.hasNonNull(Constants.JSON_DELTA_LINK)) {
entitySet.setDeltaLink(URI.create(tree.get(Constants.JSON_DELTA_LINK).textValue()));
tree.remove(Constants.JSON_DELTA_LINK);
}
}
@Override
public Entity entity(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException {
try {
JsonParser parser = new JsonFactory(new ObjectMapper()).createParser(stream);
final ObjectNode tree = parser.getCodec().readTree(parser);
return consumeEntityNode(edmEntityType, tree);
} catch (JsonParseException e) {
throw new DeserializerException("An JsonParseException occourred", e,
DeserializerException.MessageKeys.JSON_SYNTAX_EXCEPTION);
} catch (IOException e) {
throw new DeserializerException("An IOException occourred", e, DeserializerException.MessageKeys.IO_EXCEPTION);
}
}
private Entity consumeEntityNode(EdmEntityType edmEntityType, final ObjectNode tree) throws DeserializerException {
EntityImpl entity = new EntityImpl();
entity.setType(edmEntityType.getFullQualifiedName().getFullQualifiedNameAsString());
// Check and consume all Properties
List<String> propertyNames = edmEntityType.getPropertyNames();
for (String propertyName : propertyNames) {
JsonNode jsonNode = tree.get(propertyName);
if (jsonNode != null) {
EdmProperty edmProperty = (EdmProperty) edmEntityType.getProperty(propertyName);
if (jsonNode.isNull() == true && edmProperty.isNullable() != null
&& edmProperty.isNullable().booleanValue() == false) {
throw new DeserializerException("Property: " + propertyName + " must not be null.",
DeserializerException.MessageKeys.INVALID_NULL_PROPERTY, propertyName);
}
Property property = consumePropertyNode(edmProperty, jsonNode);
entity.addProperty(property);
tree.remove(propertyName);
}
}
// Check and consume all expanded Navigation Properties
List<String> navigationPropertyNames = edmEntityType.getNavigationPropertyNames();
for (String navigationPropertyName : navigationPropertyNames) {
// read expanded navigation property
JsonNode jsonNode = tree.get(navigationPropertyName);
if (jsonNode != null) {
EdmNavigationProperty edmNavigationProperty = edmEntityType.getNavigationProperty(navigationPropertyName);
if (jsonNode.isNull() == true && edmNavigationProperty.isNullable() != null
&& edmNavigationProperty.isNullable().booleanValue() == false) {
throw new DeserializerException("Property: " + navigationPropertyName + " must not be null.",
DeserializerException.MessageKeys.INVALID_NULL_PROPERTY, navigationPropertyName);
}
LinkImpl link = new LinkImpl();
link.setTitle(navigationPropertyName);
if (jsonNode.isArray() && edmNavigationProperty.isCollection()) {
link.setType(ODataLinkType.ENTITY_SET_NAVIGATION.toString());
EntitySetImpl inlineEntitySet = new EntitySetImpl();
consumeEntitySetArray(inlineEntitySet, edmNavigationProperty.getType(), jsonNode);
link.setInlineEntitySet(inlineEntitySet);
} else if (!jsonNode.isArray() && !jsonNode.isValueNode() && !edmNavigationProperty.isCollection()) {
link.setType(ODataLinkType.ENTITY_NAVIGATION.toString());
if (!jsonNode.isNull()) {
Entity inlineEntity = consumeEntityNode(edmNavigationProperty.getType(), (ObjectNode) jsonNode);
link.setInlineEntity(inlineEntity);
}
} else {
throw new DeserializerException("Invalid value: " + jsonNode.getNodeType()
+ " for expanded navigation porperty: " + navigationPropertyName,
DeserializerException.MessageKeys.INVALID_VALUE_FOR_NAVIGATION_PROPERTY, navigationPropertyName);
}
entity.getNavigationLinks().add(link);
tree.remove(navigationPropertyName);
}
}
// Check and consume all Annotations
consumeODataEntityAnnotations(tree, entity, edmEntityType);
final List<String> toRemove = new ArrayList<String>();
Iterator<Entry<String, JsonNode>> fieldsIterator = tree.fields();
// TODO: Add custom annotation support
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = (Map.Entry<String, JsonNode>) fieldsIterator.next();
if (field.getKey().endsWith(Constants.JSON_NAVIGATION_LINK)) {
final Link link = new LinkImpl();
link.setTitle(getAnnotationName(field));
link.setRel(ODataServiceVersion.V40.getNamespace(ODataServiceVersion.NamespaceKey.NAVIGATION_LINK_REL)
+ getAnnotationName(field));
if (field.getValue().isValueNode()) {
link.setHref(field.getValue().textValue());
link.setType(ODataLinkType.ENTITY_NAVIGATION.toString());
}
entity.getNavigationLinks().add(link);
toRemove.add(field.getKey());
} else if (field.getKey().endsWith(Constants.JSON_ASSOCIATION_LINK)) {
final LinkImpl link = new LinkImpl();
link.setTitle(getAnnotationName(field));
link.setRel(ODataServiceVersion.V40.getNamespace(ODataServiceVersion.NamespaceKey.ASSOCIATION_LINK_REL)
+ getAnnotationName(field));
link.setHref(field.getValue().textValue());
link.setType(ODataLinkType.ASSOCIATION.toString());
entity.getAssociationLinks().add(link);
toRemove.add(field.getKey());
}
}
// remove here to avoid iterator issues.
tree.remove(toRemove);
if (tree.size() != 0) {
throw new DeserializerException("Tree should be empty but still has content left.",
DeserializerException.MessageKeys.TREE_NOT_EMPTY);
}
return entity;
}
private String getAnnotationName(final Map.Entry<String, JsonNode> entry) {
return entry.getKey().substring(0, entry.getKey().indexOf('@'));
}
private void consumeODataEntityAnnotations(ObjectNode tree, EntityImpl entity, EdmEntityType edmEntityType) {
final URI contextURL;
if (tree.hasNonNull(Constants.JSON_CONTEXT)) {
contextURL = URI.create(tree.get(Constants.JSON_CONTEXT).textValue());
tree.remove(Constants.JSON_CONTEXT);
} else if (tree.hasNonNull(Constants.JSON_METADATA)) {
contextURL = URI.create(tree.get(Constants.JSON_METADATA).textValue());
tree.remove(Constants.JSON_METADATA);
} else {
contextURL = null;
}
if (contextURL != null) {
entity.setBaseURI(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA));
}
if (tree.hasNonNull(Constants.JSON_ETAG)) {
entity.setETag(tree.get(Constants.JSON_ETAG).textValue());
tree.remove(Constants.JSON_ETAG);
}
if (tree.hasNonNull(Constants.JSON_TYPE)) {
entity.setType(new EdmTypeInfo.Builder().setTypeExpression(tree.get(Constants.JSON_TYPE).textValue()).build()
.internal());
tree.remove(Constants.JSON_TYPE);
}
if (tree.hasNonNull(Constants.JSON_ID)) {
entity.setId(URI.create(tree.get(Constants.JSON_ID).textValue()));
tree.remove(Constants.JSON_ID);
}
if (tree.hasNonNull(Constants.JSON_READ_LINK)) {
final LinkImpl link = new LinkImpl();
link.setRel(Constants.SELF_LINK_REL);
link.setHref(tree.get(Constants.JSON_READ_LINK).textValue());
entity.setSelfLink(link);
tree.remove(Constants.JSON_READ_LINK);
}
if (tree.hasNonNull(Constants.JSON_EDIT_LINK)) {
final LinkImpl link = new LinkImpl();
link.setRel(Constants.EDIT_LINK_REL);
link.setHref(tree.get(Constants.JSON_EDIT_LINK).textValue());
entity.setEditLink(link);
tree.remove(Constants.JSON_EDIT_LINK);
}
// TODO: Should we check if this is a media resource?
if (tree.hasNonNull(Constants.JSON_MEDIA_READ_LINK)) {
entity.setMediaContentSource(URI.create(tree.get(Constants.JSON_MEDIA_READ_LINK).textValue()));
tree.remove(Constants.JSON_MEDIA_READ_LINK);
}
if (tree.hasNonNull(Constants.JSON_MEDIA_EDIT_LINK)) {
entity.setMediaContentSource(URI.create(tree.get(Constants.JSON_MEDIA_EDIT_LINK).textValue()));
tree.remove(Constants.JSON_MEDIA_EDIT_LINK);
}
if (tree.hasNonNull(Constants.JSON_MEDIA_CONTENT_TYPE)) {
entity.setMediaContentType(tree.get(Constants.JSON_MEDIA_CONTENT_TYPE).textValue());
tree.remove(Constants.JSON_MEDIA_CONTENT_TYPE);
}
if (tree.hasNonNull(Constants.JSON_MEDIA_ETAG)) {
entity.setMediaETag(tree.get(Constants.JSON_MEDIA_ETAG).textValue());
tree.remove(Constants.JSON_MEDIA_ETAG);
}
}
private Property consumePropertyNode(EdmProperty edmProperty, JsonNode jsonNode) throws DeserializerException {
Property property = new PropertyImpl();
property.setName(edmProperty.getName());
property.setType(edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString());
if (edmProperty.isCollection()) {
if (!jsonNode.isArray()) {
throw new DeserializerException("Value for property: " + edmProperty.getName()
+ " must be an arrat but is not.", DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY,
edmProperty.getName());
}
List<Object> valueArray = new ArrayList<Object>();
Iterator<JsonNode> iterator = jsonNode.iterator();
switch (edmProperty.getType().getKind()) {
case PRIMITIVE:
while (iterator.hasNext()) {
JsonNode arrayElement = iterator.next();
Object value = readPrimitiveValue(edmProperty, arrayElement);
valueArray.add(value);
}
property.setValue(ValueType.COLLECTION_PRIMITIVE, valueArray);
break;
case DEFINITION:
while (iterator.hasNext()) {
JsonNode arrayElement = iterator.next();
Object value = readTypeDefinitionValue(edmProperty, arrayElement);
valueArray.add(value);
}
property.setValue(ValueType.COLLECTION_PRIMITIVE, valueArray);
case ENUM:
while (iterator.hasNext()) {
JsonNode arrayElement = iterator.next();
Object value = readEnumValue(edmProperty, arrayElement);
valueArray.add(value);
}
property.setValue(ValueType.COLLECTION_ENUM, valueArray);
break;
case COMPLEX:
while (iterator.hasNext()) {
JsonNode arrayElement = iterator.next();
// read and add all complex properties
Object value = readComplexValue(edmProperty, arrayElement);
valueArray.add(value);
// If navigationProperties are present we have to consume them and create a LinkedComplexValue Object
// TODO: Complex Type Navigation Deserialization
// read and add all annotations
// TODO: read Complex Type Annotations
// Afterwards the node must be empty
if (arrayElement.size() != 0) {
throw new DeserializerException("Tree should be empty but still has content left.",
DeserializerException.MessageKeys.TREE_NOT_EMPTY);
}
}
property.setValue(ValueType.COLLECTION_COMPLEX, valueArray);
break;
default:
throw new DeserializerException("Invalid Type Kind for a property found: " + edmProperty.getType().getKind(),
DeserializerException.MessageKeys.INVALID_TYPE_FOR_PROPERTY, edmProperty.getName());
}
} else {
switch (edmProperty.getType().getKind()) {
case PRIMITIVE:
Object value = readPrimitiveValue(edmProperty, jsonNode);
property.setValue(ValueType.PRIMITIVE, value);
break;
case DEFINITION:
value = readTypeDefinitionValue(edmProperty, jsonNode);
property.setValue(ValueType.PRIMITIVE, value);
case ENUM:
value = readEnumValue(edmProperty, jsonNode);
property.setValue(ValueType.PRIMITIVE, value);
break;
case COMPLEX:
// read and add all complex properties
value = readComplexValue(edmProperty, jsonNode);
property.setValue(ValueType.COMPLEX, value);
// read and add all navigation properties
// TODO: Complex Type Navigation Deserialization
// read and add all annotations
// TODO: read Complex Type Annotations
// Afterwards the node must be empty
if (jsonNode.size() != 0) {
throw new DeserializerException("Tree should be empty but still has content left.",
DeserializerException.MessageKeys.TREE_NOT_EMPTY);
}
break;
default:
throw new DeserializerException("Invalid Type Kind for a property found: " + edmProperty.getType().getKind(),
DeserializerException.MessageKeys.INVALID_TYPE_FOR_PROPERTY, edmProperty.getName());
}
}
return property;
}
private Object readComplexValue(EdmProperty edmComplexProperty, JsonNode jsonNode) throws DeserializerException {
if (jsonNode.isArray() || !jsonNode.isContainerNode()) {
throw new DeserializerException(
"Inavlid value for property: " + edmComplexProperty.getName() + " must not be an array or primitive value.",
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmComplexProperty.getName());
}
// Even if there are no properties defined we have to give back an empty list
List<Property> propertyList = new ArrayList<Property>();
EdmComplexType edmType = (EdmComplexType) edmComplexProperty.getType();
// Check and consume all Properties
for (String propertyName : edmType.getPropertyNames()) {
EdmProperty edmProperty = (EdmProperty) edmType.getProperty(propertyName);
JsonNode subNode = jsonNode.get(propertyName);
if (subNode != null) {
if (subNode.isNull() && edmProperty.isNullable() != null && edmProperty.isNullable().booleanValue() == false) {
throw new DeserializerException("Property: " + propertyName + " must not be null.",
DeserializerException.MessageKeys.INVALID_NULL_PROPERTY, propertyName);
}
Property property = consumePropertyNode(edmProperty, subNode);
propertyList.add(property);
((ObjectNode) jsonNode).remove(propertyName);
}
}
return propertyList;
}
private Object readTypeDefinitionValue(EdmProperty edmProperty, JsonNode jsonNode) throws DeserializerException {
if (!jsonNode.isValueNode()) {
throw new DeserializerException(
"Inavlid value for property: " + edmProperty.getName() + " must not be an object or array.",
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmProperty.getName());
}
try {
EdmTypeDefinition edmTypeDefinition = (EdmTypeDefinition) edmProperty.getType();
Object value =
edmTypeDefinition.valueOfString(jsonNode.asText(), edmProperty.isNullable(),
edmTypeDefinition.getMaxLength(),
edmTypeDefinition.getPrecision(), edmTypeDefinition.getScale(), edmTypeDefinition.isUnicode(),
edmTypeDefinition.getDefaultType());
return value;
} catch (EdmPrimitiveTypeException e) {
throw new DeserializerException(
"Inavlid value: " + jsonNode.asText() + " for property: " + edmProperty.getName(), e,
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmProperty.getName());
}
}
private Object readEnumValue(EdmProperty edmProperty, JsonNode jsonNode) throws DeserializerException {
if (!jsonNode.isValueNode()) {
throw new DeserializerException(
"Inavlid value for property: " + edmProperty.getName() + " must not be an object or array.",
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmProperty.getName());
}
try {
EdmEnumType edmEnumType = (EdmEnumType) edmProperty.getType();
Object value =
edmEnumType
.valueOfString(jsonNode.asText(), edmProperty.isNullable(), edmProperty.getMaxLength(), edmProperty
.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), edmEnumType.getDefaultType());
return value;
} catch (EdmPrimitiveTypeException e) {
throw new DeserializerException(
"Inavlid value: " + jsonNode.asText() + " for property: " + edmProperty.getName(), e,
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmProperty.getName());
}
}
private Object readPrimitiveValue(EdmProperty edmProperty, JsonNode jsonNode) throws DeserializerException {
if (!jsonNode.isValueNode()) {
throw new DeserializerException(
"Inavlid value for property: " + edmProperty.getName() + " must not be an object or array.",
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmProperty.getName());
}
try {
EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmProperty.getType();
Object value =
edmPrimitiveType.valueOfString(jsonNode.asText(), edmProperty.isNullable(),
edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(),
edmProperty.isUnicode(), edmPrimitiveType.getDefaultType());
return value;
} catch (EdmPrimitiveTypeException e) {
throw new DeserializerException(
"Inavlid value: " + jsonNode.asText() + " for property: " + edmProperty.getName(), e,
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, edmProperty.getName());
}
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.deserializer.json;
import static org.junit.Assert.assertNotNull;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.junit.Test;
public class ODataJsonDeserializerBasicTest {
@Test
public void checkSupportedJsonFormats() throws Exception {
ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
assertNotNull(deserializer);
deserializer = null;
deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON_NO_METADATA);
assertNotNull(deserializer);
deserializer = null;
deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON_FULL_METADATA);
assertNotNull(deserializer);
deserializer = null;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.deserializer.json;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
public class AbstractODataDeserializerTest {
protected static final Edm edm = OData.newInstance().createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
protected InputStream getFileAsStream(final String filename) throws IOException {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
if (in == null) {
throw new IOException("Requested file '" + filename + "' was not found.");
}
return in;
}
}

View File

@ -0,0 +1,69 @@
/*
* 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.deserializer.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.InputStream;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.domain.ODataLinkType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.junit.Test;
public class ODataDeserializerDeepInsertTest extends AbstractODataDeserializerTest {
@Test
public void esAllPrimExpandedToOne() throws Exception {
EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimOne.json");
Entity entity = OData.newInstance().createDeserializer(ODataFormat.JSON).entity(stream, edmEntityType);
Link navigationLink = entity.getNavigationLink("NavPropertyETTwoPrimOne");
assertNotNull(navigationLink);
assertEquals("NavPropertyETTwoPrimOne", navigationLink.getTitle());
assertEquals(ODataLinkType.ENTITY_NAVIGATION.toString(), navigationLink.getType());
assertNotNull(navigationLink.getInlineEntity());
assertNull(navigationLink.getInlineEntitySet());
}
@Test
public void esAllPrimExpandedToMany() throws Exception {
EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
InputStream stream = getFileAsStream("EntityESAllPrimExpandedNavPropertyETTwoPrimMany.json");
Entity entity = OData.newInstance().createDeserializer(ODataFormat.JSON).entity(stream, edmEntityType);
Link navigationLink = entity.getNavigationLink("NavPropertyETTwoPrimMany");
assertNotNull(navigationLink);
assertEquals("NavPropertyETTwoPrimMany", navigationLink.getTitle());
assertEquals(ODataLinkType.ENTITY_SET_NAVIGATION.toString(), navigationLink.getType());
assertNull(navigationLink.getInlineEntity());
assertNotNull(navigationLink.getInlineEntitySet());
assertEquals(1, navigationLink.getInlineEntitySet().getEntities().size());
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.deserializer.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.InputStream;
import java.math.BigDecimal;
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.Property;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.junit.Test;
public class ODataDeserializerEntitySetTest extends AbstractODataDeserializerTest {
@Test
public void esAllPrim() throws Exception {
EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"));
InputStream stream = getFileAsStream("ESAllPrim.json");
EntitySet entitySet = OData.newInstance().createDeserializer(ODataFormat.JSON).entitySet(stream, edmEntityType);
assertNotNull(entitySet);
assertEquals(3, entitySet.getEntities().size());
//Check first entity
Entity entity = entitySet.getEntities().get(0);
List<Property> properties = entity.getProperties();
assertNotNull(properties);
assertEquals(16, properties.size());
assertEquals(new Short((short) 32767), entity.getProperty("PropertyInt16").getValue());
assertEquals("First Resource - positive values", entity.getProperty("PropertyString").getValue());
assertEquals(new Boolean(true), entity.getProperty("PropertyBoolean").getValue());
assertEquals(new Short((short) 255), entity.getProperty("PropertyByte").getValue());
assertEquals(new Byte((byte) 127), entity.getProperty("PropertySByte").getValue());
assertEquals(new Integer(2147483647), entity.getProperty("PropertyInt32").getValue());
assertEquals(new Long(9223372036854775807l), entity.getProperty("PropertyInt64").getValue());
assertEquals(new Float(1.79E20), entity.getProperty("PropertySingle").getValue());
assertEquals(new Double(-1.79E19), entity.getProperty("PropertyDouble").getValue());
assertEquals(new BigDecimal(34), entity.getProperty("PropertyDecimal").getValue());
assertNotNull(entity.getProperty("PropertyBinary").getValue());
assertNotNull(entity.getProperty("PropertyDate").getValue());
assertNotNull(entity.getProperty("PropertyDateTimeOffset").getValue());
assertNotNull(entity.getProperty("PropertyDuration").getValue());
assertNotNull(entity.getProperty("PropertyGuid").getValue());
assertNotNull(entity.getProperty("PropertyTimeOfDay").getValue());
}
@Test
public void eSCompCollComp() throws Exception {
EdmEntityType edmEntityType = edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETCompCollComp"));
InputStream stream = getFileAsStream("ESCompCollComp.json");
EntitySet entitySet = OData.newInstance().createDeserializer(ODataFormat.JSON).entitySet(stream, edmEntityType);
assertNotNull(entitySet);
assertEquals(2, entitySet.getEntities().size());
//Since entity deserialization is called we do not check all entities here excplicitly
}
}

View File

@ -0,0 +1,236 @@
/*
* 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.deserializer.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
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.ValueType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.junit.Test;
public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTest {
@Test
public void simpleEntityETAllPrim() throws Exception {
String entityString =
"{\"PropertyInt16\":32767," +
"\"PropertyString\":\"First Resource - positive values\"," +
"\"PropertyBoolean\":true," +
"\"PropertyByte\":255," +
"\"PropertySByte\":127," +
"\"PropertyInt32\":2147483647," +
"\"PropertyInt64\":9223372036854775807," +
"\"PropertySingle\":1.79E20," +
"\"PropertyDouble\":-1.79E19," +
"\"PropertyDecimal\":34," +
"\"PropertyBinary\":\"ASNFZ4mrze8=\"," +
"\"PropertyDate\":\"2012-12-03\"," +
"\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," +
"\"PropertyDuration\":\"PT6S\"," +
"\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," +
"\"PropertyTimeOfDay\":\"03:26:05\"}";
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
Entity entity =
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim")));
assertNotNull(entity);
List<Property> properties = entity.getProperties();
assertNotNull(properties);
assertEquals(16, properties.size());
assertEquals(new Short((short) 32767), entity.getProperty("PropertyInt16").getValue());
assertEquals("First Resource - positive values", entity.getProperty("PropertyString").getValue());
assertEquals(new Boolean(true), entity.getProperty("PropertyBoolean").getValue());
assertEquals(new Short((short) 255), entity.getProperty("PropertyByte").getValue());
assertEquals(new Byte((byte) 127), entity.getProperty("PropertySByte").getValue());
assertEquals(new Integer(2147483647), entity.getProperty("PropertyInt32").getValue());
assertEquals(new Long(9223372036854775807l), entity.getProperty("PropertyInt64").getValue());
assertEquals(new Float(1.79E20), entity.getProperty("PropertySingle").getValue());
assertEquals(new Double(-1.79E19), entity.getProperty("PropertyDouble").getValue());
assertEquals(new BigDecimal(34), entity.getProperty("PropertyDecimal").getValue());
assertNotNull(entity.getProperty("PropertyBinary").getValue());
assertNotNull(entity.getProperty("PropertyDate").getValue());
assertNotNull(entity.getProperty("PropertyDateTimeOffset").getValue());
assertNotNull(entity.getProperty("PropertyDuration").getValue());
assertNotNull(entity.getProperty("PropertyGuid").getValue());
assertNotNull(entity.getProperty("PropertyTimeOfDay").getValue());
}
@Test
public void simpleEntityETCompAllPrim() throws Exception {
String entityString = "{\"PropertyInt16\":32767," +
"\"PropertyComp\":{" +
"\"PropertyString\":\"First Resource - first\"," +
"\"PropertyBinary\":\"ASNFZ4mrze8=\"," +
"\"PropertyBoolean\":true," +
"\"PropertyByte\":255," +
"\"PropertyDate\":\"2012-10-03\"," +
"\"PropertyDateTimeOffset\":\"2012-10-03T07:16:23.1234567Z\"," +
"\"PropertyDecimal\":34.27," +
"\"PropertySingle\":1.79E20," +
"\"PropertyDouble\":-1.79E19," +
"\"PropertyDuration\":\"PT6S\"," +
"\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," +
"\"PropertyInt16\":32767," +
"\"PropertyInt32\":2147483647," +
"\"PropertyInt64\":9223372036854775807," +
"\"PropertySByte\":127," +
"\"PropertyTimeOfDay\":\"01:00:01\"}}";
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
Entity entity =
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETCompAllPrim")));
assertNotNull(entity);
List<Property> properties = entity.getProperties();
assertNotNull(properties);
assertEquals(2, properties.size());
assertEquals(new Short((short) 32767), entity.getProperty("PropertyInt16").getValue());
assertNotNull(entity.getProperty("PropertyComp"));
assertNotNull(entity.getProperty("PropertyComp") instanceof List);
List<Property> complexProperties = entity.getProperty("PropertyComp").asComplex();
assertEquals(16, complexProperties.size());
}
@Test
public void simpleEntityETCollAllPrim() throws Exception {
final String entityString = "{"
+ "\"PropertyInt16\":1,"
+ "\"CollPropertyString\":"
+ "[\"Employee1@company.example\",\"Employee2@company.example\",\"Employee3@company.example\"],"
+ "\"CollPropertyBoolean\":[true,false,true],"
+ "\"CollPropertyByte\":[50,200,249],"
+ "\"CollPropertySByte\":[-120,120,126],"
+ "\"CollPropertyInt16\":[1000,2000,30112],"
+ "\"CollPropertyInt32\":[23232323,11223355,10000001],"
+ "\"CollPropertyInt64\":[929292929292,333333333333,444444444444],"
+ "\"CollPropertySingle\":[1790.0,26600.0,3210.0],"
+ "\"CollPropertyDouble\":[-17900.0,-2.78E7,3210.0],"
+ "\"CollPropertyDecimal\":[12,-2,1234],"
+ "\"CollPropertyBinary\":[\"q83v\",\"ASNF\",\"VGeJ\"],"
+ "\"CollPropertyDate\":[\"1958-12-03\",\"1999-08-05\",\"2013-06-25\"],"
+ "\"CollPropertyDateTimeOffset\":[\"2015-08-12T03:08:34Z\",\"1970-03-28T12:11:10Z\","
+ "\"1948-02-17T09:09:09Z\"],"
+ "\"CollPropertyDuration\":[\"PT13S\",\"PT5H28M0S\",\"PT1H0S\"],"
+ "\"CollPropertyGuid\":[\"ffffff67-89ab-cdef-0123-456789aaaaaa\",\"eeeeee67-89ab-cdef-0123-456789bbbbbb\","
+ "\"cccccc67-89ab-cdef-0123-456789cccccc\"],"
+ "\"CollPropertyTimeOfDay\":[\"04:14:13\",\"23:59:59\",\"01:12:33\"]"
+ "}";
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
Entity entity =
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETCollAllPrim")));
assertNotNull(entity);
List<Property> properties = entity.getProperties();
assertNotNull(properties);
assertEquals(17, properties.size());
// All properties need 3 entires
for (Property prop : properties) {
if (!prop.getName().equals("PropertyInt16")) {
assertEquals(ValueType.COLLECTION_PRIMITIVE, prop.getValueType());
assertTrue(prop.getValue() instanceof List);
List<? extends Object> asCollection = prop.asCollection();
assertEquals(3, asCollection.size());
}
}
Property property = entity.getProperty("CollPropertyBoolean");
List<? extends Object> asCollection = property.asCollection();
assertEquals(true, asCollection.get(0));
assertEquals(false, asCollection.get(1));
assertEquals(true, asCollection.get(2));
}
@SuppressWarnings("unchecked")
@Test
public void simpleEntityETMixPrimCollComp() throws Exception {
final String entityString = "{"
+ "\"PropertyInt16\":32767,"
+ "\"CollPropertyString\":"
+ "[\"Employee1@company.example\",\"Employee2@company.example\",\"Employee3@company.example\"],"
+ "\"PropertyComp\":{\"PropertyInt16\":111,\"PropertyString\":\"TEST A\"},"
+ "\"CollPropertyComp\":["
+ "{\"PropertyInt16\":123,\"PropertyString\":\"TEST 1\"},"
+ "{\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"},"
+ "{\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"}]}";
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
Entity entity =
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETMixPrimCollComp")));
assertNotNull(entity);
List<Property> properties = entity.getProperties();
assertNotNull(properties);
assertEquals(4, properties.size());
Property property = entity.getProperty("CollPropertyComp");
assertEquals(ValueType.COLLECTION_COMPLEX, property.getValueType());
assertTrue(property.getValue() instanceof List);
List<? extends Object> asCollection = property.asCollection();
assertEquals(3, asCollection.size());
for (Object arrayElement : asCollection) {
assertTrue(arrayElement instanceof List);
List<Object> castedArrayElement = (List<Object>) arrayElement;
assertEquals(2, castedArrayElement.size());
}
}
@Test
public void simpleEntityWithContextURL() throws Exception {
String entityString =
"{\"@odata.context\": \"$metadata#ESAllPrim/$entity\"," +
"\"PropertyInt16\":32767," +
"\"PropertyString\":\"First Resource - positive values\"," +
"\"PropertyBoolean\":true," +
"\"PropertyByte\":255," +
"\"PropertySByte\":127," +
"\"PropertyInt32\":2147483647," +
"\"PropertyInt64\":9223372036854775807," +
"\"PropertySingle\":1.79E20," +
"\"PropertyDouble\":-1.79E19," +
"\"PropertyDecimal\":34," +
"\"PropertyBinary\":\"ASNFZ4mrze8=\"," +
"\"PropertyDate\":\"2012-12-03\"," +
"\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," +
"\"PropertyDuration\":\"PT6S\"," +
"\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," +
"\"PropertyTimeOfDay\":\"03:26:05\"}";
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON);
Entity entity =
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim")));
assertNotNull(entity);
}
}

View File

@ -0,0 +1,56 @@
{
"@odata.context" : "$metadata#ESAllPrim",
"value" : [{
"PropertyInt16" : 32767,
"PropertyString" : "First Resource - positive values",
"PropertyBoolean" : true,
"PropertyByte" : 255,
"PropertySByte" : 127,
"PropertyInt32" : 2147483647,
"PropertyInt64" : 9223372036854775807,
"PropertySingle" : 1.79000000E+20,
"PropertyDouble" : -1.7900000000000000E+19,
"PropertyDecimal" : 34,
"PropertyBinary" : "ASNFZ4mrze8=",
"PropertyDate" : "2012-12-03",
"PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
"PropertyDuration" : "P0DT0H0M6S",
"PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
"PropertyTimeOfDay" : "03:26:05"
}, {
"PropertyInt16" : -32768,
"PropertyString" : "Second Resource - negative values",
"PropertyBoolean" : false,
"PropertyByte" : 0,
"PropertySByte" : -128,
"PropertyInt32" : -2147483648,
"PropertyInt64" : -9223372036854775808,
"PropertySingle" : -1.79000000E+08,
"PropertyDouble" : -1.7900000000000000E+05,
"PropertyDecimal" : -34,
"PropertyBinary" : "ASNFZ4mrze8=",
"PropertyDate" : "2015-11-05",
"PropertyDateTimeOffset" : "2005-12-03T07:17:08Z",
"PropertyDuration" : "P0DT0H0M9S",
"PropertyGuid" : "76543201-23ab-cdef-0123-456789dddfff",
"PropertyTimeOfDay" : "23:49:14"
}, {
"PropertyInt16" : 0,
"PropertyString" : "",
"PropertyBoolean" : false,
"PropertyByte" : 0,
"PropertySByte" : 0,
"PropertyInt32" : 0,
"PropertyInt64" : 0,
"PropertySingle" : 0.00000000E+00,
"PropertyDouble" : 0.0000000000000000E+00,
"PropertyDecimal" : 0,
"PropertyBinary" : "",
"PropertyDate" : "1970-01-01",
"PropertyDateTimeOffset" : "2005-12-03T00:00:00Z",
"PropertyDuration" : "P0DT0H0M0S",
"PropertyGuid" : "76543201-23ab-cdef-0123-456789cccddd",
"PropertyTimeOfDay" : "00:01:01"
}
]
}

View File

@ -0,0 +1,35 @@
{
"@odata.context" : "$metadata#ESCompCollComp",
"value" : [{
"PropertyInt16" : 32767,
"PropertyComp" : {
"CollPropertyComp" : [{
"PropertyInt16" : 555,
"PropertyString" : "1 Test Complex in Complex Property"
}, {
"PropertyInt16" : 666,
"PropertyString" : "2 Test Complex in Complex property"
}, {
"PropertyInt16" : 777,
"PropertyString" : "3 Test Complex in Complex property"
}
]
}
}, {
"PropertyInt16" : 12345,
"PropertyComp" : {
"CollPropertyComp" : [{
"PropertyInt16" : 888,
"PropertyString" : "11 Test Complex in Complex property"
}, {
"PropertyInt16" : 999,
"PropertyString" : "12 Test Complex in Complex property"
}, {
"PropertyInt16" : 0,
"PropertyString" : "13 Test Complex in Complex property"
}
]
}
}
]
}

View File

@ -0,0 +1,24 @@
{
"@odata.context" : "$metadata#ESAllPrim/$entity",
"PropertyInt16" : 32767,
"PropertyString" : "First Resource - positive values",
"PropertyBoolean" : true,
"PropertyByte" : 255,
"PropertySByte" : 127,
"PropertyInt32" : 2147483647,
"PropertyInt64" : 9223372036854775807,
"PropertySingle" : 1.79000000E+20,
"PropertyDouble" : -1.7900000000000000E+19,
"PropertyDecimal" : 34,
"PropertyBinary" : "ASNFZ4mrze8=",
"PropertyDate" : "2012-12-03",
"PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
"PropertyDuration" : "P0DT0H0M6S",
"PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
"PropertyTimeOfDay" : "03:26:05",
"NavPropertyETTwoPrimMany" : [{
"PropertyInt16" : -365,
"PropertyString" : "Test String2"
}
]
}

View File

@ -0,0 +1,23 @@
{
"@odata.context" : "$metadata#ESAllPrim/$entity",
"PropertyInt16" : 32767,
"PropertyString" : "First Resource - positive values",
"PropertyBoolean" : true,
"PropertyByte" : 255,
"PropertySByte" : 127,
"PropertyInt32" : 2147483647,
"PropertyInt64" : 9223372036854775807,
"PropertySingle" : 1.79000000E+20,
"PropertyDouble" : -1.7900000000000000E+19,
"PropertyDecimal" : 34,
"PropertyBinary" : "ASNFZ4mrze8=",
"PropertyDate" : "2012-12-03",
"PropertyDateTimeOffset" : "2012-12-03T07:16:23Z",
"PropertyDuration" : "P0DT0H0M6S",
"PropertyGuid" : "01234567-89ab-cdef-0123-456789abcdef",
"PropertyTimeOfDay" : "03:26:05",
"NavPropertyETTwoPrimOne" : {
"PropertyInt16" : 32767,
"PropertyString" : "Test String4"
}
}