コード例 #1
0
ファイル: EpmSyndicationReader.cs プロジェクト: nickchal/pash
 private void ReadParentSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata)
 {
     switch (targetSegment.SegmentName)
     {
         case "author":
         {
             AtomPersonMetadata personMetadata = entryMetadata.Authors.FirstOrDefault<AtomPersonMetadata>();
             if (personMetadata != null)
             {
                 this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, personMetadata);
             }
             return;
         }
         case "contributor":
         {
             AtomPersonMetadata metadata2 = entryMetadata.Contributors.FirstOrDefault<AtomPersonMetadata>();
             if (metadata2 != null)
             {
                 this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, metadata2);
             }
             return;
         }
     }
     throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadParentSegment_TargetSegmentName));
 }
コード例 #2
0
        /// <summary>
        /// Reads an EPM for the entire entry.
        /// </summary>
        private void ReadEntryEpm()
        {
            // Note that this property access will create empty entry metadata if none were read yet.
            AtomEntryMetadata entryMetadata = this.EntryState.AtomEntryMetadata;

            Debug.Assert(entryMetadata != null, "entryMetadata != null");

            // If there are no syndication mappings, just return null.
            EpmTargetPathSegment syndicationRootSegment = this.EntryState.CachedEpm.EpmTargetTree.SyndicationRoot;

            Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root.");
            if (syndicationRootSegment.SubSegments.Count == 0)
            {
                return;
            }

            foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments)
            {
                if (targetSegment.HasContent)
                {
                    this.ReadPropertyValueSegment(targetSegment, entryMetadata);
                }
                else
                {
                    this.ReadParentSegment(targetSegment, entryMetadata);
                }
            }
        }
コード例 #3
0
ファイル: EpmCustomWriter.cs プロジェクト: tapika/swupd
        /// <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);
            }
        }
コード例 #4
0
ファイル: EpmCustomWriter.cs プロジェクト: modulexcite/pash-1
        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();
        }
コード例 #5
0
 private void ReadTextConstructEpm(EpmTargetPathSegment targetSegment, AtomTextConstruct textConstruct)
 {
     if ((textConstruct != null) && (textConstruct.Text != null))
     {
         base.SetEntryEpmValue(targetSegment.EpmInfo, textConstruct.Text);
     }
 }
コード例 #6
0
        protected AtomPersonMetadata ReadAtomPersonConstruct(EpmTargetPathSegment epmTargetPathSegment)
        {
            AtomPersonMetadata metadata = new AtomPersonMetadata();

            if (base.XmlReader.IsEmptyElement)
            {
                goto Label_011B;
            }
            base.XmlReader.Read();
Label_0022:
            switch (base.XmlReader.NodeType)
            {
            case XmlNodeType.Element:
                EpmTargetPathSegment segment;
                string str2;
                if ((base.XmlReader.NamespaceEquals(this.AtomNamespace) && this.ShouldReadElement(epmTargetPathSegment, base.XmlReader.LocalName, out segment)) && ((str2 = base.XmlReader.LocalName) != null))
                {
                    if (!(str2 == "name"))
                    {
                        if (str2 == "uri")
                        {
                            Uri    xmlBaseUri     = base.XmlReader.XmlBaseUri;
                            string uriFromPayload = this.ReadElementStringValue();
                            if (segment != null)
                            {
                                metadata.UriFromEpm = uriFromPayload;
                            }
                            if (this.ReadAtomMetadata)
                            {
                                metadata.Uri = base.ProcessUriFromPayload(uriFromPayload, xmlBaseUri);
                            }
                            goto Label_0109;
                        }
                        if (str2 == "email")
                        {
                            metadata.Email = this.ReadElementStringValue();
                            goto Label_0109;
                        }
                    }
                    else
                    {
                        metadata.Name = this.ReadElementStringValue();
                        goto Label_0109;
                    }
                }
                break;

            case XmlNodeType.EndElement:
                goto Label_0109;
            }
            base.XmlReader.Skip();
Label_0109:
            if (base.XmlReader.NodeType != XmlNodeType.EndElement)
            {
                goto Label_0022;
            }
Label_011B:
            base.XmlReader.Read();
            return(metadata);
        }
コード例 #7
0
        private void ReadParentSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata)
        {
            switch (targetSegment.SegmentName)
            {
            case "author":
            {
                AtomPersonMetadata personMetadata = entryMetadata.Authors.FirstOrDefault <AtomPersonMetadata>();
                if (personMetadata != null)
                {
                    this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, personMetadata);
                }
                return;
            }

            case "contributor":
            {
                AtomPersonMetadata metadata2 = entryMetadata.Contributors.FirstOrDefault <AtomPersonMetadata>();
                if (metadata2 != null)
                {
                    this.ReadPersonEpm(ReaderUtils.GetPropertiesList(base.EntryState.Entry.Properties), base.EntryState.EntityType.ToTypeReference(), targetSegment, metadata2);
                }
                return;
            }
            }
            throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadParentSegment_TargetSegmentName));
        }
コード例 #8
0
 private void WriteParentSegment(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
 {
     if (targetSegment.SegmentName == "author")
     {
         AtomPersonMetadata item = this.WritePersonEpm(targetSegment, epmValueCache, typeReference);
         if (item != null)
         {
             List <AtomPersonMetadata> authors = (List <AtomPersonMetadata>) this.entryMetadata.Authors;
             if (authors == null)
             {
                 authors = new List <AtomPersonMetadata>();
                 this.entryMetadata.Authors = authors;
             }
             authors.Add(item);
         }
     }
     else
     {
         if (!(targetSegment.SegmentName == "contributor"))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteParentSegment_TargetSegmentName));
         }
         AtomPersonMetadata metadata2 = this.WritePersonEpm(targetSegment, epmValueCache, typeReference);
         if (metadata2 != null)
         {
             List <AtomPersonMetadata> contributors = (List <AtomPersonMetadata>) this.entryMetadata.Contributors;
             if (contributors == null)
             {
                 contributors = new List <AtomPersonMetadata>();
                 this.entryMetadata.Contributors = contributors;
             }
             contributors.Add(metadata2);
         }
     }
 }
コード例 #9
0
ファイル: EpmCustomWriter.cs プロジェクト: tapika/swupd
        /// <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);
            }
        }
コード例 #10
0
        /// <summary>
        /// Reads an attribute for custom EPM.
        /// </summary>
        /// <param name="entryState">The reader entry state for the entry being read.</param>
        /// <param name="epmTargetPathSegmentForElement">The EPM target segment for the element to which the attribute belongs.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Attribute - the attribute to read.
        /// Post-Condition: XmlNodeType.Attribute - the same attribute, the method doesn't move the reader.
        ///
        /// The method works on any attribute, it checks if the attribute should be used for EPM or not.
        /// </remarks>
        private void ReadCustomEpmAttribute(IODataAtomReaderEntryState entryState, EpmTargetPathSegment epmTargetPathSegmentForElement)
        {
            Debug.Assert(entryState != null, "entryState != null");
            this.AssertXmlCondition(XmlNodeType.Attribute);
            Debug.Assert(epmTargetPathSegmentForElement != null, "epmTargetPathSegmentForElement != null");

            string localName    = this.XmlReader.LocalName;
            string namespaceUri = this.XmlReader.NamespaceURI;
            EpmTargetPathSegment attributeSegment = epmTargetPathSegmentForElement.SubSegments.FirstOrDefault(
                segment => segment.IsAttribute &&
                string.CompareOrdinal(segment.AttributeName, localName) == 0 &&
                string.CompareOrdinal(segment.SegmentNamespaceUri, namespaceUri) == 0);

            if (attributeSegment != null)
            {
                // Don't add values which we already have
                // Both WCF DS client and server will only read the first value from custom EPM for any given EPM info.
                // It also follows the behavior for syndication EPM, where we read only the first author if there are multiple (for example).
                if (!entryState.EpmCustomReaderValueCache.Contains(attributeSegment.EpmInfo))
                {
                    // Note that there's no way for an attribute to specify null value.
                    entryState.EpmCustomReaderValueCache.Add(attributeSegment.EpmInfo, this.XmlReader.Value);
                }
            }
        }
