/// <summary> /// Reads an EPM for the entire entry. /// </summary> private void ReadEntryEpm() { // Note that this property access will create empty entry metadata if none were read yet. AtomEntryMetadata entryMetadata = this.EntryState.AtomEntryMetadata; Debug.Assert(entryMetadata != null, "entryMetadata != null"); // If there are no syndication mappings, just return null. EpmTargetPathSegment syndicationRootSegment = this.EntryState.CachedEpm.EpmTargetTree.SyndicationRoot; Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root."); if (syndicationRootSegment.SubSegments.Count == 0) { return; } foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments) { if (targetSegment.HasContent) { this.ReadPropertyValueSegment(targetSegment, entryMetadata); } else { this.ReadParentSegment(targetSegment, entryMetadata); } } }
private void ReadParentSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata) { switch (targetSegment.SegmentName) { case "author": { AtomPersonMetadata personMetadata = entryMetadata.Authors.FirstOrDefault <AtomPersonMetadata>(); if (personMetadata != null) { this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, personMetadata); } return; } case "contributor": { AtomPersonMetadata metadata2 = entryMetadata.Contributors.FirstOrDefault <AtomPersonMetadata>(); if (metadata2 != null) { this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, metadata2); } return; } } throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadParentSegment_TargetSegmentName)); }
private void TryAnnotateV2FeedPackage(ODataEntry entry, EntityInstanceContext entityInstanceContext) { var instance = entityInstanceContext.EntityInstance as V2FeedPackage; if (instance != null) { // Set Atom entry metadata var atomEntryMetadata = new AtomEntryMetadata(); atomEntryMetadata.Title = instance.Id; if (!string.IsNullOrEmpty(instance.Authors)) { atomEntryMetadata.Authors = new[] { new AtomPersonMetadata { Name = instance.Authors } }; } if (instance.LastUpdated > DateTime.MinValue) { atomEntryMetadata.Updated = instance.LastUpdated; } if (!string.IsNullOrEmpty(instance.Summary)) { atomEntryMetadata.Summary = instance.Summary; } entry.SetAnnotation(atomEntryMetadata); // Add package download link entry.MediaResource = new ODataStreamReferenceValue { ContentType = ContentType, ReadLink = BuildLinkForStreamProperty("v2", instance.Id, instance.Version, entityInstanceContext.Request) }; } }
private void ReadParentSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata) { switch (targetSegment.SegmentName) { case "author": { AtomPersonMetadata personMetadata = entryMetadata.Authors.FirstOrDefault<AtomPersonMetadata>(); if (personMetadata != null) { this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, personMetadata); } return; } case "contributor": { AtomPersonMetadata metadata2 = entryMetadata.Contributors.FirstOrDefault<AtomPersonMetadata>(); if (metadata2 != null) { this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, metadata2); } return; } } throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadParentSegment_TargetSegmentName)); }
/// <summary> /// Reads a leaf segment which maps to a property value. /// </summary> /// <param name="targetSegment">The segment being read.</param> /// <param name="entryMetadata">The ATOM entry metadata to read from.</param> private void ReadPropertyValueSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata) { Debug.Assert(targetSegment != null, "targetSegment != null"); Debug.Assert(entryMetadata != null, "entryMetadata != null"); EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo; Debug.Assert( epmInfo != null && epmInfo.Attribute != null, "If the segment has content it must have EpmInfo which in turn must have the Epm attribute"); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: if (this.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { if (entryMetadata.UpdatedString != null) { this.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.UpdatedString); } } else if (entryMetadata.Updated.HasValue) { this.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Updated.Value)); } break; case SyndicationItemProperty.Published: if (this.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { if (entryMetadata.PublishedString != null) { this.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.PublishedString); } } else if (entryMetadata.Published.HasValue) { this.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Published.Value)); } break; case SyndicationItemProperty.Rights: this.ReadTextConstructEpm(targetSegment, entryMetadata.Rights); break; case SyndicationItemProperty.Summary: this.ReadTextConstructEpm(targetSegment, entryMetadata.Summary); break; case SyndicationItemProperty.Title: this.ReadTextConstructEpm(targetSegment, entryMetadata.Title); break; default: throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadEntryEpm_ContentTarget)); } }
internal static void AddCategoryToEntryMetadata(AtomEntryMetadata entryMetadata, AtomCategoryMetadata categoryMetadata) { if (object.ReferenceEquals(entryMetadata.Categories, EmptyCategoriesList)) { entryMetadata.Categories = new ReadOnlyEnumerable<AtomCategoryMetadata>(); } ReaderUtils.GetSourceListOfEnumerable<AtomCategoryMetadata>(entryMetadata.Categories, "Categories").Add(categoryMetadata); }
internal static void AddLinkToEntryMetadata(AtomEntryMetadata entryMetadata, AtomLinkMetadata linkMetadata) { if (object.ReferenceEquals(entryMetadata.Links, EmptyLinksList)) { entryMetadata.Links = new ReadOnlyEnumerable<AtomLinkMetadata>(); } ReaderUtils.GetSourceListOfEnumerable<AtomLinkMetadata>(entryMetadata.Links, "Links").Add(linkMetadata); }
internal static void AddContributorToEntryMetadata(AtomEntryMetadata entryMetadata, AtomPersonMetadata contributorMetadata) { if (object.ReferenceEquals(entryMetadata.Contributors, EmptyPersonsList)) { entryMetadata.Contributors = new ReadOnlyEnumerable<AtomPersonMetadata>(); } ReaderUtils.GetSourceListOfEnumerable<AtomPersonMetadata>(entryMetadata.Contributors, "Contributors").Add(contributorMetadata); }
internal void WriteEntryTypeName(string typeName, AtomEntryMetadata entryMetadata) { if (typeName != null) { AtomCategoryMetadata category = ODataAtomWriterMetadataUtils.MergeCategoryMetadata((entryMetadata == null) ? null : entryMetadata.CategoryWithTypeName, typeName, base.MessageWriterSettings.WriterBehavior.ODataTypeScheme); this.atomEntryMetadataSerializer.WriteCategory(category); } }
public static AtomEntryMetadata Atom(this ODataEntry entry) { ExceptionUtils.CheckArgumentNotNull<ODataEntry>(entry, "entry"); AtomEntryMetadata annotation = entry.GetAnnotation<AtomEntryMetadata>(); if (annotation == null) { annotation = new AtomEntryMetadata(); entry.SetAnnotation<AtomEntryMetadata>(annotation); } return annotation; }
/// <summary> /// Writes the edit link element for an entry. /// </summary> /// <param name="editLink">The edit link URL.</param> /// <param name="entryMetadata">The ATOM entry metatadata for the current entry.</param> internal void WriteEntryEditLink(Uri editLink, AtomEntryMetadata entryMetadata) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(editLink != null, "editLink != null"); // we allow additional link metadata to specify the title, type, hreflang or length of the link AtomLinkMetadata editLinkMetadata = entryMetadata == null ? null : entryMetadata.EditLink; // <link rel="edit" href="LinkHRef" .../> this.WriteReadOrEditLink(editLink, editLinkMetadata, AtomConstants.AtomEditRelationAttributeValue); }
private void ReadPropertyValueSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata) { switch (targetSegment.EpmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: if (base.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient) { if (!entryMetadata.Updated.HasValue) { break; } base.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Updated.Value)); return; } if (entryMetadata.UpdatedString == null) { break; } base.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.UpdatedString); return; case SyndicationItemProperty.Published: if (base.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient) { if (entryMetadata.Published.HasValue) { base.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Published.Value)); return; } break; } if (entryMetadata.PublishedString == null) { break; } base.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.PublishedString); return; case SyndicationItemProperty.Rights: this.ReadTextConstructEpm(targetSegment, entryMetadata.Rights); return; case SyndicationItemProperty.Summary: this.ReadTextConstructEpm(targetSegment, entryMetadata.Summary); return; case SyndicationItemProperty.Title: this.ReadTextConstructEpm(targetSegment, entryMetadata.Title); return; default: throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadEntryEpm_ContentTarget)); } }
public static AtomEntryMetadata Atom(this ODataEntry entry) { ExceptionUtils.CheckArgumentNotNull <ODataEntry>(entry, "entry"); AtomEntryMetadata annotation = entry.GetAnnotation <AtomEntryMetadata>(); if (annotation == null) { annotation = new AtomEntryMetadata(); entry.SetAnnotation <AtomEntryMetadata>(annotation); } return(annotation); }
/// <summary> /// Writes the type name category element for the entry. /// </summary> /// <param name="typeName">The type name to write.</param> /// <param name="entryMetadata">The entry metadata if available.</param> internal void WriteEntryTypeName(string typeName, AtomEntryMetadata entryMetadata) { DebugUtils.CheckNoExternalCallers(); if (typeName != null) { AtomCategoryMetadata mergedCategoryMetadata = ODataAtomWriterMetadataUtils.MergeCategoryMetadata( entryMetadata == null ? null : entryMetadata.CategoryWithTypeName, typeName, this.MessageWriterSettings.WriterBehavior.ODataTypeScheme); this.atomEntryMetadataSerializer.WriteCategory(mergedCategoryMetadata); } }
public static AtomEntryMetadata Atom(this ODataEntry entry) { ExceptionUtils.CheckArgumentNotNull(entry, "entry"); AtomEntryMetadata entryMetadata = entry.GetAnnotation<AtomEntryMetadata>(); if (entryMetadata == null) { entryMetadata = new AtomEntryMetadata(); entry.SetAnnotation(entryMetadata); } return entryMetadata; }
/// <summary> /// Adds a new author to entry metadata. /// </summary> /// <param name="entryMetadata">The entry metadata to add the author to.</param> /// <param name="authorMetadata">The author metadata to add.</param> internal static void AddAuthorToEntryMetadata(AtomEntryMetadata entryMetadata, AtomPersonMetadata authorMetadata) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entryMetadata != null, "entryMetadata != null"); Debug.Assert(authorMetadata != null, "authorMetadata != null"); if (object.ReferenceEquals(entryMetadata.Authors, EmptyPersonsList)) { entryMetadata.Authors = new ReadOnlyEnumerable<AtomPersonMetadata>(); } ReaderUtils.GetSourceListOfEnumerable(entryMetadata.Authors, "Authors").Add(authorMetadata); }
public static AtomEntryMetadata Atom(this ODataEntry entry) { ExceptionUtils.CheckArgumentNotNull(entry, "entry"); AtomEntryMetadata entryMetadata = entry.GetAnnotation <AtomEntryMetadata>(); if (entryMetadata == null) { entryMetadata = new AtomEntryMetadata(); entry.SetAnnotation(entryMetadata); } return(entryMetadata); }
protected override void StartEntry(ODataEntry entry) { this.CheckAndWriteParentNavigationLinkStartForInlineElement(); if (entry != null) { this.StartEntryXmlCustomization(entry); this.atomOutputContext.XmlWriter.WriteStartElement("", "entry", "http://www.w3.org/2005/Atom"); if (base.IsTopLevel) { this.atomEntryAndFeedSerializer.WriteBaseUriAndDefaultNamespaceAttributes(); } string eTag = entry.ETag; if (eTag != null) { ODataAtomWriterUtils.WriteETag(this.atomOutputContext.XmlWriter, eTag); } AtomEntryScope currentEntryScope = this.CurrentEntryScope; AtomEntryMetadata entryMetadata = entry.Atom(); string id = entry.Id; if (id != null) { this.atomEntryAndFeedSerializer.WriteEntryId(id); currentEntryScope.SetWrittenElement(AtomElement.Id); } string typeName = entry.TypeName; SerializationTypeNameAnnotation annotation = entry.GetAnnotation <SerializationTypeNameAnnotation>(); if (annotation != null) { typeName = annotation.TypeName; } this.atomEntryAndFeedSerializer.WriteEntryTypeName(typeName, entryMetadata); Uri editLink = entry.EditLink; if (editLink != null) { this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata); currentEntryScope.SetWrittenElement(AtomElement.EditLink); } Uri readLink = entry.ReadLink; if (readLink != null) { this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata); currentEntryScope.SetWrittenElement(AtomElement.ReadLink); } } }
private void ReadEntryEpm() { AtomEntryMetadata atomEntryMetadata = base.EntryState.AtomEntryMetadata; EpmTargetPathSegment syndicationRoot = base.EntryState.CachedEpm.EpmTargetTree.SyndicationRoot; if (syndicationRoot.SubSegments.Count != 0) { foreach (EpmTargetPathSegment segment2 in syndicationRoot.SubSegments) { if (segment2.HasContent) { this.ReadPropertyValueSegment(segment2, atomEntryMetadata); } else { this.ReadParentSegment(segment2, atomEntryMetadata); } } } }
/// <summary> /// Reads a non-leaf segment which has sub segments. /// </summary> /// <param name="targetSegment">The segment being read.</param> /// <param name="entryMetadata">The ATOM entry metadata to read from.</param> private void ReadParentSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata) { Debug.Assert(targetSegment != null, "targetSegment != null"); Debug.Assert(entryMetadata != null, "entryMetadata != null"); switch (targetSegment.SegmentName) { case AtomConstants.AtomAuthorElementName: // If a singleton property (non-collection) is mapped to author and there are multiple authors // EPM uses the first author. AtomPersonMetadata authorMetadata = entryMetadata.Authors.FirstOrDefault(); if (authorMetadata != null) { this.ReadPersonEpm( ReaderUtils.GetPropertiesList(this.EntryState.Entry.Properties), this.EntryState.EntityType.ToTypeReference(), targetSegment, authorMetadata); } break; case AtomConstants.AtomContributorElementName: // If a singleton property (non-collection) is mapped to contributor and there are multiple contributors // EPM uses the first contributor. AtomPersonMetadata contributorMetadata = entryMetadata.Contributors.FirstOrDefault(); if (contributorMetadata != null) { this.ReadPersonEpm( ReaderUtils.GetPropertiesList(this.EntryState.Entry.Properties), this.EntryState.EntityType.ToTypeReference(), targetSegment, contributorMetadata); } break; default: throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadParentSegment_TargetSegmentName)); } }
internal static AtomEntryMetadata MergeCustomAndEpmEntryMetadata(AtomEntryMetadata customEntryMetadata, AtomEntryMetadata epmEntryMetadata, ODataWriterBehavior writerBehavior) { AtomEntryMetadata metadata; if ((customEntryMetadata != null) && (writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient)) { if (customEntryMetadata.Updated.HasValue) { customEntryMetadata.UpdatedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Updated.Value); } if (customEntryMetadata.Published.HasValue) { customEntryMetadata.PublishedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Published.Value); } } if (TryMergeIfNull <AtomEntryMetadata>(customEntryMetadata, epmEntryMetadata, out metadata)) { return(metadata); } epmEntryMetadata.Title = MergeAtomTextValue(customEntryMetadata.Title, epmEntryMetadata.Title, "Title"); epmEntryMetadata.Summary = MergeAtomTextValue(customEntryMetadata.Summary, epmEntryMetadata.Summary, "Summary"); epmEntryMetadata.Rights = MergeAtomTextValue(customEntryMetadata.Rights, epmEntryMetadata.Rights, "Rights"); if (writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { epmEntryMetadata.PublishedString = MergeTextValue(customEntryMetadata.PublishedString, epmEntryMetadata.PublishedString, "PublishedString"); epmEntryMetadata.UpdatedString = MergeTextValue(customEntryMetadata.UpdatedString, epmEntryMetadata.UpdatedString, "UpdatedString"); } else { epmEntryMetadata.Published = MergeDateTimeValue(customEntryMetadata.Published, epmEntryMetadata.Published, "Published"); epmEntryMetadata.Updated = MergeDateTimeValue(customEntryMetadata.Updated, epmEntryMetadata.Updated, "Updated"); } epmEntryMetadata.Authors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Authors, epmEntryMetadata.Authors); epmEntryMetadata.Contributors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Contributors, epmEntryMetadata.Contributors); epmEntryMetadata.Categories = MergeSyndicationMapping <AtomCategoryMetadata>(customEntryMetadata.Categories, epmEntryMetadata.Categories); epmEntryMetadata.Links = MergeSyndicationMapping <AtomLinkMetadata>(customEntryMetadata.Links, epmEntryMetadata.Links); epmEntryMetadata.Source = customEntryMetadata.Source; return(epmEntryMetadata); }
private void WriteEntry(IExpandedResult expanded, object element, bool resourceInstanceInFeed, ResourceType expectedType) { Uri uri; Func<ProjectionNode, bool> predicate = null; base.IncrementSegmentResultCount(); ODataEntry entry = new ODataEntry(); AtomEntryMetadata annotation = new AtomEntryMetadata(); entry.SetAnnotation<AtomEntryMetadata>(annotation); string name = expectedType.Name; ResourceType actualResourceType = WebUtil.GetNonPrimitiveResourceType(base.Provider, element); if (actualResourceType.ResourceTypeKind != ResourceTypeKind.EntityType) { throw new DataServiceException(500, System.Data.Services.Strings.BadProvider_InconsistentEntityOrComplexTypeUsage(actualResourceType.FullName)); } Uri absoluteUri = Serializer.GetIdAndEditLink(element, actualResourceType, base.Provider, base.CurrentContainer, base.AbsoluteServiceUri, out uri); Uri relativeUri = new Uri(absoluteUri.AbsoluteUri.Substring(base.AbsoluteServiceUri.AbsoluteUri.Length), UriKind.Relative); entry.MediaResource = this.GetMediaResource(element, actualResourceType, name, relativeUri); entry.TypeName = actualResourceType.FullName; entry.Id = uri.AbsoluteUri; entry.EditLink = relativeUri; AtomLinkMetadata metadata2 = new AtomLinkMetadata { Title = name }; annotation.EditLink = metadata2; string eTagValue = base.GetETagValue(element, actualResourceType); if (eTagValue != null) { entry.ETag = eTagValue; } IEnumerable<ProjectionNode> projections = base.GetProjections(); if (projections != null) { if (predicate == null) { predicate = projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(actualResourceType); } projections = projections.Where<ProjectionNode>(predicate); entry.SetAnnotation<ProjectedPropertiesAnnotation>(new ProjectedPropertiesAnnotation(from p in projections select p.PropertyName)); } entry.AssociationLinks = this.GetEntityAssociationLinks(actualResourceType, relativeUri, projections); this.PopulateODataOperations(element, resourceInstanceInFeed, entry, actualResourceType); this.odataWriter.WriteStart(entry); this.WriteNavigationProperties(expanded, element, resourceInstanceInFeed, actualResourceType, absoluteUri, relativeUri, projections); entry.Properties = this.GetEntityProperties(element, actualResourceType, relativeUri, projections); this.odataWriter.WriteEnd(); }
/// <summary> /// Write the ATOM metadata for an entry /// </summary> /// <param name="entryMetadata">The entry metadata to write.</param> /// <param name="epmEntryMetadata">The ATOM metadata for the entry which came from EPM.</param> /// <param name="updatedTime">Value for the atom:updated element.</param> internal void WriteEntryMetadata(AtomEntryMetadata entryMetadata, AtomEntryMetadata epmEntryMetadata, string updatedTime) { DebugUtils.CheckNoExternalCallers(); this.atomEntryMetadataSerializer.WriteEntryMetadata(entryMetadata, epmEntryMetadata, updatedTime); }
internal void WriteEntryMetadata(AtomEntryMetadata entryMetadata, AtomEntryMetadata epmEntryMetadata, string updatedTime) { AtomEntryMetadata metadata = ODataAtomWriterMetadataEpmMergeUtils.MergeCustomAndEpmEntryMetadata(entryMetadata, epmEntryMetadata, base.MessageWriterSettings.WriterBehavior); if (metadata == null) { base.WriteEmptyElement("", "title", "http://www.w3.org/2005/Atom"); base.WriteElementWithTextContent("", "updated", "http://www.w3.org/2005/Atom", updatedTime); base.WriteEmptyAuthor(); } else { base.WriteTextConstruct("", "title", "http://www.w3.org/2005/Atom", metadata.Title); AtomTextConstruct summary = metadata.Summary; if (summary != null) { base.WriteTextConstruct("", "summary", "http://www.w3.org/2005/Atom", summary); } string textContent = base.UseClientFormatBehavior ? metadata.PublishedString : (metadata.Published.HasValue ? ODataAtomConvert.ToAtomString(metadata.Published.Value) : null); if (textContent != null) { base.WriteElementWithTextContent("", "published", "http://www.w3.org/2005/Atom", textContent); } string str2 = base.UseClientFormatBehavior ? metadata.UpdatedString : (metadata.Updated.HasValue ? ODataAtomConvert.ToAtomString(metadata.Updated.Value) : null); str2 = str2 ?? updatedTime; base.WriteElementWithTextContent("", "updated", "http://www.w3.org/2005/Atom", str2); bool flag = false; IEnumerable <AtomPersonMetadata> authors = metadata.Authors; if (authors != null) { foreach (AtomPersonMetadata metadata2 in authors) { if (metadata2 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_AuthorMetadataMustNotContainNull); } base.XmlWriter.WriteStartElement("", "author", "http://www.w3.org/2005/Atom"); base.WritePersonMetadata(metadata2); base.XmlWriter.WriteEndElement(); flag = true; } } if (!flag) { base.WriteEmptyAuthor(); } IEnumerable <AtomPersonMetadata> contributors = metadata.Contributors; if (contributors != null) { foreach (AtomPersonMetadata metadata3 in contributors) { if (metadata3 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_ContributorMetadataMustNotContainNull); } base.XmlWriter.WriteStartElement("", "contributor", "http://www.w3.org/2005/Atom"); base.WritePersonMetadata(metadata3); base.XmlWriter.WriteEndElement(); } } IEnumerable <AtomLinkMetadata> links = metadata.Links; if (links != null) { foreach (AtomLinkMetadata metadata4 in links) { if (metadata4 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_LinkMetadataMustNotContainNull); } base.WriteAtomLink(metadata4, null); } } IEnumerable <AtomCategoryMetadata> categories = metadata.Categories; if (categories != null) { foreach (AtomCategoryMetadata metadata5 in categories) { if (metadata5 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_CategoryMetadataMustNotContainNull); } base.WriteCategory(metadata5); } } if (metadata.Rights != null) { base.WriteTextConstruct("", "rights", "http://www.w3.org/2005/Atom", metadata.Rights); } AtomFeedMetadata source = metadata.Source; if (source != null) { bool flag2; base.XmlWriter.WriteStartElement("", "source", "http://www.w3.org/2005/Atom"); this.SourceMetadataSerializer.WriteFeedMetadata(source, null, updatedTime, out flag2); base.XmlWriter.WriteEndElement(); } } }
internal void WriteEntryMetadata(AtomEntryMetadata entryMetadata, AtomEntryMetadata epmEntryMetadata, string updatedTime) { AtomEntryMetadata metadata = ODataAtomWriterMetadataEpmMergeUtils.MergeCustomAndEpmEntryMetadata(entryMetadata, epmEntryMetadata, base.MessageWriterSettings.WriterBehavior); if (metadata == null) { base.WriteEmptyElement("", "title", "http://www.w3.org/2005/Atom"); base.WriteElementWithTextContent("", "updated", "http://www.w3.org/2005/Atom", updatedTime); base.WriteEmptyAuthor(); } else { base.WriteTextConstruct("", "title", "http://www.w3.org/2005/Atom", metadata.Title); AtomTextConstruct summary = metadata.Summary; if (summary != null) { base.WriteTextConstruct("", "summary", "http://www.w3.org/2005/Atom", summary); } string textContent = base.UseClientFormatBehavior ? metadata.PublishedString : (metadata.Published.HasValue ? ODataAtomConvert.ToAtomString(metadata.Published.Value) : null); if (textContent != null) { base.WriteElementWithTextContent("", "published", "http://www.w3.org/2005/Atom", textContent); } string str2 = base.UseClientFormatBehavior ? metadata.UpdatedString : (metadata.Updated.HasValue ? ODataAtomConvert.ToAtomString(metadata.Updated.Value) : null); str2 = str2 ?? updatedTime; base.WriteElementWithTextContent("", "updated", "http://www.w3.org/2005/Atom", str2); bool flag = false; IEnumerable<AtomPersonMetadata> authors = metadata.Authors; if (authors != null) { foreach (AtomPersonMetadata metadata2 in authors) { if (metadata2 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_AuthorMetadataMustNotContainNull); } base.XmlWriter.WriteStartElement("", "author", "http://www.w3.org/2005/Atom"); base.WritePersonMetadata(metadata2); base.XmlWriter.WriteEndElement(); flag = true; } } if (!flag) { base.WriteEmptyAuthor(); } IEnumerable<AtomPersonMetadata> contributors = metadata.Contributors; if (contributors != null) { foreach (AtomPersonMetadata metadata3 in contributors) { if (metadata3 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_ContributorMetadataMustNotContainNull); } base.XmlWriter.WriteStartElement("", "contributor", "http://www.w3.org/2005/Atom"); base.WritePersonMetadata(metadata3); base.XmlWriter.WriteEndElement(); } } IEnumerable<AtomLinkMetadata> links = metadata.Links; if (links != null) { foreach (AtomLinkMetadata metadata4 in links) { if (metadata4 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_LinkMetadataMustNotContainNull); } base.WriteAtomLink(metadata4, null); } } IEnumerable<AtomCategoryMetadata> categories = metadata.Categories; if (categories != null) { foreach (AtomCategoryMetadata metadata5 in categories) { if (metadata5 == null) { throw new ODataException(Strings.ODataAtomWriterMetadataUtils_CategoryMetadataMustNotContainNull); } base.WriteCategory(metadata5); } } if (metadata.Rights != null) { base.WriteTextConstruct("", "rights", "http://www.w3.org/2005/Atom", metadata.Rights); } AtomFeedMetadata source = metadata.Source; if (source != null) { bool flag2; base.XmlWriter.WriteStartElement("", "source", "http://www.w3.org/2005/Atom"); this.SourceMetadataSerializer.WriteFeedMetadata(source, null, updatedTime, out flag2); base.XmlWriter.WriteEndElement(); } } }
/// <summary> /// Reads an element in ATOM namespace in the content of the entry element. /// </summary> /// <param name="entryState">The reader entry state for the entry being read.</param> /// <remarks> /// Pre-Condition: XmlNodeType.Element (atom:*) - the ATOM element to read. /// Post-Condition: Any - the node after the ATOM element which was read. /// </remarks> internal void ReadAtomElementInEntryContent(IODataAtomReaderEntryState entryState) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entryState != null, "entryState != null"); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert(this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace, "Only atom:* elements can be read by this method."); ODataEntityPropertyMappingCache cachedEpm = entryState.CachedEpm; EpmTargetPathSegment epmTargetPathSegment = null; if (cachedEpm != null) { epmTargetPathSegment = cachedEpm.EpmTargetTree.SyndicationRoot; } EpmTargetPathSegment subSegment; if (this.ShouldReadElement(epmTargetPathSegment, this.XmlReader.LocalName, out subSegment)) { switch (this.XmlReader.LocalName) { case AtomConstants.AtomAuthorElementName: this.ReadAuthorElement(entryState, subSegment); return; case AtomConstants.AtomContributorElementName: this.ReadContributorElement(entryState, subSegment); return; case AtomConstants.AtomUpdatedElementName: { AtomEntryMetadata entryMetadata = entryState.AtomEntryMetadata; if (this.UseClientFormatBehavior) { if (this.ShouldReadSingletonElement(entryMetadata.UpdatedString != null)) { entryMetadata.UpdatedString = this.ReadAtomDateConstructAsString(); return; } } else { if (this.ShouldReadSingletonElement(entryMetadata.Updated.HasValue)) { entryMetadata.Updated = this.ReadAtomDateConstruct(); return; } } } break; case AtomConstants.AtomPublishedElementName: { AtomEntryMetadata entryMetadata = entryState.AtomEntryMetadata; if (this.UseClientFormatBehavior) { if (this.ShouldReadSingletonElement(entryMetadata.PublishedString != null)) { entryMetadata.PublishedString = this.ReadAtomDateConstructAsString(); return; } } else { if (this.ShouldReadSingletonElement(entryMetadata.Published.HasValue)) { entryMetadata.Published = this.ReadAtomDateConstruct(); return; } } } break; case AtomConstants.AtomRightsElementName: if (this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Rights != null)) { entryState.AtomEntryMetadata.Rights = this.ReadAtomTextConstruct(); return; } break; case AtomConstants.AtomSourceElementName: if (this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Source != null)) { entryState.AtomEntryMetadata.Source = this.ReadAtomSourceInEntryContent(); return; } break; case AtomConstants.AtomSummaryElementName: if (this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Summary != null)) { entryState.AtomEntryMetadata.Summary = this.ReadAtomTextConstruct(); return; } break; case AtomConstants.AtomTitleElementName: if (this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Title != null)) { entryState.AtomEntryMetadata.Title = this.ReadAtomTextConstruct(); return; } break; default: break; } } // Skip everything we didn't read. this.XmlReader.Skip(); }
/// <summary> /// Constructor. /// </summary> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="atomOutputContext">The output context currently in use.</param> private EpmSyndicationWriter(EpmTargetTree epmTargetTree, ODataAtomOutputContext atomOutputContext) : base(atomOutputContext) { this.epmTargetTree = epmTargetTree; this.entryMetadata = new AtomEntryMetadata(); }
/// <summary> /// Merges custom and EPM ATOM metadata. /// </summary> /// <param name="customEntryMetadata">The custom ATOM metadata, or null if there were no custom ATOM metadata.</param> /// <param name="epmEntryMetadata">The EPM ATOM metadata, or null if there are no EPM mappings to syndication targets.</param> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance configuring the writer.</param> /// <returns>The merged ATOM metadata to write to the output.</returns> /// <remarks>The merge means that if one of the sides has null, the other is used, otherwise if both are non-null /// we verify that the values are the same, otherwise we throw.</remarks> internal static AtomEntryMetadata MergeCustomAndEpmEntryMetadata(AtomEntryMetadata customEntryMetadata, AtomEntryMetadata epmEntryMetadata, ODataWriterBehavior writerBehavior) { DebugUtils.CheckNoExternalCallers(); if (customEntryMetadata != null && writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { // ODataLib supports specifying ATOM metadata for entries even in the WCF DS client mode; // WCF DS itself will never do this but ODataLib clients using this mode might. We have // to convert potential Published and Updated values to the internal string properties // used in WCF DS client mode. if (customEntryMetadata.Updated.HasValue) { customEntryMetadata.UpdatedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Updated.Value); } if (customEntryMetadata.Published.HasValue) { customEntryMetadata.PublishedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Published.Value); } } AtomEntryMetadata simpleMergeResult; if (TryMergeIfNull(customEntryMetadata, epmEntryMetadata, out simpleMergeResult)) { return(simpleMergeResult); } // We will be modifying the EPM metadata adding the custom into it // The reason is that with EPM we can be sure that the enumerations are of type List (since they were created like that) and thus // we can safely add items into those without reallocating the collections. // Merge Title epmEntryMetadata.Title = MergeAtomTextValue(customEntryMetadata.Title, epmEntryMetadata.Title, "Title"); // Merge Summary epmEntryMetadata.Summary = MergeAtomTextValue(customEntryMetadata.Summary, epmEntryMetadata.Summary, "Summary"); // Merge Rights epmEntryMetadata.Rights = MergeAtomTextValue(customEntryMetadata.Rights, epmEntryMetadata.Rights, "Rights"); if (writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { // Merge PublishedString epmEntryMetadata.PublishedString = MergeTextValue(customEntryMetadata.PublishedString, epmEntryMetadata.PublishedString, "PublishedString"); // Merge UpdatedString epmEntryMetadata.UpdatedString = MergeTextValue(customEntryMetadata.UpdatedString, epmEntryMetadata.UpdatedString, "UpdatedString"); } else { // Merge Published epmEntryMetadata.Published = MergeDateTimeValue(customEntryMetadata.Published, epmEntryMetadata.Published, "Published"); // Merge Updated epmEntryMetadata.Updated = MergeDateTimeValue(customEntryMetadata.Updated, epmEntryMetadata.Updated, "Updated"); } // Merge authors epmEntryMetadata.Authors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Authors, epmEntryMetadata.Authors); // Merge contributors epmEntryMetadata.Contributors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Contributors, epmEntryMetadata.Contributors); // Merge Categories epmEntryMetadata.Categories = MergeSyndicationMapping <AtomCategoryMetadata>(customEntryMetadata.Categories, epmEntryMetadata.Categories); // Merge Links epmEntryMetadata.Links = MergeSyndicationMapping <AtomLinkMetadata>(customEntryMetadata.Links, epmEntryMetadata.Links); // Source // Copy the source element over from custom metadata since EPM doesn't use it yet. Debug.Assert(epmEntryMetadata.Source == null, "Once EPM actually writes to source element, implement the merge with custom metadata here."); epmEntryMetadata.Source = customEntryMetadata.Source; return(epmEntryMetadata); }
internal void WriteEntryEditLink(Uri editLink, AtomEntryMetadata entryMetadata) { AtomLinkMetadata linkMetadata = (entryMetadata == null) ? null : entryMetadata.EditLink; this.WriteReadOrEditLink(editLink, linkMetadata, "edit"); }
protected override void EndEntry(ODataEntry entry) { if (entry == null) { this.CheckAndWriteParentNavigationLinkEndForInlineElement(); } else { IEdmEntityType entryEntityType = base.EntryEntityType; EntryPropertiesValueCache propertyValueCache = new EntryPropertiesValueCache(entry); ODataEntityPropertyMappingCache cache2 = this.atomOutputContext.Model.EnsureEpmCache(entryEntityType, 0x7fffffff); if (cache2 != null) { EpmWriterUtils.CacheEpmProperties(propertyValueCache, cache2.EpmSourceTree); } ProjectedPropertiesAnnotation projectedProperties = entry.GetAnnotation <ProjectedPropertiesAnnotation>(); AtomEntryScope currentEntryScope = this.CurrentEntryScope; AtomEntryMetadata entryMetadata = entry.Atom(); if (!currentEntryScope.IsElementWritten(AtomElement.Id)) { this.atomEntryAndFeedSerializer.WriteEntryId(entry.Id); } Uri editLink = entry.EditLink; if ((editLink != null) && !currentEntryScope.IsElementWritten(AtomElement.EditLink)) { this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata); } Uri readLink = entry.ReadLink; if ((readLink != null) && !currentEntryScope.IsElementWritten(AtomElement.ReadLink)) { this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata); } AtomEntryMetadata epmEntryMetadata = null; if (cache2 != null) { ODataVersionChecker.CheckEntityPropertyMapping(this.atomOutputContext.Version, entryEntityType, this.atomOutputContext.Model); epmEntryMetadata = EpmSyndicationWriter.WriteEntryEpm(cache2.EpmTargetTree, propertyValueCache, entryEntityType.ToTypeReference().AsEntity(), this.atomOutputContext); } this.atomEntryAndFeedSerializer.WriteEntryMetadata(entryMetadata, epmEntryMetadata, this.updatedTime); IEnumerable <ODataProperty> entryStreamProperties = propertyValueCache.EntryStreamProperties; if (entryStreamProperties != null) { foreach (ODataProperty property in entryStreamProperties) { this.atomEntryAndFeedSerializer.WriteStreamProperty(property, entryEntityType, base.DuplicatePropertyNamesChecker, projectedProperties); } } IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks; if (associationLinks != null) { foreach (ODataAssociationLink link in associationLinks) { this.atomEntryAndFeedSerializer.WriteAssociationLink(link, entryEntityType, base.DuplicatePropertyNamesChecker, projectedProperties); } } IEnumerable <ODataAction> actions = entry.Actions; if (actions != null) { foreach (ODataAction action in actions) { ValidationUtils.ValidateOperationNotNull(action, true); this.atomEntryAndFeedSerializer.WriteOperation(action); } } IEnumerable <ODataFunction> functions = entry.Functions; if (functions != null) { foreach (ODataFunction function in functions) { ValidationUtils.ValidateOperationNotNull(function, false); this.atomEntryAndFeedSerializer.WriteOperation(function); } } this.WriteEntryContent(entry, entryEntityType, propertyValueCache, (cache2 == null) ? null : cache2.EpmSourceTree.Root, projectedProperties); if (cache2 != null) { EpmCustomWriter.WriteEntryEpm(this.atomOutputContext.XmlWriter, cache2.EpmTargetTree, propertyValueCache, entryEntityType.ToTypeReference().AsEntity(), this.atomOutputContext); } this.atomOutputContext.XmlWriter.WriteEndElement(); this.EndEntryXmlCustomization(entry); this.CheckAndWriteParentNavigationLinkEndForInlineElement(); } }
internal void WriteEntryReadLink(Uri readLink, AtomEntryMetadata entryMetadata) { AtomLinkMetadata linkMetadata = (entryMetadata == null) ? null : entryMetadata.SelfLink; this.WriteReadOrEditLink(readLink, linkMetadata, "self"); }
internal void WriteEntryMetadata(AtomEntryMetadata entryMetadata, AtomEntryMetadata epmEntryMetadata, string updatedTime) { this.atomEntryMetadataSerializer.WriteEntryMetadata(entryMetadata, epmEntryMetadata, updatedTime); }
/// <summary> /// Start writing an entry. /// </summary> /// <param name="entry">The entry to write.</param> protected override void StartEntry(ODataEntry entry) { this.CheckAndWriteParentNavigationLinkStartForInlineElement(); Debug.Assert( this.ParentNavigationLink == null || !this.ParentNavigationLink.IsCollection.Value, "We should have already verified that the IsCollection matches the actual content of the link (feed/entry)."); if (entry == null) { Debug.Assert(this.ParentNavigationLink != null, "When entry == null, it has to be an expanded single entry navigation."); // this is a null expanded single entry and it is null, an empty <m:inline /> will be written. return; } this.StartEntryXmlCustomization(entry); // <entry> this.atomOutputContext.XmlWriter.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomEntryElementName, AtomConstants.AtomNamespace); if (this.IsTopLevel) { this.atomEntryAndFeedSerializer.WriteBaseUriAndDefaultNamespaceAttributes(); } string etag = entry.ETag; if (etag != null) { // TODO, ckerer: if this is a top-level entry also put the ETag into the headers. ODataAtomWriterUtils.WriteETag(this.atomOutputContext.XmlWriter, etag); } AtomEntryScope currentEntryScope = this.CurrentEntryScope; AtomEntryMetadata entryMetadata = entry.Atom(); // Write the id if it's available here. // If it's not available here we will try to write it at the end of the entry again. string entryId = entry.Id; if (entryId != null) { this.atomEntryAndFeedSerializer.WriteEntryId(entryId); currentEntryScope.SetWrittenElement(AtomElement.Id); } // <category term="type" scheme="odatascheme"/> // If no type information is provided, don't include the category element for type at all // NOTE: the validation of the type name is done by the core writer. string typeName = entry.TypeName; SerializationTypeNameAnnotation serializationTypeNameAnnotation = entry.GetAnnotation <SerializationTypeNameAnnotation>(); if (serializationTypeNameAnnotation != null) { typeName = serializationTypeNameAnnotation.TypeName; } this.atomEntryAndFeedSerializer.WriteEntryTypeName(typeName, entryMetadata); // Write the edit link if it's available here. // If it's not available here we will try to write it at the end of the entry again. Uri editLink = entry.EditLink; if (editLink != null) { this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata); currentEntryScope.SetWrittenElement(AtomElement.EditLink); } // Write the self link if it's available here. // If it's not available here we will try to write it at the end of the entry again. Uri readLink = entry.ReadLink; if (readLink != null) { this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata); currentEntryScope.SetWrittenElement(AtomElement.ReadLink); } }
internal void ReadAtomElementInEntryContent(IODataAtomReaderEntryState entryState) { EpmTargetPathSegment segment2; ODataEntityPropertyMappingCache cachedEpm = entryState.CachedEpm; EpmTargetPathSegment parentSegment = null; if (cachedEpm != null) { parentSegment = cachedEpm.EpmTargetTree.SyndicationRoot; } if (base.ShouldReadElement(parentSegment, base.XmlReader.LocalName, out segment2)) { switch (base.XmlReader.LocalName) { case "author": this.ReadAuthorElement(entryState, segment2); return; case "contributor": this.ReadContributorElement(entryState, segment2); return; case "updated": { AtomEntryMetadata atomEntryMetadata = entryState.AtomEntryMetadata; if (!base.UseClientFormatBehavior) { if (!this.ShouldReadSingletonElement(atomEntryMetadata.Updated.HasValue)) { break; } atomEntryMetadata.Updated = base.ReadAtomDateConstruct(); return; } if (!this.ShouldReadSingletonElement(atomEntryMetadata.UpdatedString != null)) { break; } atomEntryMetadata.UpdatedString = base.ReadAtomDateConstructAsString(); return; } case "published": { AtomEntryMetadata metadata2 = entryState.AtomEntryMetadata; if (!base.UseClientFormatBehavior) { if (this.ShouldReadSingletonElement(metadata2.Published.HasValue)) { metadata2.Published = base.ReadAtomDateConstruct(); return; } break; } if (!this.ShouldReadSingletonElement(metadata2.PublishedString != null)) { break; } metadata2.PublishedString = base.ReadAtomDateConstructAsString(); return; } case "rights": if (!this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Rights != null)) { break; } entryState.AtomEntryMetadata.Rights = base.ReadAtomTextConstruct(); return; case "source": if (!this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Source != null)) { break; } entryState.AtomEntryMetadata.Source = this.ReadAtomSourceInEntryContent(); return; case "summary": if (!this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Summary != null)) { break; } entryState.AtomEntryMetadata.Summary = base.ReadAtomTextConstruct(); return; case "title": if (!this.ShouldReadSingletonElement(entryState.AtomEntryMetadata.Title != null)) { break; } entryState.AtomEntryMetadata.Title = base.ReadAtomTextConstruct(); return; } } base.XmlReader.Skip(); }
protected override void EndEntry(ODataEntry entry) { Debug.Assert( this.ParentNavigationLink == null || !this.ParentNavigationLink.IsCollection.Value, "We should have already verified that the IsCollection matches the actual content of the link (feed/entry)."); if (entry == null) { Debug.Assert(this.ParentNavigationLink != null, "When entry == null, it has to be an expanded single entry navigation."); // this is a null expanded single entry and it is null, an empty <m:inline /> will be written. this.CheckAndWriteParentNavigationLinkEndForInlineElement(); return; } IEdmEntityType entryType = this.EntryEntityType; // Initialize the property value cache and cache the entry properties. EntryPropertiesValueCache propertyValueCache = new EntryPropertiesValueCache(entry); // NOTE: when writing, we assume the model has been validated already and thus pass int.MaxValue for the maxMappingCount. ODataEntityPropertyMappingCache epmCache = this.atomOutputContext.Model.EnsureEpmCache(entryType, /*maxMappingCount*/ int.MaxValue); // Populate the property value cache based on the EPM source tree information. // We do this since we need to write custom EPM after the properties below and don't // want to cache all properties just for the case that they are used in a custom EPM. if (epmCache != null) { EpmWriterUtils.CacheEpmProperties(propertyValueCache, epmCache.EpmSourceTree); } // Get the projected properties annotation ProjectedPropertiesAnnotation projectedProperties = entry.GetAnnotation <ProjectedPropertiesAnnotation>(); AtomEntryScope currentEntryScope = this.CurrentEntryScope; AtomEntryMetadata entryMetadata = entry.Atom(); if (!currentEntryScope.IsElementWritten(AtomElement.Id)) { // NOTE: We write even null id, in that case we generate an empty atom:id element. this.atomEntryAndFeedSerializer.WriteEntryId(entry.Id); } Uri editLink = entry.EditLink; if (editLink != null && !currentEntryScope.IsElementWritten(AtomElement.EditLink)) { this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata); } Uri readLink = entry.ReadLink; if (readLink != null && !currentEntryScope.IsElementWritten(AtomElement.ReadLink)) { this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata); } // write entry metadata including syndication EPM AtomEntryMetadata epmEntryMetadata = null; if (epmCache != null) { ODataVersionChecker.CheckEntityPropertyMapping(this.atomOutputContext.Version, entryType, this.atomOutputContext.Model); epmEntryMetadata = EpmSyndicationWriter.WriteEntryEpm( epmCache.EpmTargetTree, propertyValueCache, entryType.ToTypeReference().AsEntity(), this.atomOutputContext); } this.atomEntryAndFeedSerializer.WriteEntryMetadata(entryMetadata, epmEntryMetadata, this.updatedTime); // stream properties IEnumerable <ODataProperty> streamProperties = propertyValueCache.EntryStreamProperties; if (streamProperties != null) { foreach (ODataProperty streamProperty in streamProperties) { this.atomEntryAndFeedSerializer.WriteStreamProperty( streamProperty, entryType, this.DuplicatePropertyNamesChecker, projectedProperties); } } // association links IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks; if (associationLinks != null) { foreach (ODataAssociationLink associationLink in associationLinks) { this.atomEntryAndFeedSerializer.WriteAssociationLink( associationLink, entryType, this.DuplicatePropertyNamesChecker, projectedProperties); } } // actions IEnumerable <ODataAction> actions = entry.Actions; if (actions != null) { foreach (ODataAction action in actions) { ValidationUtils.ValidateOperationNotNull(action, true); this.atomEntryAndFeedSerializer.WriteOperation(action); } } // functions IEnumerable <ODataFunction> functions = entry.Functions; if (functions != null) { foreach (ODataFunction function in functions) { ValidationUtils.ValidateOperationNotNull(function, false); this.atomEntryAndFeedSerializer.WriteOperation(function); } } // write the content this.WriteEntryContent( entry, entryType, propertyValueCache, epmCache == null ? null : epmCache.EpmSourceTree.Root, projectedProperties); // write custom EPM if (epmCache != null) { EpmCustomWriter.WriteEntryEpm( this.atomOutputContext.XmlWriter, epmCache.EpmTargetTree, propertyValueCache, entryType.ToTypeReference().AsEntity(), this.atomOutputContext); } // </entry> this.atomOutputContext.XmlWriter.WriteEndElement(); this.EndEntryXmlCustomization(entry); this.CheckAndWriteParentNavigationLinkEndForInlineElement(); }
/// <summary> /// Adds a new link to entry metadata. /// </summary> /// <param name="entryMetadata">The entry metadata to add the link to.</param> /// <param name="linkMetadata">The link metadata to add.</param> internal static void AddLinkToEntryMetadata(AtomEntryMetadata entryMetadata, AtomLinkMetadata linkMetadata) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entryMetadata != null, "entryMetadata != null"); Debug.Assert(linkMetadata != null, "linkMetadata != null"); if (object.ReferenceEquals(entryMetadata.Links, EmptyLinksList)) { entryMetadata.Links = new ReadOnlyEnumerable<AtomLinkMetadata>(); } ReaderUtils.GetSourceListOfEnumerable(entryMetadata.Links, "Links").Add(linkMetadata); }
/// <summary> /// Adds a new category to entry metadata. /// </summary> /// <param name="entryMetadata">The entry metadata to add the category to.</param> /// <param name="categoryMetadata">The category metadata to add.</param> internal static void AddCategoryToEntryMetadata(AtomEntryMetadata entryMetadata, AtomCategoryMetadata categoryMetadata) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entryMetadata != null, "entryMetadata != null"); Debug.Assert(categoryMetadata != null, "categoryMetadata != null"); if (object.ReferenceEquals(entryMetadata.Categories, EmptyCategoriesList)) { entryMetadata.Categories = new ReadOnlyEnumerable<AtomCategoryMetadata>(); } ReaderUtils.GetSourceListOfEnumerable(entryMetadata.Categories, "Categories").Add(categoryMetadata); }
internal void WriteEntryMetadata(AtomEntryMetadata entryMetadata, AtomEntryMetadata epmEntryMetadata, string updatedTime) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(!string.IsNullOrEmpty(updatedTime), "!string.IsNullOrEmpty(updatedTime)"); #if DEBUG DateTimeOffset tempDateTimeOffset; Debug.Assert(DateTimeOffset.TryParse(updatedTime, out tempDateTimeOffset), "DateTimeOffset.TryParse(updatedTime, out tempDateTimeOffset)"); #endif // TODO: 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 mergedEntryMetadata = ODataAtomWriterMetadataEpmMergeUtils.MergeCustomAndEpmEntryMetadata(entryMetadata, epmEntryMetadata, this.MessageWriterSettings.WriterBehavior); if (mergedEntryMetadata == null) { // write all required metadata elements with default content // <atom:title></atom:title> this.WriteEmptyElement( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace); // <atom:updated>dateTimeOffset</atom:updated> // NOTE: the <updated> element is required and if not specified we use a single 'default/current' date/time for the whole payload. this.WriteElementWithTextContent( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomUpdatedElementName, AtomConstants.AtomNamespace, updatedTime); this.WriteEmptyAuthor(); } else { // <atom:title>text</atom:title> // NOTE: writes an empty element even if no title was specified since the title is required this.WriteTextConstruct(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, mergedEntryMetadata.Title); AtomTextConstruct summary = mergedEntryMetadata.Summary; if (summary != null) { // <atom:summary>text</atom:summary> this.WriteTextConstruct(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomSummaryElementName, AtomConstants.AtomNamespace, summary); } string published = this.UseClientFormatBehavior ? mergedEntryMetadata.PublishedString : mergedEntryMetadata.Published.HasValue ? ODataAtomConvert.ToAtomString(mergedEntryMetadata.Published.Value) : null; if (published != null) { // <atom:published>dateTimeOffset</atom:published> this.WriteElementWithTextContent( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomPublishedElementName, AtomConstants.AtomNamespace, published); } // <atom:updated>date</atom:updated> string updated = this.UseClientFormatBehavior ? mergedEntryMetadata.UpdatedString : mergedEntryMetadata.Updated.HasValue ? ODataAtomConvert.ToAtomString(mergedEntryMetadata.Updated.Value) : null; // NOTE: the <updated> element is required and if not specified we use a single 'default/current' date/time for the whole payload. updated = updated ?? updatedTime; this.WriteElementWithTextContent( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomUpdatedElementName, AtomConstants.AtomNamespace, updated); bool wroteAuthor = false; IEnumerable <AtomPersonMetadata> authors = mergedEntryMetadata.Authors; if (authors != null) { foreach (AtomPersonMetadata author in authors) { if (author == null) { throw new ODataException(ODataErrorStrings.ODataAtomWriterMetadataUtils_AuthorMetadataMustNotContainNull); } // <atom:author>author data</atom:author> this.XmlWriter.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomAuthorElementName, AtomConstants.AtomNamespace); this.WritePersonMetadata(author); this.XmlWriter.WriteEndElement(); wroteAuthor = true; } } if (!wroteAuthor) { // write empty authors since they are required this.WriteEmptyAuthor(); } IEnumerable <AtomPersonMetadata> contributors = mergedEntryMetadata.Contributors; if (contributors != null) { foreach (AtomPersonMetadata contributor in contributors) { if (contributor == null) { throw new ODataException(ODataErrorStrings.ODataAtomWriterMetadataUtils_ContributorMetadataMustNotContainNull); } // <atom:contributor>contributor data</atom:contributor> this.XmlWriter.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomContributorElementName, AtomConstants.AtomNamespace); this.WritePersonMetadata(contributor); this.XmlWriter.WriteEndElement(); } } IEnumerable <AtomLinkMetadata> links = mergedEntryMetadata.Links; if (links != null) { foreach (AtomLinkMetadata link in links) { if (link == null) { throw new ODataException(ODataErrorStrings.ODataAtomWriterMetadataUtils_LinkMetadataMustNotContainNull); } // <atom:link>...</atom:link> this.WriteAtomLink(link, null /*edit-link-etag*/); } } IEnumerable <AtomCategoryMetadata> categories = mergedEntryMetadata.Categories; if (categories != null) { foreach (AtomCategoryMetadata category in categories) { if (category == null) { throw new ODataException(ODataErrorStrings.ODataAtomWriterMetadataUtils_CategoryMetadataMustNotContainNull); } // <atom:category term="..." scheme="..." label="..."></atom:category> this.WriteCategory(category); } } if (mergedEntryMetadata.Rights != null) { // <atom:rights>rights</atom:rights> this.WriteTextConstruct( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomRightsElementName, AtomConstants.AtomNamespace, mergedEntryMetadata.Rights); } AtomFeedMetadata source = mergedEntryMetadata.Source; if (source != null) { // <atom:source> this.XmlWriter.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomSourceElementName, AtomConstants.AtomNamespace); bool authorWritten; this.SourceMetadataSerializer.WriteFeedMetadata(source, null /* feed */, updatedTime, out authorWritten); // </atom:source> this.XmlWriter.WriteEndElement(); } } }