Esempio n. 1
0
        /// <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;
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 4
0
        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);
                }
            }
        }
Esempio n. 5
0
        /// <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));
        }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 10
0
 /// <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;
 }
Esempio n. 13
0
 internal static void WriteEntryEpm(XmlWriter writer, EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference entityType, ODataAtomOutputContext atomOutputContext)
 {
     new EpmCustomWriter(atomOutputContext).WriteEntryEpm(writer, epmTargetTree, epmValueCache, entityType);
 }
Esempio n. 14
0
        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));
            }
        }
Esempio n. 15
0
        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;
        }
Esempio n. 19
0
 /// <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;
 }
Esempio n. 20
0
 internal static AtomEntryMetadata WriteEntryEpm(EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, IEdmEntityTypeReference type, ODataAtomOutputContext atomOutputContext)
 {
     EpmSyndicationWriter writer = new EpmSyndicationWriter(epmTargetTree, atomOutputContext);
     return writer.WriteEntryEpm(epmValueCache, type);
 }