コード例 #11
0
        /// <summary>
        /// Determines if we need to read a child element (either for EPM or for ATOM metadata).
        /// </summary>
        /// <param name="parentSegment">The parent EPM target path segment.</param>
        /// <param name="segmentName">The name of the element/segment to read.</param>
        /// <param name="subSegment">The EPM target path subsegment which describes the element, or null if there's none.</param>
        /// <returns>true if the subelement should be read, false otherwise.</returns>
        protected bool ShouldReadElement(EpmTargetPathSegment parentSegment, string segmentName, out EpmTargetPathSegment subSegment)
        {
            subSegment = null;

            // NOTE: We should always read the element if this.ReadAtomMetadata is true, but we still
            //       need to search for a matching subsegment when ATOM metadata reading is on and this
            //       element is also an EPM target. This is less efficient than returning early, but
            //       needed for the URI case, since callers need to know whether to save the URI value
            //       in the special UriFromEpm property.
            if (parentSegment != null)
            {
                subSegment = parentSegment.SubSegments.FirstOrDefault(segment => string.CompareOrdinal(segment.SegmentName, segmentName) == 0);
                Debug.Assert(
                    subSegment == null || subSegment.SegmentNamespaceUri == AtomConstants.AtomNamespace,
                    "Only elements from ATOM namespace should appear in the syndication mappings.");

                // We do not read out-of-content EPM if the KeepInContent=true.
                if (subSegment != null && subSegment.EpmInfo != null && subSegment.EpmInfo.Attribute.KeepInContent)
                {
                    return(this.ReadAtomMetadata);
                }
            }

            return(subSegment != null || this.ReadAtomMetadata);
        }
コード例 #12
0
        /// <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));
        }
コード例 #13
0
        /// <summary>
        /// Reads a leaf segment which maps to a property value.
        /// </summary>
        /// <param name="targetSegment">The segment being read.</param>
        /// <param name="entryMetadata">The ATOM entry metadata to read from.</param>
        private void ReadPropertyValueSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");
            Debug.Assert(entryMetadata != null, "entryMetadata != null");

            EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo;

            Debug.Assert(
                epmInfo != null && epmInfo.Attribute != null,
                "If the segment has content it must have EpmInfo which in turn must have the Epm attribute");

            switch (epmInfo.Attribute.TargetSyndicationItem)
            {
            case SyndicationItemProperty.Updated:
                if (this.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient)
                {
                    if (entryMetadata.UpdatedString != null)
                    {
                        this.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.UpdatedString);
                    }
                }
                else if (entryMetadata.Updated.HasValue)
                {
                    this.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Updated.Value));
                }

                break;

            case SyndicationItemProperty.Published:
                if (this.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient)
                {
                    if (entryMetadata.PublishedString != null)
                    {
                        this.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.PublishedString);
                    }
                }
                else if (entryMetadata.Published.HasValue)
                {
                    this.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Published.Value));
                }

                break;

            case SyndicationItemProperty.Rights:
                this.ReadTextConstructEpm(targetSegment, entryMetadata.Rights);
                break;

            case SyndicationItemProperty.Summary:
                this.ReadTextConstructEpm(targetSegment, entryMetadata.Summary);
                break;

            case SyndicationItemProperty.Title:
                this.ReadTextConstructEpm(targetSegment, entryMetadata.Title);
                break;

            default:
                throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadEntryEpm_ContentTarget));
            }
        }
コード例 #14
0
ファイル: EpmCustomWriter.cs プロジェクト: modulexcite/pash-1
 private static void WriteNamespaceDeclaration(XmlWriter writer, EpmTargetPathSegment targetSegment, ref string alreadyDeclaredPrefix)
 {
     if (alreadyDeclaredPrefix == null)
     {
         writer.WriteAttributeString("xmlns", targetSegment.SegmentNamespacePrefix, "http://www.w3.org/2000/xmlns/", targetSegment.SegmentNamespaceUri);
         alreadyDeclaredPrefix = targetSegment.SegmentNamespacePrefix;
     }
 }
コード例 #15
0
        private AtomPersonMetadata WritePersonEpm(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
        {
            AtomPersonMetadata metadata = null;

            foreach (EpmTargetPathSegment segment in targetSegment.SubSegments)
            {
                string str = this.GetPropertyValueAsText(segment, epmValueCache, typeReference);
                if (str != null)
                {
                    switch (segment.EpmInfo.Attribute.TargetSyndicationItem)
                    {
                    case SyndicationItemProperty.AuthorEmail:
                    case SyndicationItemProperty.ContributorEmail:
                    {
                        if ((str != null) && (str.Length > 0))
                        {
                            if (metadata == null)
                            {
                                metadata = new AtomPersonMetadata();
                            }
                            metadata.Email = str;
                        }
                        continue;
                    }

                    case SyndicationItemProperty.AuthorName:
                    case SyndicationItemProperty.ContributorName:
                    {
                        if (str != null)
                        {
                            if (metadata == null)
                            {
                                metadata = new AtomPersonMetadata();
                            }
                            metadata.Name = str;
                        }
                        continue;
                    }

                    case SyndicationItemProperty.AuthorUri:
                    case SyndicationItemProperty.ContributorUri:
                    {
                        if ((str != null) && (str.Length > 0))
                        {
                            if (metadata == null)
                            {
                                metadata = new AtomPersonMetadata();
                            }
                            metadata.UriFromEpm = str;
                        }
                        continue;
                    }
                    }
                    throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WritePersonEpm));
                }
            }
            return(metadata);
        }
コード例 #16
0
ファイル: EpmTargetPathSegment.cs プロジェクト: tapika/swupd
        /// <summary>Used for creating non-root nodes in the syndication/custom trees</summary>
        /// <param name="segmentName">Name of xml element/attribute</param>
        /// <param name="segmentNamespaceUri">URI of the namespace for <paramref name="segmentName"/></param>
        /// <param name="parentSegment">Reference to the parent node if this is a sub-node, useful for traversals in visitors</param>
        internal EpmTargetPathSegment(String segmentName, String segmentNamespaceUri, EpmTargetPathSegment parentSegment)
            : this()
        {
            Debug.Assert(segmentName == null || segmentName.Length > 0, "Empty segment name is not allowed.");

            this.segmentName         = segmentName;
            this.segmentNamespaceUri = segmentNamespaceUri;
            this.parentSegment       = parentSegment;
        }
コード例 #17
0
ファイル: EpmCustomWriter.cs プロジェクト: modulexcite/pash-1
        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));
        }
コード例 #18
0
ファイル: EpmCustomWriter.cs プロジェクト: modulexcite/pash-1
        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);
            }
        }
コード例 #19
0
        private void ReadPropertyValueSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata)
        {
            switch (targetSegment.EpmInfo.Attribute.TargetSyndicationItem)
            {
            case SyndicationItemProperty.Updated:
                if (base.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient)
                {
                    if (!entryMetadata.Updated.HasValue)
                    {
                        break;
                    }
                    base.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Updated.Value));
                    return;
                }
                if (entryMetadata.UpdatedString == null)
                {
                    break;
                }
                base.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.UpdatedString);
                return;

            case SyndicationItemProperty.Published:
                if (base.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient)
                {
                    if (entryMetadata.Published.HasValue)
                    {
                        base.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Published.Value));
                        return;
                    }
                    break;
                }
                if (entryMetadata.PublishedString == null)
                {
                    break;
                }
                base.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.PublishedString);
                return;

            case SyndicationItemProperty.Rights:
                this.ReadTextConstructEpm(targetSegment, entryMetadata.Rights);
                return;

            case SyndicationItemProperty.Summary:
                this.ReadTextConstructEpm(targetSegment, entryMetadata.Summary);
                return;

            case SyndicationItemProperty.Title:
                this.ReadTextConstructEpm(targetSegment, entryMetadata.Title);
                return;

            default:
                throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadEntryEpm_ContentTarget));
            }
        }
コード例 #20
0
 private void ReadContributorElement(IODataAtomReaderEntryState entryState, EpmTargetPathSegment epmTargetPathSegment)
 {
     if (this.ShouldReadCollectionElement(entryState.AtomEntryMetadata.Contributors.Any <AtomPersonMetadata>()))
     {
         AtomMetadataReaderUtils.AddContributorToEntryMetadata(entryState.AtomEntryMetadata, base.ReadAtomPersonConstruct(epmTargetPathSegment));
     }
     else
     {
         base.XmlReader.Skip();
     }
 }
コード例 #21
0
        internal EpmCustomContentWriterNodeData(EpmCustomContentWriterNodeData parentData, EpmTargetPathSegment segment, object element, EpmContentSerializer.EpmNullValuedPropertyTree nullValuedProperties, DataServiceProviderWrapper provider)
