[OLINGO-317] Support for JSON variants in server serializer
This commit is contained in:
parent
cadd647616
commit
210cf9b37d
|
@ -22,8 +22,10 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.commons.api.format.AcceptType;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.processor.CustomContentTypeSupportProcessor;
|
||||
|
@ -34,8 +36,6 @@ import org.apache.olingo.server.api.uri.queryoption.FormatOption;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.util.TypeUtil;
|
||||
|
||||
public class ContentNegotiator {
|
||||
|
||||
private final static Logger LOG = LoggerFactory.getLogger(ContentNegotiator.class);
|
||||
|
@ -49,9 +49,8 @@ public class ContentNegotiator {
|
|||
if (processorClass == MetadataProcessor.class) {
|
||||
defaults.add(new FormatContentTypeMapping("xml", ContentType.APPLICATION_XML.toContentTypeString()));
|
||||
} else {
|
||||
// defaults.add(new FormatContentTypeMapping("json", ContentType.APPLICATION_JSON.toContentTypeString()));
|
||||
defaults.add(new FormatContentTypeMapping("json", ContentType.APPLICATION_JSON.toContentTypeString()
|
||||
+ ";odata.metadata=minimal"));
|
||||
defaults.add(new FormatContentTypeMapping("json",
|
||||
ODataFormat.JSON.getContentType(ODataServiceVersion.V40).toContentTypeString()));
|
||||
}
|
||||
|
||||
return defaults;
|
||||
|
@ -84,7 +83,7 @@ public class ContentNegotiator {
|
|||
if (formatOption != null) {
|
||||
|
||||
if ("json".equalsIgnoreCase(formatOption.getText().trim())) {
|
||||
requestedContentType = ContentType.create(ContentType.APPLICATION_JSON, "odata.metadata=minimal");
|
||||
requestedContentType = ODataFormat.JSON.getContentType(ODataServiceVersion.V40);
|
||||
for (FormatContentTypeMapping entry : supportedContentTypes) {
|
||||
if (requestedContentType.isCompatible(ContentType.create(entry.getContentType().trim()))) {
|
||||
supported = true;
|
||||
|
@ -136,7 +135,7 @@ public class ContentNegotiator {
|
|||
}
|
||||
|
||||
if (requestedContentType == null) {
|
||||
throw new RuntimeException("unsupported accept content type: " + acceptedContentTypes + " != "
|
||||
throw new ODataRuntimeException("unsupported accept content type: " + acceptedContentTypes + " != "
|
||||
+ supportedContentTypes);
|
||||
}
|
||||
} else {
|
||||
|
@ -144,7 +143,7 @@ public class ContentNegotiator {
|
|||
if (processorClass == MetadataProcessor.class) {
|
||||
requestedContentType = ContentType.APPLICATION_XML;
|
||||
} else {
|
||||
requestedContentType = ContentType.create(ContentType.APPLICATION_JSON, "odata.metadata=minimal");
|
||||
requestedContentType = ODataFormat.JSON.getContentType(ODataServiceVersion.V40);
|
||||
}
|
||||
|
||||
for (FormatContentTypeMapping entry : supportedContentTypes) {
|
||||
|
@ -156,7 +155,7 @@ public class ContentNegotiator {
|
|||
}
|
||||
|
||||
if (!supported) {
|
||||
throw new RuntimeException("unsupported accept content type: " + requestedContentType + " != "
|
||||
throw new ODataRuntimeException("unsupported accept content type: " + requestedContentType + " != "
|
||||
+ supportedContentTypes);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ public class ODataImpl extends OData {
|
|||
ODataSerializer serializer;
|
||||
switch (format) {
|
||||
case JSON:
|
||||
serializer = new ODataJsonSerializer();
|
||||
case JSON_NO_METADATA:
|
||||
case JSON_FULL_METADATA:
|
||||
serializer = new ODataJsonSerializer(format);
|
||||
break;
|
||||
case XML:
|
||||
serializer = new ODataXmlSerializerImpl();
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
|||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
|
||||
|
@ -54,6 +55,12 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger(ODataJsonSerializer.class);
|
||||
|
||||
private final ODataFormat format;
|
||||
|
||||
public ODataJsonSerializer(final ODataFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream serviceDocument(final Edm edm, final String serviceRoot) {
|
||||
CircleStreamBuffer buffer;
|
||||
|
@ -100,6 +107,19 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
throw new ODataRuntimeException("Metadata in JSON format not supported!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream error(final ODataError error) {
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
new ODataErrorSerializer().writeErrorDocument(json, error);
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
throw new ODataRuntimeException(e);
|
||||
}
|
||||
return buffer.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
|
||||
final ContextURL contextURL) {
|
||||
|
@ -107,7 +127,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
json.writeStartObject();
|
||||
if (contextURL != null) {
|
||||
if (contextURL != null && format != ODataFormat.JSON_NO_METADATA) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
|
||||
}
|
||||
if (entitySet.getCount() != null) {
|
||||
|
@ -149,17 +169,19 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
protected void writeEntity(final EdmEntityType entityType, final Entity entity, final ContextURL contextURL,
|
||||
final JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
||||
json.writeStartObject();
|
||||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
|
||||
}
|
||||
if (entity.getETag() != null) {
|
||||
json.writeStringField("@odata.etag", entity.getETag());
|
||||
}
|
||||
if (entity.getMediaETag() != null) {
|
||||
json.writeStringField("@odata.mediaEtag", entity.getMediaETag());
|
||||
}
|
||||
if (entity.getMediaContentType() != null) {
|
||||
json.writeStringField("@odata.mediaContentType", entity.getMediaContentType());
|
||||
if (format != ODataFormat.JSON_NO_METADATA) {
|
||||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
|
||||
}
|
||||
if (entity.getETag() != null) {
|
||||
json.writeStringField("@odata.etag", entity.getETag());
|
||||
}
|
||||
if (entity.getMediaETag() != null) {
|
||||
json.writeStringField("@odata.mediaEtag", entity.getMediaETag());
|
||||
}
|
||||
if (entity.getMediaContentType() != null) {
|
||||
json.writeStringField("@odata.mediaContentType", entity.getMediaContentType());
|
||||
}
|
||||
}
|
||||
for (final String propertyName : entityType.getPropertyNames()) {
|
||||
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
|
||||
|
@ -185,7 +207,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
writePrimitive(edmProperty, property, json);
|
||||
} else if (property.isLinkedComplex()) {
|
||||
writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), json);
|
||||
} else if (property.isComplex()) {
|
||||
} else if(property.isComplex()) {
|
||||
writeComplexValue(edmProperty, property.asComplex(), json);
|
||||
} else {
|
||||
throw new ODataRuntimeException("Property type not yet supported!");
|
||||
|
@ -193,7 +215,6 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeCollection(EdmProperty edmProperty, Property property, JsonGenerator json)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
json.writeStartArray();
|
||||
|
@ -257,7 +278,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
|
||||
private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
|
||||
JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
||||
JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
||||
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
|
||||
json.writeStartObject();
|
||||
for (final String propertyName : type.getPropertyNames()) {
|
||||
|
@ -275,18 +296,4 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream error(ODataError error) {
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
ODataErrorSerializer ser = new ODataErrorSerializer();
|
||||
ser.writeErrorDocument(json, error);
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
throw new ODataRuntimeException(e);
|
||||
}
|
||||
return buffer.getInputStream();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
|
|||
response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode());
|
||||
return;
|
||||
}
|
||||
ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
|
||||
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
try {
|
||||
final EntitySet entitySet = readEntitySetInternal(edmEntitySet, request.getRawBaseUri());
|
||||
|
@ -90,7 +90,7 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
|
|||
response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode());
|
||||
return;
|
||||
}
|
||||
ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
|
||||
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
try {
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
|
|||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
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.core.serializer.json.ODataJsonSerializer;
|
||||
import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
|
||||
|
@ -184,16 +185,12 @@ public class JsonDataProviderTest {
|
|||
EntitySet outSet = jdp.readAll(entitySet);
|
||||
|
||||
|
||||
ODataJsonSerializer serializer = new ODataJsonSerializer();
|
||||
ODataJsonSerializer serializer = new ODataJsonSerializer(ODataFormat.JSON);
|
||||
ContextURL contextUrl = null;
|
||||
InputStream is = serializer.entitySet(entitySet, outSet, contextUrl);
|
||||
|
||||
StringHelper.Stream stream = StringHelper.toStream(is);
|
||||
|
||||
// System.out.println("========== " + entitySet.getName() + " =================");
|
||||
// stream.print();
|
||||
// System.out.println("\n========== " + entitySet.getName() + " =================");
|
||||
|
||||
Assert.assertEquals(expectedLength, stream.asString().length());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core.serializer.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
|
@ -29,6 +29,7 @@ import org.apache.olingo.commons.api.edm.Edm;
|
|||
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
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.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
@ -42,7 +43,7 @@ public class ODataJsonSerializerTest {
|
|||
private final EdmEntityContainer entityContainer = edm.getEntityContainer(
|
||||
new FullQualifiedName("com.sap.odata.test1", "Container"));
|
||||
private final DataProvider data = new DataProvider(edm);
|
||||
private ODataSerializer serializer = new ODataJsonSerializer();
|
||||
private ODataSerializer serializer = new ODataJsonSerializer(ODataFormat.JSON);
|
||||
|
||||
@Test
|
||||
public void entitySimple() throws Exception {
|
||||
|
@ -50,7 +51,7 @@ public class ODataJsonSerializerTest {
|
|||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
ContextURL.getInstance(URI.create("$metadata#ESAllPrim/$entity")));
|
||||
final String resultString = streamToString(result);
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{"
|
||||
+ "\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
|
||||
+ "\"PropertyInt16\":32767,"
|
||||
|
@ -81,7 +82,7 @@ public class ODataJsonSerializerTest {
|
|||
entitySet.setNext(URI.create("/next"));
|
||||
InputStream result = serializer.entitySet(edmEntitySet, entitySet,
|
||||
ContextURL.getInstance(URI.create("$metadata#ESAllPrim")));
|
||||
final String resultString = streamToString(result);
|
||||
final String resultString = IOUtils.toString(result);
|
||||
|
||||
Assert.assertTrue(resultString.matches("\\{"
|
||||
+ "\"@odata\\.context\":\"\\$metadata#ESAllPrim\","
|
||||
|
@ -104,7 +105,7 @@ public class ODataJsonSerializerTest {
|
|||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
ContextURL.getInstance(URI.create("$metadata#ESCollAllPrim/$entity")));
|
||||
final String resultString = streamToString(result);
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{"
|
||||
+ "\"@odata.context\":\"$metadata#ESCollAllPrim/$entity\","
|
||||
+ "\"PropertyInt16\":1,"
|
||||
|
@ -136,7 +137,7 @@ public class ODataJsonSerializerTest {
|
|||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
ContextURL.getInstance(URI.create("$metadata#ESCompAllPrim/$entity")));
|
||||
final String resultString = streamToString(result);
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{"
|
||||
+ "\"@odata.context\":\"$metadata#ESCompAllPrim/$entity\","
|
||||
+ "\"PropertyInt16\":32767,"
|
||||
|
@ -167,7 +168,7 @@ public class ODataJsonSerializerTest {
|
|||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
ContextURL.getInstance(URI.create("$metadata#ESMixPrimCollComp/$entity")));
|
||||
final String resultString = streamToString(result);
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{"
|
||||
+ "\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
|
||||
+ "\"PropertyInt16\":32767,"
|
||||
|
@ -180,16 +181,29 @@ public class ODataJsonSerializerTest {
|
|||
Assert.assertEquals(expectedResult, resultString);
|
||||
}
|
||||
|
||||
private String streamToString(InputStream input) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
StringBuilder result = new StringBuilder();
|
||||
@Test
|
||||
public void entityTwoPrimNoMetadata() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
|
||||
.entity(edmEntitySet.getEntityType(), entity, ContextURL.getInstance(URI.create("contextURL")));
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"}";
|
||||
Assert.assertEquals(expectedResult, resultString);
|
||||
}
|
||||
|
||||
int count = input.read(buffer);
|
||||
while (count >= 0) {
|
||||
result.append(new String(buffer, 0, count, "UTF-8"));
|
||||
count = input.read(buffer);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
@Test
|
||||
public void entitySetTwoPrimNoMetadata() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||
final EntitySet entitySet = data.readAll(edmEntitySet);
|
||||
InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
|
||||
.entitySet(edmEntitySet, entitySet, ContextURL.getInstance(URI.create("contextURL")));
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{\"value\":["
|
||||
+ "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"},"
|
||||
+ "{\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"},"
|
||||
+ "{\"PropertyInt16\":-32766,\"PropertyString\":\"Test String3\"},"
|
||||
+ "{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"}]}";
|
||||
Assert.assertEquals(expectedResult, resultString);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue