/// <summary>
        /// Writes the self or edit link.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="link">Uri object for the link.</param>
        /// <param name="linkRelation">Relationship value. Either "edit" or "self".</param>
        /// <param name="title">Title for the link.</param>
        internal static void WriteReadOrEditLink(XmlWriter writer, Uri baseUri, Uri link, string linkRelation, string title)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");

            if (link != null)
            {
                // <atom:link>
                writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomLinkElementName,
                    AtomConstants.AtomNamespace);

                writer.WriteAttributeString(
                    AtomConstants.AtomLinkRelationAttributeName,
                    linkRelation);

                writer.WriteAttributeString(
                    AtomConstants.AtomTitleElementName,
                    title ?? String.Empty);

                writer.WriteAttributeString(
                    AtomConstants.AtomHRefAttributeName,
                    AtomUtils.ToUrlAttributeValue(link, baseUri));

                // </atom:link>
                writer.WriteEndElement();
            }
        }
        /// <summary>
        /// Write the metadata for an OData association link; makes sure any duplicate of the link's values duplicated in metadata are equal.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="entry">The entry for which to write the association link.</param>
        /// <param name="associationLink">The association link for which to write the metadata.</param>
        internal static void WriteODataAssociationLinkMetadata(XmlWriter writer, Uri baseUri, ODataEntry entry, ODataAssociationLink associationLink)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(associationLink != null, "link != null");
            Debug.Assert(!string.IsNullOrEmpty(associationLink.Name), "The link name was not verified yet.");
            Debug.Assert(associationLink.Url != null, "The link Url was not verified yet.");

            string linkRelation = AtomUtils.ComputeODataAssociationLinkRelation(associationLink);
            string linkHref     = AtomUtils.ToUrlAttributeValue(associationLink.Url, baseUri);
            string linkHrefLang = null;
            string linkType     = MimeConstants.MimeApplicationXml;
            string linkTitle    = associationLink.Name;
            int?   linkLength   = null;

            AtomLinkMetadata  linkMetadata  = null;
            AtomEntryMetadata entryMetadata = entry.Atom();

            if (entryMetadata != null)
            {
                // TODO: Determine the link metadata from the entry
            }

            if (linkMetadata != null)
            {
                Uri metadataHref = linkMetadata.Href;
                if (metadataHref != null)
                {
                    string metadataHrefString = AtomUtils.ToUrlAttributeValue(metadataHref, baseUri);
                    if (metadataHrefString != linkHref)
                    {
                        throw new ODataException(Strings.ODataAtomWriter_LinkMetadataHrefMustBeEqualWithLinkUrl(metadataHrefString, linkHref));
                    }
                }

                string metadataRelation = linkMetadata.Relation;
                if (metadataRelation != null && metadataRelation != linkRelation)
                {
                    throw new ODataException(Strings.ODataAtomWriter_LinkMetadataRelationMustBeEqualWithComputedRelation(metadataRelation, linkRelation));
                }

                string metadataType = linkMetadata.MediaType;
                if (metadataType != null && metadataType != linkType)
                {
                    throw new ODataException(Strings.ODataAtomWriter_LinkMetadataMediaTypeMustBeEqualWithComputedType(metadataRelation, linkType));
                }

                string metadataTitle = linkMetadata.Title;
                if (metadataTitle != null && metadataTitle != linkTitle)
                {
                    throw new ODataException(Strings.ODataAtomWriter_LinkMetadataTitleMustBeEqualWithLinkName(metadataTitle, linkTitle));
                }

                linkHrefLang = linkMetadata.HrefLang;
                linkLength   = linkMetadata.Length;
            }

            WriteAtomLinkMetadataAttributes(writer, linkRelation, linkHref, linkHrefLang, linkTitle, linkType, linkLength);
        }
        /// <summary>
        /// Writes the specified start/end tags and the specified person metadata as content
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="personMetadata">The person metadata to write.</param>
        internal static void WritePersonMetadata(XmlWriter writer, Uri baseUri, AtomPersonMetadata personMetadata)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(personMetadata != null, "Person metadata must not be null.");

            // <atom:name>name of person</atom:name>
            // NOTE: write an empty element if no name is specified because the element is required.
            ODataAtomWriterUtils.WriteElementWithTextContent(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomPersonNameElementName, AtomConstants.AtomNamespace, personMetadata.Name);

            string uriString = personMetadata.UriFromEpm;

            if (uriString != null)
            {
                Debug.Assert(
                    personMetadata.Uri == null,
                    "If the internal UriFromEpm was used, then the Uri property must be left null. The merge between custom and EPM is probably wrong.");
            }
            else
            {
                Uri uri = personMetadata.Uri;
                if (uri != null)
                {
                    uriString = AtomUtils.ToUrlAttributeValue(uri, baseUri);
                }
            }

            if (uriString != null)
            {
                ODataAtomWriterUtils.WriteElementWithTextContent(
                    writer,
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomPersonUriElementName,
                    AtomConstants.AtomNamespace,
                    uriString);
            }

            string email = personMetadata.Email;

            if (email != null)
            {
                ODataAtomWriterUtils.WriteElementWithTextContent(
                    writer,
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomPersonEmailElementName,
                    AtomConstants.AtomNamespace,
                    email);
            }
        }
        /// <summary>
        /// Write the metadata of a link in ATOM format
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="linkMetadata">The link metadata to write.</param>
        internal static void WriteAtomLinkMetadata(XmlWriter writer, Uri baseUri, AtomLinkMetadata linkMetadata)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(linkMetadata != null, "Link metadata must not be null.");

            // <atom:link ... >
            writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomLinkElementName, AtomConstants.AtomNamespace);

            string linkHref = linkMetadata.Href == null ? null : AtomUtils.ToUrlAttributeValue(linkMetadata.Href, baseUri);

            WriteAtomLinkMetadataAttributes(writer, linkMetadata.Relation, linkHref, linkMetadata.HrefLang, linkMetadata.Title, linkMetadata.MediaType, linkMetadata.Length);

            // </atom:link>
            writer.WriteEndElement();
        }
        /// <summary>
        /// Write the ATOM metadata for an entry
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="entry">The entry for which to write the metadata.</param>
        /// <param name="epmEntryMetadata">The ATOM metadata for the entry which came from EPM.</param>
        internal static void WriteEntryMetadata(XmlWriter writer, Uri baseUri, ODataEntry entry, AtomEntryMetadata epmEntryMetadata)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");

            // TODO, ckerer: implement the rule around authors (an entry has to have an author directly or in the <entry:source> unless the feed has an author).
            //               currently we make all entries have an author.
            AtomEntryMetadata customEntryMetadata = entry.GetAnnotation <AtomEntryMetadata>();
            AtomEntryMetadata entryMetadata       = ODataAtomWriterMetadataEpmMergeUtils.MergeCustomAndEpmEntryMetadata(customEntryMetadata, epmEntryMetadata);

            if (entryMetadata == null)
            {
                // write all required metadata elements with default content

                // <atom:title></atom:title>
                ODataAtomWriterUtils.WriteEmptyElement(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace);

                // <atom:updated>dateTimeOffset</atom:updated>
                // NOTE: the <updated> element is required and if not specified the best we can do is to create a default
                //       one with the current date/time.
                ODataAtomWriterUtils.WriteElementWithTextContent(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomUpdatedElementName, AtomConstants.AtomNamespace, ODataAtomConvert.ToString(DateTimeOffset.UtcNow));

                WriteEmptyAuthor(writer);
            }
            else
            {
                // <atom:title>text</atom:title>
                // NOTE: writes an empty element even if no title was specified since the title is required
                ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, entryMetadata.Title);

                AtomTextConstruct summary = entryMetadata.Summary;
                if (summary != null)
                {
                    // <atom:summary>text</atom:summary>
                    ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomSummaryElementName, AtomConstants.AtomNamespace, summary);
                }

                DateTimeOffset?published = entryMetadata.Published;
                if (published.HasValue)
                {
                    // <atom:published>dateTimeOffset</atom:published>
                    ODataAtomWriterUtils.WriteElementWithTextContent(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomPublishedElementName, AtomConstants.AtomNamespace, ODataAtomConvert.ToString(published.Value));
                }

                // <atom:updated>date</atom:updated>
                // NOTE: the <updated> element is required and if not specified the best we can do is to create a default
                //       one with the current date/time.
                DateTimeOffset updated = entryMetadata.Updated.HasValue ? entryMetadata.Updated.Value : DateTimeOffset.UtcNow;
                ODataAtomWriterUtils.WriteElementWithTextContent(
                    writer,
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomUpdatedElementName,
                    AtomConstants.AtomNamespace,
                    ODataAtomConvert.ToString(updated));

                bool wroteAuthor = false;
                IEnumerable <AtomPersonMetadata> authors = entryMetadata.Authors;
                if (authors != null)
                {
                    foreach (AtomPersonMetadata author in authors)
                    {
                        if (author == null)
                        {
                            throw new ODataException(Strings.ODataAtomWriterMetadataUtils_AuthorMetadataMustNotContainNull);
                        }

                        // <atom:author>author data</atom:author>
                        writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomAuthorElementName, AtomConstants.AtomNamespace);
                        WritePersonMetadata(writer, baseUri, author);
                        writer.WriteEndElement();
                        wroteAuthor = true;
                    }
                }

                if (!wroteAuthor)
                {
                    // write empty authors since they are required
                    WriteEmptyAuthor(writer);
                }

                IEnumerable <AtomPersonMetadata> contributors = entryMetadata.Contributors;
                if (contributors != null)
                {
                    foreach (AtomPersonMetadata contributor in contributors)
                    {
                        if (contributor == null)
                        {
                            throw new ODataException(Strings.ODataAtomWriterMetadataUtils_ContributorMetadataMustNotContainNull);
                        }

                        // <atom:contributor>contributor data</atom:contributor>
                        writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomContributorElementName, AtomConstants.AtomNamespace);
                        WritePersonMetadata(writer, baseUri, contributor);
                        writer.WriteEndElement();
                    }
                }

                IEnumerable <AtomLinkMetadata> links = entryMetadata.Links;
                if (links != null)
                {
                    foreach (AtomLinkMetadata link in links)
                    {
                        if (link == null)
                        {
                            throw new ODataException(Strings.ODataAtomWriterMetadataUtils_LinkMetadataMustNotContainNull);
                        }

                        // <atom:link>...</atom:link>
                        WriteAtomLinkMetadata(writer, baseUri, link);
                    }
                }

                IEnumerable <AtomCategoryMetadata> categories = entryMetadata.Categories;
                if (categories != null)
                {
                    foreach (AtomCategoryMetadata category in categories)
                    {
                        if (category == null)
                        {
                            throw new ODataException(Strings.ODataAtomWriterMetadataUtils_CategoryMetadataMustNotContainNull);
                        }

                        // <atom:category term="..." scheme="..." label="..."></atom:category>
                        WriteCategory(writer, category);
                    }
                }

                if (entryMetadata.Rights != null)
                {
                    // <atom:rights>rights</atom:rights>
                    ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomRightsElementName, AtomConstants.AtomNamespace, entryMetadata.Rights);
                }

                Uri icon = entryMetadata.Icon;
                if (icon != null)
                {
                    // <atom:icon>Uri</atom:icon>
                    ODataAtomWriterUtils.WriteElementWithTextContent(
                        writer,
                        AtomConstants.AtomNamespacePrefix,
                        AtomConstants.AtomIconElementName,
                        AtomConstants.AtomNamespace,
                        AtomUtils.ToUrlAttributeValue(icon, baseUri));
                }

                AtomFeedMetadata source = entryMetadata.Source;
                if (source != null)
                {
                    // <atom:source>
                    writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomSourceElementName, AtomConstants.AtomNamespace);

                    WriteFeedMetadata(writer, baseUri, source, null);

                    // </atom:source>
                    writer.WriteEndElement();
                }
            }
        }
        /// <summary>
        /// Write the given feed metadata in atom format
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="feedMetadata">The metadata to write.</param>
        /// <param name="feed">The feed for which to write the meadata or null if it is the metadata of an atom:source element.</param>
        private static void WriteFeedMetadata(XmlWriter writer, Uri baseUri, AtomFeedMetadata feedMetadata, ODataFeed feed)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(feedMetadata != null, "Feed metadata must not be null!");

            // <atom:id>text</atom:id>
            // NOTE: this is the Id of the feed. For a regular feed this is stored on the feed itself;
            // if used in the context of an <atom:source> element it is stored in metadata
            Debug.Assert(feed == null || !string.IsNullOrEmpty(feed.Id), "The feed Id should have been validated by now.");
            string id = feed == null ? feedMetadata.SourceId : feed.Id;

            ODataAtomWriterUtils.WriteElementWithTextContent(
                writer,
                AtomConstants.AtomNamespacePrefix,
                AtomConstants.AtomIdElementName,
                AtomConstants.AtomNamespace,
                id);

            // <atom:title>text</atom:title>
            // NOTE: write an empty element if no title is specified since the element is required
            ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, feedMetadata.Title);

            if (feedMetadata.Subtitle != null)
            {
                // <atom:subtitle>text</atom:subtitle>
                ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomSubtitleElementName, AtomConstants.AtomNamespace, feedMetadata.Subtitle);
            }

            // <atom:updated>date</atom:updated>
            // NOTE: the <updated> element is required and if not specified the best we can do is to create a default
            //       one with the current date/time.
            DateTimeOffset updated = feedMetadata.Updated.HasValue ? feedMetadata.Updated.Value : DateTimeOffset.UtcNow;

            ODataAtomWriterUtils.WriteElementWithTextContent(
                writer,
                AtomConstants.AtomNamespacePrefix,
                AtomConstants.AtomUpdatedElementName,
                AtomConstants.AtomNamespace,
                ODataAtomConvert.ToString(updated));

            IEnumerable <AtomPersonMetadata> authors = feedMetadata.Authors;

            if (authors != null)
            {
                foreach (AtomPersonMetadata author in authors)
                {
                    // <atom:author>author data</atom:author>
                    writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomAuthorElementName, AtomConstants.AtomNamespace);
                    WritePersonMetadata(writer, baseUri, author);
                    writer.WriteEndElement();
                }
            }

            IEnumerable <AtomLinkMetadata> links = feedMetadata.Links;

            if (links != null)
            {
                foreach (AtomLinkMetadata link in links)
                {
                    // <atom:link>...</atom:link>
                    WriteAtomLinkMetadata(writer, baseUri, link);
                }
            }

            IEnumerable <AtomCategoryMetadata> categories = feedMetadata.Categories;

            if (categories != null)
            {
                foreach (AtomCategoryMetadata category in categories)
                {
                    // <atom:category term="..." scheme="..." label="..."></atom:category>
                    WriteCategory(writer, category);
                }
            }

            Uri logo = feedMetadata.Logo;

            if (logo != null)
            {
                // <atom:logo>Uri</atom:logo>
                ODataAtomWriterUtils.WriteElementWithTextContent(
                    writer,
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomLogoElementName,
                    AtomConstants.AtomNamespace,
                    AtomUtils.ToUrlAttributeValue(logo, baseUri));
            }

            if (feedMetadata.Rights != null)
            {
                // <atom:rights>rights</atom:rights>
                ODataAtomWriterMetadataUtils.WriteTextConstruct(
                    writer,
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomRightsElementName,
                    AtomConstants.AtomNamespace,
                    feedMetadata.Rights);
            }

            IEnumerable <AtomPersonMetadata> contributors = feedMetadata.Contributors;

            if (contributors != null)
            {
                foreach (AtomPersonMetadata contributor in contributors)
                {
                    // <atom:contributor>contributor data</atom:contributor>
                    writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomContributorElementName, AtomConstants.AtomNamespace);
                    WritePersonMetadata(writer, baseUri, contributor);
                    writer.WriteEndElement();
                }
            }

            AtomGeneratorMetadata generator = feedMetadata.Generator;

            if (generator != null)
            {
                // <atom:generator uri="..." version="...">name</atom:generator>
                writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomGeneratorElementName, AtomConstants.AtomNamespace);
                if (generator.Uri != null)
                {
                    writer.WriteAttributeString(AtomConstants.AtomGeneratorUriAttributeName, AtomUtils.ToUrlAttributeValue(generator.Uri, baseUri));
                }

                if (!string.IsNullOrEmpty(generator.Version))
                {
                    writer.WriteAttributeString(AtomConstants.AtomGeneratorVersionAttributeName, generator.Version);
                }

                writer.WriteString(generator.Name);
                writer.WriteEndElement();
            }

            Uri icon = feedMetadata.Icon;

            if (icon != null)
            {
                // <atom:icon>Uri</atom:icon>
                ODataAtomWriterUtils.WriteElementWithTextContent(
                    writer,
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomIconElementName,
                    AtomConstants.AtomNamespace,
                    AtomUtils.ToUrlAttributeValue(icon, baseUri));
            }
        }
        /// <summary>
        /// Writes a named stream to the ATOM payload including an
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="namedStream">The named stream to create the payload for.</param>
        internal static void WriteNamedStream(XmlWriter writer, Uri baseUri, ODataMediaResource namedStream)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(namedStream != null, "Named stream must not be null.");

            // <atom:link rel="...2007/08/dataservices/mediaresource/name">
            writer.WriteStartElement(
                AtomConstants.AtomNamespacePrefix,
                AtomConstants.AtomLinkElementName,
                AtomConstants.AtomNamespace);

            writer.WriteAttributeString(
                AtomConstants.AtomLinkRelationAttributeName,
                AtomUtils.ComputeNamedStreamRelation(namedStream, false));

            writer.WriteAttributeString(
                AtomConstants.AtomTitleElementName,
                namedStream.Name);

            Uri readLink = namedStream.ReadLink;

            if (readLink != null)
            {
                // TODO, ckerer: should we throw when no source link is provided?
                writer.WriteAttributeString(
                    AtomConstants.AtomHRefAttributeName,
                    AtomUtils.ToUrlAttributeValue(readLink, baseUri));
            }

            writer.WriteAttributeString(
                AtomConstants.AtomTypeAttributeName,
                namedStream.ContentType);

            writer.WriteEndElement();

            if (namedStream.EditLink != null)
            {
                // <atom:link rel="...2007/08/dataservices/edit-media/name">
                writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomLinkElementName,
                    AtomConstants.AtomNamespace);

                writer.WriteAttributeString(
                    AtomConstants.AtomLinkRelationAttributeName,
                    AtomUtils.ComputeNamedStreamRelation(namedStream, true));

                writer.WriteAttributeString(
                    AtomConstants.AtomTitleElementName,
                    namedStream.Name);

                Uri editLink = namedStream.EditLink;
                if (editLink != null)
                {
                    writer.WriteAttributeString(
                        AtomConstants.AtomHRefAttributeName,
                        AtomUtils.ToUrlAttributeValue(editLink, baseUri));
                }

                writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    namedStream.ContentType);

                string etag = namedStream.ETag;
                if (etag != null)
                {
                    WriteETag(writer, etag);
                }

                writer.WriteEndElement();
            }
        }