#endif
        {
            this.XmlContentStream = parentData.XmlContentStream;
            this.XmlContentWriter = parentData.XmlContentWriter;
#if ASTORIA_CLIENT
            this.PopulateData(segment, element);
#else
            this.PopulateData(segment, element, nullValuedProperties, provider);
#endif
        }
コード例 #22
0
        private void ReadCustomEpmAttribute(IODataAtomReaderEntryState entryState, EpmTargetPathSegment epmTargetPathSegmentForElement)
        {
            string localName             = base.XmlReader.LocalName;
            string namespaceUri          = base.XmlReader.NamespaceURI;
            EpmTargetPathSegment segment = epmTargetPathSegmentForElement.SubSegments.FirstOrDefault <EpmTargetPathSegment>(x => (x.IsAttribute && (string.CompareOrdinal(x.AttributeName, localName) == 0)) && (string.CompareOrdinal(x.SegmentNamespaceUri, namespaceUri) == 0));

            if ((segment != null) && !entryState.EpmCustomReaderValueCache.Contains(segment.EpmInfo))
            {
                entryState.EpmCustomReaderValueCache.Add(segment.EpmInfo, base.XmlReader.Value);
            }
        }
コード例 #23
0
        internal bool TryReadExtensionElementInEntryContent(IODataAtomReaderEntryState entryState)
        {
            ODataEntityPropertyMappingCache cachedEpm = entryState.CachedEpm;

            if (cachedEpm == null)
            {
                return(false);
            }
            EpmTargetPathSegment nonSyndicationRoot = cachedEpm.EpmTargetTree.NonSyndicationRoot;

            return(this.TryReadCustomEpmElement(entryState, nonSyndicationRoot));
        }
コード例 #24
0
ファイル: EpmCustomWriter.cs プロジェクト: tapika/swupd
        /// <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();
        }
コード例 #25
0
        private bool TryReadCustomEpmElement(IODataAtomReaderEntryState entryState, EpmTargetPathSegment epmTargetPathSegment)
        {
            string localName    = base.XmlReader.LocalName;
            string namespaceUri = base.XmlReader.NamespaceURI;
            EpmTargetPathSegment epmTargetPathSegmentForElement = epmTargetPathSegment.SubSegments.FirstOrDefault <EpmTargetPathSegment>(segment => (!segment.IsAttribute && (string.CompareOrdinal(segment.SegmentName, localName) == 0)) && (string.CompareOrdinal(segment.SegmentNamespaceUri, namespaceUri) == 0));

            if ((epmTargetPathSegmentForElement != null) && (!epmTargetPathSegmentForElement.HasContent || !entryState.EpmCustomReaderValueCache.Contains(epmTargetPathSegmentForElement.EpmInfo)))
            {
                while (base.XmlReader.MoveToNextAttribute())
                {
                    this.ReadCustomEpmAttribute(entryState, epmTargetPathSegmentForElement);
                }
                base.XmlReader.MoveToElement();
                if (epmTargetPathSegmentForElement.HasContent)
                {
                    string str = base.ReadElementStringValue();
                    entryState.EpmCustomReaderValueCache.Add(epmTargetPathSegmentForElement.EpmInfo, str);
                    goto Label_0115;
                }
                if (!base.XmlReader.IsEmptyElement)
                {
                    base.XmlReader.Read();
                    while (base.XmlReader.NodeType != XmlNodeType.EndElement)
                    {
                        switch (base.XmlReader.NodeType)
                        {
                        case XmlNodeType.Element:
                        {
                            if (!this.TryReadCustomEpmElement(entryState, epmTargetPathSegmentForElement))
                            {
                                base.XmlReader.Skip();
                            }
                            continue;
                        }

                        case XmlNodeType.EndElement:
                        {
                            continue;
                        }
                        }
                        base.XmlReader.Skip();
                    }
                }
            }
            else
            {
                return(false);
            }
            base.XmlReader.Read();
Label_0115:
            return(true);
        }
コード例 #26
0
ファイル: EpmTargetTree.cs プロジェクト: tapika/swupd
        /// <summary>
        /// Removes a path in the tree which is obtained by looking at the EntityPropertyMappingAttribute in the <paramref name="epmInfo"/>
        /// </summary>
        /// <param name="epmInfo">EnitityPropertyMappingInfo holding the target path</param>
        internal void Remove(EntityPropertyMappingInfo epmInfo)
        {
            Debug.Assert(epmInfo != null, "epmInfo != null");

            String targetName   = epmInfo.Attribute.TargetPath;
            String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;

            EpmTargetPathSegment        currentSegment    = epmInfo.IsSyndicationMapping ? this.SyndicationRoot : this.NonSyndicationRoot;
            List <EpmTargetPathSegment> activeSubSegments = currentSegment.SubSegments;

            Debug.Assert(!String.IsNullOrEmpty(targetName), "Must have been validated during EntityPropertyMappingAttribute construction");
            String[] targetSegments = targetName.Split('/');
            for (int i = 0; i < targetSegments.Length; i++)
            {
                String targetSegment = targetSegments[i];

                Debug.Assert(targetSegment.Length > 0 && (targetSegment[0] != '@' || i == targetSegments.Length - 1), "Target segments should have been checked when adding the path to the tree");

                EpmTargetPathSegment foundSegment = activeSubSegments.FirstOrDefault(
                    segment => segment.SegmentName == targetSegment &&
                    (epmInfo.IsSyndicationMapping || segment.SegmentNamespaceUri == namespaceUri));
                if (foundSegment != null)
                {
                    currentSegment = foundSegment;
                }
                else
                {
                    return;
                }

                activeSubSegments = currentSegment.SubSegments;
            }

            // Recursively remove all the parent segments which will have no more children left
            // after removal of the current segment node
            if (currentSegment.EpmInfo != null)
            {
                // Since we are removing a property with KeepInContent false, we should decrement the count
                if (!currentSegment.EpmInfo.Attribute.KeepInContent)
                {
                    this.countOfNonContentV2mappings--;
                }

                EpmTargetPathSegment parentSegment = null;
                do
                {
                    parentSegment = currentSegment.ParentSegment;
                    parentSegment.SubSegments.Remove(currentSegment);
                    currentSegment = parentSegment;
                }while (currentSegment.ParentSegment != null && !currentSegment.HasContent && currentSegment.SubSegments.Count == 0);
            }
        }
コード例 #27
0
        /// <summary>
        /// Reads the value of the ATOM text construct and sets it to the EPM.
        /// </summary>
        /// <param name="targetSegment">The EPM target segment for the value to read.</param>
        /// <param name="textConstruct">The text construct to read it from (can be null).</param>
        private void ReadTextConstructEpm(EpmTargetPathSegment targetSegment, AtomTextConstruct textConstruct)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");
            Debug.Assert(targetSegment.HasContent, "We can only read text construct values into segments which are mapped to a leaf property.");

            if (textConstruct != null)
            {
                if (textConstruct.Text != null)
                {
                    this.SetEntryEpmValue(targetSegment.EpmInfo, textConstruct.Text);
                }
            }
        }
コード例 #28
0
ファイル: EpmTargetTree.cs プロジェクト: tapika/swupd
        /// <summary>Checks the validity of a tree.</summary>
        /// <param name="currentSegment">The segment to validate.</param>
        private static void DebugValidate(EpmTargetPathSegment currentSegment)
        {
            if (currentSegment.ParentSegment != null)
            {
                Debug.Assert(!currentSegment.ParentSegment.IsAttribute, "Attributes must be leaf nodes.");
            }

            // Walk recursively subsegments and validate them
            foreach (EpmTargetPathSegment subSegment in currentSegment.SubSegments)
            {
                DebugValidate(subSegment);
            }
        }
コード例 #29
0
ファイル: EpmCustomWriter.cs プロジェクト: modulexcite/pash-1
        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);
                }
            }
        }
コード例 #30
0
        internal EpmCustomContentWriterNodeData(EpmTargetPathSegment segment, object element, EpmContentSerializer.EpmNullValuedPropertyTree nullValuedProperties, DataServiceProviderWrapper provider)
#endif
        {
            this.XmlContentStream = new MemoryStream();
            XmlWriterSettings customContentWriterSettings = new XmlWriterSettings();
            customContentWriterSettings.OmitXmlDeclaration = true;
            customContentWriterSettings.ConformanceLevel = ConformanceLevel.Fragment;
            this.XmlContentWriter = XmlWriter.Create(this.XmlContentStream, customContentWriterSettings);
#if ASTORIA_CLIENT
            this.PopulateData(segment, element);
#else
            this.PopulateData(segment, element, nullValuedProperties, provider);
#endif
        }
