| /******************************************************************************* |
| * 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, isIdTag); |
| 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, boolean isIdTag) |
| 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) { |
| if (isIdTag) { |
| keyValue = ""; |
| } else { |
| 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("0"); |
| } 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; |
| } |
| } |