Contained entity CRUD tests

This commit is contained in:
Francesco Chicchiriccò 2014-04-15 18:41:53 +02:00
parent 68f27d57a1
commit 4376658343
22 changed files with 384 additions and 196 deletions

View File

@ -20,19 +20,6 @@ package org.apache.olingo.fit;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.core.data.AtomFeedImpl;
import org.apache.olingo.commons.core.data.LinkImpl;
import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.serializer.JsonFeedContainer;
import org.apache.olingo.fit.serializer.JsonEntryContainer;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.DataBinder;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -83,6 +70,12 @@ import org.apache.olingo.commons.api.data.Container;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.core.data.AtomFeedImpl;
import org.apache.olingo.commons.core.data.LinkImpl;
import org.apache.olingo.commons.core.data.AtomEntryImpl;
import org.apache.olingo.commons.core.data.AtomPropertyImpl;
import org.apache.olingo.commons.core.data.AtomSerializer;
@ -98,12 +91,17 @@ import org.apache.olingo.fit.methods.PATCH;
import org.apache.olingo.fit.serializer.FITAtomDeserializer;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.FSManager;
import org.apache.olingo.fit.utils.Commons;
import org.apache.olingo.fit.utils.AbstractJSONUtilities;
import org.apache.olingo.fit.utils.AbstractUtilities;
import org.apache.olingo.fit.utils.AbstractXMLUtilities;
import org.apache.olingo.fit.utils.LinkInfo;
import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.serializer.JsonFeedContainer;
import org.apache.olingo.fit.serializer.JsonEntryContainer;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.DataBinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -114,9 +112,9 @@ public abstract class AbstractServices {
*/
protected static final Logger LOG = LoggerFactory.getLogger(AbstractServices.class);
private Pattern requestPatter = Pattern.compile("(.*) (http://.*) HTTP/.*");
private static final Pattern REQUEST_PATTERN = Pattern.compile("(.*) (http://.*) HTTP/.*");
private static final String boundary = "batch_243234_25424_ef_892u748";
private static final String BOUNDARY = "batch_243234_25424_ef_892u748";
protected final ODataServiceVersion version;
@ -193,10 +191,10 @@ public abstract class AbstractServices {
@POST
@Path("/$batch")
@Consumes("multipart/mixed")
@Produces("application/octet-stream; boundary=" + boundary)
@Produces("application/octet-stream; boundary=" + BOUNDARY)
public Response batch(final @Multipart MultipartBody attachment) {
try {
return xml.createBatchResponse(exploreMultipart(attachment.getAllAttachments(), boundary), boundary);
return xml.createBatchResponse(exploreMultipart(attachment.getAllAttachments(), BOUNDARY), BOUNDARY);
} catch (IOException e) {
return xml.createFaultResponse(Accept.XML.toString(version), e);
}
@ -209,7 +207,7 @@ public abstract class AbstractServices {
Header header = en.nextElement();
final String request = header.getName() + ":" + header.getValue();
final Matcher matcher = requestPatter.matcher(request);
final Matcher matcher = REQUEST_PATTERN.matcher(request);
if (matcher.find()) {
final MultivaluedMap<String, String> headers = new MultivaluedHashMap<String, String>();
@ -343,7 +341,7 @@ public abstract class AbstractServices {
bos.write(Constants.CRLF);
for (Map.Entry<String, List<Object>> header : response.getHeaders().entrySet()) {
StringBuilder builder = new StringBuilder();
final StringBuilder builder = new StringBuilder();
for (Object value : header.getValue()) {
if (builder.length() > 0) {
builder.append(", ");
@ -593,7 +591,7 @@ public abstract class AbstractServices {
} else {
final Container<JSONEntryImpl> jcontainer =
mapper.readValue(IOUtils.toInputStream(entity), new TypeReference<JSONEntryImpl>() {
});
});
entry = (new DataBinder(version)).
getAtomEntry(jcontainer.getObject());
@ -666,13 +664,13 @@ public abstract class AbstractServices {
replaceAll("\"Salary\":[0-9]*,", "\"Salary\":0,").
replaceAll("\"Title\":\".*\"", "\"Title\":\"[Sacked]\"").
replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>.*\\</d:Salary\\>",
"<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
"<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
replaceAll("\\<d:Title\\>.*\\</d:Title\\>", "<d:Title>[Sacked]</d:Title>");
final FSManager fsManager = FSManager.instance(version);
fsManager.putInMemory(IOUtils.toInputStream(newContent, "UTF-8"),
fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
ConstantKey.ENTITY), utils.getKey()));
ConstantKey.ENTITY), utils.getKey()));
return utils.getValue().createResponse(null, null, utils.getKey(), Response.Status.NO_CONTENT);
} catch (Exception e) {
@ -724,9 +722,9 @@ public abstract class AbstractServices {
final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
newContent = newContent.
replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
"\"Salary\":" + newSalary + ",").
"\"Salary\":" + newSalary + ",").
replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
"<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
"<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
}
FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, "UTF-8"),
@ -858,7 +856,7 @@ public abstract class AbstractServices {
mapper.writeValue(
writer, new JsonFeedContainer<JSONFeedImpl>(container.getContextURL(), container.getMetadataETag(),
new DataBinder(version).getJsonFeed(container.getObject())));
new DataBinder(version).getJsonFeed(container.getObject())));
}
return xml.createResponse(new ByteArrayInputStream(content.toByteArray()),
@ -1040,7 +1038,7 @@ public abstract class AbstractServices {
final ObjectMapper mapper = Commons.getJsonMapper(version);
mapper.writeValue(
writer, new JsonEntryContainer<JSONEntryImpl>(container.getContextURL(), container.getMetadataETag(),
(new DataBinder(version)).getJsonEntry((AtomEntryImpl) container.getObject())));
(new DataBinder(version)).getJsonEntry((AtomEntryImpl) container.getObject())));
}
return xml.createResponse(new ByteArrayInputStream(content.toByteArray()),
@ -1469,27 +1467,50 @@ public abstract class AbstractServices {
private Response navigateEntity(
final Accept acceptType,
String entitySetName,
String entityId,
String path) throws Exception {
final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
final LinkInfo linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.XML);
final Map.Entry<String, List<String>> links = xml.extractLinkURIs(linkInfo.getLinks());
final String entitySetName,
final String entityId,
final String path) throws Exception {
final LinkInfo linkInfo;
InputStream stream;
if (version.compareTo(ODataServiceVersion.V30) <= 0) {
linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.XML);
final Map.Entry<String, List<String>> links = xml.extractLinkURIs(linkInfo.getLinks());
switch (acceptType) {
case JSON:
case JSON_FULLMETA:
case JSON_NOMETA:
stream = json.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
stream = json.wrapJsonEntities(stream);
break;
default:
stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
switch (acceptType) {
case JSON:
case JSON_FULLMETA:
case JSON_NOMETA:
stream = json.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
stream = json.wrapJsonEntities(stream);
break;
default:
stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
}
} else {
linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.ATOM);
if (acceptType == Accept.ATOM) {
stream = linkInfo.getLinks();
} else {
final FITAtomDeserializer atomDeserializer = Commons.getAtomDeserializer(version);
final DataBinder dataBinder = new DataBinder(version);
final ObjectMapper mapper = Commons.getJsonMapper(version);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final Object object;
if (linkInfo.isFeed()) {
final Container<AtomFeedImpl> container = atomDeserializer.read(linkInfo.getLinks(), AtomFeedImpl.class);
object = dataBinder.getJsonFeed(container.getObject());
} else {
final Container<AtomEntryImpl> container = atomDeserializer.read(linkInfo.getLinks(), AtomEntryImpl.class);
object = dataBinder.getJsonEntry(container.getObject());
}
mapper.writeValue(baos, object);
stream = new ByteArrayInputStream(baos.toByteArray());
}
}
final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
return xml.createResponse(stream, Commons.getETag(basePath, version), acceptType);
}