コード例 #31
0
        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));
        }
コード例 #32
0
        /// <summary>
        /// Reads a contributor element.
        /// </summary>
        /// <param name="entryState">The reader entry state for the entry being read.</param>
        /// <param name="epmTargetPathSegment">The EPM target path segment for the element to read, or null if no EPM for that element is defined.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element (atom:contributor) - the atom:contributor element to read.
        /// Post-Condition: Any                                    - the node after the atom:contributor element which was read.
        /// </remarks>
        private void ReadContributorElement(IODataAtomReaderEntryState entryState, EpmTargetPathSegment epmTargetPathSegment)
        {
            Debug.Assert(entryState != null, "entryState != null");
            this.AssertXmlCondition(XmlNodeType.Element);
            Debug.Assert(
                this.XmlReader.LocalName == AtomConstants.AtomContributorElementName && this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace,
                "Only atom:contributor elements can be read by this method.");

            if (this.ShouldReadCollectionElement(entryState.AtomEntryMetadata.Contributors.Any()))
            {
                entryState.AtomEntryMetadata.AddContributor(this.ReadAtomPersonConstruct(epmTargetPathSegment));
            }
            else
            {
                this.XmlReader.Skip();
            }
        }
コード例 #33
0
ファイル: EpmTargetTree.cs プロジェクト: tapika/swupd
        /// <summary>Checks if mappings could potentially result in mixed content and dis-allows it.</summary>
        /// <param name="currentSegment">Segment being processed.</param>
        /// <param name="ancestorHasContent">Does any of the ancestors have content.</param>
        /// <returns>boolean indicating if the tree is valid or not.</returns>
        private static bool HasMixedContent(EpmTargetPathSegment currentSegment, bool ancestorHasContent)
        {
            foreach (EpmTargetPathSegment childSegment in currentSegment.SubSegments.Where(s => !s.IsAttribute))
            {
                if (childSegment.HasContent && ancestorHasContent)
                {
                    return(true);
                }

                if (HasMixedContent(childSegment, childSegment.HasContent || ancestorHasContent))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #34
0
ファイル: EpmSyndicationReader.cs プロジェクト: nickchal/pash
 private void ReadPersonEpm(IList targetList, IEdmTypeReference targetTypeReference, EpmTargetPathSegment targetSegment, AtomPersonMetadata personMetadata)
 {
     foreach (EpmTargetPathSegment segment in targetSegment.SubSegments)
     {
         switch (segment.EpmInfo.Attribute.TargetSyndicationItem)
         {
             case SyndicationItemProperty.AuthorEmail:
             case SyndicationItemProperty.ContributorEmail:
             {
                 string email = personMetadata.Email;
                 if (email != null)
                 {
                     base.SetEpmValue(targetList, targetTypeReference, segment.EpmInfo, email);
                 }
                 break;
             }
             case SyndicationItemProperty.AuthorName:
             case SyndicationItemProperty.ContributorName:
             {
                 string name = personMetadata.Name;
                 if (name != null)
                 {
                     base.SetEpmValue(targetList, targetTypeReference, segment.EpmInfo, name);
                 }
                 break;
             }
             case SyndicationItemProperty.AuthorUri:
             case SyndicationItemProperty.ContributorUri:
             {
                 string uriFromEpm = personMetadata.UriFromEpm;
                 if (uriFromEpm != null)
                 {
                     base.SetEpmValue(targetList, targetTypeReference, segment.EpmInfo, uriFromEpm);
                 }
                 break;
             }
             default:
                 throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadPersonEpm));
         }
     }
 }
コード例 #35
0
ファイル: EpmTargetTree.cs プロジェクト: nickchal/pash
 private static bool HasMixedContent(EpmTargetPathSegment currentSegment, bool ancestorHasContent)
 {
     foreach (EpmTargetPathSegment segment in from s in currentSegment.SubSegments
         where !s.IsAttribute
         select s)
     {
         if (segment.HasContent && ancestorHasContent)
         {
             return true;
         }
         if (HasMixedContent(segment, segment.HasContent || ancestorHasContent))
         {
             return true;
         }
     }
     return false;
 }
コード例 #36
0
        /// <summary>
        /// Writes EPM value to a person construct (author or contributor).
        /// </summary>
        /// <param name="targetSegment">The target segment which points to either author or contributor element.</param>
        /// <param name="epmValueCache">The EPM value cache to use to get property values.</param>
        /// <param name="resourceType">The resource type of the entry being processed.</param>
        /// <param name="metadata">The metadata provider to use.</param>
        /// <returns>The person metadata or null if no person metadata should be written for this mapping.</returns>
        private static AtomPersonMetadata WritePersonEpm(
            EpmTargetPathSegment targetSegment, 
            EntryPropertiesValueCache epmValueCache, 
            ResourceType resourceType,
            DataServiceMetadataProviderWrapper metadata)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");
            Debug.Assert(
                targetSegment.SegmentName == AtomConstants.AtomAuthorElementName || targetSegment.SegmentName == AtomConstants.AtomContributorElementName, 
                "targetSegment must be author or contributor.");

            AtomPersonMetadata personMetadata = null;
            foreach (EpmTargetPathSegment subSegment in targetSegment.SubSegments)
            {
                Debug.Assert(subSegment.HasContent, "sub segment of author segment must have content, there are no subsegments which don't have content under author.");
                string textPropertyValue = GetEntryPropertyValueAsText(subSegment, epmValueCache, resourceType, metadata);

                if (textPropertyValue == null)
                {
                    // TODO: In Multi-Values or in V3 mapping nulls to author/contributor subelements is not legal since there's no way to express it.
                    // author/contributor subelements don't allow extension attributes, so we can't add the m:null attribute.
                    continue;
                }

                // Initialize the person element only if we actually need to write something to it.
                if (personMetadata == null)
                {
                    personMetadata = new AtomPersonMetadata();
                }

                Debug.Assert(subSegment.EpmInfo != null && subSegment.EpmInfo.Attribute != null, "The author subsegment must have EPM info and EPM attribute.");
                switch (subSegment.EpmInfo.Attribute.TargetSyndicationItem)
                {
                    case SyndicationItemProperty.AuthorName:
                    case SyndicationItemProperty.ContributorName:
                        personMetadata.Name = textPropertyValue;
                        break;
                    case SyndicationItemProperty.AuthorEmail:
                    case SyndicationItemProperty.ContributorEmail:
                        // TODO: Validate the email value. In V3 or in multi-values the email value must not be null and it must not be empty
                        // since the syndication API doesn't allow empty email values (see below) and it's questionable if ATOM allows it itself.

                        // In case the value is empty the syndication API will actually omit the email element from the payload
                        // we have to simulate that behavior here by not setting the property in that case.
                        if (textPropertyValue.Length > 0)
                        {
                            personMetadata.Email = textPropertyValue;
                        }

                        break;
                    case SyndicationItemProperty.AuthorUri:
                    case SyndicationItemProperty.ContributorUri:
                        // TODO: Validate the uri value. In V3 or in multi-values the uri value must not be null and it must not be empty
                        // since the syndication API doesn't allow empty uri values (see below) and it's questionable if ATOM allows it itself.

                        // In case the value is empty the syndication API will actually omit the uri element from the payload
                        // we have to simulate that behavior here by not setting the property in that case.
                        if (textPropertyValue.Length > 0)
                        {
                            personMetadata.UriFromEpm = textPropertyValue;
                        }

                        break;
                    default:
                        throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WritePersonEpm));
                }
            }

            return personMetadata;
        }
コード例 #37
0
        /// <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="resourceType">The resource type of the entry being processed.</param>
        /// <param name="metadata">The metadata provider to use.</param>
        /// <returns>The test representation of the value, or the method throws if the text representation was not possible to obtain.</returns>
        private static string GetEntryPropertyValueAsText(
            EpmTargetPathSegment targetSegment, 
            EntryPropertiesValueCache epmValueCache, 
            ResourceType resourceType,
            DataServiceMetadataProviderWrapper metadata)
        {
            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(resourceType != null, "resourceType != null");

            bool nullOnParentProperty;
            object propertyValue = targetSegment.EpmInfo.ReadEntryPropertyValue(epmValueCache, resourceType, metadata, out nullOnParentProperty);
            return EpmWriterUtils.GetPropertyValueAsText(propertyValue);
        }