Example #8
0
        /// <summary>
        /// Write the content of the given entry.
        /// </summary>
        /// <param name="entry">The entry for which to write properties.</param>
        /// <param name="entryType">The <see cref="ResourceType"/> of the entry (or null if not metadata is available).</param>
        /// <param name="propertiesValueCache">The cache of properties.</param>
        /// <param name="rootSourcePathSegment">The root of the EPM source tree, if there's an EPM applied.</param>
        private void WriteEntryContent(ODataEntry entry, ResourceType entryType, EntryPropertiesValueCache propertiesValueCache, EpmSourcePathSegment rootSourcePathSegment)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(propertiesValueCache != null, "propertiesValueCache != null");

            ODataMediaResource mediaResource = entry.MediaResource;

            if (mediaResource == null)
            {
                // <content type="application/xml">
                this.writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomContentElementName,
                    AtomConstants.AtomNamespace);

                this.writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    MimeConstants.MimeApplicationXml);

                // <m:properties>
                // we always write the <m:properties> element even if there are no properties
                this.writer.WriteStartElement(
                    AtomConstants.ODataMetadataNamespacePrefix,
                    AtomConstants.AtomPropertiesElementName,
                    AtomConstants.ODataMetadataNamespace);

                ODataAtomWriterUtils.WriteProperties(
                    this.writer,
                    this.MetadataProvider,
                    entryType,
                    propertiesValueCache.EntryProperties,
                    this.Version,
                    false,
                    propertiesValueCache,
                    rootSourcePathSegment);

                // </m:properties>
                this.writer.WriteEndElement();

                // </content>
                this.writer.WriteEndElement();
            }
            else
            {
                Uri mediaEditLink = mediaResource.EditLink;
                if (mediaEditLink != null)
                {
                    // <link rel="edit-media" href="href" />
                    this.writer.WriteStartElement(
                        AtomConstants.AtomNamespacePrefix,
                        AtomConstants.AtomLinkElementName,
                        AtomConstants.AtomNamespace);

                    this.writer.WriteAttributeString(
                        AtomConstants.AtomLinkRelationAttributeName,
                        AtomConstants.AtomEditMediaRelationAttributeValue);

                    this.writer.WriteAttributeString(
                        AtomConstants.AtomHRefAttributeName,
                        AtomUtils.ToUrlAttributeValue(mediaEditLink, this.BaseUri));

                    string mediaETag = mediaResource.ETag;
                    if (mediaETag != null)
                    {
                        this.writer.WriteAttributeString(
                            AtomConstants.ODataMetadataNamespacePrefix,
                            AtomConstants.ODataETagAttributeName,
                            AtomConstants.ODataMetadataNamespace,
                            mediaETag);
                    }

                    // </link>
                    this.writer.WriteEndElement();
                }

                Debug.Assert(mediaEditLink != null || mediaResource.ETag == null, "The default stream edit link and etag should have been validated by now.");

                // <content type="type" src="src">
                this.writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomContentElementName,
                    AtomConstants.AtomNamespace);

                Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now.");
                this.writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    mediaResource.ContentType);

                Debug.Assert(mediaResource.ReadLink != null, "The default stream read link should have been validated by now.");
                this.writer.WriteAttributeString(
                    AtomConstants.MediaLinkEntryContentSourceAttributeName,
                    AtomUtils.ToUrlAttributeValue(mediaResource.ReadLink, this.BaseUri));

                // </content>
                this.writer.WriteEndElement();

                // <m:properties>
                // we always write the <m:properties> element even if there are no properties
                this.writer.WriteStartElement(
                    AtomConstants.ODataMetadataNamespacePrefix,
                    AtomConstants.AtomPropertiesElementName,
                    AtomConstants.ODataMetadataNamespace);

                ODataAtomWriterUtils.WriteProperties(
                    this.writer,
                    this.MetadataProvider,
                    entryType,
                    propertiesValueCache.EntryProperties,
                    this.Version,
                    false,
                    propertiesValueCache,
                    rootSourcePathSegment);

                // </m:properties>
                this.writer.WriteEndElement();
            }
        }
Example #9
0
        /// <summary>
        /// Finish writing a feed.
        /// </summary>
        /// <param name="feed">The feed to write.</param>
        protected override void EndFeed(ODataFeed feed)
        {
            Debug.Assert(feed != null, "feed != null");

            Uri nextPageLink = feed.NextPageLink;

            if (nextPageLink != null)
            {
                // <atom:link rel="next" href="next-page-link" />
                this.writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomLinkElementName, AtomConstants.AtomNamespace);
                this.writer.WriteAttributeString(AtomConstants.AtomLinkRelationAttributeName, AtomConstants.AtomLinkRelationNextAttributeValue);
                this.writer.WriteAttributeString(AtomConstants.AtomHRefAttributeName, AtomUtils.ToUrlAttributeValue(nextPageLink, this.BaseUri));
                this.writer.WriteEndElement();
            }

            ODataAtomWriterMetadataUtils.WriteFeedMetadata(this.writer, this.BaseUri, feed);

            // </atom:feed>
            this.writer.WriteEndElement();
        }