private void WriteEntryContent(ODataEntry entry, IEdmEntityType entryType, EntryPropertiesValueCache propertiesValueCache, EpmSourcePathSegment rootSourcePathSegment, ProjectedPropertiesAnnotation projectedProperties) { ODataStreamReferenceValue mediaResource = entry.MediaResource; if (mediaResource == null) { this.atomOutputContext.XmlWriter.WriteStartElement("", "content", "http://www.w3.org/2005/Atom"); this.atomOutputContext.XmlWriter.WriteAttributeString("type", "application/xml"); this.atomEntryAndFeedSerializer.WriteProperties(entryType, propertiesValueCache.EntryProperties, false, new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart), new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd), base.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties); this.atomOutputContext.XmlWriter.WriteEndElement(); } else { WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true); this.atomEntryAndFeedSerializer.WriteEntryMediaEditLink(mediaResource); if (mediaResource.ReadLink != null) { this.atomOutputContext.XmlWriter.WriteStartElement("", "content", "http://www.w3.org/2005/Atom"); this.atomOutputContext.XmlWriter.WriteAttributeString("type", mediaResource.ContentType); this.atomOutputContext.XmlWriter.WriteAttributeString("src", this.atomEntryAndFeedSerializer.UriToUrlAttributeValue(mediaResource.ReadLink)); this.atomOutputContext.XmlWriter.WriteEndElement(); } this.atomEntryAndFeedSerializer.WriteProperties(entryType, propertiesValueCache.EntryProperties, false, new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart), new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd), base.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties); } }
/// <summary> /// Writes an EPM attribute target. /// </summary> /// <param name="writer">The writer to write to.</param> /// <param name="targetSegment">The target segment describing the attribute to write.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="entityType">The type of the entry.</param> /// <param name="alreadyDeclaredPrefix">The name of the prefix if it was already declared.</param> private void WriteAttributeEpm( XmlWriter writer, EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ref string alreadyDeclaredPrefix) { Debug.Assert(writer != null, "writer != null"); Debug.Assert(targetSegment != null && targetSegment.IsAttribute, "Only attribute target segments are supported by this method."); Debug.Assert(targetSegment.HasContent, "Attribute target segments must have content."); string textPropertyValue = this.GetEntryPropertyValueAsText(targetSegment, epmValueCache, entityType); Debug.Assert(textPropertyValue != null, "Text value of a property mapped to attribute must not be null, the GetEntryPropertyValueAsText should take care of that."); // If the prefix is null, the WCF DS will still write it as the default namespace, so we need it to be an empty string. string attributePrefix = targetSegment.SegmentNamespacePrefix ?? string.Empty; writer.WriteAttributeString(attributePrefix, targetSegment.AttributeName, targetSegment.SegmentNamespaceUri, textPropertyValue); // Write out the declaration explicitely only if the prefix is not empty (just like the WCF DS does) if (attributePrefix.Length > 0) { WriteNamespaceDeclaration(writer, targetSegment, ref alreadyDeclaredPrefix); } }
private void WriteElementEpm(XmlWriter writer, EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ref string alreadyDeclaredPrefix) { string prefix = targetSegment.SegmentNamespacePrefix ?? string.Empty; writer.WriteStartElement(prefix, targetSegment.SegmentName, targetSegment.SegmentNamespaceUri); if (prefix.Length > 0) { WriteNamespaceDeclaration(writer, targetSegment, ref alreadyDeclaredPrefix); } foreach (EpmTargetPathSegment segment in targetSegment.SubSegments) { if (segment.IsAttribute) { this.WriteAttributeEpm(writer, segment, epmValueCache, entityType, ref alreadyDeclaredPrefix); } } if (targetSegment.HasContent) { string str2 = this.GetEntryPropertyValueAsText(targetSegment, epmValueCache, entityType); ODataAtomWriterUtils.WriteString(writer, str2); } else { foreach (EpmTargetPathSegment segment2 in targetSegment.SubSegments) { if (!segment2.IsAttribute) { this.WriteElementEpm(writer, segment2, epmValueCache, entityType, ref alreadyDeclaredPrefix); } } } writer.WriteEndElement(); }
/// <summary> /// Writes the custom mapped EPM properties to an XML writer which is expected to be positioned such to write /// a child element of the entry element. /// </summary> /// <param name="writer">The XmlWriter to write to.</param> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="entityType">The type of the entry.</param> private void WriteEntryEpm( XmlWriter writer, EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { Debug.Assert(writer != null, "writer != null"); Debug.Assert(epmTargetTree != null, "epmTargetTree != null"); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(entityType != null, "For any EPM to exist the metadata must be available."); // If there are no custom mappings, just return null. EpmTargetPathSegment customRootSegment = epmTargetTree.NonSyndicationRoot; Debug.Assert(customRootSegment != null, "EPM Target tree must always have non-syndication root."); if (customRootSegment.SubSegments.Count == 0) { return; } foreach (EpmTargetPathSegment targetSegment in customRootSegment.SubSegments) { Debug.Assert(!targetSegment.IsAttribute, "Target segments under the custom root must be for elements only."); string alreadyDeclaredPrefix = null; this.WriteElementEpm(writer, targetSegment, epmValueCache, entityType, ref alreadyDeclaredPrefix); } }
/// <summary> /// Given a target segment the method returns the text value of the property mapped to that segment to be used in EPM. /// </summary> /// <param name="targetSegment">The target segment to read the value for.</param> /// <param name="epmValueCache">EPM value cache to use to get property values, or a primitive value</param> /// <param name="typeReference">The type of the entry or collection item.</param> /// <returns>The test representation of the value, or the method throws if the text representation was not possible to obtain.</returns> private string GetPropertyValueAsText( EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference) { Debug.Assert(targetSegment != null, "targetSegment != null"); Debug.Assert(targetSegment.HasContent, "The target segment to read property for must have content."); Debug.Assert(targetSegment.EpmInfo != null, "The EPM info must be available on the target segment to read its property."); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(typeReference != null, "typeReference != null"); object propertyValue; EntryPropertiesValueCache entryPropertiesValueCache = epmValueCache as EntryPropertiesValueCache; if (entryPropertiesValueCache != null) { propertyValue = this.ReadEntryPropertyValue( targetSegment.EpmInfo, entryPropertiesValueCache, typeReference.AsEntity()); } else { propertyValue = epmValueCache; ValidationUtils.ValidateIsExpectedPrimitiveType(propertyValue, typeReference); } return(EpmWriterUtils.GetPropertyValueAsText(propertyValue)); }
private string GetEntryPropertyValueAsText(EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { object propertyValue = base.ReadEntryPropertyValue(targetSegment.EpmInfo, epmValueCache, entityType); if (propertyValue == null) { return string.Empty; } return EpmWriterUtils.GetPropertyValueAsText(propertyValue); }
private void WriteAttributeEpm(XmlWriter writer, EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ref string alreadyDeclaredPrefix) { string str = this.GetEntryPropertyValueAsText(targetSegment, epmValueCache, entityType); string prefix = targetSegment.SegmentNamespacePrefix ?? string.Empty; writer.WriteAttributeString(prefix, targetSegment.AttributeName, targetSegment.SegmentNamespaceUri, str); if (prefix.Length > 0) { WriteNamespaceDeclaration(writer, targetSegment, ref alreadyDeclaredPrefix); } }
/// <summary> /// Cache all the properties and collection item enumerations needed for EPM processing. /// </summary> /// <param name="propertyValueCache">The property value cache to cache the EPM related properties in.</param> /// <param name="sourceTree">The source tree describing all properties taking part in entity property mappings.</param> internal static void CacheEpmProperties(EntryPropertiesValueCache propertyValueCache, EpmSourceTree sourceTree) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(propertyValueCache != null, "propertyValueCache != null"); Debug.Assert(sourceTree != null, "sourceTree != null"); EpmSourcePathSegment rootSegment = sourceTree.Root; Debug.Assert(rootSegment.PropertyName == null, "Root segment should have 'null' property name."); CacheEpmSourcePathSegments(propertyValueCache, rootSegment.SubProperties, propertyValueCache.EntryProperties); }
/// <summary> /// Writes the custom mapped EPM properties to an XML writer which is expected to be positioned such to write /// a child element of the entry element. /// </summary> /// <param name="writer">The XmlWriter to write to.</param> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="entityType">The type of the entry.</param> /// <param name="atomOutputContext">The output context currently in use.</param> internal static void WriteEntryEpm( XmlWriter writer, EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ODataAtomOutputContext atomOutputContext) { DebugUtils.CheckNoExternalCallers(); EpmCustomWriter epmWriter = new EpmCustomWriter(atomOutputContext); epmWriter.WriteEntryEpm(writer, epmTargetTree, epmValueCache, entityType); }
private void WriteEntryEpm(XmlWriter writer, EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { EpmTargetPathSegment nonSyndicationRoot = epmTargetTree.NonSyndicationRoot; if (nonSyndicationRoot.SubSegments.Count != 0) { foreach (EpmTargetPathSegment segment2 in nonSyndicationRoot.SubSegments) { string alreadyDeclaredPrefix = null; this.WriteElementEpm(writer, segment2, epmValueCache, entityType, ref alreadyDeclaredPrefix); } } }
/// <summary> /// Writes an EPM element target. /// </summary> /// <param name="writer">The writer to write to.</param> /// <param name="targetSegment">The target segment describing the element to write.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="entityType">The type of the entry.</param> /// <param name="alreadyDeclaredPrefix">The name of the prefix if it was already declared.</param> private void WriteElementEpm( XmlWriter writer, EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ref string alreadyDeclaredPrefix) { Debug.Assert(writer != null, "writer != null"); Debug.Assert(targetSegment != null && !targetSegment.IsAttribute, "Only element target segments are supported by this method."); // If the prefix is null, the WCF DS will still write it as the default namespace, so we need it to be an empty string. string elementPrefix = targetSegment.SegmentNamespacePrefix ?? string.Empty; writer.WriteStartElement(elementPrefix, targetSegment.SegmentName, targetSegment.SegmentNamespaceUri); // Write out the declaration explicitly only if the prefix is not empty (just like the WCF DS does) if (elementPrefix.Length > 0) { WriteNamespaceDeclaration(writer, targetSegment, ref alreadyDeclaredPrefix); } // Serialize the sub segment attributes first foreach (EpmTargetPathSegment subSegment in targetSegment.SubSegments) { if (subSegment.IsAttribute) { this.WriteAttributeEpm(writer, subSegment, epmValueCache, entityType, ref alreadyDeclaredPrefix); } } if (targetSegment.HasContent) { Debug.Assert(!targetSegment.SubSegments.Any(subSegment => !subSegment.IsAttribute), "If the segment has a content, it must not have any element children."); string textPropertyValue = this.GetEntryPropertyValueAsText(targetSegment, epmValueCache, entityType); ODataAtomWriterUtils.WriteString(writer, textPropertyValue); } else { // Serialize the sub segment elements now foreach (EpmTargetPathSegment subSegment in targetSegment.SubSegments) { if (!subSegment.IsAttribute) { this.WriteElementEpm(writer, subSegment, epmValueCache, entityType, ref alreadyDeclaredPrefix); } } } // Close the element writer.WriteEndElement(); }
/// <summary> /// Writes the syndication part of EPM for an entry into ATOM metadata OM. /// </summary> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="type">The type of the entry.</param> /// <param name="atomOutputContext">The output context currently in use.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> internal static AtomEntryMetadata WriteEntryEpm( EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(epmTargetTree != null, "epmTargetTree != null"); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(type != null, "For any EPM to exist the metadata must be available."); EpmSyndicationWriter epmWriter = new EpmSyndicationWriter(epmTargetTree, atomOutputContext); return epmWriter.WriteEntryEpm(epmValueCache, type); }
/// <summary> /// Writes the syndication part of EPM for an entry into ATOM metadata OM. /// </summary> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="type">The type of the entry.</param> /// <param name="atomOutputContext">The output context currently in use.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> internal static AtomEntryMetadata WriteEntryEpm( EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(epmTargetTree != null, "epmTargetTree != null"); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(type != null, "For any EPM to exist the metadata must be available."); EpmSyndicationWriter epmWriter = new EpmSyndicationWriter(epmTargetTree, atomOutputContext); return(epmWriter.WriteEntryEpm(epmValueCache, type)); }
private string GetPropertyValueAsText(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference) { object obj2; EntryPropertiesValueCache cache = epmValueCache as EntryPropertiesValueCache; if (cache != null) { obj2 = base.ReadEntryPropertyValue(targetSegment.EpmInfo, cache, typeReference.AsEntity()); } else { obj2 = epmValueCache; ValidationUtils.ValidateIsExpectedPrimitiveType(obj2, typeReference); } return(EpmWriterUtils.GetPropertyValueAsText(obj2)); }
/// <summary> /// Reads a property value starting on an entry. /// </summary> /// <param name="epmInfo">The EPM info which describes the mapping for which to read the property value.</param> /// <param name="epmValueCache">The EPM value cache for the entry to read from.</param> /// <param name="entityType">The type of the entry.</param> /// <returns>The value of the property (may be null), or null if the property itself was not found due to one of its parent properties being null.</returns> protected object ReadEntryPropertyValue( EntityPropertyMappingInfo epmInfo, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { Debug.Assert(epmInfo != null, "epmInfo != null"); Debug.Assert(epmInfo.PropertyValuePath != null, "The PropertyValuePath should have been initialized by now."); Debug.Assert(epmInfo.PropertyValuePath.Length > 0, "The PropertyValuePath must not be empty for an entry property."); Debug.Assert(entityType != null, "entityType != null"); // TODO - It might be possible to avoid the "value" type checks below if we do property value validation based on the type return(this.ReadPropertyValue( epmInfo, epmValueCache.EntryProperties, 0, entityType, epmValueCache)); }
/// <summary> /// Reads a property value starting on an entry. /// </summary> /// <param name="epmInfo">The EPM info which describes the mapping for which to read the property value.</param> /// <param name="epmValueCache">The EPM value cache for the entry to read from.</param> /// <param name="entityType">The type of the entry.</param> /// <returns>The value of the property (may be null), or null if the property itself was not found due to one of its parent properties being null.</returns> protected object ReadEntryPropertyValue( EntityPropertyMappingInfo epmInfo, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { Debug.Assert(epmInfo != null, "epmInfo != null"); Debug.Assert(epmInfo.PropertyValuePath != null, "The PropertyValuePath should have been initialized by now."); Debug.Assert(epmInfo.PropertyValuePath.Length > 0, "The PropertyValuePath must not be empty for an entry property."); Debug.Assert(entityType != null, "entityType != null"); // TODO - It might be possible to avoid the "value" type checks below if we do property value validation based on the type return this.ReadPropertyValue( epmInfo, epmValueCache.EntryProperties, 0, entityType, epmValueCache); }
/// <summary> /// Given a target segment the method returns the text value of the property mapped to that segment to be used in EPM. /// </summary> /// <param name="targetSegment">The target segment to read the value for.</param> /// <param name="epmValueCache">The entry EPM value cache to use.</param> /// <param name="entityType">The entity type of the entry being processed.</param> /// <returns>The test representation of the value, or the method throws if the text representation was not possible to obtain.</returns> private string GetEntryPropertyValueAsText( EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { Debug.Assert(targetSegment != null, "targetSegment != null"); Debug.Assert(targetSegment.HasContent, "The target segment to read property for must have content."); Debug.Assert(targetSegment.EpmInfo != null, "The EPM info must be available on the target segment to read its property."); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(entityType != null, "entityType != null"); object propertyValue = this.ReadEntryPropertyValue( targetSegment.EpmInfo, epmValueCache, entityType); if (propertyValue == null) { // nulls are written out as empty strings always (and they're written into content as well) return(string.Empty); } return(EpmWriterUtils.GetPropertyValueAsText(propertyValue)); }
internal static AtomEntryMetadata WriteEntryEpm(EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext) { EpmSyndicationWriter writer = new EpmSyndicationWriter(epmTargetTree, atomOutputContext); return writer.WriteEntryEpm(epmValueCache, type); }
protected object ReadEntryPropertyValue(EntityPropertyMappingInfo epmInfo, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { return this.ReadPropertyValue(epmInfo, epmValueCache.EntryProperties, 0, entityType, epmValueCache); }
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(); }
internal static AtomEntryMetadata WriteEntryEpm(EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext) { EpmSyndicationWriter writer = new EpmSyndicationWriter(epmTargetTree, atomOutputContext); return(writer.WriteEntryEpm(epmValueCache, type)); }
private AtomEntryMetadata WriteEntryEpm(EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { EpmTargetPathSegment syndicationRoot = this.epmTargetTree.SyndicationRoot; if (syndicationRoot.SubSegments.Count == 0) { return null; } foreach (EpmTargetPathSegment segment2 in syndicationRoot.SubSegments) { if (!segment2.HasContent) { goto Label_018C; } EntityPropertyMappingInfo epmInfo = segment2.EpmInfo; object propertyValue = base.ReadEntryPropertyValue(epmInfo, epmValueCache, entityType); string propertyValueAsText = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: { if (base.WriterBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient) { break; } this.entryMetadata.UpdatedString = CreateDateTimeStringValue(propertyValue, base.WriterBehavior); continue; } case SyndicationItemProperty.Published: { if (base.WriterBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient) { goto Label_00FE; } this.entryMetadata.PublishedString = CreateDateTimeStringValue(propertyValue, base.WriterBehavior); continue; } case SyndicationItemProperty.Rights: { this.entryMetadata.Rights = CreateAtomTextConstruct(propertyValueAsText, epmInfo.Attribute.TargetTextContentKind); continue; } case SyndicationItemProperty.Summary: { this.entryMetadata.Summary = CreateAtomTextConstruct(propertyValueAsText, epmInfo.Attribute.TargetTextContentKind); continue; } case SyndicationItemProperty.Title: { this.entryMetadata.Title = CreateAtomTextConstruct(propertyValueAsText, epmInfo.Attribute.TargetTextContentKind); continue; } default: throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } this.entryMetadata.Updated = new DateTimeOffset?(CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, base.WriterBehavior)); continue; Label_00FE: this.entryMetadata.Published = new DateTimeOffset?(CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, base.WriterBehavior)); continue; Label_018C: this.WriteParentSegment(segment2, epmValueCache, entityType); } return this.entryMetadata; }
/// <summary> /// Writes the syndication part of EPM for an entry into ATOM metadata OM. /// </summary> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="entityType">The type of the entry.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> private AtomEntryMetadata WriteEntryEpm( EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { // If there are no syndication mappings, just return null. EpmTargetPathSegment syndicationRootSegment = this.epmTargetTree.SyndicationRoot; Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root."); if (syndicationRootSegment.SubSegments.Count == 0) { return null; } foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments) { if (targetSegment.HasContent) { 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"); object propertyValue = this.ReadEntryPropertyValue( epmInfo, epmValueCache, entityType); string textPropertyValue = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: if (this.WriterBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { this.entryMetadata.UpdatedString = EpmSyndicationWriter.CreateDateTimeStringValue(propertyValue, this.WriterBehavior); } else { this.entryMetadata.Updated = EpmSyndicationWriter.CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, this.WriterBehavior); } break; case SyndicationItemProperty.Published: if (this.WriterBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { this.entryMetadata.PublishedString = EpmSyndicationWriter.CreateDateTimeStringValue(propertyValue, this.WriterBehavior); } else { this.entryMetadata.Published = EpmSyndicationWriter.CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, this.WriterBehavior); } break; case SyndicationItemProperty.Rights: this.entryMetadata.Rights = EpmSyndicationWriter.CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind); break; case SyndicationItemProperty.Summary: this.entryMetadata.Summary = EpmSyndicationWriter.CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind); break; case SyndicationItemProperty.Title: this.entryMetadata.Title = EpmSyndicationWriter.CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind); break; default: throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } } else { this.WriteParentSegment(targetSegment, epmValueCache, entityType); } } return this.entryMetadata; }
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 static void CacheEpmProperties(EntryPropertiesValueCache propertyValueCache, EpmSourceTree sourceTree) { EpmSourcePathSegment root = sourceTree.Root; CacheEpmSourcePathSegments(propertyValueCache, root.SubProperties, propertyValueCache.EntryProperties); }
/// <summary> /// Given a target segment the method returns the text value of the property mapped to that segment to be used in EPM. /// </summary> /// <param name="targetSegment">The target segment to read the value for.</param> /// <param name="epmValueCache">The entry EPM value cache to use.</param> /// <param name="entityType">The entity type of the entry being processed.</param> /// <returns>The test representation of the value, or the method throws if the text representation was not possible to obtain.</returns> private string GetEntryPropertyValueAsText( EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { Debug.Assert(targetSegment != null, "targetSegment != null"); Debug.Assert(targetSegment.HasContent, "The target segment to read property for must have content."); Debug.Assert(targetSegment.EpmInfo != null, "The EPM info must be available on the target segment to read its property."); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(entityType != null, "entityType != null"); object propertyValue = this.ReadEntryPropertyValue( targetSegment.EpmInfo, epmValueCache, entityType); if (propertyValue == null) { // nulls are written out as empty strings always (and they're written into content as well) return string.Empty; } return EpmWriterUtils.GetPropertyValueAsText(propertyValue); }
internal static void WriteEntryEpm(XmlWriter writer, EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ODataAtomOutputContext atomOutputContext) { new EpmCustomWriter(atomOutputContext).WriteEntryEpm(writer, epmTargetTree, epmValueCache, entityType); }
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(); } }
private AtomEntryMetadata WriteEntryEpm(EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { EpmTargetPathSegment syndicationRoot = this.epmTargetTree.SyndicationRoot; if (syndicationRoot.SubSegments.Count == 0) { return(null); } foreach (EpmTargetPathSegment segment2 in syndicationRoot.SubSegments) { if (!segment2.HasContent) { goto Label_018C; } EntityPropertyMappingInfo epmInfo = segment2.EpmInfo; object propertyValue = base.ReadEntryPropertyValue(epmInfo, epmValueCache, entityType); string propertyValueAsText = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: { if (base.WriterBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient) { break; } this.entryMetadata.UpdatedString = CreateDateTimeStringValue(propertyValue, base.WriterBehavior); continue; } case SyndicationItemProperty.Published: { if (base.WriterBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient) { goto Label_00FE; } this.entryMetadata.PublishedString = CreateDateTimeStringValue(propertyValue, base.WriterBehavior); continue; } case SyndicationItemProperty.Rights: { this.entryMetadata.Rights = CreateAtomTextConstruct(propertyValueAsText, epmInfo.Attribute.TargetTextContentKind); continue; } case SyndicationItemProperty.Summary: { this.entryMetadata.Summary = CreateAtomTextConstruct(propertyValueAsText, epmInfo.Attribute.TargetTextContentKind); continue; } case SyndicationItemProperty.Title: { this.entryMetadata.Title = CreateAtomTextConstruct(propertyValueAsText, epmInfo.Attribute.TargetTextContentKind); continue; } default: throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } this.entryMetadata.Updated = new DateTimeOffset?(CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, base.WriterBehavior)); continue; Label_00FE: this.entryMetadata.Published = new DateTimeOffset?(CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, base.WriterBehavior)); continue; Label_018C: this.WriteParentSegment(segment2, epmValueCache, entityType); } return(this.entryMetadata); }
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> /// 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="IEdmEntityType"/> 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> /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param> private void WriteEntryContent( ODataEntry entry, IEdmEntityType entryType, EntryPropertiesValueCache propertiesValueCache, EpmSourcePathSegment rootSourcePathSegment, ProjectedPropertiesAnnotation projectedProperties) { Debug.Assert(entry != null, "entry != null"); Debug.Assert(propertiesValueCache != null, "propertiesValueCache != null"); ODataStreamReferenceValue mediaResource = entry.MediaResource; if (mediaResource == null) { // <content type="application/xml"> this.atomOutputContext.XmlWriter.WriteStartElement( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomContentElementName, AtomConstants.AtomNamespace); this.atomOutputContext.XmlWriter.WriteAttributeString( AtomConstants.AtomTypeAttributeName, MimeConstants.MimeApplicationXml); this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero(); this.atomEntryAndFeedSerializer.WriteProperties( entryType, propertiesValueCache.EntryProperties, false /* isWritingCollection */, this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart, this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd, this.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties); this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero(); // </content> this.atomOutputContext.XmlWriter.WriteEndElement(); } else { WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true); this.atomEntryAndFeedSerializer.WriteEntryMediaEditLink(mediaResource); if (mediaResource.ReadLink != null) { // <content type="type" src="src"> this.atomOutputContext.XmlWriter.WriteStartElement( AtomConstants.AtomNamespacePrefix, AtomConstants.AtomContentElementName, AtomConstants.AtomNamespace); Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now. If we have a read link we must have a non-empty content type as well."); this.atomOutputContext.XmlWriter.WriteAttributeString( AtomConstants.AtomTypeAttributeName, mediaResource.ContentType); this.atomOutputContext.XmlWriter.WriteAttributeString( AtomConstants.MediaLinkEntryContentSourceAttributeName, this.atomEntryAndFeedSerializer.UriToUrlAttributeValue(mediaResource.ReadLink)); // </content> this.atomOutputContext.XmlWriter.WriteEndElement(); } this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero(); this.atomEntryAndFeedSerializer.WriteProperties( entryType, propertiesValueCache.EntryProperties, false /* isWritingCollection */, this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart, this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd, this.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties); this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero(); } }
private string GetEntryPropertyValueAsText(EpmTargetPathSegment targetSegment, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { object propertyValue = base.ReadEntryPropertyValue(targetSegment.EpmInfo, epmValueCache, entityType); if (propertyValue == null) { return(string.Empty); } return(EpmWriterUtils.GetPropertyValueAsText(propertyValue)); }
/// <summary> /// Writes the syndication part of EPM for an entry into ATOM metadata OM. /// </summary> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="entityType">The type of the entry.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> private AtomEntryMetadata WriteEntryEpm( EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { // If there are no syndication mappings, just return null. EpmTargetPathSegment syndicationRootSegment = this.epmTargetTree.SyndicationRoot; Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root."); if (syndicationRootSegment.SubSegments.Count == 0) { return(null); } foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments) { if (targetSegment.HasContent) { 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"); object propertyValue = this.ReadEntryPropertyValue( epmInfo, epmValueCache, entityType); string textPropertyValue = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: if (this.WriterBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { this.entryMetadata.UpdatedString = EpmSyndicationWriter.CreateDateTimeStringValue(propertyValue, this.WriterBehavior); } else { this.entryMetadata.Updated = EpmSyndicationWriter.CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, this.WriterBehavior); } break; case SyndicationItemProperty.Published: if (this.WriterBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient) { this.entryMetadata.PublishedString = EpmSyndicationWriter.CreateDateTimeStringValue(propertyValue, this.WriterBehavior); } else { this.entryMetadata.Published = EpmSyndicationWriter.CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, this.WriterBehavior); } break; case SyndicationItemProperty.Rights: this.entryMetadata.Rights = EpmSyndicationWriter.CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind); break; case SyndicationItemProperty.Summary: this.entryMetadata.Summary = EpmSyndicationWriter.CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind); break; case SyndicationItemProperty.Title: this.entryMetadata.Title = EpmSyndicationWriter.CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind); break; default: throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } } else { this.WriteParentSegment(targetSegment, epmValueCache, entityType); } } return(this.entryMetadata); }
protected object ReadEntryPropertyValue(EntityPropertyMappingInfo epmInfo, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType) { return(this.ReadPropertyValue(epmInfo, epmValueCache.EntryProperties, 0, entityType, epmValueCache)); }