[OLINGO-317] Minor bugfixes
This commit is contained in:
parent
a2874142c5
commit
8221545085
|
@ -108,6 +108,14 @@ public interface Entity extends Linked, Annotatable {
|
|||
*/
|
||||
List<ODataOperation> getOperations();
|
||||
|
||||
/**
|
||||
* Add property to this Entity.
|
||||
*
|
||||
* @param property property which is added
|
||||
* @return this Entity for fluid/flow adding
|
||||
*/
|
||||
Entity addProperty(Property property);
|
||||
|
||||
/**
|
||||
* Gets properties.
|
||||
*
|
||||
|
|
|
@ -50,7 +50,7 @@ public class AcceptType {
|
|||
private static final String PARAMETER_Q = "q";
|
||||
private static final Pattern Q_PARAMETER_VALUE_PATTERN = Pattern.compile("1|0|1\\.0{1,3}|0\\.\\d{1,3}");
|
||||
|
||||
public static final AcceptType WILDCARD = create(MEDIA_TYPE_WILDCARD, MEDIA_TYPE_WILDCARD, null, 1F);
|
||||
public static final AcceptType WILDCARD = create(MEDIA_TYPE_WILDCARD, MEDIA_TYPE_WILDCARD, createParameterMap(), 1F);
|
||||
|
||||
private final String type;
|
||||
private final String subtype;
|
||||
|
@ -66,7 +66,7 @@ public class AcceptType {
|
|||
this.quality = quality;
|
||||
}
|
||||
|
||||
private TreeMap<String, String> createParameterMap() {
|
||||
private static TreeMap<String, String> createParameterMap() {
|
||||
return new TreeMap<String, String>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(final String o1, final String o2) {
|
||||
|
|
|
@ -131,6 +131,12 @@ public class EntityImpl extends AbstractODataObject implements Entity {
|
|||
return operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity addProperty(Property property) {
|
||||
properties.add(property);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Property> getProperties() {
|
||||
return properties;
|
||||
|
|
|
@ -19,12 +19,26 @@
|
|||
package org.apache.olingo.commons.core.data;
|
||||
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
|
||||
public class PropertyImpl extends AbstractValuable implements Property {
|
||||
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public PropertyImpl() {
|
||||
}
|
||||
|
||||
public PropertyImpl(String type, String name) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public PropertyImpl(String type, String name, ValueType valueType, Object value) {
|
||||
this(name, type);
|
||||
setValue(valueType, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
|
@ -115,32 +115,22 @@ public final class EdmDateTime extends SingletonPrimitiveType {
|
|||
final Boolean isNullable, final Integer maxLength, final Integer precision,
|
||||
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
|
||||
|
||||
Date date = null;
|
||||
Integer fractionalSecs = null;
|
||||
if (value instanceof Calendar) {
|
||||
final Calendar calendar = (Calendar) value;
|
||||
date = calendar.getTime();
|
||||
fractionalSecs = calendar.get(Calendar.MILLISECOND);
|
||||
}
|
||||
if (value instanceof Timestamp) {
|
||||
final Timestamp timestamp = (Timestamp) value;
|
||||
date = new Date(timestamp.getTime());
|
||||
fractionalSecs = timestamp.getNanos();
|
||||
}
|
||||
|
||||
Date date = calendar.getTime();
|
||||
Integer fractionalSecs = calendar.get(Calendar.MILLISECOND);
|
||||
final StringBuilder result = new StringBuilder().append(DATE_FORMAT.get().format(date));
|
||||
|
||||
try {
|
||||
if (value instanceof Timestamp) {
|
||||
EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
|
||||
} else {
|
||||
EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision);
|
||||
}
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new EdmPrimitiveTypeException(
|
||||
"EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)", e);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
} else if (value instanceof Timestamp) {
|
||||
final Timestamp timestamp = (Timestamp) value;
|
||||
Date date = new Date(timestamp.getTime());
|
||||
Integer fractionalSecs = timestamp.getNanos();
|
||||
final StringBuilder result = new StringBuilder().append(DATE_FORMAT.get().format(date));
|
||||
EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
|
||||
return result.toString();
|
||||
} else {
|
||||
throw new EdmPrimitiveTypeException("EdmDateTime only supports conversion from Calendar and Timestamp");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.apache.olingo.server.api.ODataHttpHandler;
|
|||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.core.edm.provider.EdmProviderImpl;
|
||||
import org.apache.olingo.server.core.serializer.ODataJsonSerializer;
|
||||
import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
|
||||
import org.apache.olingo.server.core.serializer.ODataXmlSerializerImpl;
|
||||
|
||||
public class ODataImpl extends OData {
|
||||
|
|
|
@ -16,20 +16,23 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.core.serializer;
|
||||
package org.apache.olingo.server.core.serializer.json;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
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;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.LinkedComplexValue;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
|
@ -38,7 +41,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
|||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.core.serializer.json.ServiceDocumentJsonSerializer;
|
||||
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -128,10 +130,17 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
json.writeStringField("@odata.mediaContentType", entity.getMediaContentType());
|
||||
}
|
||||
for (final String propertyName : entityType.getPropertyNames()) {
|
||||
json.writeFieldName(propertyName);
|
||||
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
|
||||
final Property property = entity.getProperty(propertyName);
|
||||
if (property == null) {
|
||||
writeProperty(edmProperty, property, json);
|
||||
}
|
||||
json.writeEndObject();
|
||||
}
|
||||
|
||||
protected void writeProperty(final EdmProperty edmProperty, final Property property, JsonGenerator json)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
json.writeFieldName(edmProperty.getName());
|
||||
if (property == null || property.isNull()) {
|
||||
if (edmProperty.isNullable() == Boolean.FALSE) {
|
||||
throw new ODataRuntimeException("Non-nullable property not present!");
|
||||
} else {
|
||||
|
@ -139,11 +148,51 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
} else {
|
||||
if (edmProperty.isPrimitive()) {
|
||||
if (property.isPrimitive()) {
|
||||
writePrimitiveValue(edmProperty, property.asPrimitive(), json);
|
||||
} else if (property.isGeospatial()) {
|
||||
throw new ODataRuntimeException("Property type not yet supported!");
|
||||
} else if (property.isEnum()) {
|
||||
json.writeString(property.asEnum().toString());
|
||||
} else {
|
||||
throw new ODataRuntimeException("Inconsistent property type!");
|
||||
}
|
||||
} else if (edmProperty.isCollection()) {
|
||||
json.writeStartArray();
|
||||
for (Object value : property.asCollection()) {
|
||||
switch (property.getValueType()) {
|
||||
case COLLECTION_PRIMITIVE:
|
||||
writePrimitiveValue(edmProperty, value, json);
|
||||
break;
|
||||
case COLLECTION_GEOSPATIAL:
|
||||
throw new ODataRuntimeException("Property type not yet supported!");
|
||||
case COLLECTION_ENUM:
|
||||
json.writeString(value.toString());
|
||||
break;
|
||||
case COLLECTION_LINKED_COMPLEX:
|
||||
writeLinkedComplexValue(edmProperty, (LinkedComplexValue) value, json);
|
||||
break;
|
||||
default:
|
||||
throw new ODataRuntimeException("Property type not yet supported!");
|
||||
}
|
||||
}
|
||||
json.writeEndArray();
|
||||
} else {
|
||||
if (property.isLinkedComplex()) {
|
||||
writeLinkedComplexValue(edmProperty, property.asLinkedComplex(), json);
|
||||
} else {
|
||||
throw new ODataRuntimeException("Property type not yet supported!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void writePrimitiveValue(final EdmProperty edmProperty, final Object primitiveValue, JsonGenerator json)
|
||||
throws EdmPrimitiveTypeException, IOException {
|
||||
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
|
||||
final String value = type.valueToString(property.asPrimitive(),
|
||||
final String value = type.valueToString(primitiveValue,
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(),
|
||||
edmProperty.isUnicode());
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
|
||||
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) {
|
||||
json.writeBoolean(Boolean.parseBoolean(value));
|
||||
} else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte)
|
||||
|
@ -158,14 +207,29 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
} else {
|
||||
json.writeString(value);
|
||||
}
|
||||
} else {
|
||||
throw new ODataRuntimeException("Non-primitive properties not yet supported!");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLinkedComplexValue(final EdmProperty edmProperty, final LinkedComplexValue linkedComplexValue,
|
||||
JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
|
||||
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
|
||||
final List<Property> properties = linkedComplexValue.getValue();
|
||||
json.writeStartObject();
|
||||
for (final String propertyName : type.getPropertyNames()) {
|
||||
final Property property = findProperty(propertyName, properties);
|
||||
writeProperty((EdmProperty) type.getProperty(propertyName), property, json);
|
||||
}
|
||||
json.writeEndObject();
|
||||
}
|
||||
|
||||
private Property findProperty(String propertyName, List<Property> properties) {
|
||||
for (final Property property : properties) {
|
||||
if (propertyName.equals(property.getName())) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
|
||||
final ContextURL contextURL) {
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.server.core.serializer.json;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.core.data.EntityImpl;
|
||||
import org.apache.olingo.commons.core.data.PropertyImpl;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ODataJsonSerializerTest {
|
||||
|
||||
public static final String PROPERTY_1 = "Property1";
|
||||
|
||||
private ContextURL contextUrl;
|
||||
private EdmEntityType edmEntityType;
|
||||
private final Logger LOG = LoggerFactory.getLogger(ODataJsonSerializerTest.class);
|
||||
|
||||
private ODataJsonSerializer serializer = new ODataJsonSerializer();
|
||||
|
||||
@Before
|
||||
public void prepare() throws Exception {
|
||||
contextUrl = ContextURL.getInstance(new URI("http://localhost:8080/test.svc"));
|
||||
edmEntityType = Mockito.mock(EdmEntityType.class);
|
||||
List<String> propertyNames = Arrays.asList(PROPERTY_1);
|
||||
Mockito.when(edmEntityType.getPropertyNames()).thenReturn(propertyNames);
|
||||
|
||||
EdmProperty edmElement = Mockito.mock(EdmProperty.class);
|
||||
Mockito.when(edmElement.getName()).thenReturn(PROPERTY_1);
|
||||
Mockito.when(edmElement.isPrimitive()).thenReturn(true);
|
||||
Mockito.when(edmElement.getMaxLength()).thenReturn(20);
|
||||
Mockito.when(edmElement.getType()).thenReturn(EdmString.getInstance());
|
||||
Mockito.when(edmEntityType.getProperty(PROPERTY_1)).thenReturn(edmElement);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entitySimple() throws Exception {
|
||||
|
||||
// Entity entity = new EntityImpl();
|
||||
// entity.addProperty(new PropertyImpl("Edm.String", PROPERTY_1, ValueType.PRIMITIVE, "Value_1"));
|
||||
Entity entity = new EntityImpl();
|
||||
PropertyImpl property = new PropertyImpl("Edm.String", PROPERTY_1);
|
||||
property.setValue(ValueType.PRIMITIVE, "Value_1");
|
||||
entity.addProperty(property);
|
||||
|
||||
InputStream result = serializer.entity(edmEntityType, entity, contextUrl);
|
||||
String resultString = streamToString(result);
|
||||
// System.out.println(resultString);
|
||||
Assert.assertEquals("{\"@odata.context\":\"http://localhost:8080/test.svc\",\"Property1\":\"Value_1\"}",
|
||||
resultString);
|
||||
}
|
||||
|
||||
private String streamToString(InputStream result) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int count = result.read(buffer);
|
||||
while (count >= 0) {
|
||||
sb.append(new String(buffer, 0, count, "UTF-8"));
|
||||
count = result.read(buffer);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ import org.apache.olingo.commons.api.edm.Edm;
|
|||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.data.EntityImpl;
|
||||
import org.apache.olingo.commons.core.data.EntitySetImpl;
|
||||
import org.apache.olingo.commons.core.data.PropertyImpl;
|
||||
|
@ -71,7 +72,7 @@ public class SampleJsonProcessor implements EntitySetProcessor, EntityProcessor
|
|||
ContextURL.getInstance(URI.create("dummyContextURL"))));
|
||||
LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
|
||||
|
||||
response.setStatusCode(200);
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
|
||||
}
|
||||
|
||||
|
@ -90,7 +91,7 @@ public class SampleJsonProcessor implements EntitySetProcessor, EntityProcessor
|
|||
ContextURL.getInstance(URI.create("dummyContextURL"))));
|
||||
LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
|
||||
|
||||
response.setStatusCode(200);
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
|
||||
}
|
||||
|
||||
|
@ -98,17 +99,14 @@ public class SampleJsonProcessor implements EntitySetProcessor, EntityProcessor
|
|||
Entity entity = new EntityImpl();
|
||||
Property property = new PropertyImpl();
|
||||
property.setName("PropertyString");
|
||||
property.setType("String"); //"dummyType");
|
||||
property.setValue(ValueType.PRIMITIVE, "dummyValue");
|
||||
entity.getProperties().add(property);
|
||||
Property propertyInt = new PropertyImpl();
|
||||
propertyInt.setName("PropertyInt16");
|
||||
// propertyInt.setType("Edm.Int32");
|
||||
propertyInt.setValue(ValueType.PRIMITIVE, 42);
|
||||
entity.getProperties().add(propertyInt);
|
||||
Property propertyGuid = new PropertyImpl();
|
||||
propertyGuid.setName("PropertyGuid");
|
||||
propertyGuid.setType("Edm.Guid");
|
||||
propertyGuid.setValue(ValueType.PRIMITIVE, UUID.randomUUID());
|
||||
entity.getProperties().add(propertyGuid);
|
||||
return entity;
|
||||
|
|
Loading…
Reference in New Issue