blob: ea00c6fc7f732763f96bde46f8df6ed67c8450a1 [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.core.ep.producer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.olingo.odata2.api.ODataCallback;
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.edm.EdmType;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
import org.apache.olingo.odata2.api.exception.ODataApplicationException;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
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 AtomEntryEntityProducer {
private String etag;
private String location;
private final EntityProviderWriteProperties properties;
public AtomEntryEntityProducer(final EntityProviderWriteProperties properties) throws EntityProviderException {
this.properties = properties == null ? EntityProviderWriteProperties.serviceRoot(null).build() : properties;
}
public void append(final XMLStreamWriter writer, final EntityInfoAggregator eia, final Map<String, Object> data,
final boolean isRootElement, final boolean isFeedPart) throws EntityProviderException {
try {
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());
}
if (!properties.isContentOnly() && !properties.isOmitETag()) {
etag = createETag(eia, data);
if (etag != null) {
writer.writeAttribute(Edm.NAMESPACE_M_2007_08, FormatXml.M_ETAG, etag);
}
}
String selfLink = null;
if (!properties.isContentOnly()) {
// write all atom infos (mandatory and optional)
selfLink = createSelfLink(eia, data, null);
appendAtomMandatoryParts(writer, eia, data, selfLink);
appendAtomOptionalParts(writer, eia, data);
}
if (eia.getEntityType().hasStream()) {
// write all links
if (!properties.isContentOnly()) {
appendAtomEditLink(writer, eia, selfLink);
appendAtomContentLink(writer, eia, data, selfLink);
appendAtomNavigationLinks(writer, eia, data);
} else {
appendAdditinalLinks(writer, eia, data);
}
// write properties/content
appendCustomProperties(writer, eia, data);
if (!properties.isContentOnly()) {
appendAtomContentPart(writer, eia, data, selfLink);
}
appendProperties(writer, eia, data);
} else {
// write all links
if (!properties.isContentOnly()) {
appendAtomEditLink(writer, eia, selfLink);
appendAtomNavigationLinks(writer, eia, data);
} else {
appendAdditinalLinks(writer, eia, data);
}
// write properties/content
appendCustomProperties(writer, eia, data);
writer.writeStartElement(FormatXml.ATOM_CONTENT);
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_XML.toString());
appendProperties(writer, eia, data);
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);
}
}
private void appendAdditinalLinks(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data)
throws EntityProviderException, EdmException, URISyntaxException {
final Map<String, Map<String, Object>> links = properties.getAdditionalLinks();
if (links != null && !links.isEmpty()) {
for (Entry<String, Map<String, Object>> entry : links.entrySet()) {
Map<String, Object> navigationKeyMap = entry.getValue();
final boolean isFeed =
(eia.getNavigationPropertyInfo(entry.getKey()).getMultiplicity() == EdmMultiplicity.MANY);
if (navigationKeyMap != null && !navigationKeyMap.isEmpty()) {
final EntityInfoAggregator targetEntityInfo = EntityInfoAggregator.create(
eia.getEntitySet().getRelatedEntitySet(
(EdmNavigationProperty) eia.getEntityType().getProperty(entry.getKey())));
appendAtomNavigationLink(writer, createSelfLink(targetEntityInfo, navigationKeyMap, null), entry.getKey(),
isFeed, eia, data);
}
}
}
}
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();
XmlPropertyEntityProducer aps = new XmlPropertyEntityProducer(properties);
aps.appendCustomProperty(writer, name, info, data.get(name));
}
}
protected static String createETag(final EntityInfoAggregator eia, final Map<String, Object> data)
throws EntityProviderException {
try {
String etag = null;
Collection<EntityPropertyInfo> propertyInfos = eia.getETagPropertyInfos();
for (EntityPropertyInfo propertyInfo : propertyInfos) {
EdmType edmType = propertyInfo.getType();
if (edmType instanceof EdmSimpleType) {
EdmSimpleType edmSimpleType = (EdmSimpleType) edmType;
if (etag == null) {
etag =
edmSimpleType.valueToString(data.get(propertyInfo.getName()), EdmLiteralKind.DEFAULT, propertyInfo
.getFacets());
} else {
etag =
etag
+ Edm.DELIMITER
+ edmSimpleType.valueToString(data.get(propertyInfo.getName()), EdmLiteralKind.DEFAULT,
propertyInfo.getFacets());
}
}
}
if (etag != null) {
etag = "W/\"" + etag + "\"";
}
return etag;
} catch (EdmSimpleTypeException e) {
throw new EntityProviderProducerException(e.getMessageReference(), e);
}
}
private void appendAtomNavigationLinks(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException, EdmException, URISyntaxException {
for (String name : eia.getSelectedNavigationPropertyNames()) {
final boolean isFeed = (eia.getNavigationPropertyInfo(name).getMultiplicity() == EdmMultiplicity.MANY);
final Map<String, Map<String, Object>> links = properties.getAdditionalLinks();
final Map<String, Object> key = links == null ? null : links.get(name);
if (key == null || key.isEmpty()) {
appendAtomNavigationLink(writer, createSelfLink(eia, data, name), name, isFeed, eia, data);
} else {
final EntityInfoAggregator targetEntityInfo = EntityInfoAggregator.create(
eia.getEntitySet().getRelatedEntitySet((EdmNavigationProperty) eia.getEntityType().getProperty(name)));
appendAtomNavigationLink(writer, createSelfLink(targetEntityInfo, key, null), name, isFeed, eia, data);
}
}
}
private void appendAtomNavigationLink(final XMLStreamWriter writer, final String target,
final String navigationPropertyName, final boolean isFeed, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException, EdmException, URISyntaxException {
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());
appendInlineFeed(writer, navigationPropertyName, eia, data, target);
} else {
writer.writeAttribute(FormatXml.ATOM_TYPE, ContentType.APPLICATION_ATOM_XML_ENTRY.toString());
appendInlineEntry(writer, navigationPropertyName, eia, data);
}
writer.writeEndElement();
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
private void appendInlineFeed(final XMLStreamWriter writer, final String navigationPropertyName,
final EntityInfoAggregator eia, final Map<String, Object> data, final String self)
throws EntityProviderException, XMLStreamException, EdmException, URISyntaxException {
if (eia.getExpandedNavigationPropertyNames().contains(navigationPropertyName)) {
if (properties.getCallbacks() != null && properties.getCallbacks().containsKey(navigationPropertyName)) {
writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_INLINE);
EdmNavigationProperty navProp = (EdmNavigationProperty) eia.getEntityType().getProperty(navigationPropertyName);
WriteFeedCallbackContext context = new WriteFeedCallbackContext();
context.setSourceEntitySet(eia.getEntitySet());
context.setNavigationProperty(navProp);
context.setEntryData(data);
context.setCurrentWriteProperties(properties);
ExpandSelectTreeNode subNode = properties.getExpandSelectTree().getLinks().get(navigationPropertyName);
context.setCurrentExpandSelectTreeNode(subNode);
context.setSelfLink(new URI(self));
ODataCallback callback = properties.getCallbacks().get(navigationPropertyName);
if (callback == null) {
throw new EntityProviderProducerException(EntityProviderException.EXPANDNOTSUPPORTED);
}
WriteFeedCallbackResult result;
try {
result = ((OnWriteFeedContent) callback).retrieveFeedResult(context);
} catch (ODataApplicationException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
List<Map<String, Object>> inlineData = result.getFeedData();
if (inlineData == null) {
inlineData = new ArrayList<Map<String, Object>>();
}
EntityProviderWriteProperties inlineProperties = result.getInlineProperties();
EdmEntitySet inlineEntitySet = eia.getEntitySet().getRelatedEntitySet(navProp);
AtomFeedProducer inlineFeedProducer = new AtomFeedProducer(inlineProperties);
EntityInfoAggregator inlineEia =
EntityInfoAggregator.create(inlineEntitySet, inlineProperties.getExpandSelectTree());
inlineFeedProducer.append(writer, inlineEia, inlineData, true);
writer.writeEndElement();
}
}
}
private void appendInlineEntry(final XMLStreamWriter writer, final String navigationPropertyName,
final EntityInfoAggregator eia, final Map<String, Object> data) throws EntityProviderException,
XMLStreamException, EdmException {
if (eia.getExpandedNavigationPropertyNames().contains(navigationPropertyName)) {
if (properties.getCallbacks() != null && properties.getCallbacks().containsKey(navigationPropertyName)) {
writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_INLINE);
EdmNavigationProperty navProp = (EdmNavigationProperty) eia.getEntityType().getProperty(navigationPropertyName);
WriteEntryCallbackContext context = new WriteEntryCallbackContext();
context.setSourceEntitySet(eia.getEntitySet());
context.setCurrentWriteProperties(properties);
context.setNavigationProperty(navProp);
context.setEntryData(data);
ExpandSelectTreeNode subNode = properties.getExpandSelectTree().getLinks().get(navigationPropertyName);
context.setCurrentExpandSelectTreeNode(subNode);
ODataCallback callback = properties.getCallbacks().get(navigationPropertyName);
if (callback == null) {
throw new EntityProviderProducerException(EntityProviderException.EXPANDNOTSUPPORTED);
}
WriteEntryCallbackResult result;
try {
result = ((OnWriteEntryContent) callback).retrieveEntryResult(context);
} catch (ODataApplicationException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
Map<String, Object> inlineData = result.getEntryData();
if (inlineData != null && !inlineData.isEmpty()) {
EntityProviderWriteProperties inlineProperties = result.getInlineProperties();
EdmEntitySet inlineEntitySet = eia.getEntitySet().getRelatedEntitySet(navProp);
AtomEntryEntityProducer inlineProducer = new AtomEntryEntityProducer(inlineProperties);
EntityInfoAggregator inlineEia =
EntityInfoAggregator.create(inlineEntitySet, inlineProperties.getExpandSelectTree());
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.writeEmptyElement(FormatXml.ATOM_CONTENT);
writer.writeAttribute(FormatXml.ATOM_TYPE, mediaResourceMimeType);
writer.writeAttribute(FormatXml.ATOM_SRC, self);
} catch (XMLStreamException e) {
throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
}
}
private void appendAtomMandatoryParts(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data, final String selfLink) throws EntityProviderException {
try {
writer.writeStartElement(FormatXml.ATOM_ID);
location = properties.getServiceRoot().toASCIIString() + selfLink;
writer.writeCharacters(location);
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 = st.valueToString(object, EdmLiteralKind.DEFAULT, titleInfo.getFacets());
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 {
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();
}
return EdmDateTimeOffset.getInstance().valueToString(updateDate, EdmLiteralKind.DEFAULT, updateFacets);
}
private String getTargetPathValue(final EntityInfoAggregator eia, final String targetPath,
final Map<String, Object> data) throws EntityProviderException {
try {
EntityPropertyInfo 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 (EdmSimpleTypeException e) {
throw new EntityProviderProducerException(e.getMessageReference(), 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)
throws EntityProviderException {
StringBuilder sb = new StringBuilder();
if (!eia.isDefaultEntityContainer()) {
sb.append(Encoder.encode(eia.getEntityContainerName())).append(Edm.DELIMITER);
}
sb.append(Encoder.encode(eia.getEntitySetName()));
sb.append("(").append(createEntryKey(eia, data)).append(")").append(extension == null ? "" : ("/" + extension));
return sb.toString();
}
private static String createEntryKey(final EntityInfoAggregator entityInfo, final Map<String, Object> data)
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 {
keys.append(Encoder.encode(type.valueToString(data.get(name), EdmLiteralKind.URI,
keyPropertyInfo.getFacets())));
} catch (final EdmSimpleTypeException e) {
throw new EntityProviderProducerException(e.getMessageReference(), e);
}
}
return keys.toString();
}
private void appendProperties(final XMLStreamWriter writer, final EntityInfoAggregator eia,
final Map<String, Object> data) throws EntityProviderException {
try {
if (properties.isDataBasedPropertySerialization()) {
if (!data.isEmpty()) {
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();
}
} else {
List<String> propertyNames = eia.getSelectedPropertyNames();
if (!propertyNames.isEmpty()) {
writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_PROPERTIES);
for (String propertyName : propertyNames) {
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);
XmlPropertyEntityProducer aps = new XmlPropertyEntityProducer(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;
}
public String getETag() {
return etag;
}
public String getLocation() {
return location;
}
}