コード例 #38
0
ファイル: EpmSyndicationWriter.cs プロジェクト: nickchal/pash
 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);
 }
コード例 #39
0
        /// <summary>
        /// Writes EPM value to a person construct (author or contributor).
        /// </summary>
        /// <param name="targetSegment">The target segment which points to either author or contributor element.</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 person metadata or null if no person metadata should be written for this mapping.</returns>
        private AtomPersonMetadata WritePersonEpm(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");
            Debug.Assert(
                targetSegment.SegmentName == AtomConstants.AtomAuthorElementName || targetSegment.SegmentName == AtomConstants.AtomContributorElementName, 
                "targetSegment must be author or contributor.");

            AtomPersonMetadata personMetadata = null;
            foreach (EpmTargetPathSegment subSegment in targetSegment.SubSegments)
            {
                Debug.Assert(subSegment.HasContent, "sub segment of author segment must have content, there are no subsegments which don't have content under author.");
                Debug.Assert(
                    subSegment.EpmInfo != null && subSegment.EpmInfo.Attribute != null && subSegment.EpmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty,
                    "We should never find a subsegment without EPM attribute or for custom mapping when writing syndication person EPM.");
                string textPropertyValue = this.GetPropertyValueAsText(subSegment, epmValueCache, typeReference);

                if (textPropertyValue == null)
                {
                    // In V2 we write the mapped properties always in-content when the value is null.
                    continue;
                }

                // Initialize the person element only if we actually need to write something to it.
                Debug.Assert(subSegment.EpmInfo != null && subSegment.EpmInfo.Attribute != null, "The author subsegment must have EPM info and EPM attribute.");
                switch (subSegment.EpmInfo.Attribute.TargetSyndicationItem)
                {
                    case SyndicationItemProperty.AuthorName:
                    case SyndicationItemProperty.ContributorName:
                        if (textPropertyValue != null)
                        {
                            if (personMetadata == null)
                            {
                                personMetadata = new AtomPersonMetadata();
                            }

                            personMetadata.Name = textPropertyValue;
                        }

                        break;
                    case SyndicationItemProperty.AuthorEmail:
                    case SyndicationItemProperty.ContributorEmail:
                        if (textPropertyValue != null && textPropertyValue.Length > 0)
                        {
                            if (personMetadata == null)
                            {
                                personMetadata = new AtomPersonMetadata();
                            }

                            personMetadata.Email = textPropertyValue;
                        }

                        break;
                    case SyndicationItemProperty.AuthorUri:
                    case SyndicationItemProperty.ContributorUri:
                        if (textPropertyValue != null && textPropertyValue.Length > 0)
                        {
                            if (personMetadata == null)
                            {
                                personMetadata = new AtomPersonMetadata();
                            }

                            personMetadata.UriFromEpm = textPropertyValue;
                        }

                        break;
                    default:
                        throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WritePersonEpm));
                }
            }

            return personMetadata;
        }
コード例 #40
0
        /// <summary>
        /// Checks the validity of a tree.
        /// </summary>
        /// <param name="currentSegment">The segment to validate.</param>
        private static void DebugValidate(EpmTargetPathSegment currentSegment)
        {
            if (currentSegment.ParentSegment != null)
            {
                Debug.Assert(!currentSegment.ParentSegment.IsAttribute, "Attributes must be leaf nodes.");
                if (currentSegment.EpmInfo != null)
                {
                    switch (currentSegment.EpmInfo.MultiValueStatus)
                    {
                        case EntityPropertyMappingMultiValueStatus.None:
                            Debug.Assert(
                                currentSegment.ParentSegment.EpmInfo == null ||
                                currentSegment.ParentSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.None,
                                "non-multiValue property can only be a child of another non-multiValue property.");
                            break;
                        case EntityPropertyMappingMultiValueStatus.MultiValueProperty:
                            Debug.Assert(
                                currentSegment.ParentSegment.EpmInfo == null ||
                                (currentSegment.ParentSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.None && currentSegment.ParentSegment.ParentSegment == null),
                                "MultiValue must be child of the root only.");
                            break;
                        case EntityPropertyMappingMultiValueStatus.MultiValueItemProperty:
                            Debug.Assert(
                                currentSegment.ParentSegment.EpmInfo == null ||
                                (currentSegment.ParentSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty ||
                                 currentSegment.ParentSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueItemProperty),
                                "MultiValue item must be child of multiValue or another multiValue item only.");
                            break;
                    }
                }
            }

            // Walk recursively subsegments and validate them
            foreach (EpmTargetPathSegment subSegment in currentSegment.SubSegments)
            {
                DebugValidate(subSegment);
            }
        }
コード例 #41
0
ファイル: EpmSyndicationWriter.cs プロジェクト: nickchal/pash
 private AtomPersonMetadata WritePersonEpm(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
 {
     AtomPersonMetadata metadata = null;
     foreach (EpmTargetPathSegment segment in targetSegment.SubSegments)
     {
         string str = this.GetPropertyValueAsText(segment, epmValueCache, typeReference);
         if (str != null)
         {
             switch (segment.EpmInfo.Attribute.TargetSyndicationItem)
             {
                 case SyndicationItemProperty.AuthorEmail:
                 case SyndicationItemProperty.ContributorEmail:
                 {
                     if ((str != null) && (str.Length > 0))
                     {
                         if (metadata == null)
                         {
                             metadata = new AtomPersonMetadata();
                         }
                         metadata.Email = str;
                     }
                     continue;
                 }
                 case SyndicationItemProperty.AuthorName:
                 case SyndicationItemProperty.ContributorName:
                 {
                     if (str != null)
                     {
                         if (metadata == null)
                         {
                             metadata = new AtomPersonMetadata();
                         }
                         metadata.Name = str;
                     }
                     continue;
                 }
                 case SyndicationItemProperty.AuthorUri:
                 case SyndicationItemProperty.ContributorUri:
                 {
                     if ((str != null) && (str.Length > 0))
                     {
                         if (metadata == null)
                         {
                             metadata = new AtomPersonMetadata();
                         }
                         metadata.UriFromEpm = str;
                     }
                     continue;
                 }
             }
             throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WritePersonEpm));
         }
     }
     return metadata;
 }
コード例 #42
0
        private void PopulateData(EpmTargetPathSegment segment, object element, EpmContentSerializer.EpmNullValuedPropertyTree nullValuedProperties, DataServiceProviderWrapper provider)
#endif
        {
            if (segment.EpmInfo != null)
            {
                Object propertyValue;

                try
                {
#if ASTORIA_CLIENT
                    propertyValue = segment.EpmInfo.ReadPropertyValue(element);
#else
                    propertyValue = segment.EpmInfo.ReadPropertyValue(element, provider);
#endif
                }
                catch 
#if ASTORIA_CLIENT
                (System.Reflection.TargetInvocationException)
#else
                (System.Reflection.TargetInvocationException e)
#endif
                {
#if !ASTORIA_CLIENT
                    ErrorHandler.HandleTargetInvocationException(e);
#endif
                    throw;
                }

#if ASTORIA_CLIENT
                this.Data = propertyValue == null ? String.Empty : ClientConvert.ToString(propertyValue, false);
#else
                if (propertyValue == null || propertyValue == DBNull.Value)
                {
                    this.Data = String.Empty;
                    nullValuedProperties.Add(segment.EpmInfo);
                }
                else
                {
                    this.Data = PlainXmlSerializer.PrimitiveToString(propertyValue);
                }
#endif
            }
        }
    }
