blob: 50fe56fae56c88c215fdc7021f7da94bcf75e6a9 [file] [log] [blame]
/*******************************************************************************
* 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.odata2.client.core.ep.serializer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URISyntaxException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Map.Entry;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.edm.EdmCustomizableFeedMappings;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmFacets;
import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
import org.apache.olingo.odata2.api.edm.EdmMapping;
import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
import org.apache.olingo.odata2.api.edm.EdmSimpleType;
import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
import org.apache.olingo.odata2.api.edm.EdmTargetPath;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.client.api.ep.Entity;
import org.apache.olingo.odata2.client.api.ep.EntityCollection;
import org.apache.olingo.odata2.client.api.ep.EntityCollectionSerializerProperties;
import org.apache.olingo.odata2.client.api.ep.EntitySerializerProperties;
import org.apache.olingo.odata2.core.commons.ContentType;
import org.apache.olingo.odata2.core.commons.Encoder;
import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
import org.apache.olingo.odata2.core.ep.util.FormatXml;
/**
* Serializes an ATOM entry.
*
*/
public class AtomEntryEntitySerializer {
private final EntitySerializerProperties properties;
private static final String VALUE = "/$value";
/**
*
* @param properties
*/
public AtomEntryEntitySerializer(final EntitySerializerProperties properties) {
this.properties = properties == null ? EntitySerializerProperties.serviceRoot(null).build() : properties;
}
/**
* This serializes the xml payload entry
* @param writer
* @param eia
* @param data
* @param isRootElement
* @param isFeedPart
* @throws EntityProviderException
*/
public void append(final XMLStreamWriter writer, final EntityInfoAggregator eia, final Entity data,
final boolean isRootElement, final boolean isFeedPart) throws EntityProviderException {
try {
if (properties.getServiceRoot() == null) {
throw new EntityProviderProducerException(EntityProviderException.MANDATORY_WRITE_PROPERTY);
}
writer.writeStartElement(FormatXml.ATOM_ENTRY);
if (isRootElement) {
writer.writeDefaultNamespace(Edm.NAMESPACE_ATOM_2005);
writer.writeNamespace(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
writer.writeNamespace(Edm.PREFIX_D, Edm.NAMESPACE_D_2007_08);
}
if (!isFeedPart) {
writer.writeAttribute(Edm.PREFIX_XML, Edm.NAMESPACE_XML_1998, FormatXml.XML_BASE, properties.getServiceRoot()
.toASCIIString());
}
String selfLink = null;
if (properties.isIncludeMetadata()) {
// write all atom infos (mandatory and optional)
selfLink = createSelfLink(eia, data.getProperties(), null, properties.isKeyAutoGenerated(), false);
appendAtomMandatoryParts(writer, eia, data.getProperties());
appendAtomOptionalParts(writer, eia, data.getProperties());
appendAtomEditLink(writer, eia, selfLink);
if (eia.getEntityType().hasStream()) {
appendAtomContentLink(writer, eia, data.getProperties(), selfLink);
}
}
appendNavigationLinks(writer, eia, data);
appendCustomProperties(writer, eia, data.getProperties());
if (eia.getEntityType().hasStream()) {
if (properties.isIncludeMetadata()) {
appendAtomContentPart(writer, eia, data.getProperties(), selfLink);
}
appendProperties(writer, eia, data.getProperties());
} else {
writer.writeStartElement(FormatXml.ATOM_CONTENT);
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_XML.toString());
appendProperties(writer, eia, data.getProperties());
writer.writeEndElement();
}
writer.writeEndElement();
writer.flush();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
} catch (EdmException e) {
throw new EntityProviderProducerException(e.getMessageReference(), e);
} catch (URISyntaxException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
@SuppressWarnings("unchecked")
private void appendNavigationLinks(final XMLStreamWriter writer, //NOSONAR
final EntityInfoAggregator eia,
final Entity data)
throws EntityProviderException, EdmException, URISyntaxException, XMLStreamException {
for (Entry<String, Object> entry : data.getNavigations().entrySet()) {
final EntityInfoAggregator targetEntityInfo = EntityInfoAggregator.create(
eia.getEntitySet().getRelatedEntitySet(
(EdmNavigationProperty) eia.getEntityType().getProperty(entry.getKey())));
final boolean isFeed =
(eia.getNavigationPropertyInfo(entry.getKey()).getMultiplicity() == EdmMultiplicity.MANY);
if (entry.getValue() == null) {
throw new EntityProviderProducerException(EntityProviderProducerException.NULL_VALUE);
} else if (entry.getValue() instanceof Map) {
Map<String, Object> navigationKeyMap = (Map<String, Object>) entry.getValue();
if (navigationKeyMap != null && !navigationKeyMap.isEmpty()) {
appendAtomNavigationLink(writer, createSelfLink(targetEntityInfo, navigationKeyMap, null,
properties.isKeyAutoGenerated(), false), entry.getKey(), isFeed);
writer.writeEndElement();
}
} else if (entry.getValue() instanceof Entity) {
Entity navigationEntity = (Entity) entry.getValue();
Map<String, Object> navigationKeyMap = navigationEntity.getProperties();
if (navigationKeyMap != null && !navigationKeyMap.isEmpty()) {
String navigationPropertyName = entry.getKey();
String selfLink = createSelfLink(eia, data.getProperties(), navigationPropertyName,
properties.isKeyAutoGenerated(), false);
appendNavigationLink(writer, selfLink, navigationPropertyName);
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_ATOM_XML_ENTRY.toString());
appendInlineEntry(writer, navigationPropertyName, eia, data);
writer.writeEndElement();
}
} else if (entry.getValue() instanceof EntityCollection) {
String navigationPropertyName = entry.getKey();
String selfLink = createSelfLink(eia, data.getProperties(), navigationPropertyName,
properties.isKeyAutoGenerated(), false);
if (!((EntityCollection) entry.getValue()).getEntities().isEmpty()) {
appendNavigationLink(writer, selfLink, navigationPropertyName);
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_ATOM_XML_FEED.toString());
appendInlineFeed(writer, navigationPropertyName, eia, data);
writer.writeEndElement();
}
} else{
throw new EntityProviderProducerException(EntityProviderProducerException.INCORRECT_NAVIGATION_TYPE);
}
}
}
private void appendNavigationLink(XMLStreamWriter writer, String selfLink, String navigationPropertyName)
throws XMLStreamException {
writer.writeStartElement(FormatXml.ATOM_LINK);
writer.writeAttribute(FormatXml.ATOM_HREF, selfLink);
writer.writeAttribute(FormatXml.ATOM_REL, Edm.NAMESPACE_REL_2007_08 + navigationPropertyName);
writer.writeAttribute(FormatXml.ATOM_TITLE, navigationPropertyName);
}
private void appendCustomProperties(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException {
List<String> noneSyndicationTargetPaths = eia.getNoneSyndicationTargetPathNames();
for (String tpName : noneSyndicationTargetPaths) {
EntityPropertyInfo info = eia.getTargetPathInfo(tpName);
final String name = info.getName();
XmlPropertyEntitySerializer aps = new XmlPropertyEntitySerializer(properties);
aps.appendCustomProperty(writer, name, info, data.get(name));
}
}
private void appendAtomNavigationLink(final XMLStreamWriter writer, final String target,
final String navigationPropertyName, final boolean isFeed)
throws EntityProviderException, EdmException, URISyntaxException { //NOSONAR
try {
writer.writeStartElement(FormatXml.ATOM_LINK);
writer.writeAttribute(FormatXml.ATOM_HREF, target);
writer.writeAttribute(FormatXml.ATOM_REL, Edm.NAMESPACE_REL_2007_08 + navigationPropertyName);
writer.writeAttribute(FormatXml.ATOM_TITLE, navigationPropertyName);
if (isFeed) {
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_ATOM_XML_FEED.toString());
} else {
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_ATOM_XML_ENTRY.toString());
}
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
private void appendInlineFeed(final XMLStreamWriter writer, final String navigationPropertyName,
final EntityInfoAggregator eia, final Entity data)
throws EntityProviderException, XMLStreamException, EdmException {
if (eia.getNavigationPropertyNames().contains(navigationPropertyName) &&
data != null && data.getNavigations().containsKey(navigationPropertyName)) {
EdmNavigationProperty navProp = (EdmNavigationProperty) eia.getEntityType().getProperty(navigationPropertyName);
if (navProp == null) {
throw new EntityProviderProducerException(EntityProviderException.EXPANDNOTSUPPORTED);
}
EntityCollection inlineData;
inlineData = (EntityCollection) data.getNavigation(navigationPropertyName);
if (inlineData == null) {
inlineData = new EntityCollection();
}
if (inlineData.getEntities().isEmpty()) {
return;
}
writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_INLINE);
EntityCollectionSerializerProperties inlineProperties = inlineData.getCollectionProperties() == null
? EntityCollectionSerializerProperties.serviceRoot(data.getWriteProperties().getServiceRoot()).build()
: inlineData.getCollectionProperties();
EdmEntitySet inlineEntitySet = eia.getEntitySet().getRelatedEntitySet(navProp);
AtomFeedSerializer inlineFeedProducer = new AtomFeedSerializer(inlineProperties);
inlineData.setCollectionProperties(inlineProperties);
EntityInfoAggregator inlineEia =
EntityInfoAggregator.create(inlineEntitySet, null);
inlineFeedProducer.append(writer, inlineEia, inlineData, true);
writer.writeEndElement();
}
}
private void appendInlineEntry(final XMLStreamWriter writer, final String navigationPropertyName,
final EntityInfoAggregator eia, final Entity data) throws EntityProviderException,
XMLStreamException, EdmException {
if (data.getNavigations() != null && data.getNavigations().containsKey(navigationPropertyName)) {
EdmNavigationProperty navProp = (EdmNavigationProperty) eia.getEntityType().getProperty(navigationPropertyName);
Entity inlineData = (Entity) data.getNavigation(navigationPropertyName);
if ((inlineData == null) || inlineData.getProperties().size() == 0) {
return;
}
writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_INLINE);
if (inlineData != null && !(inlineData.getProperties().isEmpty())) {
inlineData.setWriteProperties(inlineData.getWriteProperties() == null ? data.getWriteProperties() : inlineData
.getWriteProperties());
EdmEntitySet inlineEntitySet = eia.getEntitySet().getRelatedEntitySet(navProp);
AtomEntryEntitySerializer inlineProducer = new AtomEntryEntitySerializer(inlineData.getWriteProperties());
EntityInfoAggregator inlineEia =
EntityInfoAggregator.create(inlineEntitySet, null);
inlineProducer.append(writer, inlineEia, inlineData, false, false);
}
writer.writeEndElement();
}
}
private void appendAtomEditLink(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final String selfLink) throws EntityProviderException {
try {
writer.writeStartElement(FormatXml.ATOM_LINK);
writer.writeAttribute(FormatXml.ATOM_HREF, selfLink);
writer.writeAttribute(FormatXml.ATOM_REL, Edm.LINK_REL_EDIT);
writer.writeAttribute(FormatXml.ATOM_TITLE, eia.getEntityType().getName());
writer.writeEndElement();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
} catch (EdmException e) {
throw new EntityProviderProducerException(e.getMessageReference(), e);
}
}
private void appendAtomContentLink(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data, final String selfLink) throws EntityProviderException, EdmException {
try {
String mediaResourceMimeType = null;
EdmMapping entityTypeMapping = eia.getEntityType().getMapping();
if (entityTypeMapping != null) {
String mediaResourceMimeTypeKey = entityTypeMapping.getMediaResourceMimeTypeKey();
if (mediaResourceMimeTypeKey != null) {
mediaResourceMimeType = (String) data.get(mediaResourceMimeTypeKey);
}
}
if (mediaResourceMimeType == null) {
mediaResourceMimeType = ContentType.APPLICATION_OCTET_STREAM.toString();
}
writer.writeStartElement(FormatXml.ATOM_LINK);
writer.writeAttribute(FormatXml.ATOM_HREF, selfLink + VALUE);
writer.writeAttribute(FormatXml.ATOM_REL, Edm.LINK_REL_EDIT_MEDIA);
writer.writeAttribute(FormatXml.ATOM_TYPE, mediaResourceMimeType);
writer.writeEndElement();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
private void appendAtomContentPart(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data, final String selfLink) throws EntityProviderException, EdmException {
try {
EdmMapping entityTypeMapping = eia.getEntityType().getMapping();
String self = null;
String mediaResourceMimeType = null;
if (entityTypeMapping != null) {
String mediaResourceSourceKey = entityTypeMapping.getMediaResourceSourceKey();
if (mediaResourceSourceKey != null) {
self = (String) data.get(mediaResourceSourceKey);
}
if (self == null) {
self = selfLink + VALUE;
}
String mediaResourceMimeTypeKey = entityTypeMapping.getMediaResourceMimeTypeKey();
if (mediaResourceMimeTypeKey != null) {
mediaResourceMimeType = (String) data.get(mediaResourceMimeTypeKey);
}
if (mediaResourceMimeType == null) {
mediaResourceMimeType = ContentType.APPLICATION_OCTET_STREAM.toString();
}
} else {
self = selfLink + VALUE;
mediaResourceMimeType = ContentType.APPLICATION_OCTET_STREAM.toString();
}
writer.writeStartElement(FormatXml.ATOM_CONTENT);
writer.writeAttribute(FormatXml.ATOM_TYPE, mediaResourceMimeType);
writer.writeAttribute(FormatXml.ATOM_SRC, self);
writer.writeEndElement();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
private void appendAtomMandatoryParts(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException {
try {
writer.writeStartElement(FormatXml.ATOM_ID);
String idlocation = properties.getServiceRoot().toASCIIString() + createSelfLink(
eia, data, null, properties.isKeyAutoGenerated(), true);;
writer.writeCharacters(idlocation);
writer.writeEndElement();
writer.writeStartElement(FormatXml.ATOM_TITLE);
writer.writeAttribute(FormatXml.ATOM_TYPE, FormatXml.ATOM_TEXT);
EntityPropertyInfo titleInfo = eia.getTargetPathInfo(EdmTargetPath.SYNDICATION_TITLE);
if (titleInfo != null) {
EdmSimpleType st = (EdmSimpleType) titleInfo.getType();
Object object = data.get(titleInfo.getName());
String title = null;
try { //NOSONAR
title = st.valueToString(object, EdmLiteralKind.DEFAULT, titleInfo.getFacets());
} catch (EdmSimpleTypeException e) {
throw new EntityProviderProducerException(EdmSimpleTypeException.getMessageReference(
e.getMessageReference()).updateContent(e.getMessageReference().getContent(), titleInfo.getName()), e);
}
if (title != null) {
writer.writeCharacters(title);
}
} else {
writer.writeCharacters(eia.getEntitySetName());
}
writer.writeEndElement();
writer.writeStartElement(FormatXml.ATOM_UPDATED);
writer.writeCharacters(getUpdatedString(eia, data));
writer.writeEndElement();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
} catch (EdmSimpleTypeException e) {
throw new EntityProviderProducerException(e.getMessageReference(), e);
}
}
String getUpdatedString(final EntityInfoAggregator eia, final Map<String, Object> data)
throws EdmSimpleTypeException, EntityProviderProducerException {
Object updateDate = null;
EdmFacets updateFacets = null;
EntityPropertyInfo updatedInfo = eia.getTargetPathInfo(EdmTargetPath.SYNDICATION_UPDATED);
if (updatedInfo != null) {
updateDate = data.get(updatedInfo.getName());
if (updateDate != null) {
updateFacets = updatedInfo.getFacets();
}
}
if (updateDate == null) {
updateDate = new Date();
}
try {
return EdmDateTimeOffset.getInstance().valueToString(updateDate, EdmLiteralKind.DEFAULT, updateFacets);
} catch (final EdmSimpleTypeException e) {
throw new EntityProviderProducerException(
EdmSimpleTypeException.getMessageReference(e.getMessageReference()).
updateContent(e.getMessageReference().getContent(),
updatedInfo == null ? null : updatedInfo.getName()), e);
}
}
private String getTargetPathValue(final EntityInfoAggregator eia, final String targetPath,
final Map<String, Object> data) throws EntityProviderException {
EntityPropertyInfo info = null;
try {
info = eia.getTargetPathInfo(targetPath);
if (info != null) {
EdmSimpleType type = (EdmSimpleType) info.getType();
Object value = data.get(info.getName());
return type.valueToString(value, EdmLiteralKind.DEFAULT, info.getFacets());
}
return null;
} catch (final EdmSimpleTypeException e) {
throw new EntityProviderProducerException(
EdmSimpleTypeException.getMessageReference(e.getMessageReference()).
updateContent(e.getMessageReference().getContent(), info.getName()), e);
}
}
private void appendAtomOptionalParts(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException {
try {
String authorEmail = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_AUTHOREMAIL, data);
String authorName = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_AUTHORNAME, data);
String authorUri = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_AUTHORURI, data);
if (authorEmail != null || authorName != null || authorUri != null) {
writer.writeStartElement(FormatXml.ATOM_AUTHOR);
appendAtomOptionalPart(writer, FormatXml.ATOM_AUTHOR_NAME, authorName, false);
appendAtomOptionalPart(writer, FormatXml.ATOM_AUTHOR_EMAIL, authorEmail, false);
appendAtomOptionalPart(writer, FormatXml.ATOM_AUTHOR_URI, authorUri, false);
writer.writeEndElement();
}
String summary = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_SUMMARY, data);
appendAtomOptionalPart(writer, FormatXml.ATOM_SUMMARY, summary, true);
String contributorName = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_CONTRIBUTORNAME, data);
String contributorEmail = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_CONTRIBUTOREMAIL, data);
String contributorUri = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_CONTRIBUTORURI, data);
if (contributorEmail != null || contributorName != null || contributorUri != null) {
writer.writeStartElement(FormatXml.ATOM_CONTRIBUTOR);
appendAtomOptionalPart(writer, FormatXml.ATOM_CONTRIBUTOR_NAME, contributorName, false);
appendAtomOptionalPart(writer, FormatXml.ATOM_CONTRIBUTOR_EMAIL, contributorEmail, false);
appendAtomOptionalPart(writer, FormatXml.ATOM_CONTRIBUTOR_URI, contributorUri, false);
writer.writeEndElement();
}
String rights = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_RIGHTS, data);
appendAtomOptionalPart(writer, FormatXml.ATOM_RIGHTS, rights, true);
String published = getTargetPathValue(eia, EdmTargetPath.SYNDICATION_PUBLISHED, data);
appendAtomOptionalPart(writer, FormatXml.ATOM_PUBLISHED, published, false);
String term = eia.getEntityType().getNamespace() + Edm.DELIMITER + eia.getEntityType().getName();
writer.writeStartElement(FormatXml.ATOM_CATEGORY);
writer.writeAttribute(FormatXml.ATOM_CATEGORY_TERM, term);
writer.writeAttribute(FormatXml.ATOM_CATEGORY_SCHEME, Edm.NAMESPACE_SCHEME_2007_08);
writer.writeEndElement();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
} catch (EdmException e) {
throw new EntityProviderProducerException(e.getMessageReference(), e);
}
}
private void appendAtomOptionalPart(final XMLStreamWriter writer, final String name, final String value,
final boolean writeType) throws EntityProviderException {
try {
if (value != null) {
writer.writeStartElement(name);
if (writeType) {
writer.writeAttribute(FormatXml.ATOM_TYPE, FormatXml.ATOM_TEXT);
}
writer.writeCharacters(value);
writer.writeEndElement();
}
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
static String createSelfLink(final EntityInfoAggregator eia, final Map<String, Object> data, final String extension,
boolean isKeyAutoGenerated, boolean isIdTag)
throws EntityProviderException {
StringBuilder sb = new StringBuilder();
if (!eia.isDefaultEntityContainer()) {
sb.append(Encoder.encode(eia.getEntityContainerName())).append(Edm.DELIMITER);
}
sb.append(Encoder.encode(eia.getEntitySetName()));
String keyValue = createEntryKey(eia, data, isKeyAutoGenerated);
if (isIdTag && isKeyAutoGenerated && "".equals(keyValue) && keyValue.length() == 0) {
sb.append(extension == null ? "" : ("/" + extension));
} else {
sb.append("(").append(keyValue).append(")").
append(extension == null ? "" : ("/" + extension));
}
return sb.toString();
}
private static String createEntryKey(final EntityInfoAggregator entityInfo, final Map<String, Object> data,
boolean isKeyAutoGenerated)
throws EntityProviderException {
final List<EntityPropertyInfo> keyPropertyInfos = entityInfo.getKeyPropertyInfos();
StringBuilder keys = new StringBuilder();
for (final EntityPropertyInfo keyPropertyInfo : keyPropertyInfos) {
if (keys.length() > 0) {
keys.append(',');
}
final String name = keyPropertyInfo.getName();
if (keyPropertyInfos.size() > 1) {
keys.append(Encoder.encode(name)).append('=');
}
final EdmSimpleType type = (EdmSimpleType) keyPropertyInfo.getType();
try {
String keyValue = null;
if (isKeyAutoGenerated && data.get(name) == null) {
// Every time default values for the key is generated
// if it is not there and auto generation has to be done by the server
Object value = fetchDefaultValue(type.getDefaultType());
keyValue = Encoder.encode(type.valueToString(value, EdmLiteralKind.URI,
keyPropertyInfo.getFacets()));
} else {
keyValue = Encoder.encode(type.valueToString(data.get(name), EdmLiteralKind.URI,
keyPropertyInfo.getFacets()));
}
keys.append(keyValue);
} catch (final EdmSimpleTypeException e) {
throw new EntityProviderProducerException(
EdmSimpleTypeException.getMessageReference(e.getMessageReference()).
updateContent(e.getMessageReference().getContent(), name), e);
}
}
return keys.toString();
}
private static Object fetchDefaultValue(Class<?> edmType) throws EntityProviderProducerException {
if (edmType == boolean.class || edmType == Boolean.class) {
return false;
} else if (edmType == String.class) {
return "A";
} else if (edmType == byte.class || edmType == Byte.class) {
return new Byte(Byte.parseByte("0"));
} else if (edmType == char.class) {
return new Character('A');
} else if (edmType == short.class || edmType == Short.class) {
return new Short(Short.parseShort("0"));
} else if (edmType == int.class || edmType == Integer.class) {
return new Integer(0);
} else if (edmType == long.class || edmType == Long.class) {
return new Long(0L);
} else if (edmType == float.class || edmType == Float.class) {
return new Float(0.0f);
} else if (edmType == double.class || edmType == Double.class) {
return new Double(0.0d);
} else if (edmType == BigDecimal.class) {
return BigDecimal.valueOf(0.0);
} else if (edmType == UUID.class) {
return UUID.fromString("00000000-0000-0000-0000-000000000000");
} else if (edmType == Timestamp.class) {
return new Timestamp(Calendar.getInstance().getTimeInMillis());
} else if (edmType == Calendar.class) {
return Calendar.getInstance();
} else if (edmType == byte[].class || edmType == Byte[].class) {
return new byte[0];
} else if (edmType == Date.class) {
return new Date();
} else if (edmType == BigInteger.class) {
return new BigInteger("0");
} else if (edmType == Time.class) {
return new Time(0L);
} else {
throw new EntityProviderProducerException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED);
}
}
private void appendProperties(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException {
try {
{
if (!data.isEmpty() && data.size() > 0) {
writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_PROPERTIES);
for (String propertyName : eia.getPropertyNames()) {
if (data.containsKey(propertyName)) {
appendPropertyNameValue(writer, eia, data, propertyName);
}
}
writer.writeEndElement();
}
}
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
/**
* @param writer
* @param eia
* @param data
* @param propertyName
* @throws EntityProviderException
*/
private void appendPropertyNameValue(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data, String propertyName) throws EntityProviderException {
EntityPropertyInfo propertyInfo = eia.getPropertyInfo(propertyName);
if (isNotMappedViaCustomMapping(propertyInfo)) {
Object value = data.get(propertyName);
XmlPropertyEntitySerializer aps = new XmlPropertyEntitySerializer(properties);
aps.append(writer, propertyInfo.getName(), propertyInfo, value);
}
}
private boolean isNotMappedViaCustomMapping(final EntityPropertyInfo propertyInfo) {
EdmCustomizableFeedMappings customMapping = propertyInfo.getCustomMapping();
if (customMapping != null && customMapping.isFcKeepInContent() != null) {
return customMapping.isFcKeepInContent();
}
return true;
}
}