[OLINGO-754] IEEE754Compatible support for ODataJsonSerializer
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/974abcb4 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/974abcb4 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/974abcb4 Branch: refs/heads/olingo712 Commit: 974abcb40f98e28813e4561f80a38e6899907b8f Parents: 5501e8e Author: Christian Holzer <[email protected]> Authored: Tue Jun 2 15:52:57 2015 +0200 Committer: Christian Holzer <[email protected]> Committed: Wed Jun 17 17:46:56 2015 +0200 ---------------------------------------------------------------------- .../olingo/commons/api/format/ContentType.java | 4 +- .../serializer/ComplexSerializerOptions.java | 18 +- .../EntityCollectionSerializerOptions.java | 16 +- .../api/serializer/EntitySerializerOptions.java | 16 +- .../server/api/serializer/ODataSerializer.java | 15 +- .../serializer/PrimitiveSerializerOptions.java | 18 +- .../ReferenceCollectionSerializerOptions.java | 83 +++++++ .../serializer/ReferenceSerializerOptions.java | 57 +++++ .../olingo/server/core/ContentNegotiator.java | 12 + .../serializer/json/ODataJsonSerializer.java | 123 +++++----- .../serializer/xml/ODataXmlSerializerImpl.java | 8 +- .../server/core/ContentNegotiatorTest.java | 43 ++-- .../processor/TechnicalEntityProcessor.java | 23 +- .../json/ODataJsonDeserializerEntityTest.java | 34 ++- .../json/ODataJsonSerializerTest.java | 232 ++++++++++++++++++- 15 files changed, 587 insertions(+), 115 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java index 4e2eb04..6949538 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java @@ -75,7 +75,9 @@ public final class ContentType { public static final ContentType MULTIPART_FORM_DATA = new ContentType(MULTIPART, "form-data", null); public static final String PARAMETER_CHARSET_UTF8 = "charset=utf-8"; - + public static final String PARAMETER_IEEE754_COMPATIBLE = "IEEE754Compatible=true"; + public static final String PARAMETER_IEEE754_COMPATIBLE_FALSE = "IEEE754Compatible=false"; + private final String type; private final String subtype; private final Map<String, String> parameters; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java index b89dac8..79e4400 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java @@ -28,7 +28,8 @@ public class ComplexSerializerOptions { private ContextURL contextURL; private ExpandOption expand; private SelectOption select; - + private boolean isIEEE754Compatible; + /** Gets the {@link ContextURL}. */ public ContextURL getContextURL() { return contextURL; @@ -43,7 +44,12 @@ public class ComplexSerializerOptions { public SelectOption getSelect() { return select; } - + + /** Serialize Edm.Int64 and Edm.Durration as strings **/ + public boolean isIEEE754Compatible() { + return isIEEE754Compatible; + } + private ComplexSerializerOptions() {} /** Initializes the options builder. */ @@ -77,7 +83,13 @@ public class ComplexSerializerOptions { options.select = select; return this; } - + + /** Set to serialize Edm.Int64 and Edm.Decimal as strings */ + public Builder setIEEE754Compatible(final boolean isIEEE754Compatible) { + options.isIEEE754Compatible = isIEEE754Compatible; + return this; + } + /** Builds the OData serializer options. */ public ComplexSerializerOptions build() { return options; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java index bbfe1bf..996a086 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java @@ -31,7 +31,8 @@ public class EntityCollectionSerializerOptions { private ExpandOption expand; private SelectOption select; private boolean onlyReferences; - + private boolean isIEEE754Compatible; + /** Gets the {@link ContextURL}. */ public ContextURL getContextURL() { return contextURL; @@ -57,6 +58,11 @@ public class EntityCollectionSerializerOptions { return onlyReferences; } + /** Serialize Edm.Int64 and Edm.Durration as strings **/ + public boolean isIEEE754Compatible() { + return isIEEE754Compatible; + } + /** Initializes the options builder. */ public static Builder with() { return new Builder(); @@ -100,7 +106,13 @@ public class EntityCollectionSerializerOptions { options.onlyReferences = ref; return this; } - + + /** Set to serialize Edm.Int64 and Edm.Decimal as strings */ + public Builder setIEEE754Compatible(final boolean isIEEE754Compatible) { + options.isIEEE754Compatible = isIEEE754Compatible; + return this; + } + /** Builds the OData serializer options. */ public EntityCollectionSerializerOptions build() { return options; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java index 563b058..208bcdd 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java @@ -28,7 +28,8 @@ public class EntitySerializerOptions { private ExpandOption expand; private SelectOption select; private boolean onlyReferences; - + private boolean isIEEE754Compatible; + /** Gets the {@link ContextURL}. */ public ContextURL getContextURL() { return contextURL; @@ -49,6 +50,11 @@ public class EntitySerializerOptions { return onlyReferences; } + /** Serialize Edm.Int64 and Edm.Durration as strings **/ + public boolean isIEEE754Compatible() { + return isIEEE754Compatible; + } + private EntitySerializerOptions() {} /** Initializes the options builder. */ @@ -88,7 +94,13 @@ public class EntitySerializerOptions { options.onlyReferences = ref; return this; } - + + /** Set to serialize Edm.Int64 and Edm.Decimal as strings */ + public Builder setIEEE754Compatible(final boolean isIEEE754Compatible) { + options.isIEEE754Compatible = isIEEE754Compatible; + return this; + } + /** Builds the OData serializer options. */ public EntitySerializerOptions build() { return options; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java index 3727064..21066bb 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java @@ -18,7 +18,6 @@ */ package org.apache.olingo.server.api.serializer; -import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.Property; @@ -119,18 +118,18 @@ public interface ODataSerializer { * @param metadata metadata for the service * @param edmEntitySet {@link EdmEntitySet} * @param entity data of the entity - * @param contextURL {@link ContextURL} + * @param options {@link ReferenceSerializerOptions} */ - SerializerResult reference(ServiceMetadata metadata, EdmEntitySet edmEntitySet, Entity entity, - ContextURL contextURL) throws SerializerException; - + SerializerResult reference(ServiceMetadata metadata, EdmEntitySet edmEntitySet, Entity entity, + ReferenceSerializerOptions options) throws SerializerException; + /** * Writes entity-collection references into an InputStream. * @param metadata metadata for the service * @param edmEntitySet {@link EdmEntitySet} * @param entityCollection data of the entity collection - * @param contextURL {@link ContextURL} + * @param ReferenceCollectionSerializerOptions {@link ReferenceCollectionSerializerOptions} */ - SerializerResult referenceCollection(ServiceMetadata metadata, EdmEntitySet edmEntitySet, - EntityCollection entityCollection, ContextURL contextURL) throws SerializerException; + SerializerResult referenceCollection(ServiceMetadata metadata, EdmEntitySet edmEntitySet, + EntityCollection entityCollection, ReferenceCollectionSerializerOptions options) throws SerializerException; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java index bd34599..2b586e1 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java @@ -30,7 +30,8 @@ public class PrimitiveSerializerOptions { private Integer precision; private Integer scale; private Boolean isUnicode; - + private boolean isIEEE754Compatible; + /** Gets the {@link ContextURL}. */ public ContextURL getContextURL() { return contextURL; @@ -60,7 +61,12 @@ public class PrimitiveSerializerOptions { public Boolean isUnicode() { return isUnicode; } - + + /** Serialize Edm.Int64 and Edm.Durration as strings **/ + public boolean isIEEE754Compatible() { + return isIEEE754Compatible; + } + private PrimitiveSerializerOptions() {} /** Initializes the options builder. */ @@ -112,7 +118,13 @@ public class PrimitiveSerializerOptions { options.isUnicode = isUnicode; return this; } - + + /** Set to serialize Edm.Int64 and Edm.Decimal as strings */ + public Builder setIEEE754Compatible(final boolean isIEEE754Compatible) { + options.isIEEE754Compatible = isIEEE754Compatible; + return this; + } + /** Sets all facets from an EDM property. */ public Builder facetsFrom(final EdmProperty property) { options.isNullable = property.isNullable(); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceCollectionSerializerOptions.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceCollectionSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceCollectionSerializerOptions.java new file mode 100644 index 0000000..4d88895 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceCollectionSerializerOptions.java @@ -0,0 +1,83 @@ +/* + * 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.api.serializer; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.server.api.uri.queryoption.CountOption; + +/** Options for the OData serializer. */ +public class ReferenceCollectionSerializerOptions { + private ContextURL contextURL; + private boolean isIEEE754Compatible; + private CountOption count; + + /** Gets the {@link ContextURL}. */ + public ContextURL getContextURL() { + return contextURL; + } + + /** Gets the $count system query option. */ + public CountOption getCount() { + return count; + } + + /** Serialize Edm.Int64 and Edm.Durration as strings **/ + public boolean isIEEE754Compatible() { + return isIEEE754Compatible; + } + + private ReferenceCollectionSerializerOptions() {} + + /** Initializes the options builder. */ + public static Builder with() { + return new Builder(); + } + + /** Builder of OData serializer options. */ + public static final class Builder { + private ReferenceCollectionSerializerOptions options; + + public Builder() { + options = new ReferenceCollectionSerializerOptions(); + } + + /** Sets the {@link ContextURL}. */ + public Builder contextURL(final ContextURL contextURL) { + options.contextURL = contextURL; + return this; + } + + /** Sets the $count system query option. */ + public Builder count(final CountOption count) { + options.count = count; + return this; + } + + /** Set to serialize Edm.Int64 and Edm.Decimal as strings */ + public Builder setIEEE754Compatible(final boolean isIEEE754Compatible) { + options.isIEEE754Compatible = isIEEE754Compatible; + return this; + } + + /** Builds the OData serializer options. */ + public ReferenceCollectionSerializerOptions build() { + return options; + } + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceSerializerOptions.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceSerializerOptions.java new file mode 100644 index 0000000..0479ca4 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ReferenceSerializerOptions.java @@ -0,0 +1,57 @@ +/* + * 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.api.serializer; + +import org.apache.olingo.commons.api.data.ContextURL; + +public class ReferenceSerializerOptions { + private ContextURL contextURL; + + /** Gets the {@link ContextURL}. */ + public ContextURL getContextURL() { + return contextURL; + } + + private ReferenceSerializerOptions() {} + + /** Initializes the options builder. */ + public static Builder with() { + return new Builder(); + } + + /** Builder of OData serializer options. */ + public static final class Builder { + private ReferenceSerializerOptions options; + + public Builder() { + options = new ReferenceSerializerOptions(); + } + + /** Sets the {@link ContextURL}. */ + public Builder contextURL(final ContextURL contextURL) { + options.contextURL = contextURL; + return this; + } + + /** Builds the OData serializer options. */ + public ReferenceSerializerOptions build() { + return options; + } + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java index 351b769..e127dcd 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ContentNegotiator.java @@ -133,6 +133,18 @@ public class ContentNegotiator { throw new IllegalArgumentException("charset not supported: " + acceptedType); } } + + if(acceptedType.getParameters().containsKey("ieee754compatible")) { + final String value = acceptedType.getParameters().get("ieee754compatible"); + if("true".equalsIgnoreCase(value)) { + contentType = ContentType.create(contentType, ContentType.PARAMETER_IEEE754_COMPATIBLE); + } else if("false".equalsIgnoreCase(value)) { + contentType = ContentType.create(contentType, ContentType.PARAMETER_IEEE754_COMPATIBLE_FALSE); + } else { + throw new IllegalArgumentException("Invalid IEEE754Compatible value " + acceptedType); + } + } + if (acceptedType.matches(contentType)) { return contentType; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java index 168adfa..fddef6a 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java @@ -50,6 +50,8 @@ import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions import org.apache.olingo.server.api.serializer.EntitySerializerOptions; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriHelper; @@ -150,14 +152,14 @@ public class ODataJsonSerializer implements ODataSerializer { if (options != null && options.getCount() != null && options.getCount().getValue() && entitySet.getCount() != null) { - writeCount(entitySet, json); + writeCount(entitySet, options == null ? false : options.isIEEE754Compatible(), json); } json.writeFieldName(Constants.VALUE); if (options == null) { - writeEntitySet(metadata, entityType, entitySet, null, null, false, json); + writeEntitySet(metadata, entityType, entitySet, null, null, false, false, json); } else { writeEntitySet(metadata, entityType, entitySet, - options.getExpand(), options.getSelect(), options.onlyReferences(), json); + options.getExpand(), options.getSelect(), options.onlyReferences(), options.isIEEE754Compatible(), json); } if (entitySet.getNext() != null) { writeNextLink(entitySet, json); @@ -180,7 +182,8 @@ public class ODataJsonSerializer implements ODataSerializer { writeEntity(metadata, entityType, entity, contextURL, options == null ? null : options.getExpand(), options == null ? null : options.getSelect(), - options == null ? false : options.onlyReferences(), json); + options == null ? false : options.onlyReferences(), + options == null ? false : options.isIEEE754Compatible(), json); json.close(); } catch (final IOException e) { throw new SerializerException("An I/O exception occurred.", e, @@ -210,7 +213,7 @@ public class ODataJsonSerializer implements ODataSerializer { protected void writeEntitySet(final ServiceMetadata metadata, final EdmEntityType entityType, final EntityCollection entitySet, final ExpandOption expand, final SelectOption select, - final boolean onlyReference, final JsonGenerator json) throws IOException, + final boolean onlyReference, final boolean isIEEE754Compatible, final JsonGenerator json) throws IOException, SerializerException { json.writeStartArray(); for (final Entity entity : entitySet.getEntities()) { @@ -219,7 +222,7 @@ public class ODataJsonSerializer implements ODataSerializer { json.writeStringField(Constants.JSON_ID, entity.getId().toASCIIString()); json.writeEndObject(); } else { - writeEntity(metadata, entityType, entity, null, expand, select, false, json); + writeEntity(metadata, entityType, entity, null, expand, select, false, isIEEE754Compatible, json); } } json.writeEndArray(); @@ -227,8 +230,8 @@ public class ODataJsonSerializer implements ODataSerializer { protected void writeEntity(final ServiceMetadata metadata, final EdmEntityType entityType, final Entity entity, final ContextURL contextURL, final ExpandOption expand, - final SelectOption select, final boolean onlyReference, final JsonGenerator json) - throws IOException, SerializerException { + final SelectOption select, final boolean onlyReference, final boolean isIEEE7854Compatible, + final JsonGenerator json) throws IOException, SerializerException { json.writeStartObject(); if (format != ODataFormat.JSON_NO_METADATA) { if (contextURL != null) { // top-level entity @@ -260,8 +263,8 @@ public class ODataJsonSerializer implements ODataSerializer { if (!resolvedType.equals(entityType)) { json.writeStringField(Constants.JSON_TYPE, "#" + entity.getType()); } - writeProperties(resolvedType, entity.getProperties(), select, json); - writeNavigationProperties(metadata, resolvedType, entity, expand, json); + writeProperties(resolvedType, entity.getProperties(), select, isIEEE7854Compatible, json); + writeNavigationProperties(metadata, resolvedType, entity, expand, isIEEE7854Compatible, json); json.writeEndObject(); } } @@ -315,7 +318,8 @@ public class ODataJsonSerializer implements ODataSerializer { } protected void writeProperties(final EdmStructuredType type, final List<Property> properties, - final SelectOption select, final JsonGenerator json) throws IOException, SerializerException { + final SelectOption select, final boolean isIEEE754Compatible, final JsonGenerator json) + throws IOException, SerializerException { final boolean all = ExpandSelectHelper.isAll(select); final Set<String> selected = all ? null : ExpandSelectHelper.getSelectedPropertyNames(select.getSelectItems()); @@ -325,14 +329,14 @@ public class ODataJsonSerializer implements ODataSerializer { final Property property = findProperty(propertyName, properties); final Set<List<String>> selectedPaths = all || edmProperty.isPrimitive() ? null : ExpandSelectHelper.getSelectedPaths(select.getSelectItems(), propertyName); - writeProperty(edmProperty, property, selectedPaths, json); + writeProperty(edmProperty, property, selectedPaths, isIEEE754Compatible, json); } } } protected void writeNavigationProperties(final ServiceMetadata metadata, final EdmStructuredType type, final Linked linked, final ExpandOption expand, - final JsonGenerator json) throws SerializerException, IOException { + final boolean isIEEE754Compatible, final JsonGenerator json) throws SerializerException, IOException { if (ExpandSelectHelper.hasExpand(expand)) { final boolean expandAll = ExpandSelectHelper.isExpandAll(expand); final Set<String> expanded = expandAll ? null : @@ -349,9 +353,8 @@ public class ODataJsonSerializer implements ODataSerializer { } writeExpandedNavigationProperty(metadata, property, navigationLink, innerOptions == null ? null : innerOptions.getExpandOption(), - innerOptions == null ? null : innerOptions.getSelectOption(), - innerOptions == null ? false: innerOptions.isRef(), - json); + innerOptions == null ? null : innerOptions.getSelectOption(), + isIEEE754Compatible, json); } } } @@ -359,7 +362,7 @@ public class ODataJsonSerializer implements ODataSerializer { protected void writeExpandedNavigationProperty(final ServiceMetadata metadata, final EdmNavigationProperty property, final Link navigationLink, - final ExpandOption innerExpand, final SelectOption innerSelect, boolean onlyReference, + final ExpandOption innerExpand, final SelectOption innerSelect, final boolean isIEEE754Compatible, final JsonGenerator json) throws IOException, SerializerException { json.writeFieldName(property.getName()); @@ -369,20 +372,21 @@ public class ODataJsonSerializer implements ODataSerializer { json.writeEndArray(); } else { writeEntitySet(metadata, property.getType(), navigationLink.getInlineEntitySet(), innerExpand, - innerSelect, onlyReference, json); + innerSelect, false, isIEEE754Compatible, json); } } else { if (navigationLink == null || navigationLink.getInlineEntity() == null) { json.writeNull(); } else { writeEntity(metadata, property.getType(), navigationLink.getInlineEntity(), null, - innerExpand, innerSelect, onlyReference, json); + innerExpand, innerSelect, false, isIEEE754Compatible, json); } } } protected void writeProperty(final EdmProperty edmProperty, final Property property, - final Set<List<String>> selectedPaths, final JsonGenerator json) throws IOException, SerializerException { + final Set<List<String>> selectedPaths, final boolean isIEEE754Compatible, final JsonGenerator json) + throws IOException, SerializerException { json.writeFieldName(edmProperty.getName()); if (property == null || property.isNull()) { if (edmProperty.isNullable() == Boolean.FALSE) { @@ -392,36 +396,38 @@ public class ODataJsonSerializer implements ODataSerializer { json.writeNull(); } } else { - writePropertyValue(edmProperty, property, selectedPaths, json); + writePropertyValue(edmProperty, property, selectedPaths, isIEEE754Compatible, json); } } private void writePropertyValue(final EdmProperty edmProperty, final Property property, final Set<List<String>> selectedPaths, - final JsonGenerator json) throws IOException, SerializerException { + final boolean isIEEE754Compatible, final JsonGenerator json) throws IOException, SerializerException { try { if (edmProperty.isPrimitive()) { if (edmProperty.isCollection()) { writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property, edmProperty.isNullable(), edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), + isIEEE754Compatible, json); } else { writePrimitive((EdmPrimitiveType) edmProperty.getType(), property, edmProperty.isNullable(), edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), - json); + isIEEE754Compatible, json); } } else if (edmProperty.isCollection()) { - writeComplexCollection((EdmComplexType) edmProperty.getType(), property, selectedPaths, json); + writeComplexCollection((EdmComplexType) edmProperty.getType(), property, + selectedPaths, isIEEE754Compatible, json); } else if (property.isComplex()) { writeComplexValue((EdmComplexType) edmProperty.getType(), property.asComplex().getValue(), - selectedPaths, json); + selectedPaths, isIEEE754Compatible, json); } else if (property.isEnum()) { writePrimitive((EdmPrimitiveType) edmProperty.getType(), property, edmProperty.isNullable(), edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), - json); + isIEEE754Compatible, json); } else { throw new SerializerException("Property type not yet supported!", SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName()); @@ -436,12 +442,13 @@ public class ODataJsonSerializer implements ODataSerializer { private void writePrimitiveCollection(final EdmPrimitiveType type, final Property property, final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode, - final JsonGenerator json) throws IOException, EdmPrimitiveTypeException, SerializerException { + final boolean isIEEE754Compatible, final JsonGenerator json) + throws IOException, EdmPrimitiveTypeException, SerializerException { json.writeStartArray(); for (Object value : property.asCollection()) { switch (property.getValueType()) { case COLLECTION_PRIMITIVE: - writePrimitiveValue(type, value, isNullable, maxLength, precision, scale, isUnicode, json); + writePrimitiveValue(type, value, isNullable, maxLength, precision, scale, isUnicode, isIEEE754Compatible, json); break; case COLLECTION_GEOSPATIAL: throw new SerializerException("Property type not yet supported!", @@ -458,13 +465,13 @@ public class ODataJsonSerializer implements ODataSerializer { } private void writeComplexCollection(final EdmComplexType type, final Property property, - final Set<List<String>> selectedPaths, final JsonGenerator json) + final Set<List<String>> selectedPaths, final boolean isIEEE754Compatible, final JsonGenerator json) throws IOException, EdmPrimitiveTypeException, SerializerException { json.writeStartArray(); for (Object value : property.asCollection()) { switch (property.getValueType()) { case COLLECTION_COMPLEX: - writeComplexValue(type, ((ComplexValue) value).getValue(), selectedPaths, json); + writeComplexValue(type, ((ComplexValue) value).getValue(), selectedPaths, isIEEE754Compatible, json); break; default: throw new SerializerException("Property type not yet supported!", @@ -476,17 +483,17 @@ public class ODataJsonSerializer implements ODataSerializer { private void writePrimitive(final EdmPrimitiveType type, final Property property, final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, - final Boolean isUnicode, final JsonGenerator json) + final Boolean isUnicode, final boolean isIEEE754Compatible, final JsonGenerator json) throws EdmPrimitiveTypeException, IOException, SerializerException { if (property.isPrimitive()) { writePrimitiveValue(type, property.asPrimitive(), - isNullable, maxLength, precision, scale, isUnicode, json); + isNullable, maxLength, precision, scale, isUnicode, isIEEE754Compatible, json); } else if (property.isGeospatial()) { throw new SerializerException("Property type not yet supported!", SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName()); } else if (property.isEnum()) { writePrimitiveValue(type, property.asEnum(), - isNullable, maxLength, precision, scale, isUnicode, json); + isNullable, maxLength, precision, scale, isUnicode, isIEEE754Compatible, json); } else { throw new SerializerException("Inconsistent property type!", SerializerException.MessageKeys.INCONSISTENT_PROPERTY_TYPE, property.getName()); @@ -496,13 +503,17 @@ public class ODataJsonSerializer implements ODataSerializer { protected void writePrimitiveValue(final EdmPrimitiveType type, final Object primitiveValue, final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode, - final JsonGenerator json) throws EdmPrimitiveTypeException, IOException { + final boolean isIEEE754Compatible, final JsonGenerator json) throws EdmPrimitiveTypeException, IOException { final String value = type.valueToString(primitiveValue, isNullable, maxLength, precision, scale, isUnicode); if (value == null) { json.writeNull(); } else if(type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) { json.writeBoolean(Boolean.parseBoolean(value)); + } else if(isIEEE754Compatible && + ( type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int64) + || type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal))) { + json.writeString(value.toString()); } else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte) || type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal) || type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Double) @@ -518,7 +529,7 @@ public class ODataJsonSerializer implements ODataSerializer { } protected void writeComplexValue(final EdmComplexType type, final List<Property> properties, - final Set<List<String>> selectedPaths, final JsonGenerator json) + final Set<List<String>> selectedPaths, final boolean isIEEE754Compatible, final JsonGenerator json) throws IOException, EdmPrimitiveTypeException, SerializerException { json.writeStartObject(); for (final String propertyName : type.getPropertyNames()) { @@ -526,7 +537,7 @@ public class ODataJsonSerializer implements ODataSerializer { if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) { writeProperty((EdmProperty) type.getProperty(propertyName), property, selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName), - json); + isIEEE754Compatible, json); } } json.writeEndObject(); @@ -559,8 +570,7 @@ public class ODataJsonSerializer implements ODataSerializer { json.writeFieldName(Constants.VALUE); writePrimitive(type, property, options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(), - options.isUnicode(), - json); + options.isUnicode(), options.isIEEE754Compatible(), json); } json.writeEndObject(); json.close(); @@ -593,10 +603,10 @@ public class ODataJsonSerializer implements ODataSerializer { } final List<Property> values = property.isNull() ? Collections.<Property> emptyList() : property.asComplex().getValue(); - writeProperties(type, values, options == null ? null : options.getSelect(), json); + writeProperties(type, values, options == null ? null : options.getSelect(), options.isIEEE754Compatible(), json); if (!property.isNull() && property.isComplex()) { writeNavigationProperties(metadata, type, property.asComplex(), - options == null ? null : options.getExpand(), json); + options == null ? null : options.getExpand(), options.isIEEE754Compatible(), json); } json.writeEndObject(); json.close(); @@ -622,8 +632,7 @@ public class ODataJsonSerializer implements ODataSerializer { json.writeFieldName(Constants.VALUE); writePrimitiveCollection(type, property, options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(), - options.isUnicode(), - json); + options.isUnicode(), options.isIEEE754Compatible(), json); json.writeEndObject(); json.close(); } catch (final IOException e) { @@ -650,7 +659,7 @@ public class ODataJsonSerializer implements ODataSerializer { } writeMetadataETag(metadata, json); json.writeFieldName(Constants.VALUE); - writeComplexCollection(type, property, null, json); + writeComplexCollection(type, property, null, options.isIEEE754Compatible(), json); json.writeEndObject(); json.close(); } catch (final IOException e) { @@ -666,8 +675,8 @@ public class ODataJsonSerializer implements ODataSerializer { @Override public SerializerResult reference(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet, - final Entity entity, final ContextURL contextURL) throws SerializerException { - + final Entity entity, final ReferenceSerializerOptions options) throws SerializerException { + final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL()); final CircleStreamBuffer buffer = new CircleStreamBuffer(); final UriHelper uriHelper = new UriHelperImpl(); @@ -685,8 +694,9 @@ public class ODataJsonSerializer implements ODataSerializer { @Override public SerializerResult referenceCollection(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet, - final EntityCollection entityCollection, final ContextURL contextURL) throws SerializerException { - + final EntityCollection entityCollection, final ReferenceCollectionSerializerOptions options) + throws SerializerException { + final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL()); final CircleStreamBuffer buffer = new CircleStreamBuffer(); final UriHelper uriHelper = new UriHelperImpl(); @@ -694,12 +704,12 @@ public class ODataJsonSerializer implements ODataSerializer { final JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream()); json.writeStartObject(); - if(entityCollection.getCount() != null) { - writeCount(entityCollection, json); - } - json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString()); writeMetadataETag(metadata, json); + if(options != null && options.getCount() != null) { + writeCount(entityCollection, (options == null) ? false : options.isIEEE754Compatible(), json); + } + writeReferenceCollection(edmEntitySet, entityCollection, uriHelper,json); if(entityCollection.getNext() != null) { @@ -718,7 +728,7 @@ public class ODataJsonSerializer implements ODataSerializer { protected void writeReferenceCollection(final EdmEntitySet edmEntitySet, final EntityCollection entityCollection, final UriHelper uriHelper, final JsonGenerator json) throws IOException, SerializerException { json.writeArrayFieldStart(Constants.VALUE); - + for(final Entity entity : entityCollection.getEntities()) { writeReference(null, edmEntitySet, entity, null, uriHelper, json); } @@ -739,8 +749,13 @@ public class ODataJsonSerializer implements ODataSerializer { json.writeEndObject(); } - private void writeCount(final EntityCollection entitySet, JsonGenerator json) throws IOException { - json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount()); + private void writeCount(final EntityCollection entitySet, final boolean isIEEE754Comptible, final JsonGenerator json) + throws IOException { + if(isIEEE754Comptible) { + json.writeStringField(Constants.JSON_COUNT, entitySet.getCount().toString()); + } else { + json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount()); + } } private void writeNextLink(final EntityCollection entitySet, JsonGenerator json) throws IOException { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java index e6b04a6..1e7349b 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java @@ -22,7 +22,6 @@ import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.data.Property; @@ -37,6 +36,8 @@ import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions import org.apache.olingo.server.api.serializer.EntitySerializerOptions; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.core.serializer.SerializerResultImpl; @@ -139,14 +140,15 @@ public class ODataXmlSerializerImpl implements ODataSerializer { @Override public SerializerResult reference(final ServiceMetadata metadata, final EdmEntitySet edmEntotySet, - final Entity entity, final ContextURL contextURL) throws SerializerException { + final Entity entity, final ReferenceSerializerOptions options) throws SerializerException { throw new SerializerException("Serialization not implemented for XML format.", SerializerException.MessageKeys.NOT_IMPLEMENTED); } @Override public SerializerResult referenceCollection(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet, - final EntityCollection entityCollection, final ContextURL contextURL) throws SerializerException { + final EntityCollection entityCollection, final ReferenceCollectionSerializerOptions optionsL) + throws SerializerException { throw new SerializerException("Serialization not implemented for XML format.", SerializerException.MessageKeys.NOT_IMPLEMENTED); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java index f84ef95..b959bb6 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/ContentNegotiatorTest.java @@ -46,32 +46,39 @@ public class ContentNegotiatorTest { static final private String ACCEPT_CASE_MIN_UTF8 = "application/json;charset=UTF-8;odata.metadata=minimal"; static final private String ACCEPT_CASE_FULL = "application/json;odata.metadata=full"; static final private String ACCEPT_CASE_NONE = "application/json;odata.metadata=none"; + static final private String ACCEPT_CASE_MIN_UTF8_IEEE754 + = "application/json;charset=UTF-8;odata.metadata=minimal;IEEE754Compatible=true"; + static final private String ACCEPT_CASE_MIN_IEEE754 + = "application/json;odata.metadata=minimal;IEEE754Compatible=true"; static final private String ACCEPT_CASE_JSONQ = "application/json;q=0.2"; static final private String ACCEPT_CASE_XML = HttpContentType.APPLICATION_XML; static final private String ACCEPT_CASE_WILDCARD1 = HttpContentType.WILDCARD; static final private String ACCEPT_CASE_WILDCARD2 = "application/*"; - + //@formatter:off (Eclipse formatter) //CHECKSTYLE:OFF (Maven checkstyle) String[][] casesServiceDocument = { - /* expected $format accept modified content types */ - { ACCEPT_CASE_MIN, null, null, null }, - { ACCEPT_CASE_MIN, "json", null, null }, - { ACCEPT_CASE_MIN, "json", ACCEPT_CASE_JSONQ, null }, - { ACCEPT_CASE_NONE, ACCEPT_CASE_NONE, null, null }, - { "a/a", "a/a", null, "a/a" }, - { ACCEPT_CASE_MIN, null, ACCEPT_CASE_JSONQ, null }, - { ACCEPT_CASE_MIN, null, ACCEPT_CASE_WILDCARD1, null }, - { ACCEPT_CASE_MIN, null, ACCEPT_CASE_WILDCARD2, null }, - { ACCEPT_CASE_MIN, null, null, ACCEPT_CASE_MIN }, - { "a/a", "a/a", null, "a/a,b/b" }, - { "a/a;x=y", "a/a", ACCEPT_CASE_WILDCARD1, "a/a;x=y" }, - { "a/a;v=w;x=y", null, "a/a;x=y", "a/a;b=c,a/a;v=w;x=y" }, - { "a/a;v=w;x=y", "a/a;x=y", null, "a/a;b=c,a/a;v=w;x=y" }, - { ACCEPT_CASE_MIN, "json", ACCEPT_CASE_MIN, null }, - { ACCEPT_CASE_FULL, null, ACCEPT_CASE_FULL, ACCEPT_CASE_FULL }, - { ACCEPT_CASE_MIN_UTF8, null, ACCEPT_CASE_MIN_UTF8, null } + /* expected $format accept modified content types */ + { ACCEPT_CASE_MIN, null, null, null }, + { ACCEPT_CASE_MIN, "json", null, null }, + { ACCEPT_CASE_MIN, "json", ACCEPT_CASE_JSONQ, null }, + { ACCEPT_CASE_NONE, ACCEPT_CASE_NONE, null, null }, + { "a/a", "a/a", null, "a/a" }, + { ACCEPT_CASE_MIN, null, ACCEPT_CASE_JSONQ, null }, + { ACCEPT_CASE_MIN, null, ACCEPT_CASE_WILDCARD1, null }, + { ACCEPT_CASE_MIN, null, ACCEPT_CASE_WILDCARD2, null }, + { ACCEPT_CASE_MIN, null, null, ACCEPT_CASE_MIN }, + { "a/a", "a/a", null, "a/a,b/b" }, + { "a/a;x=y", "a/a", ACCEPT_CASE_WILDCARD1, "a/a;x=y" }, + { "a/a;v=w;x=y", null, "a/a;x=y", "a/a;b=c,a/a;v=w;x=y" }, + { "a/a;v=w;x=y", "a/a;x=y", null, "a/a;b=c,a/a;v=w;x=y" }, + { ACCEPT_CASE_MIN, "json", ACCEPT_CASE_MIN, null }, + { ACCEPT_CASE_FULL, null, ACCEPT_CASE_FULL, ACCEPT_CASE_FULL }, + { ACCEPT_CASE_MIN_UTF8, null, ACCEPT_CASE_MIN_UTF8, null }, + { ACCEPT_CASE_MIN_IEEE754, null, ACCEPT_CASE_MIN_IEEE754, null }, + { ACCEPT_CASE_MIN_UTF8_IEEE754, null, ACCEPT_CASE_MIN_UTF8_IEEE754, null }, + { ACCEPT_CASE_MIN_IEEE754, ACCEPT_CASE_MIN_IEEE754, ACCEPT_CASE_MIN , null }, }; String[][] casesMetadata = { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index 575b914..25747bb 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -48,6 +48,8 @@ import org.apache.olingo.server.api.processor.ReferenceCollectionProcessor; import org.apache.olingo.server.api.processor.ReferenceProcessor; import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; import org.apache.olingo.server.api.serializer.EntitySerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriResourceEntitySet; @@ -435,8 +437,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final CountOption countOption = uriInfo.getCountOption(); // Serialize - final SerializerResult serializerResult = isReference ? - serializeReferenceCollection(entitySetSerialization, edmEntitySet, format) : + final SerializerResult serializerResult = (isReference) ? + serializeReferenceCollection(entitySetSerialization, edmEntitySet, format, countOption) : serializeEntityCollection(entitySetSerialization, edmEntitySet, edmEntityType, format, expand, select, countOption); @@ -461,18 +463,23 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .build()); } - private SerializerResult serializeReferenceCollection(final EntityCollection entityCollection, - final EdmEntitySet edmEntitySet, final ODataFormat format) throws ODataLibraryException { + private SerializerResult serializeReferenceCollection(final EntityCollection entityCollection, + final EdmEntitySet edmEntitySet, final ODataFormat format, final CountOption countOption) + throws ODataLibraryException { + return odata.createSerializer(format) - .referenceCollection(serviceMetadata, edmEntitySet, entityCollection, - ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()); + .referenceCollection(serviceMetadata, edmEntitySet, entityCollection,ReferenceCollectionSerializerOptions.with() + .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()) + .count(countOption) + .setIEEE754Compatible(false).build()); } private SerializerResult serializeReference(final Entity entity, final EdmEntitySet edmEntitySet, final ODataFormat format) throws ODataLibraryException { return odata.createSerializer(format) - .reference(serviceMetadata, edmEntitySet, entity, - ContextURL.with().suffix(Suffix.REFERENCE).build()); + .reference(serviceMetadata, edmEntitySet, entity, ReferenceSerializerOptions.with() + .contextURL(ContextURL.with().suffix(Suffix.REFERENCE).build()).build()); + } private SerializerResult serializeEntity(final Entity entity, http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java index 0956c91..d4739be 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java @@ -50,9 +50,11 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmDate; import org.apache.olingo.commons.core.edm.primitivetype.EdmDateTimeOffset; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.deserializer.DeserializerException; +import org.apache.olingo.server.api.deserializer.DeserializerResult; import org.apache.olingo.server.api.deserializer.ODataDeserializer; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; +import org.junit.Ignore; import org.junit.Test; public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTest { @@ -1412,7 +1414,37 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe throw e; } } - + + @Test + @Ignore + public void ieee754Compatible() throws Exception { + ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); + String entityString = + "{\"PropertyInt16\":32767," + + "\"PropertyString\":\"First Resource - positive values\"," + + "\"PropertyBoolean\":null," + + "\"PropertyByte\":255," + + "\"PropertySByte\":127," + + "\"PropertyInt32\":2147483647," + + "\"PropertyInt64\":\"9223372036854775807\"," + + "\"PropertySingle\":1.79E20," + + "\"PropertyDouble\":-1.79E19," + + "\"PropertyDecimal\":\"34\"," + + "\"PropertyBinary\":\"ASNFZ4mrze8=\"," + + "\"PropertyDate\":null," + + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," + + "\"PropertyDuration\":\"PT6S\"," + + "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," + + "\"PropertyTimeOfDay\":\"03:26:05\"}"; + + final InputStream stream = new ByteArrayInputStream(entityString.getBytes()); + final Entity entity = deserializer + .entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"))).getEntity(); + + assertEquals(9223372036854775807L, entity.getProperty("PropertyInt64").asPrimitive()); + assertEquals(34, entity.getProperty("PropertyDecimal").asPrimitive()); + } + private void checkPropertyJsonType(final String entityString) throws DeserializerException { InputStream stream = new ByteArrayInputStream(entityString.getBytes()); ODataDeserializer deserializer = OData.newInstance().createDeserializer(ODataFormat.JSON); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/974abcb4/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java index c9cfde9..2f91777 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java @@ -44,6 +44,8 @@ import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions import org.apache.olingo.server.api.serializer.EntitySerializerOptions; import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriHelper; @@ -711,7 +713,7 @@ public class ODataJsonSerializerTest { + "\"PropertyInt16\":111,\"PropertyString\":\"TEST A\"}", resultString); } - + @Test public void complexCollectionProperty() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp"); @@ -740,7 +742,7 @@ public class ODataJsonSerializerTest { final Entity entity = data.readAll(edmEntitySet).getEntities().get(0); final SerializerResult serializerResult = serializer.reference(metadata, edmEntitySet, entity, - ContextURL.with().suffix(Suffix.REFERENCE).build()); + ReferenceSerializerOptions.with().contextURL(ContextURL.with().suffix(Suffix.REFERENCE).build()).build()); final String resultString = IOUtils.toString(serializerResult.getContent()); Assert.assertEquals("{\"@odata.context\":\"$metadata#$ref\"," @@ -754,11 +756,13 @@ public class ODataJsonSerializerTest { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); final EntityCollection entityCollection = data.readAll(edmEntitySet); - final SerializerResult serializerResult = serializer.referenceCollection(metadata, - edmEntitySet, - entityCollection, - ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()); - + final SerializerResult serializerResult = serializer.referenceCollection(metadata, + edmEntitySet, + entityCollection, + ReferenceCollectionSerializerOptions.with() + .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()) + .setIEEE754Compatible(false).build()); + final String resultString = IOUtils.toString(serializerResult.getContent()); Assert.assertEquals("{\"@odata.context\":\"$metadata#Collection($ref)\"," @@ -774,15 +778,219 @@ public class ODataJsonSerializerTest { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); final EntityCollection entityCollection = new EntityCollection(); - final SerializerResult serializerResult = serializer.referenceCollection(metadata, - edmEntitySet, - entityCollection, - ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()); - + final SerializerResult serializerResult = serializer.referenceCollection(metadata, + edmEntitySet, entityCollection, + ReferenceCollectionSerializerOptions.with() + .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()) + .setIEEE754Compatible(false).build()); + final String resultString = IOUtils.toString(serializerResult.getContent()); Assert.assertEquals("{\"@odata.context\":\"$metadata#Collection($ref)\"," + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"value\":[]}", resultString); } + + @Test + public void entityIEE754Compatible() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + final Entity entity = data.readAll(edmEntitySet).getEntities().get(0); + InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity, + EntitySerializerOptions.with() + .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()) + .setIEEE754Compatible(true) + .build()).getContent(); + final String resultString = IOUtils.toString(result); + final String expectedResult = "{" + + "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"," + + "\"PropertyInt16\":32767," + + "\"PropertyString\":\"First Resource - positive values\"," + + "\"PropertyBoolean\":true," + + "\"PropertyByte\":255," + + "\"PropertySByte\":127," + + "\"PropertyInt32\":2147483647," + + "\"PropertyInt64\":\"" + Long.MAX_VALUE + "\"," + + "\"PropertySingle\":1.79E20," + + "\"PropertyDouble\":-1.79E19," + + "\"PropertyDecimal\":\"34\"," + + "\"PropertyBinary\":\"ASNFZ4mrze8=\"," + + "\"PropertyDate\":\"2012-12-03\"," + + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," + + "\"PropertyDuration\":\"PT6S\"," + + "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," + + "\"PropertyTimeOfDay\":\"03:26:05\"" + + "}"; + Assert.assertEquals(expectedResult, resultString); + } + + @Test + public void entityCollAllPrimIEEE754Compatible() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim"); + final Entity entity = data.readAll(edmEntitySet).getEntities().get(0); + InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity, + EntitySerializerOptions.with() + .contextURL(ContextURL.with().serviceRoot(URI.create("http://host/service/")) + .entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()) + .setIEEE754Compatible(true) + .build()).getContent(); + final String resultString = IOUtils.toString(result); + final String expectedResult = "{" + + "\"@odata.context\":\"http://host/service/$metadata#ESCollAllPrim/$entity\"," + + "\"PropertyInt16\":1," + + "\"CollPropertyString\":" + + "[\"[email protected]\",\"[email protected]\",\"[email protected]\"]," + + "\"CollPropertyBoolean\":[true,false,true]," + + "\"CollPropertyByte\":[50,200,249]," + + "\"CollPropertySByte\":[-120,120,126]," + + "\"CollPropertyInt16\":[1000,2000,30112]," + + "\"CollPropertyInt32\":[23232323,11223355,10000001]," + + "\"CollPropertyInt64\":[\"929292929292\",\"333333333333\",\"444444444444\"]," + + "\"CollPropertySingle\":[1790.0,26600.0,3210.0]," + + "\"CollPropertyDouble\":[-17900.0,-2.78E7,3210.0]," + + "\"CollPropertyDecimal\":[\"12\",\"-2\",\"1234\"]," + + "\"CollPropertyBinary\":[\"q83v\",\"ASNF\",\"VGeJ\"]," + + "\"CollPropertyDate\":[\"1958-12-03\",\"1999-08-05\",\"2013-06-25\"]," + + "\"CollPropertyDateTimeOffset\":[\"2015-08-12T03:08:34Z\",\"1970-03-28T12:11:10Z\"," + + "\"1948-02-17T09:09:09Z\"]," + + "\"CollPropertyDuration\":[\"PT13S\",\"PT5H28M0S\",\"PT1H0S\"]," + + "\"CollPropertyGuid\":[\"ffffff67-89ab-cdef-0123-456789aaaaaa\",\"eeeeee67-89ab-cdef-0123-456789bbbbbb\"," + + "\"cccccc67-89ab-cdef-0123-456789cccccc\"]," + + "\"CollPropertyTimeOfDay\":[\"04:14:13\",\"23:59:59\",\"01:12:33\"]" + + "}"; + Assert.assertEquals(expectedResult, resultString); + } + + @Test + public void primitiveCollectionPropertyIEEE754CompatibleInt64() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyInt64"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + + final String resultString = IOUtils.toString(serializer + .primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property, + PrimitiveSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("1").navOrPropertyPath(edmProperty.getName()).build()) + .setIEEE754Compatible(true) + .build()).getContent()); + Assert.assertEquals("{" + + "\"@odata.context\":\"$metadata#ESCollAllPrim(1)/CollPropertyInt64\"," + + "\"value\":[\"929292929292\",\"333333333333\",\"444444444444\"]}", + resultString); + } + + @Test + public void primitiveCollectionPropertyIEEE754CompatibleDecimal() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyDecimal"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + + final String resultString = IOUtils.toString(serializer + .primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property, + PrimitiveSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("1").navOrPropertyPath(edmProperty.getName()).build()) + .setIEEE754Compatible(true) + .build()).getContent()); + Assert.assertEquals("{" + + "\"@odata.context\":\"$metadata#ESCollAllPrim(1)/CollPropertyDecimal\"," + + "\"value\":[\"12\",\"-2\",\"1234\"]}", + resultString); + } + + @Test + public void primitivePropertyIEEE754CompatibleInt64() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyInt64"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + final String resultString = IOUtils.toString(serializer + .primitive((EdmPrimitiveType) edmProperty.getType(), property, + PrimitiveSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName()).build()) + .setIEEE754Compatible(true) + .build()).getContent()); + Assert.assertEquals("{" + + "\"@odata.context\":\"$metadata#ESAllPrim(32767)/PropertyInt64\"," + + "\"value\":\"" + Long.MAX_VALUE + "\"}", + resultString); + } + + @Test + public void primitivePropertyIEEE754CompatibleDecimal() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyDecimal"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + final String resultString = IOUtils.toString(serializer + .primitive((EdmPrimitiveType) edmProperty.getType(), property, + PrimitiveSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName()).build()) + .setIEEE754Compatible(true) + .build()).getContent()); + Assert.assertEquals("{" + + "\"@odata.context\":\"$metadata#ESAllPrim(32767)/PropertyDecimal\"," + + "\"value\":\"34\"}", + resultString); + } + + @Test + public void entitySetAllPrimIEEE754CompatibleCount() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + EntityCollection entitySet = data.readAll(edmEntitySet); + entitySet.setCount(entitySet.getEntities().size()); + entitySet.setNext(URI.create("/next")); + CountOption countOption = Mockito.mock(CountOption.class); + Mockito.when(countOption.getValue()).thenReturn(true); + InputStream result = serializer.entityCollection(metadata, edmEntitySet.getEntityType(), entitySet, + EntityCollectionSerializerOptions.with() + .setIEEE754Compatible(true) + .contextURL(ContextURL.with().entitySet(edmEntitySet).build()) + .count(countOption) + .build()).getContent(); + final String resultString = IOUtils.toString(result); + + Assert.assertThat(resultString, CoreMatchers.startsWith("{" + + "\"@odata.context\":\"$metadata#ESAllPrim\"," + + "\"@odata.count\":\"3\",\"value\":[")); + Assert.assertThat(resultString, CoreMatchers.endsWith("]," + + "\"@odata.nextLink\":\"/next\"}")); + + int count = 0; + int index = -1; + while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) { + count++; + } + Assert.assertEquals(3, count); + } + + @Test + public void entitySetAllPrimReferenceIEEE754CompatibleCount() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + EntityCollection entitySet = data.readAll(edmEntitySet); + entitySet.setCount(entitySet.getEntities().size()); + entitySet.setNext(URI.create("/next")); + CountOption countOption = Mockito.mock(CountOption.class); + Mockito.when(countOption.getValue()).thenReturn(true); + InputStream result = serializer.referenceCollection(metadata, edmEntitySet, entitySet, + ReferenceCollectionSerializerOptions.with() + .setIEEE754Compatible(true) + .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()) + .count(countOption) + .build()).getContent(); + final String resultString = IOUtils.toString(result); + + Assert.assertThat(resultString, CoreMatchers.startsWith("{" + + "\"@odata.context\":\"$metadata#Collection($ref)\"," + + "\"@odata.count\":\"3\",\"value\":[")); + Assert.assertThat(resultString, CoreMatchers.endsWith("]," + + "\"@odata.nextLink\":\"/next\"}")); + + int count = 0; + int index = -1; + while ((index = resultString.indexOf("ESAllPrim(", ++index)) > 0) { + count++; + } + Assert.assertEquals(3, count); + } }