コード例 #43
0
        /// <summary>
        /// Checks if mappings could potentially result in mixed content and dis-allows it.
        /// </summary>
        /// <param name="currentSegment">Segment being processed.</param>
        /// <param name="ancestorsWithContent">A list of ancestor attributes that have content. 
        /// Can contain a maximum of one attribute when the method is called, must never contain more than two.</param>
        /// <returns>boolean indicating if the tree is valid or not.</returns>
        private static bool HasMixedContent(EpmTargetPathSegment currentSegment, List<EntityPropertyMappingAttribute> ancestorsWithContent)
        {
            Debug.Assert(ancestorsWithContent != null && ancestorsWithContent.Count < 2, "Expected at most 1 ancestor with content.");

            foreach (EpmTargetPathSegment childSegment in currentSegment.SubSegments.Where(s => !s.IsAttribute))
            {
                if (childSegment.HasContent && ancestorsWithContent.Count == 1)
                {
                    ancestorsWithContent.Add(childSegment.EpmInfo.Attribute);
                    return true;
                }

                if (childSegment.HasContent)
                {
                    Debug.Assert(ancestorsWithContent.Count == 0, "Should have already returned if we had ancestors with content.");
                    ancestorsWithContent.Add(childSegment.EpmInfo.Attribute);
                }

                if (HasMixedContent(childSegment, ancestorsWithContent))
                {
                    Debug.Assert(ancestorsWithContent.Count == 2, "Must have two attributes with content to return true.");
                    return true;
                }

                if (childSegment.HasContent)
                {
                    Debug.Assert(ancestorsWithContent.Count == 1, "Should have the one item in the list that we added before.");
                    ancestorsWithContent.Clear();
                }
            }
            
            return false;
        }
コード例 #44
0
 /// <summary>
 /// Initializes the sub-trees for syndication and non-syndication content.
 /// </summary>
 internal EpmTargetTree()
 {
     DebugUtils.CheckNoExternalCallers();
     this.syndicationRoot = new EpmTargetPathSegment();
     this.nonSyndicationRoot = new EpmTargetPathSegment();
 }
コード例 #45
0
 private void PopulateData(EpmTargetPathSegment segment, object element)
コード例 #46
0
ファイル: EpmTargetTree.cs プロジェクト: nickchal/pash
 private static bool HasMixedContent(EpmTargetPathSegment currentSegment, List<EntityPropertyMappingAttribute> ancestorsWithContent)
 {
     foreach (EpmTargetPathSegment segment in from s in currentSegment.SubSegments
         where !s.IsAttribute
         select s)
     {
         if (segment.HasContent && (ancestorsWithContent.Count == 1))
         {
             ancestorsWithContent.Add(segment.EpmInfo.Attribute);
             return true;
         }
         if (segment.HasContent)
         {
             ancestorsWithContent.Add(segment.EpmInfo.Attribute);
         }
         if (HasMixedContent(segment, ancestorsWithContent))
         {
             return true;
         }
         if (segment.HasContent)
         {
             ancestorsWithContent.Clear();
         }
     }
     return false;
 }
コード例 #47
0
ファイル: EpmTargetTree.cs プロジェクト: nickchal/pash
 internal void Add(EntityPropertyMappingInfo epmInfo)
 {
     string targetPath = epmInfo.Attribute.TargetPath;
     string namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
     string targetNamespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;
     EpmTargetPathSegment parentSegment = epmInfo.IsSyndicationMapping ? this.SyndicationRoot : this.NonSyndicationRoot;
     IList<EpmTargetPathSegment> subSegments = parentSegment.SubSegments;
     string[] strArray = targetPath.Split(new char[] { '/' });
     EpmTargetPathSegment segment2 = null;
     for (int i = 0; i < strArray.Length; i++)
     {
         string targetSegment = strArray[i];
         if (targetSegment.Length == 0)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmTargetTree_InvalidTargetPath_EmptySegment(targetPath));
         }
         if ((targetSegment[0] == '@') && (i != (strArray.Length - 1)))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmTargetTree_AttributeInMiddle(targetSegment));
         }
         segment2 = subSegments.SingleOrDefault<EpmTargetPathSegment>(delegate (EpmTargetPathSegment segment) {
             if (!(segment.SegmentName == targetSegment))
             {
                 return false;
             }
             if (!epmInfo.IsSyndicationMapping)
             {
                 return segment.SegmentNamespaceUri == namespaceUri;
             }
             return true;
         });
         if (segment2 != null)
         {
             parentSegment = segment2;
         }
         else
         {
             parentSegment = new EpmTargetPathSegment(targetSegment, namespaceUri, targetNamespacePrefix, parentSegment);
             if (targetSegment[0] == '@')
             {
                 subSegments.Insert(0, parentSegment);
             }
             else
             {
                 subSegments.Add(parentSegment);
             }
         }
         subSegments = parentSegment.SubSegments;
     }
     if (parentSegment.EpmInfo != null)
     {
         throw new ODataException(Microsoft.Data.OData.Strings.EpmTargetTree_DuplicateEpmAttributesWithSameTargetName(parentSegment.EpmInfo.DefiningType.ODataFullName(), GetPropertyNameFromEpmInfo(parentSegment.EpmInfo), parentSegment.EpmInfo.Attribute.SourcePath, epmInfo.Attribute.SourcePath));
     }
     if (!epmInfo.Attribute.KeepInContent)
     {
         this.countOfNonContentV2Mappings++;
     }
     parentSegment.EpmInfo = epmInfo;
     List<EntityPropertyMappingAttribute> ancestorsWithContent = new List<EntityPropertyMappingAttribute>(2);
     if (HasMixedContent(this.NonSyndicationRoot, ancestorsWithContent))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.EpmTargetTree_InvalidTargetPath_MixedContent(ancestorsWithContent[0].TargetPath, ancestorsWithContent[1].TargetPath));
     }
 }
コード例 #48
0
        /// <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);
        }
コード例 #49
0
        /// <summary>
        /// Checks if mappings could potentially result in mixed content and dis-allows it.
        /// </summary>
        /// <param name="currentSegment">Segment being processed.</param>
        /// <param name="ancestorHasContent">Does any of the ancestors have content.</param>
        /// <returns>boolean indicating if the tree is valid or not.</returns>
        private static bool HasMixedContent(EpmTargetPathSegment currentSegment, bool ancestorHasContent)
        {
            foreach (EpmTargetPathSegment childSegment in currentSegment.SubSegments.Where(s => !s.IsAttribute))
            {
                if (childSegment.HasContent && ancestorHasContent)
                {
                    return true;
                }

                if (HasMixedContent(childSegment, childSegment.HasContent || ancestorHasContent))
                {
                    return true;
                }
            }
            
            return false;
        }
コード例 #50
0
 internal EpmCustomContentWriterNodeData(EpmCustomContentWriterNodeData parentData, EpmTargetPathSegment segment, object element)
コード例 #51
0
ファイル: ResourceType.cs プロジェクト: JianwenSun/cc
 /// <summary>
 /// Sets the value <paramref name="propertyValue"/> on the <paramref name="currentValue"/> object
 /// </summary>
 /// <param name="currentSegment">Target path segment containing the corresponding attribute information</param>
 /// <param name="currentValue">Object on which to set property</param>
 /// <param name="propertyValue">Value to be set</param>
 /// <param name="deserializer">Current deserializer</param>
 internal void SetEpmValue(EpmTargetPathSegment currentSegment, Object currentValue, object propertyValue, EpmContentDeSerializerBase deserializer)
 {
     if (currentSegment.EpmInfo.Attribute.KeepInContent == false)
     {
         this.SetPropertyValueFromPath(
                 currentSegment.EpmInfo.Attribute.SourcePath.Split('/'),
                 this,
                 currentValue,
                 propertyValue,
                 0,
                 deserializer);
     }
 }
コード例 #52
0
        /// <summary>
        /// Checks the validity of a tree.
        /// </summary>
        /// <param name="currentSegment">The segment to validate.</param>
        private static void DebugValidate(EpmTargetPathSegment currentSegment)
        {
            if (currentSegment.ParentSegment != null)
            {
                Debug.Assert(!currentSegment.ParentSegment.IsAttribute, "Attributes must be leaf nodes.");
            }

            // Walk recursively subsegments and validate them
            foreach (EpmTargetPathSegment subSegment in currentSegment.SubSegments)
            {
                DebugValidate(subSegment);
            }
        }
