[OLINGO-317] Basic media entity support and more Constants usage

This commit is contained in:
Michael Bolz 2014-07-17 10:40:54 +02:00
parent b9db730f3c
commit 31e4913950
5 changed files with 169 additions and 81 deletions

View File

@ -18,34 +18,29 @@
*/
package org.apache.olingo.server.core.serializer.json;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import java.io.IOException;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
public class ODataErrorSerializer {
private static final String ERROR = "error";
private static final String CODE = "code";
private static final String MESSAGE = "message";
private static final String TARGET = "target";
private static final String DETAILS = "details";
public void writeErrorDocument(JsonGenerator json, ODataError error) throws IOException {
if (error == null) {
throw new ODataRuntimeException("ODataError object MUST NOT be null!");
}
json.writeStartObject();
json.writeFieldName(ERROR);
json.writeFieldName(Constants.JSON_ERROR);
json.writeStartObject();
writeODataError(json, error.getCode(), error.getMessage(), error.getTarget());
if (error.getDetails() != null) {
json.writeArrayFieldStart(DETAILS);
json.writeArrayFieldStart(Constants.ERROR_DETAILS);
for (ODataErrorDetail detail : error.getDetails()) {
json.writeStartObject();
writeODataError(json, detail.getCode(), detail.getMessage(), detail.getTarget());
@ -58,21 +53,23 @@ public class ODataErrorSerializer {
json.writeEndObject();
}
private void writeODataError(JsonGenerator json, String code, String message, String target) throws IOException,
JsonGenerationException {
private void writeODataError(JsonGenerator json, String code, String message, String target) throws IOException {
json.writeFieldName(Constants.ERROR_CODE);
if (code == null) {
json.writeNullField(CODE);
json.writeNull();
} else {
json.writeStringField(CODE, code);
json.writeString(code);
}
json.writeFieldName(Constants.ERROR_MESSAGE);
if (message == null) {
json.writeNullField(MESSAGE);
json.writeNull();
} else {
json.writeStringField(MESSAGE, message);
json.writeString(message);
}
if (target != null) {
json.writeStringField(TARGET, target);
json.writeStringField(Constants.ERROR_TARGET, target);
}
}
}

View File

@ -18,9 +18,10 @@
*/
package org.apache.olingo.server.core.serializer.json;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.data.ContextURL;
@ -45,11 +46,9 @@ import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
public class ODataJsonSerializer implements ODataSerializer {
@ -64,21 +63,15 @@ public class ODataJsonSerializer implements ODataSerializer {
@Override
public InputStream serviceDocument(final Edm edm, final String serviceRoot) {
CircleStreamBuffer buffer;
BufferedWriter writer;
JsonFactory factory;
JsonGenerator gen = null;
// TODO: move stream initialization into separate method
try {
buffer = new CircleStreamBuffer();
writer = new BufferedWriter(new OutputStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET));
factory = new JsonFactory();
gen = new JsonFactory().createGenerator(buffer.getOutputStream())
.setPrettyPrinter(new DefaultPrettyPrinter());
gen = factory.createGenerator(writer);
gen.setPrettyPrinter(new DefaultPrettyPrinter());
ServiceDocumentJsonSerializer serializer = new ServiceDocumentJsonSerializer(edm, serviceRoot);
serializer.writeServiceDocument(gen);
new ServiceDocumentJsonSerializer(edm, serviceRoot).writeServiceDocument(gen);
gen.close();
@ -130,7 +123,7 @@ public class ODataJsonSerializer implements ODataSerializer {
try {
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
json.writeStartObject();
if (entitySetContextURL != null && format != ODataFormat.JSON_NO_METADATA) {
if (format != ODataFormat.JSON_NO_METADATA) {
json.writeStringField(Constants.JSON_CONTEXT, entitySetContextURL.getURI().toASCIIString());
}
if (entitySet.getCount() != null) {
@ -174,6 +167,7 @@ public class ODataJsonSerializer implements ODataSerializer {
protected void writeEntity(final EdmEntitySet entitySet, final Entity entity, final ContextURL contextURL,
final JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
final EdmEntityType entityType = entitySet.getEntityType();
json.writeStartObject();
if (format != ODataFormat.JSON_NO_METADATA) {
if (contextURL != null) {
@ -182,14 +176,15 @@ public class ODataJsonSerializer implements ODataSerializer {
if (entity.getETag() != null) {
json.writeStringField(Constants.JSON_ETAG, entity.getETag());
}
if (entity.getMediaETag() != null) {
json.writeStringField(Constants.JSON_MEDIA_ETAG, entity.getMediaETag());
}
if (entity.getMediaContentType() != null) {
json.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entity.getMediaContentType());
if (entityType.hasStream()) {
if (entity.getMediaETag() != null) {
json.writeStringField(Constants.JSON_MEDIA_ETAG, entity.getMediaETag());
}
if (entity.getMediaContentType() != null) {
json.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entity.getMediaContentType());
}
}
}
final EdmEntityType entityType = entitySet.getEntityType();
for (final String propertyName : entityType.getPropertyNames()) {
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
final Property property = entity.getProperty(propertyName);
@ -214,7 +209,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!");
@ -285,7 +280,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()) {

View File

@ -18,22 +18,18 @@
*/
package org.apache.olingo.server.core.serializer.json;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import java.io.IOException;
import org.apache.olingo.commons.api.Constants;
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.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmSingleton;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
public class ServiceDocumentJsonSerializer {
public static final String ODATA_CONTEXT = "@odata.context";
public static final String METADATA = "$metadata";
public static final String VALUE = "value";
public static final String NAME = "name";
public static final String URL = "url";
public static final String KIND = "kind";
public static final String FUNCTION_IMPORT = "FunctionImport";
@ -48,64 +44,63 @@ public class ServiceDocumentJsonSerializer {
this.serviceRoot = serviceRoot;
}
public void writeServiceDocument(final JsonGenerator gen) throws JsonGenerationException, IOException {
public void writeServiceDocument(final JsonGenerator gen) throws IOException {
gen.writeStartObject();
Object metadataUri;
if (serviceRoot == null) {
metadataUri = METADATA;
metadataUri = Constants.METADATA;
} else {
if (serviceRoot.endsWith("/")) {
metadataUri = serviceRoot + METADATA;
metadataUri = serviceRoot + Constants.METADATA;
} else {
metadataUri = serviceRoot + "/" + METADATA;
metadataUri = serviceRoot + "/" + Constants.METADATA;
}
}
gen.writeObjectField(ODATA_CONTEXT, metadataUri);
gen.writeArrayFieldStart(VALUE);
gen.writeObjectField(Constants.JSON_CONTEXT, metadataUri);
gen.writeArrayFieldStart(Constants.VALUE);
writeEntitySets(gen, edm);
writeFunctionImports(gen, edm);
writeSingletons(gen, edm);
}
private void writeEntitySets(final JsonGenerator gen, final Edm edm) throws JsonGenerationException, IOException {
private void writeEntitySets(final JsonGenerator gen, final Edm edm) throws IOException {
EdmEntityContainer container = edm.getEntityContainer(null);
for (EdmEntitySet edmEntitySet : container.getEntitySets()) {
if (edmEntitySet.isIncludeInServiceDocument()) {
gen.writeStartObject();
gen.writeObjectField(NAME, edmEntitySet.getName());
gen.writeObjectField(URL, edmEntitySet.getName());
gen.writeObjectField(Constants.JSON_NAME, edmEntitySet.getName());
gen.writeObjectField(Constants.JSON_URL, edmEntitySet.getName());
gen.writeEndObject();
}
}
}
private void writeFunctionImports(final JsonGenerator gen, final Edm edm) throws JsonGenerationException,
IOException {
private void writeFunctionImports(final JsonGenerator gen, final Edm edm) throws IOException {
EdmEntityContainer container = edm.getEntityContainer(null);
for (EdmFunctionImport edmFunctionImport : container.getFunctionImports()) {
if (edmFunctionImport.isIncludeInServiceDocument()) {
gen.writeStartObject();
gen.writeObjectField(NAME, edmFunctionImport.getName());
gen.writeObjectField(URL, edmFunctionImport.getName());
gen.writeObjectField(Constants.JSON_NAME, edmFunctionImport.getName());
gen.writeObjectField(Constants.JSON_URL, edmFunctionImport.getName());
gen.writeObjectField(KIND, FUNCTION_IMPORT);
gen.writeEndObject();
}
}
}
private void writeSingletons(final JsonGenerator gen, final Edm edm) throws JsonGenerationException, IOException {
private void writeSingletons(final JsonGenerator gen, final Edm edm) throws IOException {
EdmEntityContainer container = edm.getEntityContainer(null);
for (EdmSingleton edmSingleton : container.getSingletons()) {
gen.writeStartObject();
gen.writeObjectField(NAME, edmSingleton.getName());
gen.writeObjectField(URL, edmSingleton.getName());
gen.writeObjectField(Constants.JSON_NAME, edmSingleton.getName());
gen.writeObjectField(Constants.JSON_URL, edmSingleton.getName());
gen.writeObjectField(KIND, SINGLETON);
gen.writeEndObject();
}

View File

@ -18,6 +18,16 @@
*/
package org.apache.olingo.server.tecsvc.data;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.LinkedComplexValue;
@ -35,16 +45,6 @@ import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
import org.apache.olingo.commons.core.data.PropertyImpl;
import org.apache.olingo.server.api.uri.UriParameter;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
public class DataProvider {
private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef");
@ -61,6 +61,7 @@ public class DataProvider {
data.put("ESCollAllPrim", createESCollAllPrim());
data.put("ESMixPrimCollComp", createESMixPrimCollComp());
data.put("ESAllKey", createESAllKey());
data.put("ESMedia", createESMedia());
}
public EntitySet readAll(final EdmEntitySet edmEntitySet) throws DataProviderException {
@ -419,6 +420,32 @@ public class DataProvider {
return entitySet;
}
private EntitySet createESMedia() {
EntitySet entitySet = new EntitySetImpl();
Entity entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 1));
entity.setMediaContentType("image/png");
entitySet.getEntities().add(entity);
entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 2));
entity.setMediaContentType("image/bmp");
entitySet.getEntities().add(entity);
entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 3));
entity.setMediaContentType("image/jpeg");
entitySet.getEntities().add(entity);
entity = new EntityImpl();
entity.addProperty(createPrimitive("PropertyInt16", 4));
entity.setMediaContentType("foo");
entitySet.getEntities().add(entity);
return entitySet;
}
private Property createPrimitive(final String name, final Object value) {
return new PropertyImpl(null, name, ValueType.PRIMITIVE, value);
}

View File

@ -18,11 +18,17 @@
*/
package org.apache.olingo.server.core.serializer.json;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
@ -35,9 +41,6 @@ import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Assert;
import org.junit.Test;
import java.io.InputStream;
import java.net.URI;
public class ODataJsonSerializerTest {
private final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
@ -75,6 +78,40 @@ public class ODataJsonSerializerTest {
Assert.assertEquals(expectedResult, resultString);
}
@Test
public void entityAllPrimAllNull() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
final String expectedResult = "{\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
+ "\"PropertyInt16\":32767,"
+ "\"PropertyString\":null,\"PropertyBoolean\":null,"
+ "\"PropertyByte\":null,\"PropertySByte\":null,"
+ "\"PropertyInt32\":null,\"PropertyInt64\":null,"
+ "\"PropertySingle\":null,\"PropertyDouble\":null,\"PropertyDecimal\":null,"
+ "\"PropertyBinary\":null,"
+ "\"PropertyDate\":null,\"PropertyDateTimeOffset\":null,\"PropertyDuration\":null,"
+ "\"PropertyGuid\":null,\"PropertyTimeOfDay\":null}";
Assert.assertEquals(expectedResult, resultString);
}
@Test(expected = ODataRuntimeException.class)
public void entityAllPrimKeyNull() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.getProperties().clear();
serializer.entity(edmEntitySet, entity, null);
}
@Test(expected = ODataRuntimeException.class)
public void entityWrongData() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.getProperties().get(0).setValue(ValueType.PRIMITIVE, false);
serializer.entity(edmEntitySet, entity, null);
}
@Test
public void entitySetAllPrim() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
@ -180,6 +217,18 @@ public class ODataJsonSerializerTest {
Assert.assertEquals(expectedResult, resultString);
}
@Test
public void entityMixPrimCollCompAllNull() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
+ "\"PropertyInt16\":32767,"
+ "\"CollPropertyString\":null,\"PropertyComp\":null,\"CollPropertyComp\":null}";
Assert.assertEquals(expectedResult, resultString);
}
@Test
public void entityTwoPrimNoMetadata() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
@ -205,4 +254,29 @@ public class ODataJsonSerializerTest {
+ "{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"}]}";
Assert.assertEquals(expectedResult, resultString);
}
@Test
public void entityMedia() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.setMediaETag("theMediaETag");
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\","
+ "\"@odata.mediaEtag\":\"theMediaETag\",\"@odata.mediaContentType\":\"image/png\","
+ "\"PropertyInt16\":1}";
Assert.assertEquals(expectedResult, resultString);
}
@Test
public void entitySetMedia() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
final EntitySet entitySet = data.readAll(edmEntitySet);
final String resultString = IOUtils.toString(serializer.entitySet(edmEntitySet, entitySet, null));
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":["
+ "{\"@odata.mediaContentType\":\"image/png\",\"PropertyInt16\":1},"
+ "{\"@odata.mediaContentType\":\"image/bmp\",\"PropertyInt16\":2},"
+ "{\"@odata.mediaContentType\":\"image/jpeg\",\"PropertyInt16\":3},"
+ "{\"@odata.mediaContentType\":\"foo\",\"PropertyInt16\":4}]}";
Assert.assertEquals(expectedResult, resultString);
}
}