[OLINGO-935] better type determination for client serializer + clean-up

Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
Klaus Straubinger 2016-07-12 15:51:40 +02:00 committed by Christian Amend
parent 8d51c870fa
commit 77423380bb
8 changed files with 238 additions and 273 deletions

View File

@ -1,98 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.client.core.serialization;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.olingo.commons.api.Constants;
abstract class AbstractAtomDealer {
protected static final String TYPE_TEXT = "text";
protected final String namespaceMetadata;
protected final String namespaceData;
protected final String namespaceAtom;
protected final QName etagQName;
protected final QName metadataEtagQName;
protected final QName inlineQName;
protected final QName actionQName;
protected final QName propertiesQName;
protected final QName typeQName;
protected final QName nullQName;
protected final QName elementQName;
protected final QName countQName;
protected final QName uriQName;
protected final QName nextQName;
protected final QName annotationQName;
protected final QName contextQName;
protected final QName entryRefQName;
protected final QName propertyValueQName;
protected final QName deletedEntryQName;
protected final QName reasonQName;
protected final QName linkQName;
protected final QName deletedLinkQName;
protected final QName errorCodeQName;
protected final QName errorMessageQName;
protected final QName errorTargetQName;
public AbstractAtomDealer() {
namespaceMetadata = Constants.NS_METADATA;
namespaceData = Constants.NS_DATASERVICES;
namespaceAtom = Constants.NS_ATOM;
etagQName = new QName(namespaceMetadata, Constants.ATOM_ATTR_ETAG);
metadataEtagQName = new QName(namespaceMetadata, Constants.ATOM_ATTR_METADATAETAG);
inlineQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_INLINE);
actionQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_ACTION);
propertiesQName = new QName(namespaceMetadata, Constants.PROPERTIES);
typeQName = new QName(namespaceMetadata, Constants.ATTR_TYPE);
nullQName = new QName(namespaceMetadata, Constants.ATTR_NULL);
elementQName = new QName(namespaceMetadata, Constants.ELEM_ELEMENT);
countQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_COUNT);
uriQName = new QName(namespaceData, Constants.ELEM_URI);
nextQName = new QName(namespaceData, Constants.NEXT_LINK_REL);
annotationQName = new QName(namespaceMetadata, Constants.ANNOTATION);
contextQName = new QName(namespaceMetadata, Constants.CONTEXT);
entryRefQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_ENTRY_REF);
propertyValueQName = new QName(namespaceMetadata, Constants.VALUE);
deletedEntryQName = new QName(Constants.NS_ATOM_TOMBSTONE, Constants.ATOM_ELEM_DELETED_ENTRY);
reasonQName = new QName(namespaceMetadata, Constants.ELEM_REASON);
linkQName = new QName(namespaceMetadata, Constants.ATOM_ELEM_LINK);
deletedLinkQName = new QName(namespaceMetadata, Constants.ELEM_DELETED_LINK);
errorCodeQName = new QName(namespaceMetadata, Constants.ERROR_CODE);
errorMessageQName = new QName(namespaceMetadata, Constants.ERROR_MESSAGE);
errorTargetQName = new QName(namespaceMetadata, Constants.ERROR_TARGET);
}
protected void namespaces(final XMLStreamWriter writer) throws XMLStreamException {
writer.writeNamespace("", Constants.NS_ATOM);
writer.writeNamespace(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
writer.writeNamespace(Constants.PREFIX_METADATA, Constants.NS_METADATA);
writer.writeNamespace(Constants.PREFIX_DATASERVICES, Constants.NS_DATASERVICES);
writer.writeNamespace(Constants.PREFIX_GML, Constants.NS_GML);
writer.writeNamespace(Constants.PREFIX_GEORSS, Constants.NS_GEORSS);
}
}

View File

@ -65,7 +65,29 @@ import org.apache.olingo.commons.core.edm.EdmTypeInfo;
import com.fasterxml.aalto.stax.InputFactoryImpl; import com.fasterxml.aalto.stax.InputFactoryImpl;
public class AtomDeserializer extends AbstractAtomDealer implements ODataDeserializer { public class AtomDeserializer implements ODataDeserializer {
protected static final QName etagQName = new QName(Constants.NS_METADATA, Constants.ATOM_ATTR_ETAG);
protected static final QName metadataEtagQName = new QName(Constants.NS_METADATA, Constants.ATOM_ATTR_METADATAETAG);
protected static final QName inlineQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_INLINE);
protected static final QName actionQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_ACTION);
protected static final QName propertiesQName = new QName(Constants.NS_METADATA, Constants.PROPERTIES);
protected static final QName typeQName = new QName(Constants.NS_METADATA, Constants.ATTR_TYPE);
protected static final QName nullQName = new QName(Constants.NS_METADATA, Constants.ATTR_NULL);
protected static final QName elementQName = new QName(Constants.NS_METADATA, Constants.ELEM_ELEMENT);
protected static final QName countQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_COUNT);
protected static final QName annotationQName = new QName(Constants.NS_METADATA, Constants.ANNOTATION);
protected static final QName contextQName = new QName(Constants.NS_METADATA, Constants.CONTEXT);
protected static final QName entryRefQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_ENTRY_REF);
protected static final QName propertyValueQName = new QName(Constants.NS_METADATA, Constants.VALUE);
protected static final QName reasonQName = new QName(Constants.NS_METADATA, Constants.ELEM_REASON);
protected static final QName linkQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_LINK);
protected static final QName deletedLinkQName = new QName(Constants.NS_METADATA, Constants.ELEM_DELETED_LINK);
protected static final QName errorCodeQName = new QName(Constants.NS_METADATA, Constants.ERROR_CODE);
protected static final QName errorMessageQName = new QName(Constants.NS_METADATA, Constants.ERROR_MESSAGE);
protected static final QName errorTargetQName = new QName(Constants.NS_METADATA, Constants.ERROR_TARGET);
protected static final QName deletedEntryQName =
new QName(Constants.NS_ATOM_TOMBSTONE, Constants.ATOM_ELEM_DELETED_ENTRY);
protected static final XMLInputFactory FACTORY = new InputFactoryImpl(); protected static final XMLInputFactory FACTORY = new InputFactoryImpl();

View File