コード例 #53
0
        internal void Add(EntityPropertyMappingInfo epmInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(epmInfo != null, "epmInfo != null");

            String targetPath = epmInfo.Attribute.TargetPath;
            String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
            String namespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;

            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;
            EpmTargetPathSegment multiValueSegment = null;
            for (int i = 0; i < targetSegments.Length; i++)
            {
                String targetSegment = targetSegments[i];

                if (targetSegment.Length == 0)
                {
                    throw new ODataException(Strings.EpmTargetTree_InvalidTargetPath(targetPath));
                }

                if (targetSegment[0] == '@' && i != targetSegments.Length - 1)
                {
                    throw new ODataException(Strings.EpmTargetTree_AttributeInMiddle(targetSegment));
                }

                foundSegment = activeSubSegments.SingleOrDefault(
                    segment => segment.SegmentName == targetSegment &&
                    (epmInfo.IsSyndicationMapping || segment.SegmentNamespaceUri == namespaceUri) &&
                    segment.MatchCriteria(epmInfo.CriteriaValue, epmInfo.Criteria));

                if (foundSegment != null)
                {
                    currentSegment = foundSegment;
                    if (currentSegment.EpmInfo != null && currentSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty)
                    {
                        multiValueSegment = currentSegment;
                    }
                }
                else
                {
                    currentSegment = new EpmTargetPathSegment(targetSegment, namespaceUri, namespacePrefix, currentSegment);
                    currentSegment.Criteria = epmInfo.Criteria;
                    currentSegment.CriteriaValue = epmInfo.CriteriaValue;

                    if (targetSegment[0] == '@')
                    {
                        activeSubSegments.Insert(0, currentSegment);
                    }
                    else
                    {
                        activeSubSegments.Add(currentSegment);
                    }
                }

                activeSubSegments = currentSegment.SubSegments;
            }

            // If we're adding a multiValue property to already existing segment which maps to a non-multiValue property (no EpmInfo or one pointing to a non-multiValue property)
            // OR if we're adding a non-multiValue property to a segment which has multiValue in its path
            //   we need to fail, since it's invalid to have multiValue property being mapped to the same top-level element as anything else.
            if ((epmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty && 
                    foundSegment != null &&
                    (foundSegment.EpmInfo == null || foundSegment.EpmInfo.MultiValueStatus != EntityPropertyMappingMultiValueStatus.MultiValueProperty)) ||
                (epmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.None &&
                    multiValueSegment != null))
            {
                EntityPropertyMappingInfo multiValuePropertyEpmInfo = epmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty ?
                    epmInfo : multiValueSegment.EpmInfo;

                // Trying to map MultiValue property to the same target as something else which was already mapped there
                // It is ok to map to atom:category and atom:link elements with different sources only if the criteria values are different.
                if (epmInfo.CriteriaValue != null)
                {
                    throw new ODataException(Strings.EpmTargetTree_MultiValueAndNormalPropertyMappedToTheSameConditionalTopLevelElement(
                        multiValuePropertyEpmInfo.Attribute.SourcePath,
                        epmInfo.DefiningType.Name,
                        EpmTargetTree.GetPropertyNameFromEpmInfo(multiValuePropertyEpmInfo),
                        epmInfo.CriteriaValue));
                }
                else
                {
                    throw new ODataException(Strings.EpmTargetTree_MultiValueAndNormalPropertyMappedToTheSameTopLevelElement(
                        multiValuePropertyEpmInfo.Attribute.SourcePath,
                        epmInfo.DefiningType.Name,
                        EpmTargetTree.GetPropertyNameFromEpmInfo(multiValuePropertyEpmInfo)));
                }
            }

            Debug.Assert(
                epmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.None || epmInfo.IsSyndicationMapping,
                "Custom EPM mapping is not supported for multiValue properties.");

            // We only allow multiValues to map to ATOM constructs which can be repeated.
            if (epmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueItemProperty)
            {
                Debug.Assert(
                    epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty, 
                    "Trying to add custom mapped property to a syndication target tree.");

                // Right now all the SyndicationItemProperty targets which do not have SyndicationParent.Entry are valid targets for multiValues
                // and all the ones which have SyndicationParent.Entry (Title, Updated etc.) are not valid targets for multiValues.
                if (epmInfo.SyndicationParent == EpmSyndicationParent.Entry)
                {
                    throw new ODataException(Strings.EpmTargetTree_MultiValueMappedToNonRepeatableAtomElement(
                        epmInfo.Attribute.SourcePath,
                        epmInfo.DefiningType.Name,
                        EpmTargetTree.GetPropertyNameFromEpmInfo(epmInfo)));
                }
            }

            Debug.Assert(
                epmInfo.MultiValueStatus != EntityPropertyMappingMultiValueStatus.MultiValueProperty || targetSegments.Length == 1,
                "MultiValue property itself can only be mapped to the top-level element.");

            if (currentSegment.EpmInfo != null)
            {
                if (currentSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty)
                {
                    Debug.Assert(
                        epmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty,
                        "MultiValue property values can't be mapped directly to the top-level element content (no such syndication mapping exists).");

                    // The info we're trying to add is a multiValue property, which would mean two multiValue properties trying to map to the same top-level element.
                    // This can happen if the base type defines mapping for a multiValue property and the derived type defines it again
                    //   in which case we will try to add the derived type mapping again.
                    // So we need to check that these properties are from the same source
                    // It is ok to map to atom:category and atom:link elements with different sources only if the criteria values are different.
                    if (epmInfo.Attribute.SourcePath != currentSegment.EpmInfo.Attribute.SourcePath)
                    {
                        if (epmInfo.CriteriaValue != null)
                        {
                            throw new ODataException(Strings.EpmTargetTree_TwoMultiValuePropertiesMappedToTheSameConditionalTopLevelElement(
                                currentSegment.EpmInfo.Attribute.SourcePath,
                                epmInfo.Attribute.SourcePath,
                                epmInfo.DefiningType.Name,
                                epmInfo.CriteriaValue));
                        }
                        else
                        {
                            throw new ODataException(Strings.EpmTargetTree_TwoMultiValuePropertiesMappedToTheSameTopLevelElement(
                                currentSegment.EpmInfo.Attribute.SourcePath,
                                epmInfo.Attribute.SourcePath,
                                epmInfo.DefiningType.Name));
                        }
                    }

                    Debug.Assert(
                        !foundSegment.EpmInfo.DefiningTypesAreEqual(epmInfo),
                        "Trying to add a multiValue property mapping for the same property on the same type twice. The souce tree should have prevented this from happening.");

                    // If the sources are the same (and the types are different), we can safely overwrite the epmInfo
                    // with the new one (which is for the derived type)
                    // The epm info is stored below.
                }
                else
                {
                    Debug.Assert(
                        epmInfo.MultiValueStatus != EntityPropertyMappingMultiValueStatus.MultiValueProperty,
                        "Only non-multiValue propeties should get here, we cover the rest above.");

                    // Two EpmAttributes with same TargetName in the inheritance hierarchy
                    throw new ODataException(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)
            {
                if (epmInfo.IsAtomLinkMapping || epmInfo.IsAtomCategoryMapping)
                {
                    this.countOfNonContentV3mappings++;
                }
                else
                {
                    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 ODataException(Strings.EpmTargetTree_InvalidTargetPath(targetPath));
            }
        }
コード例 #54
0
        /// <summary>
        /// Override of the base Visitor method, which actually performs mapping search and serialization
        /// </summary>
        /// <param name="targetSegment">Current segment being checked for mapping</param>
        /// <param name="kind">Which sub segments to serialize</param>
        /// <param name="provider">Data Service provider used for rights verification.</param>
        protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind, DataServiceProviderWrapper provider)
        {
            if (targetSegment.HasContent)
            {
                EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo;
                Object propertyValue;
                
                try
                {
                    propertyValue = epmInfo.ReadPropertyValue(this.Element, provider);
                }
                catch (System.Reflection.TargetInvocationException e)
                {
                    ErrorHandler.HandleTargetInvocationException(e);
                    throw;
                }

                if (propertyValue == null)
                {
                    this.nullValuedProperties.Add(epmInfo);
                }

                String textPropertyValue = propertyValue != null ? PlainXmlSerializer.PrimitiveToString(propertyValue) : String.Empty;
                TextSyndicationContentKind contentKind = (TextSyndicationContentKind)epmInfo.Attribute.TargetTextContentKind;

                switch (epmInfo.Attribute.TargetSyndicationItem)
                {
                    case SyndicationItemProperty.AuthorEmail:
                        this.CreateAuthor(false);
                        this.author.Email = textPropertyValue;
                        break;
                    case SyndicationItemProperty.AuthorName:
                        this.CreateAuthor(false);
                        this.author.Name = textPropertyValue;    
                        this.authorNamePresent = true;
                        break;
                    case SyndicationItemProperty.AuthorUri:
                        this.CreateAuthor(false);
                        this.author.Uri = textPropertyValue;
                        break;
                    case SyndicationItemProperty.ContributorEmail:
                    case SyndicationItemProperty.ContributorName:
                    case SyndicationItemProperty.ContributorUri:
                        this.SetContributorProperty(epmInfo.Attribute.TargetSyndicationItem, textPropertyValue);
                        break;
                    case SyndicationItemProperty.Updated:
                        this.Target.LastUpdatedTime = EpmSyndicationContentSerializer.GetDate(propertyValue, Strings.EpmSerializer_UpdatedHasWrongType);
                        break;
                    case SyndicationItemProperty.Published:
                        this.Target.PublishDate = EpmSyndicationContentSerializer.GetDate(propertyValue, Strings.EpmSerializer_PublishedHasWrongType);
                        break;
                    case SyndicationItemProperty.Rights:
                        this.Target.Copyright = new TextSyndicationContent(textPropertyValue, contentKind);
                        break;
                    case SyndicationItemProperty.Summary:
                        this.Target.Summary = new TextSyndicationContent(textPropertyValue, contentKind);
                        break;
                    case SyndicationItemProperty.Title:
                        this.Target.Title = new TextSyndicationContent(textPropertyValue, contentKind);
                        break;
                    default:
                        Debug.Fail("Unhandled SyndicationItemProperty enum value - should never get here.");
                        break;
                }
            }
            else
            {
                base.Serialize(targetSegment, kind, provider);
            }
        }
コード例 #55
0
ファイル: EpmSyndicationWriter.cs プロジェクト: nickchal/pash
 private void WriteParentSegment(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
 {
     if (targetSegment.SegmentName == "author")
     {
         AtomPersonMetadata item = this.WritePersonEpm(targetSegment, epmValueCache, typeReference);
         if (item != null)
         {
             List<AtomPersonMetadata> authors = (List<AtomPersonMetadata>) this.entryMetadata.Authors;
             if (authors == null)
             {
                 authors = new List<AtomPersonMetadata>();
                 this.entryMetadata.Authors = authors;
             }
             authors.Add(item);
         }
     }
     else
     {
         if (!(targetSegment.SegmentName == "contributor"))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteParentSegment_TargetSegmentName));
         }
         AtomPersonMetadata metadata2 = this.WritePersonEpm(targetSegment, epmValueCache, typeReference);
         if (metadata2 != null)
         {
             List<AtomPersonMetadata> contributors = (List<AtomPersonMetadata>) this.entryMetadata.Contributors;
             if (contributors == null)
             {
                 contributors = new List<AtomPersonMetadata>();
                 this.entryMetadata.Contributors = contributors;
             }
             contributors.Add(metadata2);
         }
     }
 }