View File

@ -223,7 +223,7 @@ public class V4Services extends AbstractServices {
final ObjectMapper mapper = Commons.getJsonMapper(version);
final DataBinder dataBinder = new DataBinder(version);
Container<JSONEntryImpl> jsonContainer = mapper.readValue(IOUtils.toInputStream(changes),
final Container<JSONEntryImpl> jsonContainer = mapper.readValue(IOUtils.toInputStream(changes),
new TypeReference<JSONEntryImpl>() {
});
jsonContainer.getObject().setType(typeInfo.getFullQualifiedName().toString());
@ -243,7 +243,6 @@ public class V4Services extends AbstractServices {
return xml.createResponse(null, null, acceptType, Response.Status.NO_CONTENT);
} catch (Exception e) {
e.printStackTrace();
return xml.createFaultResponse(accept, e);
}
}

View File

@ -359,7 +359,7 @@ public abstract class AbstractJSONUtilities extends AbstractUtilities {
node.set(Constants.get(version, ConstantKey.JSON_NEXTLINK_NAME), new TextNode(next));
}
return IOUtils.toInputStream(node.toString(), "UTf-8");
return IOUtils.toInputStream(node.toString(), "UTF-8");
}
@Override

View File

@ -365,7 +365,7 @@ public abstract class AbstractUtilities {
fsManager.putInMemory(
IOUtils.toInputStream(entity), fsManager.getAbsolutePath(path + Constants.get(version, ConstantKey.ENTITY),
Accept.JSON_FULLMETA));
Accept.JSON_FULLMETA));
// -----------------------------------------
return readEntity(entitySetName, entityKey, getDefaultFormat()).getValue();
@ -415,7 +415,6 @@ public abstract class AbstractUtilities {
}
public Response createBatchResponse(final InputStream stream, final String boundary) {
final Response.ResponseBuilder builder = Response.accepted(stream);
builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
return builder.build();
@ -423,6 +422,7 @@ public abstract class AbstractUtilities {
public Response createResponse(
final InputStream entity, final String etag, final Accept accept, final Response.Status status) {
final Response.ResponseBuilder builder = Response.ok();
if (version.compareTo(ODataServiceVersion.V30) <= 0) {
builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
@ -444,8 +444,8 @@ public abstract class AbstractUtilities {
try {
final InputStream toBeStreamedBack;
if (accept != null && (Accept.JSON == accept || Accept.JSON_NOMETA == accept)) {
toBeStreamedBack = Commons.changeFormat(entity, accept);
if (Accept.JSON == accept || Accept.JSON_NOMETA == accept) {
toBeStreamedBack = Commons.changeFormat(entity, version, accept);
} else {
toBeStreamedBack = entity;
}
@ -685,10 +685,10 @@ public abstract class AbstractUtilities {
}
public String getLinksBasePath(final String entitySetName, final String entityId) {
return entitySetName + File.separatorChar + Commons.getEntityKey(entityId) + File.separatorChar
+ Constants.get(version, ConstantKey.LINKS_FILE_PATH) + File.separatorChar;
return entitySetName + File.separatorChar + Commons.getEntityKey(entityId) + File.separatorChar
+ Constants.get(version, ConstantKey.LINKS_FILE_PATH) + File.separatorChar;
}
/**
* Retrieves entity links about the given link name.
*

View File

@ -251,7 +251,7 @@ public abstract class Commons {
return IOUtils.toInputStream(links.toString(), "UTf-8");
}
public static InputStream changeFormat(final InputStream is, final Accept target) {
public static InputStream changeFormat(final InputStream is, final ODataServiceVersion version, final Accept target) {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
@ -260,7 +260,7 @@ public abstract class Commons {
final ObjectMapper mapper = new ObjectMapper();
final JsonNode node =
changeFormat((ObjectNode) mapper.readTree(new ByteArrayInputStream(bos.toByteArray())), target);
changeFormat((ObjectNode) mapper.readTree(new ByteArrayInputStream(bos.toByteArray())), version, target);
return IOUtils.toInputStream(node.toString(), "UTF-8");
} catch (Exception e) {
@ -272,30 +272,35 @@ public abstract class Commons {
}
@SuppressWarnings("fallthrough")
public static JsonNode changeFormat(final ObjectNode node, final Accept target) {
public static JsonNode changeFormat(final ObjectNode node, final ODataServiceVersion version, final Accept target) {
final List<String> toBeRemoved = new ArrayList<String>();
final Map<String, JsonNode> toBeReplaced = new HashMap<String, JsonNode>();
switch (target) {
case JSON_NOMETA:
// nometa + minimal
toBeRemoved.add(Constants.get(ConstantKey.JSON_ODATAMETADATA_NAME));
toBeRemoved.add(Constants.get(version, ConstantKey.JSON_ODATAMETADATA_NAME));
case JSON:
// minimal
toBeRemoved.add(Constants.get(ConstantKey.JSON_EDITLINK_NAME));
toBeRemoved.add(Constants.get(ConstantKey.JSON_ID_NAME));
toBeRemoved.add(Constants.get(ConstantKey.JSON_TYPE_NAME));
toBeRemoved.add(Constants.get(version, ConstantKey.JSON_EDITLINK_NAME));
toBeRemoved.add(Constants.get(version, ConstantKey.JSON_ID_NAME));
toBeRemoved.add(Constants.get(version, ConstantKey.JSON_TYPE_NAME));
final Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
while (fields.hasNext()) {
final Map.Entry<String, JsonNode> field = fields.next();
if (field.getKey().endsWith(Constants.get(ConstantKey.JSON_MEDIA_SUFFIX))
|| field.getKey().endsWith(Constants.get(ConstantKey.JSON_NAVIGATION_SUFFIX))
|| field.getKey().endsWith(Constants.get(ConstantKey.JSON_TYPE_SUFFIX))) {
if (field.getKey().endsWith(Constants.get(version, ConstantKey.JSON_MEDIA_SUFFIX))
|| field.getKey().endsWith(Constants.get(version, ConstantKey.JSON_NAVIGATION_SUFFIX))
|| field.getKey().endsWith(Constants.get(version, ConstantKey.JSON_TYPE_SUFFIX))) {
toBeRemoved.add(field.getKey());
} else if (field.getValue().isObject()) {
toBeReplaced.put(field.getKey(), changeFormat((ObjectNode) field.getValue(), target));
changeFormat((ObjectNode) field.getValue(), version, target);
} else if (field.getValue().isArray()) {
for (final Iterator<JsonNode> subItor = field.getValue().elements(); subItor.hasNext();) {
final JsonNode subNode = subItor.next();
if (subNode.isObject()) {
changeFormat((ObjectNode) subNode, version, target);
}
}
}
}
case JSON_FULLMETA:
@ -305,14 +310,7 @@ public abstract class Commons {
default:
throw new UnsupportedOperationException(target.name());
}
for (String field : toBeRemoved) {
node.remove(field);
}
for (Map.Entry<String, JsonNode> field : toBeReplaced.entrySet()) {
node.replace(field.getKey(), field.getValue());
}
node.remove(toBeRemoved);
return node;
}

View File

@ -41,6 +41,8 @@ public class Constants {
// -----------------------------
// V4 only
// -----------------------------
v4constants.put(ConstantKey.JSON_ID_NAME, "@odata.id");
v4constants.put(ConstantKey.JSON_TYPE_NAME, "@odata.type");
v4constants.put(ConstantKey.JSON_NAVIGATION_SUFFIX, "@odata.navigationLink");
v4constants.put(ConstantKey.DATASERVICES_NS, "http://docs.oasis-open.org/odata/ns/dataservices");
v4constants.put(ConstantKey.METADATA_NS, "http://docs.oasis-open.org/odata/ns/metadata");

View File

@ -203,20 +203,20 @@ public class DataBinder {
public JSONPropertyImpl getJsonProperty(final AtomPropertyImpl atomproperty) {
final JSONPropertyImpl jsonproperty = new JSONPropertyImpl();
BeanUtils.copyProperties(atomproperty, jsonproperty, "value");
if (atomproperty.getValue() instanceof ComplexValueImpl) {
if (atomproperty.getValue().isComplex()) {
final ComplexValueImpl complex = new ComplexValueImpl();
jsonproperty.setValue(complex);
for (Property field : atomproperty.getValue().asComplex().get()) {
complex.get().add(getJsonProperty((AtomPropertyImpl) field));
}
} else if (atomproperty.getValue() instanceof CollectionValueImpl) {
} else if (atomproperty.getValue().isCollection()) {
final CollectionValueImpl collection = new CollectionValueImpl();
jsonproperty.setValue(collection);
for (Value element : atomproperty.getValue().asCollection().get()) {
if (element instanceof ComplexValueImpl) {
if (element.isComplex()) {
final ComplexValueImpl complex = new ComplexValueImpl();
collection.get().add(complex);

View File

@ -21,9 +21,9 @@
-->
<entry xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts(101)/MyPaymentInstruments/$entity">
<category term="#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/TheStoredPI"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BillingStatements"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BackupStoredPI"/>
<id/>
<title/>
<updated>2014-04-14T12:47:37Z</updated>

View File

@ -25,9 +25,9 @@
<updated>2014-04-14T12:45:33Z</updated>
<entry>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/TheStoredPI"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BillingStatements"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BackupStoredPI"/>
<id/>
<title/>
<updated>2014-04-14T12:45:33Z</updated>
@ -44,10 +44,10 @@
</entry>
<entry>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/CreditRecords" type="application/atom+xml;type=feed" title="CreditRecords" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/TheStoredPI"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BillingStatements"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BackupStoredPI"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/CreditRecords" type="application/atom+xml;type=feed" title="CreditRecords" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/CreditRecords"/>
<id/>
<title/>
<updated>2014-04-14T12:45:33Z</updated>
@ -69,10 +69,10 @@
</entry>
<entry>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/CreditRecords" type="application/atom+xml;type=feed" title="CreditRecords" href="potato"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/TheStoredPI"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BillingStatements"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BackupStoredPI"/>
<link rel="http://docs.oasis-open.org/odata/ns/related/CreditRecords" type="application/atom+xml;type=feed" title="CreditRecords" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/CreditRecords"/>
<id/>
<title/>
<updated>2014-04-14T12:45:33Z</updated>

View File

@ -58,6 +58,10 @@
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
@ -70,10 +74,27 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<systemPropertyVariables>
<propertyName>org.slf4j.simpleLogger.defaultLogLevel</propertyName>
<org.slf4j.simpleLogger.defaultLogLevel>ERROR</org.slf4j.simpleLogger.defaultLogLevel>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<systemPropertyVariables>
<propertyName>org.slf4j.simpleLogger.defaultLogLevel</propertyName>
<org.slf4j.simpleLogger.defaultLogLevel>DEBUG</org.slf4j.simpleLogger.defaultLogLevel>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>

View File

@ -0,0 +1,98 @@
/*
* 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.client.core.it;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.core.data.AtomEntryImpl;
import org.apache.olingo.commons.core.data.JSONEntryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractBaseTestITCase {
/**
* Logger.
*/
protected static final Logger LOG = LoggerFactory.getLogger(AbstractBaseTestITCase.class);
@SuppressWarnings("rawtypes")
protected abstract CommonODataClient getClient();
protected void debugEntry(final Entry entry, final String message) {
if (LOG.isDebugEnabled()) {
final StringWriter writer = new StringWriter();
getClient().getSerializer().entry(entry, writer);
writer.flush();
LOG.debug(message + "\n{}", writer.toString());
}
}
protected void debugFeed(final Feed feed, final String message) {
if (LOG.isDebugEnabled()) {
final StringWriter writer = new StringWriter();
getClient().getSerializer().feed(feed, writer);
writer.flush();
LOG.debug(message + "\n{}", writer.toString());
}
}
protected void debugODataProperty(final CommonODataProperty property, final String message) {
LOG.debug(message + "\n{}", property.toString());
}
protected void debugODataValue(final ODataValue value, final String message) {
LOG.debug(message + "\n{}", value.toString());
}
protected void debugODataEntity(final CommonODataEntity entity, final String message) {
if (LOG.isDebugEnabled()) {
StringWriter writer = new StringWriter();
getClient().getSerializer().entry(getClient().getBinder().getEntry(entity, AtomEntryImpl.class), writer);
writer.flush();
LOG.debug(message + " (Atom)\n{}", writer.toString());
writer = new StringWriter();
getClient().getSerializer().entry(getClient().getBinder().getEntry(entity, JSONEntryImpl.class), writer);
writer.flush();
LOG.debug(message + " (JSON)\n{}", writer.toString());
}
}
protected void debugInputStream(final InputStream input, final String message) {
if (LOG.isDebugEnabled()) {
try {
LOG.debug(message + "\n{}", IOUtils.toString(input));
} catch (IOException e) {
LOG.error("Error writing stream", e);
} finally {
IOUtils.closeQuietly(input);
}
}
}
}

View File

@ -22,6 +22,7 @@ import org.apache.olingo.client.api.CommonODataClient;
public abstract class AbstractMetadataTestITCase {
@SuppressWarnings("rawtypes")
protected abstract CommonODataClient getClient();
protected String getTestServiceRoot() {

View File

@ -26,8 +26,6 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
@ -36,7 +34,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
@ -52,9 +49,8 @@ import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.client.api.v3.ODataClient;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.client.core.it.AbstractBaseTestITCase;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
@ -68,19 +64,9 @@ import org.apache.olingo.commons.api.domain.v3.ODataEntity;
import org.apache.olingo.commons.api.domain.v3.ODataProperty;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataPubFormat;
import org.apache.olingo.commons.core.data.AtomEntryImpl;
import org.apache.olingo.commons.core.data.JSONEntryImpl;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractTestITCase {
/**
* Logger.
*/
protected static final Logger LOG = LoggerFactory.getLogger(AbstractTestITCase.class);
public abstract class AbstractTestITCase extends AbstractBaseTestITCase {
protected static final FullQualifiedName TEST_PRODUCT_TYPE =
new FullQualifiedName("Microsoft.Test.OData.Services.AstoriaDefaultService.Product");
@ -114,6 +100,7 @@ public abstract class AbstractTestITCase {
client = ODataClientFactory.getV3();
}
@Override
protected ODataClient getClient() {
return client;
}
@ -307,58 +294,6 @@ public abstract class AbstractTestITCase {
return entity;
}
protected void debugEntry(final Entry entry, final String message) {
if (LOG.isDebugEnabled()) {
final StringWriter writer = new StringWriter();
getClient().getSerializer().entry(entry, writer);
writer.flush();
LOG.debug(message + "\n{}", writer.toString());
}
}
protected void debugFeed(final Feed feed, final String message) {
if (LOG.isDebugEnabled()) {
final StringWriter writer = new StringWriter();
getClient().getSerializer().feed(feed, writer);
writer.flush();
LOG.debug(message + "\n{}", writer.toString());
}
}
protected void debugODataProperty(final ODataProperty property, final String message) {
LOG.debug(message + "\n{}", property.toString());
}
protected void debugODataValue(final ODataValue value, final String message) {
LOG.debug(message + "\n{}", value.toString());
}
protected void debugODataEntity(final ODataEntity entity, final String message) {
if (LOG.isDebugEnabled()) {
StringWriter writer = new StringWriter();
getClient().getSerializer().entry(getClient().getBinder().getEntry(entity, AtomEntryImpl.class), writer);
writer.flush();
LOG.debug(message + " (Atom)\n{}", writer.toString());
writer = new StringWriter();
getClient().getSerializer().entry(getClient().getBinder().getEntry(entity, JSONEntryImpl.class), writer);
writer.flush();
LOG.debug(message + " (JSON)\n{}", writer.toString());
}
}
protected void debugInputStream(final InputStream input, final String message) {
if (LOG.isDebugEnabled()) {
try {
LOG.debug(message + "\n{}", IOUtils.toString(input));
} catch (IOException e) {
LOG.error("Error writing stream", e);
} finally {
IOUtils.closeQuietly(input);
}
}
}
protected String getETag(final URI uri) {
final ODataRetrieveResponse<ODataEntity> res = getClient().getRetrieveRequestFactory().
getEntityRequest(uri).execute();

View File

@ -27,15 +27,12 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRe
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.v4.ODataClient;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.client.core.it.AbstractBaseTestITCase;
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
import org.apache.olingo.commons.api.format.ODataPubFormat;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractTestITCase {
protected static final Logger LOG = LoggerFactory.getLogger(AbstractTestITCase.class);
public abstract class AbstractTestITCase extends AbstractBaseTestITCase {
protected static ODataClient client;
@ -60,6 +57,7 @@ public abstract class AbstractTestITCase {
client = ODataClientFactory.getV4();
}
@Override
protected ODataClient getClient() {
return client;
}

View File

@ -21,20 +21,51 @@ package org.apache.olingo.client.core.it.v4;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.util.Calendar;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
import org.apache.olingo.commons.api.domain.ODataCollectionValue;
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
import org.apache.olingo.commons.api.domain.v4.ODataProperty;
import org.apache.olingo.commons.api.domain.v4.ODataValue;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataPubFormat;
import org.apache.olingo.commons.core.domain.v4.ODataEntityImpl;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
public class EntityCreateTestITCase extends AbstractTestITCase {
private void createOrder(final ODataPubFormat format, final int id) {
private static final String serviceRoot = "http://odatae2etest.azurewebsites.net/javatest/DefaultService";
// TODO: remove once fit provides contained entity CRUD
@BeforeClass
public static void checkServerIsOnline() throws IOException {
final Socket socket = new Socket();
boolean reachable = false;
try {
socket.connect(new InetSocketAddress("odatae2etest.azurewebsites.net", 80), 2000);
reachable = true;
} catch (Exception e) {
LOG.warn("External test service not reachable, ignoring this whole class: {}",
OperationImportInvokeTestITCase.class.getName());
} finally {
IOUtils.closeQuietly(socket);
}
Assume.assumeTrue(reachable);
}
private void order(final ODataPubFormat format, final int id) {
final ODataEntity order = new ODataEntityImpl(
new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.Order"));
@ -73,11 +104,67 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
@Test
public void atom() {
createOrder(ODataPubFormat.ATOM, 1000);
order(ODataPubFormat.ATOM, 1000);
}
@Test
public void json() {
createOrder(ODataPubFormat.JSON, 1001);
order(ODataPubFormat.JSON, 1001);
}
private void onContained(final ODataPubFormat format) {
final URI uri = getClient().getURIBuilder(serviceRoot).appendEntitySetSegment("Accounts").appendKeySegment(101).
appendNavigationSegment("MyPaymentInstruments").build();
// 1. read contained collection before any operation
ODataEntitySet instruments = getClient().getRetrieveRequestFactory().getEntitySetRequest(uri).execute().getBody();
assertNotNull(instruments);
final int sizeBefore = instruments.getCount();
// 2. instantiate an ODataEntity of the same type as the collection above
final ODataEntity instrument = getClient().getObjectFactory().
newEntity(new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument"));
int id = RandomUtils.nextInt(101999, 105000);
instrument.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("PaymentInstrumentID",
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(id)));
instrument.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("FriendlyName",
getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("New one")));
instrument.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("CreatedDate",
getClient().getObjectFactory().newPrimitiveValueBuilder().
setType(EdmPrimitiveTypeKind.DateTimeOffset).setValue(Calendar.getInstance()).build()));
// 3. create it as contained entity
final ODataEntityCreateRequest<ODataEntity> req = getClient().getCUDRequestFactory().
getEntityCreateRequest(uri, instrument);
final ODataEntityCreateResponse<ODataEntity> res = req.execute();
assertEquals(201, res.getStatusCode());
// 4. verify that the contained collection effectively grew
instruments = getClient().getRetrieveRequestFactory().getEntitySetRequest(uri).execute().getBody();
assertNotNull(instruments);
final int sizeAfter = instruments.getCount();
assertEquals(sizeBefore + 1, sizeAfter);
// 5. remove the contained entity created above
final ODataDeleteResponse deleteRes = getClient().getCUDRequestFactory().
getDeleteRequest(getClient().getURIBuilder(uri.toASCIIString()).appendKeySegment(id).build()).execute();
assertEquals(204, deleteRes.getStatusCode());
// 6. verify that the contained collection effectively reduced
instruments = getClient().getRetrieveRequestFactory().getEntitySetRequest(uri).execute().getBody();
assertNotNull(instruments);
final int sizeEnd = instruments.getCount();
assertEquals(sizeBefore, sizeEnd);
}
@Test
public void atomOnContained() {
onContained(ODataPubFormat.ATOM);
}
@Test
public void jsonOnContained() {
onContained(ODataPubFormat.JSON);
}
}

View File

@ -60,6 +60,7 @@ public class AtomTest extends JSONTest {
return result.toString();
}
@Override
protected void assertSimilar(final String filename, final String actual) throws Exception {
final Diff diff = new Diff(cleanup(IOUtils.toString(getClass().getResourceAsStream(filename))), actual);
diff.overrideElementQualifier(new AtomLinksQualifier());

View File

@ -33,6 +33,7 @@ import org.apache.olingo.commons.api.data.CollectionValue;
import org.apache.olingo.commons.api.data.Entry;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Linked;
import org.apache.olingo.commons.api.data.PrimitiveValue;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.Value;
import org.apache.olingo.commons.api.domain.ODataLinkType;
@ -140,6 +141,26 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
jgen.writeEndArray();
}
protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, final PrimitiveValue value)
throws IOException {
final boolean isNumber = typeInfo == null
? NumberUtils.isNumber(value.get())
: ArrayUtils.contains(NUMBER_TYPES, typeInfo.getPrimitiveTypeKind());
final boolean isBoolean = typeInfo == null
? (value.get().equalsIgnoreCase(Boolean.TRUE.toString())
|| value.get().equalsIgnoreCase(Boolean.FALSE.toString()))
: typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Boolean;
if (isNumber) {
jgen.writeNumber(value.get());
} else if (isBoolean) {
jgen.writeBoolean(BooleanUtils.toBoolean(value.get()));
} else {
jgen.writeString(value.get());
}
}
private void value(final JsonGenerator jgen, final String type, final Value value) throws IOException {
final EdmTypeInfo typeInfo = type == null
? null
@ -148,21 +169,7 @@ abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
if (value == null || value.isNull()) {
jgen.writeNull();
} else if (value.isPrimitive()) {
final boolean isNumber = typeInfo == null
? NumberUtils.isNumber(value.asPrimitive().get())
: ArrayUtils.contains(NUMBER_TYPES, typeInfo.getPrimitiveTypeKind());
final boolean isBoolean = typeInfo == null
? (value.asPrimitive().get().equalsIgnoreCase(Boolean.TRUE.toString())
|| value.asPrimitive().get().equalsIgnoreCase(Boolean.FALSE.toString()))
: typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Boolean;
if (isNumber) {
jgen.writeNumber(value.asPrimitive().get());
} else if (isBoolean) {
jgen.writeBoolean(BooleanUtils.toBoolean(value.asPrimitive().get()));
} else {
jgen.writeString(value.asPrimitive().get());
}
primitiveValue(jgen, typeInfo, value.asPrimitive());
} else if (value.isEnum()) {
jgen.writeString(value.asEnum().get());
} else if (value.isGeospatial()) {

View File

@ -271,6 +271,10 @@ public class AtomDeserializer extends AbstractAtomDealer {
break;
case PRIMITIVE:
// No type specified? Defaults to Edm.String
if (typeInfo == null) {
property.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString());
}
value = fromPrimitive(reader, start, typeInfo);
break;

View File

@ -34,6 +34,7 @@ import org.apache.olingo.commons.api.data.Feed;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.Value;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
@ -102,9 +103,11 @@ public class AtomSerializer extends AbstractAtomDealer {
}
if (StringUtils.isNotBlank(property.getType())) {
writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
Constants.ATTR_TYPE,
new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build().external(version));
final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
Constants.ATTR_TYPE, typeInfo.external(version));
}
}
if (property.getValue().isNull()) {

View File

@ -59,15 +59,11 @@ public class JSONEntrySerializer extends AbstractJsonSerializer<JSONEntryImpl> {
if (serverMode) {
if (version.compareTo(ODataServiceVersion.V40) >= 0 && StringUtils.isNotBlank(container.getMetadataETag())) {
jgen.writeStringField(
Constants.JSON_METADATA_ETAG,
container.getMetadataETag());
jgen.writeStringField(Constants.JSON_METADATA_ETAG, container.getMetadataETag());
}
if (StringUtils.isNotBlank(entry.getETag())) {
jgen.writeStringField(
version.getJSONMap().get(ODataServiceVersion.JSON_ETAG),
entry.getETag());
jgen.writeStringField(version.getJSONMap().get(ODataServiceVersion.JSON_ETAG), entry.getETag());
}
}

View File

@ -25,6 +25,7 @@ import java.io.IOException;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.Container;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
/**
* Writes out JSON string from <tt>JSONPropertyImpl</tt>.
@ -51,7 +52,12 @@ public class JSONPropertySerializer extends AbstractJsonSerializer<JSONPropertyI
if (property.getValue().isNull()) {
jgen.writeBooleanField(Constants.JSON_NULL, true);
} else if (property.getValue().isPrimitive()) {
jgen.writeStringField(Constants.VALUE, property.getValue().asPrimitive().get());
final EdmTypeInfo typeInfo = property.getType() == null
? null
: new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
jgen.writeFieldName(Constants.VALUE);
primitiveValue(jgen, typeInfo, property.getValue().asPrimitive());
} else if (property.getValue().isEnum()) {
jgen.writeStringField(Constants.VALUE, property.getValue().asEnum().get());
} else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {

15
pom.xml
View File

@ -20,7 +20,7 @@
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.olingo</groupId>
@ -210,6 +210,12 @@
<version>1.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${sl4j.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
@ -307,6 +313,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>alphabetical</runOrder>
<encoding>UTF-8</encoding>
<inputEncoding>UTF-8</inputEncoding>
@ -319,8 +326,12 @@
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<encoding>utf-8</encoding>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>alphabetical</runOrder>
<encoding>UTF-8</encoding>
<inputEncoding>UTF-8</inputEncoding>
<outputEncoding>UTF-8</outputEncoding>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
<executions>
<execution>