diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java index 63a53af14..a2ccbaea5 100644 --- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java +++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java @@ -1914,15 +1914,7 @@ public abstract class AbstractServices { alink.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getName()); - if (property.isComplex()) { - Entity inline = new EntityImpl(); - inline.setType(navProperties.get(property.getName()).getType()); - for (Property prop : property.asComplex().getValue()) { - inline.getProperties().add(prop); - } - alink.setInlineEntity(inline); - - } else if (property.isCollection()) { + if (property.isCollection()) { EntitySet inline = new EntitySetImpl(); for (Object value : property.asCollection()) { Entity inlineEntity = new EntityImpl(); @@ -1933,6 +1925,14 @@ public abstract class AbstractServices { inline.getEntities().add(inlineEntity); } alink.setInlineEntitySet(inline); + } else if (property.isComplex()) { + Entity inline = new EntityImpl(); + inline.setType(navProperties.get(property.getName()).getType()); + for (Property prop : property.asComplex().getValue()) { + inline.getProperties().add(prop); + } + alink.setInlineEntity(inline); + } else { throw new IllegalStateException("Invalid navigation property " + property); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java index 4e22b0d70..2ae47f1a7 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java @@ -740,13 +740,22 @@ public class ODataBinderImpl implements ODataBinder { // fixes enum values treated as primitive when no type information is available if (client instanceof EdmEnabledODataClient && type != null) { final EdmEnumType edmType = ((EdmEnabledODataClient) client).getEdm(metadataETag).getEnumType(type); - if (valuable.isPrimitive() && edmType != null) { + if (!valuable.isCollection() && valuable.isPrimitive() && edmType != null) { valuable.setValue(ValueType.ENUM, valuable.asPrimitive()); } } ODataValue value = null; - if (valuable.isEnum()) { + + if (valuable.isCollection()) { + value = client.getObjectFactory().newCollectionValue(type == null ? null : "Collection(" + type.toString() + ")"); + + for (Object _value : valuable.asCollection()) { + final Property fake = new PropertyImpl(); + fake.setValue(valuable.getValueType().getBaseType(), _value); + value.asCollection().add(getODataValue(type, fake, contextURL, metadataETag)); + } + } else if (valuable.isEnum()) { value = client.getObjectFactory().newEnumValue(type == null ? null : type.toString(), valuable.asEnum().toString()); } else if (valuable.isComplex()) { @@ -833,15 +842,6 @@ public class ODataBinderImpl implements ODataBinder { } value = cValue; - } else if (valuable.isCollection()) { - value = - client.getObjectFactory().newCollectionValue(type == null ? null : "Collection(" + type.toString() + ")"); - - for (Object _value : valuable.asCollection()) { - final Property fake = new PropertyImpl(); - fake.setValue(valuable.getValueType().getBaseType(), _value); - value.asCollection().add(getODataValue(type, fake, contextURL, metadataETag)); - } } } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Valuable.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Valuable.java index ca660a8a1..78989b3bf 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Valuable.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Valuable.java @@ -30,26 +30,81 @@ public interface Valuable { boolean isNull(); + /** + * Check if Valuable contains a PRIMITIVE or COLLECTION_PRIMITIVE ValueType + * + * @return true if ValueType is a PRIMITIVE or COLLECTION_PRIMITIVE, otherwise false + */ boolean isPrimitive(); + /** + * Check if Valuable contains a GEOSPATIAL or COLLECTION_GEOSPATIAL ValueType + * + * @return true if ValueType is a GEOSPATIAL or COLLECTION_GEOSPATIAL, otherwise false + */ boolean isGeospatial(); + /** + * Check if Valuable contains a ENUM or COLLECTION_ENUM ValueType + * + * @return true if ValueType is a ENUM or COLLECTION_ENUM, otherwise false + */ boolean isEnum(); + /** + * Check if Valuable contains a COMPLEX or COLLECTION_COMPLEX ValueType + * + * @return true if ValueType is a COMPLEX or COLLECTION_COMPLEX, otherwise false + */ boolean isComplex(); + /** + * Check if Valuable contains a COLLECTION_* ValueType + * + * @return true if ValueType is a COLLECTION_*, otherwise false + */ boolean isCollection(); + /** + * Get the value + * + * @return the value + */ Object getValue(); + /** + * Get the value in its primitive representation or null if it is not based on a primitive ValueType + * + * @return primitive representation or null if it is not based on a primitive ValueType + */ Object asPrimitive(); + /** + * Get the value in its enum representation or null if it is not based on a enum ValueType + * + * @return enum representation or null if it is not based on a enum ValueType + */ Object asEnum(); + /** + * Get the value in its geospatial representation or null if it is not based on a geospatial ValueType + * + * @return geospatial representation or null if it is not based on a geospatial ValueType + */ Geospatial asGeospatial(); + /** + * Get the value in its complex representation or null if it is not based on a complex ValueType + * + * @return primitive complex or null if it is not based on a complex ValueType + */ ComplexValue asComplex(); + /** + * Get the value as collection or null if it is not a collection ValueType + * + * @return collection or null if it is not a collection ValueType + */ List asCollection(); void setValue(ValueType valuetype, Object value); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValuable.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValuable.java index 6a5a96f5e..3a0651165 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValuable.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValuable.java @@ -56,21 +56,33 @@ public abstract class AbstractValuable implements Valuable, Annotatable { @Override public boolean isPrimitive() { + if(isCollection()) { + return valueType.getBaseType() == ValueType.PRIMITIVE; + } return valueType == ValueType.PRIMITIVE; } @Override public boolean isGeospatial() { + if(isCollection()) { + return valueType.getBaseType() == ValueType.GEOSPATIAL; + } return valueType == ValueType.GEOSPATIAL; } @Override public boolean isEnum() { + if(isCollection()) { + return valueType.getBaseType() == ValueType.ENUM; + } return valueType == ValueType.ENUM; } @Override public boolean isComplex() { + if(isCollection()) { + return valueType.getBaseType() == ValueType.COMPLEX; + } return valueType == ValueType.COMPLEX; } @@ -81,21 +93,33 @@ public abstract class AbstractValuable implements Valuable, Annotatable { @Override public Object asPrimitive() { + if(isCollection()) { + return null; + } return isPrimitive() ? value : null; } @Override public Geospatial asGeospatial() { + if(isCollection()) { + return null; + } return isGeospatial() ? (Geospatial) value : null; } @Override public Object asEnum() { + if(isCollection()) { + return null; + } return isEnum() ? value : null; } @Override public ComplexValue asComplex() { + if(isCollection()) { + return null; + } return isComplex() ? (ComplexValue) value : null; } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java index 6bd5fbb95..de0600894 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java @@ -141,7 +141,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize value(writer, property.getValueType(), typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(), property.getValue()); - if (!property.isNull() && property.isComplex()) { + if (!property.isNull() && property.isComplex() && !property.isCollection()) { links(writer, property.asComplex().getAssociationLinks()); links(writer, property.asComplex().getNavigationLinks()); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java index f6ddd5879..870cabd68 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java @@ -67,6 +67,8 @@ public class JsonPropertySerializer extends JsonSerializer { if (property.isNull()) { jgen.writeBooleanField(Constants.JSON_NULL, true); + } else if (property.isGeospatial() || property.isCollection()) { + valuable(jgen, property, Constants.VALUE); } else if (property.isPrimitive()) { final EdmTypeInfo typeInfo = property.getType() == null ? null @@ -76,8 +78,6 @@ public class JsonPropertySerializer extends JsonSerializer { primitiveValue(jgen, typeInfo, property.asPrimitive()); } else if (property.isEnum()) { jgen.writeStringField(Constants.VALUE, property.asEnum().toString()); - } else if (property.isGeospatial() || property.isCollection()) { - valuable(jgen, property, Constants.VALUE); } else if (property.isComplex()) { for (Property cproperty : property.asComplex().getValue()) { valuable(jgen, cproperty, cproperty.getName()); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java index 012d3a3d4..fd3fda153 100755 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java @@ -336,6 +336,8 @@ public class JsonSerializer implements ODataSerializer { if (value.isNull()) { jgen.writeNull(); + } else if (value.isCollection()) { + collection(jgen, typeInfo, value.getValueType(), value.asCollection()); } else if (value.isPrimitive()) { primitiveValue(jgen, typeInfo, value.asPrimitive()); } else if (value.isEnum()) { @@ -344,8 +346,6 @@ public class JsonSerializer implements ODataSerializer { jgen.writeStartObject(); geoSerializer.serialize(jgen, value.asGeospatial()); jgen.writeEndObject(); - } else if (value.isCollection()) { - collection(jgen, typeInfo, value.getValueType(), value.asCollection()); } else if (value.isComplex()) { complexValue(jgen, typeInfo, value.asComplex().getValue(), value.asComplex()); } @@ -355,10 +355,12 @@ public class JsonSerializer implements ODataSerializer { throws IOException, EdmPrimitiveTypeException { if (!Constants.VALUE.equals(name) && !(valuable instanceof Annotation) - && !valuable.isComplex() && !valuable.isComplex()) { + && !(valuable.isComplex() && !valuable.isCollection())) { String type = valuable.getType(); - if (StringUtils.isBlank(type) && valuable.isPrimitive() || valuable.isNull()) { + if ((!valuable.isCollection() && + StringUtils.isBlank(type) && + valuable.isPrimitive()) || valuable.isNull()) { type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString(); } if (StringUtils.isNotBlank(type) && format != ODataFormat.JSON_NO_METADATA) {