/// <summary> /// Constructor which creates an empty root. /// </summary> /// <param name="epmTargetTree">Target xml tree</param> internal EpmSourceTree(EpmTargetTree epmTargetTree) { DebugUtils.CheckNoExternalCallers(); this.root = new EpmSourcePathSegment(); this.epmTargetTree = epmTargetTree; }
/// <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> /// Constructor. /// </summary> internal EpmResourceTypeAnnotation() { DebugUtils.CheckNoExternalCallers(); // Note that we new up everything here eagerly because we will only create the EPM annotation for types // for which we know for sure that they have EPM and thus we will need all of these anyway. this.inheritedEpmAttributes = new List<EntityPropertyMappingAttribute>(); this.ownEpmAttributes = new List<EntityPropertyMappingAttribute>(); this.epmTargetTree = new EpmTargetTree(); this.epmSourceTree = new EpmSourceTree(this.epmTargetTree); }
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 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); }
/// <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)); }
/// <summary> /// Constructor. /// </summary> /// <param name="mappings">The EPM mappings to create the cache for.</param> /// <param name="model">The EDM model.</param> /// <param name="totalMappingCount">The total number of entity property mappings /// for the entity type that this cache is created for (on the type itself and all its base types).</param> internal ODataEntityPropertyMappingCache(ODataEntityPropertyMappingCollection mappings, IEdmModel model, int totalMappingCount) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(model.IsUserModel(), "model.IsUserModel()"); this.mappings = mappings; this.model = model; this.totalMappingCount = totalMappingCount; // Note that we new up everything here eagerly because we will only create the EPM annotation for types // for which we know for sure that they have EPM and thus we will need all of these anyway. this.mappingsForInheritedProperties = new List <EntityPropertyMappingAttribute>(); this.mappingsForDeclaredProperties = mappings == null ? new List <EntityPropertyMappingAttribute>() : new List <EntityPropertyMappingAttribute>(mappings); this.epmTargetTree = new EpmTargetTree(); this.epmSourceTree = new EpmSourceTree(this.epmTargetTree); }
/// <summary> /// Constructor. /// </summary> /// <param name="mappings">The EPM mappings to create the cache for.</param> /// <param name="model">The EDM model.</param> /// <param name="totalMappingCount">The total number of entity property mappings /// for the entity type that this cache is created for (on the type itself and all its base types).</param> internal ODataEntityPropertyMappingCache(ODataEntityPropertyMappingCollection mappings, IEdmModel model, int totalMappingCount) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(model.IsUserModel(), "model.IsUserModel()"); this.mappings = mappings; this.model = model; this.totalMappingCount = totalMappingCount; // Note that we new up everything here eagerly because we will only create the EPM annotation for types // for which we know for sure that they have EPM and thus we will need all of these anyway. this.mappingsForInheritedProperties = new List<EntityPropertyMappingAttribute>(); this.mappingsForDeclaredProperties = mappings == null ? new List<EntityPropertyMappingAttribute>() : new List<EntityPropertyMappingAttribute>(mappings); this.epmTargetTree = new EpmTargetTree(); this.epmSourceTree = new EpmSourceTree(this.epmTargetTree); }
/// <summary> /// Removes all data created internally by ResourceType. This is needed when building epm /// info fails since the trees may be left in undefined state (i.e. half constructed) and /// if inherited EPM attributes exist duplicates will be added. /// </summary> internal void Reset() { this.epmTargetTree = null; this.epmSourceTree = null; this.inheritedEpmInfo = null; }
internal EpmSyndicationContentSerializer(EpmTargetTree tree, object element, XmlWriter target) : base(tree, true, element, target) { }
/// <summary> /// Constructor initializes the base class be identifying itself as a syndication serializer /// </summary> /// <param name="tree">Target tree containing mapping information</param> /// <param name="element">Object to be serialized</param> /// <param name="target">SyndicationItem to which content will be added</param> /// <param name="nullValuedProperties">Null valued properties found during serialization</param> internal EpmSyndicationContentSerializer(EpmTargetTree tree, object element, SyndicationItem target, EpmContentSerializer.EpmNullValuedPropertyTree nullValuedProperties) : base(tree, true, element, target) { this.nullValuedProperties = nullValuedProperties; }
internal static void WriteEntryEpm(XmlWriter writer, EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ODataAtomOutputContext atomOutputContext) { new EpmCustomWriter(atomOutputContext).WriteEntryEpm(writer, epmTargetTree, epmValueCache, entityType); }
internal void Add(EntityPropertyMappingInfo epmInfo) { Debug.Assert(epmInfo != null, "epmInfo != null"); String targetPath = epmInfo.Attribute.TargetPath; String namespaceUri = epmInfo.Attribute.TargetNamespaceUri; EpmTargetPathSegment currentSegment = epmInfo.IsSyndicationMapping ? this.SyndicationRoot : this.NonSyndicationRoot; IList <EpmTargetPathSegment> activeSubSegments = currentSegment.SubSegments; Debug.Assert(!String.IsNullOrEmpty(targetPath), "Must have been validated during EntityPropertyMappingAttribute construction"); String[] targetSegments = targetPath.Split('/'); EpmTargetPathSegment foundSegment = null; for (int i = 0; i < targetSegments.Length; i++) { String targetSegment = targetSegments[i]; if (targetSegment.Length == 0) { throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetPath)); } if (targetSegment[0] == '@' && i != targetSegments.Length - 1) { throw new InvalidOperationException(Strings.EpmTargetTree_AttributeInMiddle(targetSegment)); } foundSegment = activeSubSegments.SingleOrDefault( segment => segment.SegmentName == targetSegment && (epmInfo.IsSyndicationMapping || segment.SegmentNamespaceUri == namespaceUri)); if (foundSegment != null) { currentSegment = foundSegment; } else { currentSegment = new EpmTargetPathSegment(targetSegment, namespaceUri, currentSegment); if (targetSegment[0] == '@') { activeSubSegments.Insert(0, currentSegment); } else { activeSubSegments.Add(currentSegment); } } activeSubSegments = currentSegment.SubSegments; } if (currentSegment.EpmInfo != null) { // Two EpmAttributes with same TargetName in the inheritance hierarchy throw new ArgumentException(Strings.EpmTargetTree_DuplicateEpmAttrsWithSameTargetName(EpmTargetTree.GetPropertyNameFromEpmInfo(currentSegment.EpmInfo), currentSegment.EpmInfo.DefiningType.Name, currentSegment.EpmInfo.Attribute.SourcePath, epmInfo.Attribute.SourcePath)); } // Increment the number of properties for which KeepInContent is false if (!epmInfo.Attribute.KeepInContent) { this.countOfNonContentV2mappings++; } currentSegment.EpmInfo = epmInfo; // Mixed content is dis-allowed. Since root has no ancestor, pass in false for ancestorHasContent if (EpmTargetTree.HasMixedContent(this.NonSyndicationRoot, false)) { throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetPath)); } }
internal static AtomEntryMetadata WriteEntryEpm(EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext) { EpmSyndicationWriter writer = new EpmSyndicationWriter(epmTargetTree, atomOutputContext); return(writer.WriteEntryEpm(epmValueCache, type)); }
/// <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> /// 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> /// 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="resourceType">The resource type of the entry.</param> /// <param name="metadata">The metadata provider to use.</param> /// <param name="version">The version of OData protocol to use.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> internal static AtomEntryMetadata WriteEntryEpm( EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, ResourceType resourceType, DataServiceMetadataProviderWrapper metadata, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(epmTargetTree != null, "epmTargetTree != null"); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(resourceType != null, "For any EPM to exist the metadata must be available."); // If there are no syndication mappings, just return null. EpmTargetPathSegment syndicationRootSegment = epmTargetTree.SyndicationRoot; Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root."); if (syndicationRootSegment.SubSegments.Count == 0) { return null; } AtomEntryMetadata entryMetadata = new AtomEntryMetadata(); foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments) { if (targetSegment.IsMultiValueProperty) { Debug.Assert( targetSegment.EpmInfo != null && targetSegment.EpmInfo.Attribute != null, "MultiValue property target segment must have EpmInfo and the Epm Attribute."); ODataVersionChecker.CheckMultiValueProperties(version, targetSegment.EpmInfo.Attribute.SourcePath); // WriteMultiValueEpm(entry, targetSegment, epmValueCache); throw new NotImplementedException(); } else 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"); bool nullOnParentProperty; object propertyValue = epmInfo.ReadEntryPropertyValue(epmValueCache, resourceType, metadata, out nullOnParentProperty); string textPropertyValue = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: entryMetadata.Updated = CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, version); break; case SyndicationItemProperty.Published: entryMetadata.Published = CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, version); break; case SyndicationItemProperty.Rights: entryMetadata.Rights = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; case SyndicationItemProperty.Summary: entryMetadata.Summary = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; case SyndicationItemProperty.Title: entryMetadata.Title = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; default: throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } } else if (targetSegment.SegmentName == AtomConstants.AtomAuthorElementName) { AtomPersonMetadata authorMetadata = WritePersonEpm(targetSegment, epmValueCache, resourceType, metadata); Debug.Assert(entryMetadata.Authors == null, "Found two mappings to author, that is invalid."); if (authorMetadata != null) { entryMetadata.Authors = CreateSinglePersonList(authorMetadata); } } else if (targetSegment.SegmentName == AtomConstants.AtomContributorElementName) { AtomPersonMetadata contributorMetadata = WritePersonEpm(targetSegment, epmValueCache, resourceType, metadata); Debug.Assert(entryMetadata.Contributors == null, "Found two mappings to contributor, that is invalid."); if (contributorMetadata != null) { entryMetadata.Contributors = CreateSinglePersonList(contributorMetadata); } } else if (targetSegment.SegmentName == AtomConstants.AtomLinkElementName) { AtomLinkMetadata linkMetadata = new AtomLinkMetadata(); //// WriteLinkEpm(entry, targetSegment, epmValueCache); Debug.Assert(targetSegment.CriteriaValue != null, "Mapping to link must be conditional."); linkMetadata.Relation = targetSegment.CriteriaValue; List<AtomLinkMetadata> links; if (entryMetadata.Links == null) { links = new List<AtomLinkMetadata>(); entryMetadata.Links = links; } else { links = entryMetadata.Links as List<AtomLinkMetadata>; Debug.Assert(links != null, "AtomEntryMetadata.Links must be of type List<AtomLinkMetadata> since we create it like that."); } links.Add(linkMetadata); throw new NotImplementedException(); } else if (targetSegment.SegmentName == AtomConstants.AtomCategoryElementName) { AtomCategoryMetadata categoryMetadata = new AtomCategoryMetadata(); //// WriteCategoryEpm(entry, targetSegment, epmValueCache) Debug.Assert(targetSegment.CriteriaValue != null, "Mapping to category must be conditional."); categoryMetadata.Scheme = targetSegment.CriteriaValue; List<AtomCategoryMetadata> categories; if (entryMetadata.Categories == null) { categories = new List<AtomCategoryMetadata>(); entryMetadata.Categories = categories; } else { categories = entryMetadata.Links as List<AtomCategoryMetadata>; Debug.Assert(categories != null, "AtomEntryMetadata.Categories must be of type List<AtomCategoryMetadata> since we create it like that."); } categories.Add(categoryMetadata); throw new NotImplementedException(); } else { throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_TargetSegment)); } } return entryMetadata; }
/// <summary>Default constructor creates a null root</summary> /// <param name="epmTargetTree">Target xml tree</param> internal EpmSourceTree(EpmTargetTree epmTargetTree) { this.root = new EpmSourcePathSegment(); this.epmTargetTree = epmTargetTree; }
internal static AtomEntryMetadata WriteEntryEpm(EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext) { EpmSyndicationWriter writer = new EpmSyndicationWriter(epmTargetTree, atomOutputContext); return writer.WriteEntryEpm(epmValueCache, type); }