@ -31,7 +31,6 @@ import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.XMLStreamWriter;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.client.api.serialization.ODataSerializer; import org.apache.olingo.client.api.serialization.ODataSerializer;
import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.api.serialization.ODataSerializerException;
@ -56,12 +55,13 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import com.fasterxml.aalto.stax.OutputFactoryImpl; import com.fasterxml.aalto.stax.OutputFactoryImpl;
public class AtomSerializer extends AbstractAtomDealer implements ODataSerializer { public class AtomSerializer implements ODataSerializer {
private static final String TYPE_TEXT = "text";
private static final XMLOutputFactory FACTORY = new OutputFactoryImpl(); private static final XMLOutputFactory FACTORY = new OutputFactoryImpl();
private final AtomGeoValueSerializer geoSerializer; private final AtomGeoValueSerializer geoSerializer;
private final boolean serverMode; private final boolean serverMode;
public AtomSerializer() { public AtomSerializer() {
@ -73,11 +73,20 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
this.serverMode = serverMode; this.serverMode = serverMode;
} }
protected void namespaces(XMLStreamWriter writer) throws XMLStreamException {
writer.writeNamespace("", Constants.NS_ATOM);
writer.writeNamespace(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
writer.writeNamespace(Constants.PREFIX_METADATA, Constants.NS_METADATA);
writer.writeNamespace(Constants.PREFIX_DATASERVICES, Constants.NS_DATASERVICES);
writer.writeNamespace(Constants.PREFIX_GML, Constants.NS_GML);
writer.writeNamespace(Constants.PREFIX_GEORSS, Constants.NS_GEORSS);
}
private void collection(final XMLStreamWriter writer, private void collection(final XMLStreamWriter writer,
final ValueType valueType, final EdmPrimitiveTypeKind kind, final List<?> value) final ValueType valueType, final EdmPrimitiveTypeKind kind, final List<?> value)
throws XMLStreamException, EdmPrimitiveTypeException { throws XMLStreamException, EdmPrimitiveTypeException {
for (Object item : value) { for (Object item : value) {
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ELEM_ELEMENT, namespaceMetadata); writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ELEM_ELEMENT, Constants.NS_METADATA);
value(writer, valueType, kind, item); value(writer, valueType, kind, item);
writer.writeEndElement(); writer.writeEndElement();
} }
@ -86,16 +95,24 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
private void value(final XMLStreamWriter writer, private void value(final XMLStreamWriter writer,
final ValueType valueType, final EdmPrimitiveTypeKind kind, final Object value) final ValueType valueType, final EdmPrimitiveTypeKind kind, final Object value)
throws XMLStreamException, EdmPrimitiveTypeException { throws XMLStreamException, EdmPrimitiveTypeException {
if (value == null || (valueType == ValueType.COMPLEX && ((ComplexValue)value).getValue().isEmpty())) { if (value == null || (valueType == ValueType.COMPLEX && ((ComplexValue) value).getValue().isEmpty())) {
writer.writeAttribute(Constants.PREFIX_METADATA, namespaceMetadata, writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA,
Constants.ATTR_NULL, Boolean.TRUE.toString()); Constants.ATTR_NULL, Boolean.TRUE.toString());
return; return;
} }
switch (valueType) { switch (valueType) {
case PRIMITIVE: case PRIMITIVE:
writer.writeCharacters(kind == null ? value.toString() : final EdmPrimitiveTypeKind valueKind = kind == null ? EdmTypeInfo.determineTypeKind(value) : kind;
EdmPrimitiveTypeFactory.getInstance(kind) // TODO: add facets if (valueKind == null) {
.valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null)); if (serverMode) {
throw new EdmPrimitiveTypeException("The primitive type could not be determined.");
} else {
writer.writeCharacters(value.toString()); // This might not be valid OData.
}
} else {
writer.writeCharacters(EdmPrimitiveTypeFactory.getInstance(valueKind) // TODO: add facets
.valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null));
}
break; break;
case ENUM: case ENUM:
writer.writeCharacters(value.toString()); writer.writeCharacters(value.toString());
@ -124,22 +141,23 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
throws XMLStreamException, EdmPrimitiveTypeException { throws XMLStreamException, EdmPrimitiveTypeException {
if (standalone) { if (standalone) {
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.VALUE, namespaceData); writer.writeStartElement(Constants.PREFIX_METADATA, Constants.VALUE, Constants.NS_DATASERVICES);
namespaces(writer); namespaces(writer);
} else { } else {
writer.writeStartElement(Constants.PREFIX_DATASERVICES, property.getName(), namespaceData); writer.writeStartElement(Constants.PREFIX_DATASERVICES, property.getName(), Constants.NS_DATASERVICES);
} }
EdmTypeInfo typeInfo = null; EdmTypeInfo typeInfo = null;
if (StringUtils.isNotBlank(property.getType())) { if (property.getType() != null) {
typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build(); typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) { if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
writer.writeAttribute(Constants.PREFIX_METADATA, namespaceMetadata, writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA,
Constants.ATTR_TYPE, typeInfo.external()); Constants.ATTR_TYPE, typeInfo.external());
} }
} }
value(writer, property.getValueType(), typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(), value(writer, property.getValueType(),
typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(),
property.getValue()); property.getValue());
if (!property.isNull() && property.isComplex() && !property.isCollection()) { if (!property.isNull() && property.isComplex() && !property.isCollection()) {
links(writer, property.asComplex().getAssociationLinks()); links(writer, property.asComplex().getAssociationLinks());
@ -196,14 +214,14 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writeLink(writer, link, new ExtraContent() { writeLink(writer, link, new ExtraContent() {
@Override @Override
public void write(XMLStreamWriter writer, Link link) throws XMLStreamException, EdmPrimitiveTypeException { public void write(XMLStreamWriter writer, Link link) throws XMLStreamException, EdmPrimitiveTypeException {
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ATOM_ELEM_INLINE, namespaceMetadata); writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ATOM_ELEM_INLINE, Constants.NS_METADATA);
if (link.getInlineEntity() != null) { if (link.getInlineEntity() != null) {
writer.writeStartElement(namespaceAtom, Constants.ATOM_ELEM_ENTRY); writer.writeStartElement(Constants.NS_ATOM, Constants.ATOM_ELEM_ENTRY);
entity(writer, link.getInlineEntity()); entity(writer, link.getInlineEntity());
writer.writeEndElement(); writer.writeEndElement();
} }
if (link.getInlineEntitySet() != null) { if (link.getInlineEntitySet() != null) {
writer.writeStartElement(namespaceAtom, Constants.ATOM_ELEM_FEED); writer.writeStartElement(Constants.NS_ATOM, Constants.ATOM_ELEM_FEED);
entitySet(writer, link.getInlineEntitySet()); entitySet(writer, link.getInlineEntitySet());
writer.writeEndElement(); writer.writeEndElement();
} }
@ -222,8 +240,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writeLink(writer, link, new ExtraContent() { writeLink(writer, link, new ExtraContent() {
@Override @Override
public void write(XMLStreamWriter writer, Link link) throws XMLStreamException, EdmPrimitiveTypeException { public void write(XMLStreamWriter writer, Link link) throws XMLStreamException, EdmPrimitiveTypeException {
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ATOM_ELEM_INLINE, namespaceMetadata); writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ATOM_ELEM_INLINE, Constants.NS_METADATA);
writer.writeStartElement(namespaceAtom, Constants.ATOM_ELEM_FEED); writer.writeStartElement(Constants.NS_ATOM, Constants.ATOM_ELEM_FEED);
for (String binding:link.getBindingLinks()) { for (String binding:link.getBindingLinks()) {
Entity entity = new Entity(); Entity entity = new Entity();
entity.setId(URI.create(binding)); entity.setId(URI.create(binding));
@ -242,10 +260,10 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
uris = new ArrayList<String>(); uris = new ArrayList<String>();
entitySetLinks.put(link.getTitle(), uris); entitySetLinks.put(link.getTitle(), uris);
} }
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null) {
uris.add(link.getHref()); uris.add(link.getHref());
} }
} else { } else {
writeLink(writer, link, new ExtraContent() { writeLink(writer, link, new ExtraContent() {
@Override @Override
public void write(XMLStreamWriter writer, Link link) public void write(XMLStreamWriter writer, Link link)
@ -266,8 +284,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writeLink(writer, link, new ExtraContent() { writeLink(writer, link, new ExtraContent() {
@Override @Override
public void write(XMLStreamWriter writer, Link link) throws XMLStreamException, EdmPrimitiveTypeException { public void write(XMLStreamWriter writer, Link link) throws XMLStreamException, EdmPrimitiveTypeException {
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ATOM_ELEM_INLINE, namespaceMetadata); writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ATOM_ELEM_INLINE, Constants.NS_METADATA);
writer.writeStartElement(namespaceAtom, Constants.ATOM_ELEM_FEED); writer.writeStartElement(Constants.NS_ATOM, Constants.ATOM_ELEM_FEED);
for (String binding:entitySetLink) { for (String binding:entitySetLink) {
Entity entity = new Entity(); Entity entity = new Entity();
entity.setId(URI.create(binding)); entity.setId(URI.create(binding));
@ -280,7 +298,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
} }
} }
} }
private void links(final XMLStreamWriter writer, final List<Link> links) private void links(final XMLStreamWriter writer, final List<Link> links)
throws XMLStreamException, EdmPrimitiveTypeException { throws XMLStreamException, EdmPrimitiveTypeException {
for (Link link : links) { for (Link link : links) {
@ -302,21 +320,21 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
throws XMLStreamException, EdmPrimitiveTypeException { throws XMLStreamException, EdmPrimitiveTypeException {
writer.writeStartElement(Constants.ATOM_ELEM_LINK); writer.writeStartElement(Constants.ATOM_ELEM_LINK);
if (StringUtils.isNotBlank(link.getRel())) { if (link.getRel() != null) {
writer.writeAttribute(Constants.ATTR_REL, link.getRel()); writer.writeAttribute(Constants.ATTR_REL, link.getRel());
} }
if (StringUtils.isNotBlank(link.getTitle())) { if (link.getTitle() != null) {
writer.writeAttribute(Constants.ATTR_TITLE, link.getTitle()); writer.writeAttribute(Constants.ATTR_TITLE, link.getTitle());
} }
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null) {
writer.writeAttribute(Constants.ATTR_HREF, link.getHref()); writer.writeAttribute(Constants.ATTR_HREF, link.getHref());
} }
if (StringUtils.isNotBlank(link.getType())) { if (link.getType() != null) {
writer.writeAttribute(Constants.ATTR_TYPE, link.getType()); writer.writeAttribute(Constants.ATTR_TYPE, link.getType());
} }
content.write(writer, link); content.write(writer, link);
for (Annotation annotation : link.getAnnotations()) { for (Annotation annotation : link.getAnnotations()) {
annotation(writer, annotation, null); annotation(writer, annotation, null);
} }
@ -324,7 +342,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
} }
private void common(final XMLStreamWriter writer, final AbstractODataObject object) throws XMLStreamException { private void common(final XMLStreamWriter writer, final AbstractODataObject object) throws XMLStreamException {
if (StringUtils.isNotBlank(object.getTitle())) { if (object.getTitle() != null) {
writer.writeStartElement(Constants.ATOM_ELEM_TITLE); writer.writeStartElement(Constants.ATOM_ELEM_TITLE);
writer.writeAttribute(Constants.ATTR_TYPE, TYPE_TEXT); writer.writeAttribute(Constants.ATTR_TYPE, TYPE_TEXT);
writer.writeCharacters(object.getTitle()); writer.writeCharacters(object.getTitle());
@ -342,7 +360,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
private void annotation(final XMLStreamWriter writer, final Annotation annotation, final String target) private void annotation(final XMLStreamWriter writer, final Annotation annotation, final String target)
throws XMLStreamException, EdmPrimitiveTypeException { throws XMLStreamException, EdmPrimitiveTypeException {
writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ANNOTATION, namespaceMetadata); writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ANNOTATION, Constants.NS_METADATA);
writer.writeAttribute(Constants.ATOM_ATTR_TERM, annotation.getTerm()); writer.writeAttribute(Constants.ATOM_ATTR_TERM, annotation.getTerm());
@ -351,15 +369,16 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
} }
EdmTypeInfo typeInfo = null; EdmTypeInfo typeInfo = null;
if (StringUtils.isNotBlank(annotation.getType())) { if (annotation.getType() != null) {
typeInfo = new EdmTypeInfo.Builder().setTypeExpression(annotation.getType()).build(); typeInfo = new EdmTypeInfo.Builder().setTypeExpression(annotation.getType()).build();
if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) { if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
writer.writeAttribute(Constants.PREFIX_METADATA, namespaceMetadata, writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA,
Constants.ATTR_TYPE, typeInfo.external()); Constants.ATTR_TYPE, typeInfo.external());
} }
} }
value(writer, annotation.getValueType(), typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(), value(writer, annotation.getValueType(),
typeInfo == null ? EdmTypeInfo.determineTypeKind(annotation.getValue()) : typeInfo.getPrimitiveTypeKind(),
annotation.getValue()); annotation.getValue());
writer.writeEndElement(); writer.writeEndElement();
@ -371,8 +390,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entity.getBaseURI().toASCIIString()); writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entity.getBaseURI().toASCIIString());
} }
if (serverMode && StringUtils.isNotBlank(entity.getETag())) { if (serverMode && entity.getETag() != null) {
writer.writeAttribute(namespaceMetadata, Constants.ATOM_ATTR_ETAG, entity.getETag()); writer.writeAttribute(Constants.NS_METADATA, Constants.ATOM_ATTR_ETAG, entity.getETag());
} }
if (entity.getId() != null) { if (entity.getId() != null) {
@ -383,7 +402,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writer.writeStartElement(Constants.ATOM_ELEM_CATEGORY); writer.writeStartElement(Constants.ATOM_ELEM_CATEGORY);
writer.writeAttribute(Constants.ATOM_ATTR_SCHEME, Constants.NS_SCHEME); writer.writeAttribute(Constants.ATOM_ATTR_SCHEME, Constants.NS_SCHEME);
if (StringUtils.isNotBlank(entity.getType())) { if (entity.getType() != null) {
writer.writeAttribute(Constants.ATOM_ATTR_TERM, writer.writeAttribute(Constants.ATOM_ATTR_TERM,
new EdmTypeInfo.Builder().setTypeExpression(entity.getType()).build().external()); new EdmTypeInfo.Builder().setTypeExpression(entity.getType()).build().external());
} }
@ -412,7 +431,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
if (serverMode) { if (serverMode) {
for (Operation operation : entity.getOperations()) { for (Operation operation : entity.getOperations()) {
writer.writeStartElement(namespaceMetadata, Constants.ATOM_ELEM_ACTION); writer.writeStartElement(Constants.NS_METADATA, Constants.ATOM_ELEM_ACTION);
writer.writeAttribute(Constants.ATTR_METADATA, operation.getMetadataAnchor()); writer.writeAttribute(Constants.ATTR_METADATA, operation.getMetadataAnchor());
writer.writeAttribute(Constants.ATTR_TITLE, operation.getTitle()); writer.writeAttribute(Constants.ATTR_TITLE, operation.getTitle());
writer.writeAttribute(Constants.ATTR_TARGET, operation.getTarget().toASCIIString()); writer.writeAttribute(Constants.ATTR_TARGET, operation.getTarget().toASCIIString());
@ -422,7 +441,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writer.writeStartElement(Constants.ATOM_ELEM_CONTENT); writer.writeStartElement(Constants.ATOM_ELEM_CONTENT);
if (entity.isMediaEntity()) { if (entity.isMediaEntity()) {
if (StringUtils.isNotBlank(entity.getMediaContentType())) { if (entity.getMediaContentType() != null) {
writer.writeAttribute(Constants.ATTR_TYPE, entity.getMediaContentType()); writer.writeAttribute(Constants.ATTR_TYPE, entity.getMediaContentType());
} }
if (entity.getMediaContentSource() != null) { if (entity.getMediaContentSource() != null) {
@ -430,11 +449,11 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
} }
writer.writeEndElement(); writer.writeEndElement();
writer.writeStartElement(namespaceMetadata, Constants.PROPERTIES); writer.writeStartElement(Constants.NS_METADATA, Constants.PROPERTIES);
properties(writer, entity.getProperties()); properties(writer, entity.getProperties());
} else { } else {
writer.writeAttribute(Constants.ATTR_TYPE, ContentType.APPLICATION_XML.toContentTypeString()); writer.writeAttribute(Constants.ATTR_TYPE, ContentType.APPLICATION_XML.toContentTypeString());
writer.writeStartElement(namespaceMetadata, Constants.PROPERTIES); writer.writeStartElement(Constants.NS_METADATA, Constants.PROPERTIES);
properties(writer, entity.getProperties()); properties(writer, entity.getProperties());
writer.writeEndElement(); writer.writeEndElement();
} }
@ -446,21 +465,21 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
} }
private void inlineEntityRef(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException { private void inlineEntityRef(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
writer.writeStartElement(namespaceMetadata, Constants.ATOM_ELEM_ENTRY_REF); writer.writeStartElement(Constants.NS_METADATA, Constants.ATOM_ELEM_ENTRY_REF);
writer.writeAttribute(Constants.ATOM_ATTR_ID, entity.getId().toASCIIString()); writer.writeAttribute(Constants.ATOM_ATTR_ID, entity.getId().toASCIIString());
writer.writeEndElement(); writer.writeEndElement();
} }
private void entityRef(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException { private void entityRef(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
writer.writeStartElement(Constants.ATOM_ELEM_ENTRY_REF); writer.writeStartElement(Constants.ATOM_ELEM_ENTRY_REF);
writer.writeDefaultNamespace(namespaceMetadata); writer.writeDefaultNamespace(Constants.NS_METADATA);
writer.writeAttribute(Constants.ATOM_ATTR_ID, entity.getId().toASCIIString()); writer.writeAttribute(Constants.ATOM_ATTR_ID, entity.getId().toASCIIString());
writer.writeEndElement(); writer.writeEndElement();
} }
private void entityRef(final XMLStreamWriter writer, final ResWrap<Entity> container) throws XMLStreamException { private void entityRef(final XMLStreamWriter writer, final ResWrap<Entity> container) throws XMLStreamException {
writer.writeStartElement(Constants.ATOM_ELEM_ENTRY_REF); writer.writeStartElement(Constants.ATOM_ELEM_ENTRY_REF);
writer.writeDefaultNamespace(namespaceMetadata); writer.writeDefaultNamespace(Constants.NS_METADATA);
addContextInfo(writer, container); addContextInfo(writer, container);
writer.writeAttribute(Constants.ATOM_ATTR_ID, container.getPayload().getId().toASCIIString()); writer.writeAttribute(Constants.ATOM_ATTR_ID, container.getPayload().getId().toASCIIString());
} }
@ -471,7 +490,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
if (entity.getType() == null && entity.getProperties().isEmpty()) { if (entity.getType() == null && entity.getProperties().isEmpty()) {
writer.writeStartDocument(); writer.writeStartDocument();
writer.setDefaultNamespace(namespaceMetadata); writer.setDefaultNamespace(Constants.NS_METADATA);
entityRef(writer, entity); entityRef(writer, entity);
} else { } else {
startDocument(writer, Constants.ATOM_ELEM_ENTRY); startDocument(writer, Constants.ATOM_ELEM_ENTRY);
@ -489,7 +508,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
if (entity.getType() == null && entity.getProperties().isEmpty()) { if (entity.getType() == null && entity.getProperties().isEmpty()) {
writer.writeStartDocument(); writer.writeStartDocument();
writer.setDefaultNamespace(namespaceMetadata); writer.setDefaultNamespace(Constants.NS_METADATA);
entityRef(writer, container); entityRef(writer, container);
} else { } else {
@ -512,7 +531,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
} }
if (entitySet.getCount() != null) { if (entitySet.getCount() != null) {
writer.writeStartElement(namespaceMetadata, Constants.ATOM_ELEM_COUNT); writer.writeStartElement(Constants.NS_METADATA, Constants.ATOM_ELEM_COUNT);
writer.writeCharacters(Integer.toString(entitySet.getCount())); writer.writeCharacters(Integer.toString(entitySet.getCount()));
writer.writeEndElement(); writer.writeEndElement();
} }
@ -587,7 +606,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
writer.writeStartDocument(); writer.writeStartDocument();
writer.writeStartElement(Constants.ELEM_LINKS); writer.writeStartElement(Constants.ELEM_LINKS);
writer.writeDefaultNamespace(namespaceData); writer.writeDefaultNamespace(Constants.NS_DATASERVICES);
writer.writeStartElement(Constants.ELEM_URI); writer.writeStartElement(Constants.ELEM_URI);
writer.writeCharacters(link.getHref()); writer.writeCharacters(link.getHref());
@ -670,12 +689,12 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
((Entity) container.getPayload()).setBaseURI(base); ((Entity) container.getPayload()).setBaseURI(base);
} }
writer.writeAttribute(namespaceMetadata, Constants.CONTEXT, writer.writeAttribute(Constants.NS_METADATA, Constants.CONTEXT,
container.getContextURL().toASCIIString()); container.getContextURL().toASCIIString());
} }
if (StringUtils.isNotBlank(container.getMetadataETag())) { if (container.getMetadataETag() != null) {
writer.writeAttribute(namespaceMetadata, Constants.ATOM_ATTR_METADATAETAG, writer.writeAttribute(Constants.NS_METADATA, Constants.ATOM_ATTR_METADATAETAG,
container.getMetadataETag()); container.getMetadataETag());
} }
} }

View File

@ -20,7 +20,6 @@ package org.apache.olingo.client.core.serialization;
import java.io.IOException; import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.Annotation; import org.apache.olingo.commons.api.data.Annotation;
@ -60,21 +59,21 @@ public class JsonEntitySerializer extends JsonSerializer {
if (container.getContextURL() != null) { if (container.getContextURL() != null) {
jgen.writeStringField(Constants.JSON_CONTEXT, container.getContextURL().toASCIIString()); jgen.writeStringField(Constants.JSON_CONTEXT, container.getContextURL().toASCIIString());
} }
if (StringUtils.isNotBlank(container.getMetadataETag())) { if (container.getMetadataETag() != null) {
jgen.writeStringField(Constants.JSON_METADATA_ETAG, container.getMetadataETag()); jgen.writeStringField(Constants.JSON_METADATA_ETAG, container.getMetadataETag());
} }
if (StringUtils.isNotBlank(entity.getETag())) { if (entity.getETag() != null) {
jgen.writeStringField(Constants.JSON_ETAG, entity.getETag()); jgen.writeStringField(Constants.JSON_ETAG, entity.getETag());
} }
} }
if (StringUtils.isNotBlank(entity.getType()) && !isODataMetadataNone(contentType)) { if (entity.getType() != null && !isODataMetadataNone) {
jgen.writeStringField(Constants.JSON_TYPE, jgen.writeStringField(Constants.JSON_TYPE,
new EdmTypeInfo.Builder().setTypeExpression(entity.getType()).build().external()); new EdmTypeInfo.Builder().setTypeExpression(entity.getType()).build().external());
} }
if (entity.getId() != null && !isODataMetadataNone(contentType)) { if (entity.getId() != null && !isODataMetadataNone) {
jgen.writeStringField(Constants.JSON_ID, entity.getId().toASCIIString()); jgen.writeStringField(Constants.JSON_ID, entity.getId().toASCIIString());
} }
@ -86,9 +85,8 @@ public class JsonEntitySerializer extends JsonSerializer {
valuable(jgen, property, property.getName()); valuable(jgen, property, property.getName());
} }
if (serverMode && entity.getEditLink() != null && StringUtils.isNotBlank(entity.getEditLink().getHref())) { if (serverMode && entity.getEditLink() != null && entity.getEditLink().getHref() != null) {
jgen.writeStringField(Constants.JSON_EDIT_LINK, jgen.writeStringField(Constants.JSON_EDIT_LINK, entity.getEditLink().getHref());
entity.getEditLink().getHref());
if (entity.isMediaEntity()) { if (entity.isMediaEntity()) {
jgen.writeStringField(Constants.JSON_MEDIA_READ_LINK, jgen.writeStringField(Constants.JSON_MEDIA_READ_LINK,
@ -96,7 +94,7 @@ public class JsonEntitySerializer extends JsonSerializer {
} }
} }
if (!isODataMetadataNone(contentType)) { if (!isODataMetadataNone) {
links(entity, jgen); links(entity, jgen);
} }
@ -119,7 +117,9 @@ public class JsonEntitySerializer extends JsonSerializer {
if (serverMode) { if (serverMode) {
for (Operation operation : entity.getOperations()) { for (Operation operation : entity.getOperations()) {
jgen.writeObjectFieldStart("#" + StringUtils.substringAfterLast(operation.getMetadataAnchor(), "#")); final String anchor = operation.getMetadataAnchor();
final int index = anchor.lastIndexOf('#');
jgen.writeObjectFieldStart('#' + anchor.substring(index < 0 ? 0 : (index + 1)));
jgen.writeStringField(Constants.ATTR_TITLE, operation.getTitle()); jgen.writeStringField(Constants.ATTR_TITLE, operation.getTitle());
jgen.writeStringField(Constants.ATTR_TARGET, operation.getTarget().toASCIIString()); jgen.writeStringField(Constants.ATTR_TARGET, operation.getTarget().toASCIIString());
jgen.writeEndObject(); jgen.writeEndObject();
@ -128,4 +128,4 @@ public class JsonEntitySerializer extends JsonSerializer {
jgen.writeEndObject(); jgen.writeEndObject();
} }
} }

View File

@ -20,7 +20,6 @@ package org.apache.olingo.client.core.serialization;
import java.io.IOException; import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.Annotation; import org.apache.olingo.commons.api.data.Annotation;
@ -54,18 +53,20 @@ public class JsonEntitySetSerializer extends JsonSerializer {
jgen.writeStringField(Constants.JSON_CONTEXT, container.getContextURL().toASCIIString()); jgen.writeStringField(Constants.JSON_CONTEXT, container.getContextURL().toASCIIString());
} }
if (StringUtils.isNotBlank(container.getMetadataETag())) { if (container.getMetadataETag() != null) {
jgen.writeStringField( jgen.writeStringField(Constants.JSON_METADATA_ETAG, container.getMetadataETag());
Constants.JSON_METADATA_ETAG,
container.getMetadataETag());
} }
} }
if (entitySet.getId() != null) { if (entitySet.getId() != null) {
jgen.writeStringField(Constants.JSON_ID, entitySet.getId().toASCIIString()); jgen.writeStringField(Constants.JSON_ID, entitySet.getId().toASCIIString());
} }
jgen.writeNumberField(Constants.JSON_COUNT, final Integer count = entitySet.getCount() == null ? entitySet.getEntities().size() : entitySet.getCount();
entitySet.getCount() == null ? entitySet.getEntities().size() : entitySet.getCount()); if (isIEEE754Compatible) {
jgen.writeStringField(Constants.JSON_COUNT, Integer.toString(count));
} else {
jgen.writeNumberField(Constants.JSON_COUNT, count);
}
if (serverMode) { if (serverMode) {
if (entitySet.getNext() != null) { if (entitySet.getNext() != null) {
jgen.writeStringField(Constants.JSON_NEXT_LINK, jgen.writeStringField(Constants.JSON_NEXT_LINK,

View File

@ -22,12 +22,11 @@ import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.client.api.serialization.ODataSerializer; import org.apache.olingo.client.api.serialization.ODataSerializer;
import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.api.serialization.ODataSerializerException;
@ -54,23 +53,24 @@ import com.fasterxml.jackson.core.JsonGenerator;
public class JsonSerializer implements ODataSerializer { public class JsonSerializer implements ODataSerializer {
private static final EdmPrimitiveTypeKind[] NUMBER_TYPES = { private static final List<EdmPrimitiveTypeKind> NUMBER_TYPES = Arrays.asList(
EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte, EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double, EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double,
EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64, EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64,
EdmPrimitiveTypeKind.Decimal EdmPrimitiveTypeKind.Decimal);
};
private final JsonGeoValueSerializer geoSerializer = new JsonGeoValueSerializer(); private final JsonGeoValueSerializer geoSerializer = new JsonGeoValueSerializer();
protected boolean serverMode; protected boolean serverMode;
protected final boolean isIEEE754Compatible;
protected ContentType contentType; protected ContentType contentType;
protected final boolean isIEEE754Compatible;
protected final boolean isODataMetadataNone;
public JsonSerializer(final boolean serverMode, final ContentType contentType) { public JsonSerializer(final boolean serverMode, final ContentType contentType) {
this.serverMode = serverMode; this.serverMode = serverMode;
this.contentType = contentType; this.contentType = contentType;
this.isIEEE754Compatible = isIEEE754Compatible(); this.isIEEE754Compatible = isIEEE754Compatible();
this.isODataMetadataNone = isODataMetadataNone();
} }
@Override @Override
@ -162,11 +162,11 @@ public class JsonSerializer implements ODataSerializer {
uris = new ArrayList<String>(); uris = new ArrayList<String>();
entitySetLinks.put(link.getTitle(), uris); entitySetLinks.put(link.getTitle(), uris);
} }
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null && !link.getHref().isEmpty()) {
uris.add(link.getHref()); uris.add(link.getHref());
} }
} else { } else {
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null && !link.getHref().isEmpty()) {
jgen.writeStringField(link.getTitle() + Constants.JSON_BIND_LINK_SUFFIX, link.getHref()); jgen.writeStringField(link.getTitle() + Constants.JSON_BIND_LINK_SUFFIX, link.getHref());
} }
} }
@ -202,19 +202,15 @@ public class JsonSerializer implements ODataSerializer {
throws IOException, EdmPrimitiveTypeException { throws IOException, EdmPrimitiveTypeException {
if (linked instanceof Entity) { if (linked instanceof Entity) {
for (Link link : ((Entity) linked).getMediaEditLinks()) { for (Link link : ((Entity) linked).getMediaEditLinks()) {
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null && !link.getHref().isEmpty()) {
jgen.writeStringField( jgen.writeStringField(link.getTitle() + Constants.JSON_MEDIA_EDIT_LINK, link.getHref());
link.getTitle() + StringUtils.prependIfMissing(Constants.JSON_MEDIA_EDIT_LINK, "@"),
link.getHref());
} }
} }
} }
for (Link link : linked.getAssociationLinks()) { for (Link link : linked.getAssociationLinks()) {
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null && !link.getHref().isEmpty()) {
jgen.writeStringField( jgen.writeStringField(link.getTitle() + Constants.JSON_ASSOCIATION_LINK, link.getHref());
link.getTitle() + Constants.JSON_ASSOCIATION_LINK,
link.getHref());
} }
} }
@ -223,10 +219,8 @@ public class JsonSerializer implements ODataSerializer {
valuable(jgen, annotation, link.getTitle() + "@" + annotation.getTerm()); valuable(jgen, annotation, link.getTitle() + "@" + annotation.getTerm());
} }
if (StringUtils.isNotBlank(link.getHref())) { if (link.getHref() != null && !link.getHref().isEmpty()) {
jgen.writeStringField( jgen.writeStringField(link.getTitle() + Constants.JSON_NAVIGATION_LINK, link.getHref());
link.getTitle() + Constants.JSON_NAVIGATION_LINK,
link.getHref());
} }
if (link.getInlineEntity() != null) { if (link.getInlineEntity() != null) {
@ -247,12 +241,13 @@ public class JsonSerializer implements ODataSerializer {
final ValueType valueType, final List<?> value) final ValueType valueType, final List<?> value)
throws IOException, EdmPrimitiveTypeException { throws IOException, EdmPrimitiveTypeException {
final EdmTypeInfo itemTypeInfo = typeInfo == null ?
null :
new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
jgen.writeStartArray(); jgen.writeStartArray();
for (Object item : value) { for (Object item : value) {
final EdmTypeInfo itemTypeInfo = typeInfo == null
? null
: new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
switch (valueType) { switch (valueType) {
case COLLECTION_PRIMITIVE: case COLLECTION_PRIMITIVE:
primitiveValue(jgen, itemTypeInfo, item); primitiveValue(jgen, itemTypeInfo, item);
@ -283,37 +278,40 @@ public class JsonSerializer implements ODataSerializer {
protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, final Object value) protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, final Object value)
throws IOException, EdmPrimitiveTypeException { throws IOException, EdmPrimitiveTypeException {
final EdmPrimitiveTypeKind kind = typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(); final EdmPrimitiveTypeKind kind = typeInfo == null ?
final boolean isNumber = kind == null ? value instanceof Number : ArrayUtils.contains(NUMBER_TYPES, kind); EdmTypeInfo.determineTypeKind(value) :
final boolean isBoolean = kind == null ? value instanceof Boolean : kind == EdmPrimitiveTypeKind.Boolean; typeInfo.getPrimitiveTypeKind();
if (value == null) { if (value == null) {
jgen.writeNull(); jgen.writeNull();
} else if (isBoolean) { } else if (kind == EdmPrimitiveTypeKind.Boolean) {
jgen.writeBoolean((Boolean) value); jgen.writeBoolean((Boolean) value);
} else if (kind == null) {
if (serverMode) {
throw new EdmPrimitiveTypeException("The primitive type could not be determined.");
} else {
jgen.writeString(value.toString()); // This might not be valid OData.
}
} else { } else {
String serialized = kind == null // TODO: add facets
? value.toString() final String serialized = EdmPrimitiveTypeFactory.getInstance(kind)
// TODO: add facets .valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null);
: EdmPrimitiveTypeFactory.getInstance(kind).
valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null); if (isIEEE754Compatible && (kind == EdmPrimitiveTypeKind.Int64 || kind == EdmPrimitiveTypeKind.Decimal)
|| !NUMBER_TYPES.contains(kind)) {
if(isIEEE754Compatible && (kind == EdmPrimitiveTypeKind.Int64 || kind == EdmPrimitiveTypeKind.Decimal)) { jgen.writeString(serialized);
jgen.writeString(serialized); } else {
} else if(isNumber) { jgen.writeNumber(serialized);
jgen.writeNumber(serialized); }
} else {
jgen.writeString(serialized);
}
} }
} }
private void complexValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, private void complexValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo,
final List<Property> value, final Linked linked) final List<Property> value, final Linked linked)
throws IOException, EdmPrimitiveTypeException { throws IOException, EdmPrimitiveTypeException {
jgen.writeStartObject(); jgen.writeStartObject();
if (typeInfo != null && !isODataMetadataNone(contentType)) { if (typeInfo != null && !isODataMetadataNone) {
jgen.writeStringField(Constants.JSON_TYPE, typeInfo.external()); jgen.writeStringField(Constants.JSON_TYPE, typeInfo.external());
} }
@ -356,14 +354,14 @@ public class JsonSerializer implements ODataSerializer {
String type = valuable.getType(); String type = valuable.getType();
if ((!valuable.isCollection() && if ((!valuable.isCollection() &&
StringUtils.isBlank(type) && (type == null || type.isEmpty()) &&
valuable.isPrimitive()) || valuable.isNull()) { valuable.isPrimitive()) || valuable.isNull()) {
type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString(); type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
} }
if (StringUtils.isNotBlank(type) && !isODataMetadataNone(contentType)) { if (type != null && !type.isEmpty() && !isODataMetadataNone) {
jgen.writeFieldName( jgen.writeStringField(
name + StringUtils.prependIfMissing(Constants.JSON_TYPE, "@")); name + Constants.JSON_TYPE,
jgen.writeString(new EdmTypeInfo.Builder().setTypeExpression(type).build().external()); new EdmTypeInfo.Builder().setTypeExpression(type).build().external());
} }
} }
@ -374,14 +372,15 @@ public class JsonSerializer implements ODataSerializer {
jgen.writeFieldName(name); jgen.writeFieldName(name);
value(jgen, valuable.getType(), valuable); value(jgen, valuable.getType(), valuable);
} }
private boolean isIEEE754Compatible() { private boolean isIEEE754Compatible() {
final String parameter = contentType.getParameters().get(ContentType.PARAMETER_IEEE754_COMPATIBLE); final String parameter = contentType.getParameters().get(ContentType.PARAMETER_IEEE754_COMPATIBLE);
return parameter == null ? false : "true".equals(parameter.toLowerCase()); return parameter == null ? false : "true".equals(parameter.toLowerCase());
} }
protected boolean isODataMetadataNone(final ContentType contentType) { private boolean isODataMetadataNone() {
return contentType.isCompatible(ContentType.APPLICATION_JSON) return contentType.isCompatible(ContentType.APPLICATION_JSON)
&& ContentType.VALUE_ODATA_METADATA_NONE.equals(contentType.getParameter(ContentType.PARAMETER_ODATA_METADATA)); && ContentType.VALUE_ODATA_METADATA_NONE.equals(
contentType.getParameter(ContentType.PARAMETER_ODATA_METADATA));
} }
} }

View File

@ -33,6 +33,7 @@ import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientLink; import org.apache.olingo.client.api.domain.ClientLink;
import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.api.domain.ClientProperty;
import org.apache.olingo.client.api.serialization.ODataSerializer;
import org.apache.olingo.client.api.serialization.ODataSerializerException; import org.apache.olingo.client.api.serialization.ODataSerializerException;
import org.apache.olingo.client.api.serialization.ODataWriter; import org.apache.olingo.client.api.serialization.ODataWriter;
import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.Constants;
@ -57,8 +58,9 @@ public class ODataWriterImpl implements ODataWriter {
writer = null; writer = null;
} }
try { try {
final ODataSerializer serializer = client.getSerializer(contentType);
for (ClientEntity entity : entities) { for (ClientEntity entity : entities) {
client.getSerializer(contentType).write(writer, client.getBinder().getEntity(entity)); serializer.write(writer, client.getBinder().getEntity(entity));
} }
return new ByteArrayInputStream(output.toByteArray()); return new ByteArrayInputStream(output.toByteArray());

View File

@ -18,6 +18,12 @@
*/ */
package org.apache.olingo.commons.core.edm; package org.apache.olingo.commons.core.edm;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmEntityType;
@ -34,7 +40,6 @@ public class EdmTypeInfo {
public static class Builder { public static class Builder {
private String typeExpression; private String typeExpression;
private String defaultNamespace;
private Edm edm; private Edm edm;
public Builder setTypeExpression(final String typeExpression) { public Builder setTypeExpression(final String typeExpression) {
@ -42,21 +47,13 @@ public class EdmTypeInfo {
return this; return this;
} }
public Builder setDefaultNamespace(final String defaultNamespace) {
this.defaultNamespace = defaultNamespace;
return this;
}
public Builder setEdm(final Edm edm) { public Builder setEdm(final Edm edm) {
this.edm = edm; this.edm = edm;
return this; return this;
} }
public EdmTypeInfo build() { public EdmTypeInfo build() {
return new EdmTypeInfo(edm, return new EdmTypeInfo(edm, typeExpression);
typeExpression.indexOf('.') == -1 && defaultNamespace != null && !defaultNamespace.isEmpty() ?
defaultNamespace + "." + typeExpression :
typeExpression);
} }
} }
@ -84,10 +81,12 @@ public class EdmTypeInfo {
baseType = typeExpression.substring(collStartIdx + 11, collEndIdx); baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
} }
baseType = baseType.replaceAll("^#", ""); if (baseType.startsWith("#")) {
baseType = baseType.substring(1);
}
final String typeName; String typeName;
final String namespace; String namespace;
final int lastDotIdx = baseType.lastIndexOf('.'); final int lastDotIdx = baseType.lastIndexOf('.');
if (lastDotIdx == -1) { if (lastDotIdx == -1) {
@ -105,7 +104,7 @@ public class EdmTypeInfo {
fullQualifiedName = new FullQualifiedName(namespace, typeName); fullQualifiedName = new FullQualifiedName(namespace, typeName);
try { try {
primitiveType = EdmPrimitiveTypeKind.valueOf(fullQualifiedName.getName()); primitiveType = EdmPrimitiveTypeKind.valueOf(typeName);
} catch (final IllegalArgumentException e) { } catch (final IllegalArgumentException e) {
primitiveType = null; primitiveType = null;
} }
@ -124,41 +123,30 @@ public class EdmTypeInfo {
} }
public String internal() { public String internal() {
final StringBuilder deserialize = new StringBuilder(); return serialize(false);
if (isCollection()) {
deserialize.append("Collection(");
}
deserialize.append(getFullQualifiedName().toString());
if (isCollection()) {
deserialize.append(")");
}
return deserialize.toString();
} }
public String external() { public String external() {
final StringBuilder serialize = new StringBuilder(); return serialize(true);
}
private String serialize(final boolean external) {
StringBuilder serialize = new StringBuilder();
if (external && (!isPrimitiveType() || isCollection())) {
serialize.append('#');
}
if (isCollection()) { if (isCollection()) {
serialize.append('#');
serialize.append("Collection("); serialize.append("Collection(");
} }
if (isPrimitiveType()) { serialize.append(external && isPrimitiveType() ?
serialize.append(getFullQualifiedName().getName()); getFullQualifiedName().getName() :
} else { getFullQualifiedName().getFullQualifiedNameAsString());
serialize.append(getFullQualifiedName().toString());
}
if (isCollection()) { if (isCollection()) {
serialize.append(")"); serialize.append(')');
}
if (!isPrimitiveType() && !isCollection()) {
serialize.insert(0, '#');
} }
return serialize.toString(); return serialize.toString();
@ -213,16 +201,48 @@ public class EdmTypeInfo {
} }
public EdmType getType() { public EdmType getType() {
return isPrimitiveType() return isPrimitiveType() ? EdmPrimitiveTypeFactory.getInstance(getPrimitiveTypeKind()) :
? EdmPrimitiveTypeFactory.getInstance(getPrimitiveTypeKind()) isTypeDefinition() ? getTypeDefinition() :
: isTypeDefinition() isEnumType() ? getEnumType() :
? getTypeDefinition() isComplexType() ? getComplexType() :
: isEnumType() isEntityType() ? getEntityType() :
? getEnumType() null;
: isComplexType() }
? getComplexType()
: isEntityType() public static EdmPrimitiveTypeKind determineTypeKind(final Object value) {
? getEntityType() if (value == null) {
: null; return null;
}
final Class<? extends Object> cls = value.getClass();
if (value instanceof Boolean || boolean.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.Boolean;
} else if (value instanceof String) {
return EdmPrimitiveTypeKind.String;
} else if (value instanceof UUID) {
return EdmPrimitiveTypeKind.Guid;
} else if (value instanceof Long || value instanceof BigInteger || long.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.Int64;
} else if (value instanceof Integer || int.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.Int32;
} else if (value instanceof Short || short.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.Int16;
} else if (value instanceof Byte || byte.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.SByte;
} else if (value instanceof BigDecimal) {
return EdmPrimitiveTypeKind.Decimal;
} else if (value instanceof Double || double.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.Double;
} else if (value instanceof Float || float.class.isAssignableFrom(cls)) {
return EdmPrimitiveTypeKind.Single;
} else if (value instanceof Calendar || value instanceof Date || value instanceof java.sql.Timestamp) {
return EdmPrimitiveTypeKind.DateTimeOffset;
} else if (value instanceof java.sql.Date) {
return EdmPrimitiveTypeKind.Date;
} else if (value instanceof java.sql.Time) {
return EdmPrimitiveTypeKind.TimeOfDay;
} else if (value instanceof byte[] || value instanceof Byte[]) {
return EdmPrimitiveTypeKind.Binary;
}
return null;
} }
} }