[OLINGO-1064] ComplexType is deserialized as Primitive Type if the value is NULL
Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
parent
7e262c8d07
commit
272719d59f
|
@ -29,6 +29,7 @@ import static org.junit.Assert.assertTrue;
|
|||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
@ -37,6 +38,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.client.api.EdmEnabledODataClient;
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.ODataClientErrorException;
|
||||
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
|
||||
|
@ -72,7 +74,9 @@ import org.apache.olingo.client.api.domain.ClientServiceDocument;
|
|||
import org.apache.olingo.client.api.domain.ClientValue;
|
||||
import org.apache.olingo.client.api.edm.xml.Reference;
|
||||
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
|
||||
import org.apache.olingo.client.api.serialization.ODataDeserializerException;
|
||||
import org.apache.olingo.client.api.uri.URIBuilder;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.client.core.uri.URIUtils;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmActionImport;
|
||||
|
@ -108,6 +112,9 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
|
|||
private static final String ES_TWO_PRIM = "ESTwoPrim";
|
||||
private static final String ES_KEY_NAV = "ESKeyNav";
|
||||
private static final String ES_MIX_PRIM_COLL_COMP = "ESMixPrimCollComp";
|
||||
private static final String PROPERTY_COMP_NAV = "CollPropertyCompNav";
|
||||
private static final String COL_PROPERTY_COMP = "CollPropertyComp";
|
||||
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
|
||||
|
||||
@Test
|
||||
public void readServiceDocument() {
|
||||
|
@ -1464,4 +1471,107 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
|
|||
|
||||
assertEquals(BigDecimal.valueOf(34), response.getBody().getPrimitiveValue().toValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test1Olingo1064() throws ODataDeserializerException {
|
||||
EdmMetadataRequest request = getClient().getRetrieveRequestFactory().getMetadataRequest(SERVICE_URI);
|
||||
assertNotNull(request);
|
||||
setCookieHeader(request);
|
||||
|
||||
ODataRetrieveResponse<Edm> response = request.execute();
|
||||
saveCookieHeader(response);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
Edm edm = response.getBody();
|
||||
|
||||
EdmEnabledODataClient odataClient = ODataClientFactory.getEdmEnabledClient(SERVICE_URI, edm, null);
|
||||
final InputStream input = Thread.currentThread().getContextClassLoader().
|
||||
getResourceAsStream("ESCompAllPrimWithValueForComplexProperty.json");
|
||||
ClientEntity entity = odataClient.getReader().readEntity(input, ContentType.JSON);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(entity.getProperty(PROPERTY_COMP).getComplexValue());
|
||||
assertEquals("olingo.odata.test1.CTAllPrim", entity.getProperty(PROPERTY_COMP).getComplexValue().getTypeName());
|
||||
assertEquals(PROPERTY_COMP, entity.getProperty(PROPERTY_COMP).getName());
|
||||
assertNull(entity.getProperty(PROPERTY_COMP).getComplexValue().get("PropertyString").getPrimitiveValue());
|
||||
assertNull(entity.getProperty(PROPERTY_COMP).getComplexValue().get("PropertyBoolean").getPrimitiveValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2Olingo1064() throws ODataDeserializerException {
|
||||
EdmMetadataRequest request = getClient().getRetrieveRequestFactory().getMetadataRequest(SERVICE_URI);
|
||||
assertNotNull(request);
|
||||
setCookieHeader(request);
|
||||
|
||||
ODataRetrieveResponse<Edm> response = request.execute();
|
||||
saveCookieHeader(response);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
Edm edm = response.getBody();
|
||||
|
||||
EdmEnabledODataClient odataClient = ODataClientFactory.getEdmEnabledClient(SERVICE_URI, edm, null);
|
||||
final InputStream input = Thread.currentThread().getContextClassLoader().
|
||||
getResourceAsStream("ESCompAllPrimWithNullValueForComplexProperty.json");
|
||||
ClientEntity entity = odataClient.getReader().readEntity(input, ContentType.JSON);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(entity.getProperty(PROPERTY_COMP).getComplexValue());
|
||||
assertEquals("olingo.odata.test1.CTAllPrim", entity.getProperty(PROPERTY_COMP).getComplexValue().getTypeName());
|
||||
assertEquals(PROPERTY_COMP, entity.getProperty(PROPERTY_COMP).getName());
|
||||
assertNull(entity.getProperty(PROPERTY_COMP).getComplexValue().get(PROPERTY_COMP).getComplexValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3Olingo1064() throws ODataDeserializerException {
|
||||
EdmMetadataRequest request = getClient().getRetrieveRequestFactory().getMetadataRequest(SERVICE_URI);
|
||||
assertNotNull(request);
|
||||
setCookieHeader(request);
|
||||
|
||||
ODataRetrieveResponse<Edm> response = request.execute();
|
||||
saveCookieHeader(response);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
Edm edm = response.getBody();
|
||||
|
||||
EdmEnabledODataClient odataClient = ODataClientFactory.getEdmEnabledClient(SERVICE_URI, edm, null);
|
||||
final InputStream input = Thread.currentThread().getContextClassLoader().
|
||||
getResourceAsStream("ESCompAllPrimWithEmptyValueForComplexProperty.json");
|
||||
ClientEntity entity = odataClient.getReader().readEntity(input, ContentType.JSON);
|
||||
assertEquals("olingo.odata.test1.CTAllPrim", entity.getProperty(PROPERTY_COMP).getComplexValue().getTypeName());
|
||||
assertEquals(PROPERTY_COMP, entity.getProperty(PROPERTY_COMP).getName());
|
||||
assertTrue(entity.getProperty(PROPERTY_COMP).getComplexValue().asJavaMap().size() == 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void test4Olingo1064() throws ODataDeserializerException {
|
||||
EdmMetadataRequest request = getClient().getRetrieveRequestFactory().getMetadataRequest(SERVICE_URI);
|
||||
assertNotNull(request);
|
||||
setCookieHeader(request);
|
||||
|
||||
ODataRetrieveResponse<Edm> response = request.execute();
|
||||
saveCookieHeader(response);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
Edm edm = response.getBody();
|
||||
|
||||
EdmEnabledODataClient odataClient = ODataClientFactory.getEdmEnabledClient(SERVICE_URI, edm, null);
|
||||
final InputStream input = Thread.currentThread().getContextClassLoader().
|
||||
getResourceAsStream("ESTwoKeyNavWithNestedComplexTypes.json");
|
||||
ClientEntity entity = odataClient.getReader().readEntity(input, ContentType.JSON);
|
||||
assertEquals("olingo.odata.test1.CTPrimComp", entity.getProperty(PROPERTY_COMP).getComplexValue().getTypeName());
|
||||
assertEquals(PROPERTY_COMP, entity.getProperty(PROPERTY_COMP).getName());
|
||||
Map<String, Object> map = entity.getProperty(PROPERTY_COMP).getComplexValue().asJavaMap();
|
||||
assertEquals(map.size(), 2);
|
||||
assertEquals(((Map<String, Object>)map.get(PROPERTY_COMP)).size(), 16);
|
||||
assertNull(entity.getProperty(PROPERTY_COMP_NAV).getComplexValue().get(PROPERTY_COMP_NAV).getComplexValue());
|
||||
assertEquals("Collection(olingo.odata.test1.CTPrimComp)", entity.getProperty(COL_PROPERTY_COMP).
|
||||
getCollectionValue().getTypeName());
|
||||
assertEquals(0, entity.getProperty(COL_PROPERTY_COMP).getCollectionValue().size());
|
||||
assertEquals("olingo.odata.test1.CTNavFiveProp", entity.getProperty(PROPERTY_COMP_NAV).
|
||||
getComplexValue().getTypeName());
|
||||
assertEquals("olingo.odata.test1.CTTwoPrim", entity.getProperty(PROPERTY_COMP_TWO_PRIM).
|
||||
getComplexValue().getTypeName());
|
||||
assertNull(entity.getProperty(PROPERTY_COMP_TWO_PRIM).getComplexValue().
|
||||
get(PROPERTY_COMP_TWO_PRIM).getComplexValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"@odata.context": "$metadata#ESCompAllPrim/$entity",
|
||||
"@odata.metadataEtag": "W/\"2010a206-ee09-4cfb-9087-df530cdbb6ea\"",
|
||||
"@odata.etag": "W/\"-32768\"",
|
||||
"PropertyInt16": -32768,
|
||||
"PropertyComp": {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"@odata.context": "$metadata#ESCompAllPrim/$entity",
|
||||
"@odata.metadataEtag": "W/\"2010a206-ee09-4cfb-9087-df530cdbb6ea\"",
|
||||
"@odata.etag": "W/\"-32768\"",
|
||||
"PropertyInt16": -32768,
|
||||
"PropertyComp": null
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"@odata.context": "$metadata#ESCompAllPrim/$entity",
|
||||
"@odata.metadataEtag": "W/\"2010a206-ee09-4cfb-9087-df530cdbb6ea\"",
|
||||
"@odata.etag": "W/\"-32768\"",
|
||||
"PropertyInt16": -32768,
|
||||
"PropertyComp": { "PropertyString": null, "PropertyBoolean": null }
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"@odata.context": "../$metadata#ESTwoKeyNav",
|
||||
"@odata.metadataEtag": "W/\"e5db7a43-370a-44d7-9600-9f0443e6e351\"",
|
||||
"PropertyInt16": 1,
|
||||
"PropertyString": "2",
|
||||
"PropertyComp": {
|
||||
"PropertyInt16": 11,
|
||||
"PropertyComp": {
|
||||
"PropertyString": "StringValue",
|
||||
"PropertyBinary": "ASNFZ4mrze8=",
|
||||
"PropertyBoolean": true,
|
||||
"PropertyByte": 255,
|
||||
"PropertyDate": "2012-12-03",
|
||||
"PropertyDateTimeOffset": null,
|
||||
"PropertyDecimal": 34,
|
||||
"PropertySingle": 17900000,
|
||||
"PropertyDouble": -17900000,
|
||||
"PropertyDuration": "PT6S",
|
||||
"PropertyGuid": "01234567-89ab-cdef-0123-456789abcdef",
|
||||
"PropertyInt16": 32767,
|
||||
"PropertyInt32": 2147483647,
|
||||
"PropertyInt64": 9223372036854775807,
|
||||
"PropertySByte": 127,
|
||||
"PropertyTimeOfDay": "21:05:59"
|
||||
}
|
||||
},
|
||||
"PropertyCompNav": {
|
||||
"PropertyInt16": 1,
|
||||
"PropertyComp": null
|
||||
},
|
||||
"CollPropertyComp": [],
|
||||
"CollPropertyCompNav": null,
|
||||
"CollPropertyString": [
|
||||
"1",
|
||||
"2"
|
||||
],
|
||||
"PropertyCompTwoPrim": null
|
||||
}
|
|
@ -874,31 +874,40 @@ public class ODataBinderImpl implements ODataBinder {
|
|||
: EdmPrimitiveTypeKind.valueOfFQN(type.toString())).
|
||||
build();
|
||||
} else if (valuable.isPrimitive() || valuable.getValueType() == null) {
|
||||
// fixes non-string values treated as string when no type information is available at de-serialization level
|
||||
if (type != null && !EdmPrimitiveTypeKind.String.getFullQualifiedName().equals(type)
|
||||
&& EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace())
|
||||
&& valuable.asPrimitive() instanceof String) {
|
||||
|
||||
final EdmPrimitiveType primitiveType =
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.valueOf(type.getName()));
|
||||
final Class<?> returnType = primitiveType.getDefaultType().isAssignableFrom(Calendar.class)
|
||||
? Timestamp.class : primitiveType.getDefaultType();
|
||||
try {
|
||||
valuable.setValue(valuable.getValueType(),
|
||||
primitiveType.valueOfString(valuable.asPrimitive().toString(),
|
||||
null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null,
|
||||
returnType));
|
||||
} catch (EdmPrimitiveTypeException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
// fixes non-string values treated as string when no type information is available at de-serialization level
|
||||
Edm edm = null;
|
||||
if (client instanceof EdmEnabledODataClient && type != null) {
|
||||
edm = ((EdmEnabledODataClient) client).getEdm(metadataETag);
|
||||
}
|
||||
if (edm != null && edm.getComplexType(type) != null) {
|
||||
ClientComplexValue cValue = client.getObjectFactory().newComplexValue(type.toString());
|
||||
cValue.add(new ClientPropertyImpl(((Property)valuable).getName(), null));
|
||||
value = cValue;
|
||||
} else {
|
||||
if (type != null && !EdmPrimitiveTypeKind.String.getFullQualifiedName().equals(type)
|
||||
&& EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace())
|
||||
&& valuable.asPrimitive() instanceof String) {
|
||||
|
||||
value = client.getObjectFactory().newPrimitiveValueBuilder().
|
||||
setValue(valuable.asPrimitive()).
|
||||
setType(type == null || !EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace())
|
||||
? null
|
||||
: EdmPrimitiveTypeKind.valueOfFQN(type.toString())).
|
||||
build();
|
||||
final EdmPrimitiveType primitiveType =
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.valueOf(type.getName()));
|
||||
final Class<?> returnType = primitiveType.getDefaultType().isAssignableFrom(Calendar.class)
|
||||
? Timestamp.class : primitiveType.getDefaultType();
|
||||
try {
|
||||
valuable.setValue(valuable.getValueType(),
|
||||
primitiveType.valueOfString(valuable.asPrimitive().toString(),
|
||||
null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null,
|
||||
returnType));
|
||||
} catch (EdmPrimitiveTypeException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
value = client.getObjectFactory().newPrimitiveValueBuilder().
|
||||
setValue(valuable.asPrimitive()).
|
||||
setType(type == null || !EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace())
|
||||
? null
|
||||
: EdmPrimitiveTypeKind.valueOfFQN(type.toString())).
|
||||
build();
|
||||
}
|
||||
} else if (valuable.isComplex()) {
|
||||
final ClientComplexValue cValue =
|
||||
client.getObjectFactory().newComplexValue(type == null ? null : type.toString());
|
||||
|
|
Loading…
Reference in New Issue