コード例 #56
0
        /// <summary>
        /// Used for creating non-root nodes in the syndication/custom trees.
        /// </summary>
        /// <param name="segmentName">Name of xml element/attribute</param>
        /// <param name="segmentNamespaceUri">URI of the namespace for <paramref name="segmentName"/></param>
        /// <param name="segmentNamespacePrefix">Namespace prefix to be used for <paramref name="segmentNamespaceUri"/></param>
        /// <param name="parentSegment">Reference to the parent node if this is a sub-node, useful for traversals in visitors</param>
        internal EpmTargetPathSegment(String segmentName, String segmentNamespaceUri, String segmentNamespacePrefix, EpmTargetPathSegment parentSegment)
            : this()
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(segmentName == null || segmentName.Length > 0, "Empty segment name is not allowed.");

            this.segmentName = segmentName;
            this.segmentNamespaceUri = segmentNamespaceUri;
            this.segmentNamespacePrefix = segmentNamespacePrefix;
            this.parentSegment = parentSegment;
        }
コード例 #57
0
ファイル: EpmSyndicationReader.cs プロジェクト: nickchal/pash
 private void ReadTextConstructEpm(EpmTargetPathSegment targetSegment, AtomTextConstruct textConstruct)
 {
     if ((textConstruct != null) && (textConstruct.Text != null))
     {
         base.SetEntryEpmValue(targetSegment.EpmInfo, textConstruct.Text);
     }
 }
コード例 #58
0
        /// <summary>
        /// Writes a non-leaf segment which has sub segments.
        /// </summary>
        /// <param name="targetSegment">The segment being written</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>
        private void WriteParentSegment(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");

            if (targetSegment.SegmentName == AtomConstants.AtomAuthorElementName)
            {
                AtomPersonMetadata authorMetadata = this.WritePersonEpm(targetSegment, epmValueCache, typeReference);

                if (authorMetadata != null)
                {
                    List<AtomPersonMetadata> authors = (List<AtomPersonMetadata>)this.entryMetadata.Authors;
                    if (authors == null)
                    {
                        authors = new List<AtomPersonMetadata>();
                        this.entryMetadata.Authors = authors;
                    }

                    authors.Add(authorMetadata);
                }
            }
            else if (targetSegment.SegmentName == AtomConstants.AtomContributorElementName)
            {
                AtomPersonMetadata contributorMetadata = this.WritePersonEpm(targetSegment, epmValueCache, typeReference);

                if (contributorMetadata != null)
                {
                    List<AtomPersonMetadata> contributors = (List<AtomPersonMetadata>)this.entryMetadata.Contributors;
                    if (contributors == null)
                    {
                        contributors = new List<AtomPersonMetadata>();
                        this.entryMetadata.Contributors = contributors;
                    }

                    contributors.Add(contributorMetadata);
                }
            }
            else
            {
                // Unhandled EpmTargetPathSegment.SegmentName.
                throw new ODataException(o.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteParentSegment_TargetSegmentName));
            }
        }
コード例 #59
0
        internal void Add(EntityPropertyMappingInfo epmInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(epmInfo != null, "epmInfo != null");

            string targetPath = epmInfo.Attribute.TargetPath;
            string namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
            string namespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;

            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 ODataException(Strings.EpmTargetTree_InvalidTargetPath_EmptySegment(targetPath));
                }

                if (targetSegment[0] == '@' && i != targetSegments.Length - 1)
                {
                    throw new ODataException(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, namespacePrefix, 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 ODataException(Strings.EpmTargetTree_DuplicateEpmAttributesWithSameTargetName(currentSegment.EpmInfo.DefiningType.ODataFullName(), EpmTargetTree.GetPropertyNameFromEpmInfo(currentSegment.EpmInfo), 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.
            List<EntityPropertyMappingAttribute> conflictingAttributes = new List<EntityPropertyMappingAttribute>(2);
            if (EpmTargetTree.HasMixedContent(this.NonSyndicationRoot, conflictingAttributes))
            {
                Debug.Assert(conflictingAttributes.Count == 2, "Expected to find exactly two conflicting attributes.");
                throw new ODataException(Strings.EpmTargetTree_InvalidTargetPath_MixedContent(conflictingAttributes[0].TargetPath, conflictingAttributes[1].TargetPath));
            }
        }
コード例 #60
0
ファイル: EpmSyndicationReader.cs プロジェクト: nickchal/pash
        private void ReadPropertyValueSegment(EpmTargetPathSegment targetSegment, AtomEntryMetadata entryMetadata)
        {
            switch (targetSegment.EpmInfo.Attribute.TargetSyndicationItem)
            {
                case SyndicationItemProperty.Updated:
                    if (base.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient)
                    {
                        if (!entryMetadata.Updated.HasValue)
                        {
                            break;
                        }
                        base.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Updated.Value));
                        return;
                    }
                    if (entryMetadata.UpdatedString == null)
                    {
                        break;
                    }
                    base.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.UpdatedString);
                    return;

                case SyndicationItemProperty.Published:
                    if (base.MessageReaderSettings.ReaderBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient)
                    {
                        if (entryMetadata.Published.HasValue)
                        {
                            base.SetEntryEpmValue(targetSegment.EpmInfo, XmlConvert.ToString(entryMetadata.Published.Value));
                            return;
                        }
                        break;
                    }
                    if (entryMetadata.PublishedString == null)
                    {
                        break;
                    }
                    base.SetEntryEpmValue(targetSegment.EpmInfo, entryMetadata.PublishedString);
                    return;

                case SyndicationItemProperty.Rights:
                    this.ReadTextConstructEpm(targetSegment, entryMetadata.Rights);
                    return;

                case SyndicationItemProperty.Summary:
                    this.ReadTextConstructEpm(targetSegment, entryMetadata.Summary);
                    return;

                case SyndicationItemProperty.Title:
                    this.ReadTextConstructEpm(targetSegment, entryMetadata.Title);
                    return;

                default:
                    throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmSyndicationReader_ReadEntryEpm_ContentTarget));
            }
        }