Example #1
0
        /// <summary>
        /// Internal interface to be overridden in the subclasses.
        /// Goes through each subsegments and invokes itself for the children
        /// </summary>
        /// <param name="targetSegment">Current root segment in the target tree</param>
        /// <param name="kind">Which sub segments to serialize</param>
        /// <param name="provider">Data Service provider used for rights verification.</param>
        protected virtual void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind, DataServiceProviderWrapper provider)
#endif
        {
            IEnumerable <EpmTargetPathSegment> segmentsToSerialize;

            switch (kind)
            {
            case EpmSerializationKind.Attributes:
                segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == true);
                break;

            case EpmSerializationKind.Elements:
                segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == false);
                break;

            default:
                Debug.Assert(kind == EpmSerializationKind.All, "Must serialize everything");
                segmentsToSerialize = targetSegment.SubSegments;
                break;
            }

            foreach (EpmTargetPathSegment segment in segmentsToSerialize)
            {
#if ASTORIA_CLIENT
                this.Serialize(segment, kind);
#else
                this.Serialize(segment, kind, provider);
#endif
            }
        }
        protected virtual void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
        {
            IEnumerable <EpmTargetPathSegment> segmentsToSerialize;

            switch (kind)
            {
            case EpmSerializationKind.Attributes:
                segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == true);
                break;

            case EpmSerializationKind.Elements:
                segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == false);
                break;

            default:
                Debug.Assert(kind == EpmSerializationKind.All, "Must serialize everything");
                segmentsToSerialize = targetSegment.SubSegments;
                break;
            }

            foreach (EpmTargetPathSegment segment in segmentsToSerialize)
            {
                this.Serialize(segment, kind);
            }
        }
        internal EpmCustomContentWriterNodeData(EpmCustomContentWriterNodeData parentData, EpmTargetPathSegment segment, object element)
        {
            this.XmlContentStream = parentData.XmlContentStream;
            this.XmlContentWriter = parentData.XmlContentWriter;
            this.PopulateData(segment, element);

        }
Example #4
0
        /// <summary>
        /// Given a segment, writes the element to xml writer corresponding to it, works recursively to write child elements/attributes
        /// </summary>
        /// <param name="targetSegment">Segment being written</param>
        /// <param name="provider">Data Service provider used for rights verification.</param>
        private void WriteElement(EpmTargetPathSegment targetSegment, DataServiceProviderWrapper provider)
#endif
        {
            // Content to be written in an element
            EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment];

            currentContent.XmlContentWriter.WriteStartElement(
                targetSegment.SegmentNamespacePrefix,
                targetSegment.SegmentName,
                targetSegment.SegmentNamespaceUri);

#if ASTORIA_CLIENT
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Attributes);
#else
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Attributes, provider);
#endif

            if (targetSegment.HasContent)
            {
                Debug.Assert(currentContent.Data != null, "Must always have non-null data content value");
                currentContent.XmlContentWriter.WriteString(currentContent.Data);
            }

#if ASTORIA_CLIENT
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Elements);
#else
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Elements, provider);
#endif

            currentContent.XmlContentWriter.WriteEndElement();
        }
Example #5
0
 /// <summary>Initialize the visitor content for all of root's grandchildren and beyond</summary>
 /// <param name="subSegment">One of root's children</param>
 /// <param name="nullValuedProperties">Null valued properties found during serialization</param>
 /// <param name="provider">Data Service provider used for rights verification.</param>
 private void InitializeSubSegmentVisitorContent(EpmTargetPathSegment subSegment, EpmContentSerializer.EpmNullValuedPropertyTree nullValuedProperties, DataServiceProviderWrapper provider)
 {
     foreach (EpmTargetPathSegment segment in subSegment.SubSegments)
     {
         this.visitorContent.Add(segment, new EpmCustomContentWriterNodeData(this.visitorContent[subSegment], segment, this.Element, nullValuedProperties, provider));
         this.InitializeSubSegmentVisitorContent(segment, nullValuedProperties, provider);
     }
 }
Example #6
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()
 {
     this.segmentName = segmentName;
     this.segmentNamespaceUri = segmentNamespaceUri;
     this.segmentNamespacePrefix = segmentNamespacePrefix;
     this.parentSegment = parentSegment;
 }
Example #7
0
 internal EpmTargetPathSegment(String segmentName, String segmentNamespaceUri, String segmentNamespacePrefix, EpmTargetPathSegment parentSegment)
     : this()
 {
     this.segmentName            = segmentName;
     this.segmentNamespaceUri    = segmentNamespaceUri;
     this.segmentNamespacePrefix = segmentNamespacePrefix;
     this.parentSegment          = parentSegment;
 }
Example #8
0
 /// <summary>Initialize the visitor content for all of root's grandchildren and beyond</summary>
 /// <param name="subSegment">One of root's children</param>
 private void InitializeSubSegmentVisitorContent(EpmTargetPathSegment subSegment)
 {
     foreach (EpmTargetPathSegment segment in subSegment.SubSegments)
     {
         this.visitorContent.Add(segment, new EpmCustomContentWriterNodeData(this.visitorContent[subSegment], segment, this.Element));
         this.InitializeSubSegmentVisitorContent(segment);
     }
 }
Example #9
0
        /// <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)
        {
            String targetName    = epmInfo.Attribute.TargetPath;
            bool   isSyndication = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
            String namespaceUri  = epmInfo.Attribute.TargetNamespaceUri;

            EpmTargetPathSegment        currentSegment    = isSyndication ? 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];

                if (targetSegment.Length == 0)
                {
                    throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
                }

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

                EpmTargetPathSegment foundSegment = activeSubSegments.FirstOrDefault(
                    segment => segment.SegmentName == targetSegment &&
                    (isSyndication || 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.HasContent)
            {
                // Since we are removing a property with KeepInContent false, we should decrement the count
                if (!currentSegment.EpmInfo.Attribute.KeepInContent)
                {
                    this.countOfNonContentProperties--;
                }

                do
                {
                    EpmTargetPathSegment parentSegment = currentSegment.ParentSegment;
                    parentSegment.SubSegments.Remove(currentSegment);
                    currentSegment = parentSegment;
                }while (currentSegment.ParentSegment != null && !currentSegment.HasContent && currentSegment.SubSegments.Count == 0);
            }
        }
 internal EpmCustomContentWriterNodeData(EpmTargetPathSegment segment, object element)
 {
     this.XmlContentStream = new MemoryStream();
     XmlWriterSettings customContentWriterSettings = new XmlWriterSettings();
     customContentWriterSettings.OmitXmlDeclaration = true;
     customContentWriterSettings.ConformanceLevel = ConformanceLevel.Fragment;
     this.XmlContentWriter = XmlWriter.Create(this.XmlContentStream, customContentWriterSettings);
     this.PopulateData(segment, element);
 }
        internal EpmCustomContentWriterNodeData(EpmTargetPathSegment segment, object element)
        {
            this.XmlContentStream = new MemoryStream();
            XmlWriterSettings customContentWriterSettings = new XmlWriterSettings();

            customContentWriterSettings.OmitXmlDeclaration = true;
            customContentWriterSettings.ConformanceLevel   = ConformanceLevel.Fragment;
            this.XmlContentWriter = XmlWriter.Create(this.XmlContentStream, customContentWriterSettings);
            this.PopulateData(segment, element);
        }
Example #12
0
 /// <summary>
 /// Matches the targetSegment with properties already applied and if finds something already applied considers it a match
 /// </summary>
 /// <param name="targetSegment">Target segment for which existing property application is checked for</param>
 /// <param name="propertiesApplied">Properties already applied based on content</param>
 /// <returns>true if already the property for the current segment has been applied</returns>
 internal static bool Match(EpmTargetPathSegment targetSegment, EpmContentDeSerializer.EpmAppliedPropertyInfo propertiesApplied)
 {
     if (!targetSegment.EpmInfo.Attribute.KeepInContent)
     {
         return(propertiesApplied.Lookup(targetSegment.EpmInfo.Attribute.SourcePath));
     }
     else
     {
         return(true);
     }
 }
        private void WriteAttribute(EpmTargetPathSegment targetSegment)
        {
            Debug.Assert(targetSegment.HasContent, "Must have content for attributes");

            EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment];
            currentContent.XmlContentWriter.WriteAttributeString(
                                    targetSegment.SegmentNamespacePrefix,
                                    targetSegment.SegmentName.Substring(1),
                                    targetSegment.SegmentNamespaceUri,
                                    currentContent.Data);
        }
 protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
 {
     if (targetSegment.IsAttribute)
     {
         this.WriteAttribute(targetSegment);
     }
     else
     {
         this.WriteElement(targetSegment);
     }
 }
Example #15
0
 protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
 {
     if (targetSegment.IsAttribute)
     {
         this.WriteAttribute(targetSegment);
     }
     else
     {
         this.WriteElement(targetSegment);
     }
 }
        private void WriteAttribute(EpmTargetPathSegment targetSegment)
        {
            Debug.Assert(targetSegment.HasContent, "Must have content for attributes");

            EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment];

            currentContent.XmlContentWriter.WriteAttributeString(
                targetSegment.SegmentNamespacePrefix,
                targetSegment.SegmentName.Substring(1),
                targetSegment.SegmentNamespaceUri,
                currentContent.Data);
        }
 /// <summary>
 /// Deserializes the attributes from the <paramref name="reader"/> and sets values on <paramref name="element"/>
 /// </summary>
 /// <param name="reader">Current content reader.</param>
 /// <param name="currentRoot">Segment which has child attribute segments.</param>
 /// <param name="element">Current object.</param>
 /// <param name="resourceType">Resource type of <paramref name="element"/></param>
 private void DeserializeAttributes(XmlReader reader, EpmTargetPathSegment currentRoot, object element, ResourceType resourceType)
 {
     foreach (var attributeSegment in currentRoot.SubSegments.Where(s => s.IsAttribute))
     {
         String attribValue = WebUtil.GetAttributeEx(reader, attributeSegment.SegmentName.Substring(1), attributeSegment.SegmentNamespaceUri);
         if (attribValue != null)
         {
             if (!EpmContentDeSerializerBase.Match(attributeSegment, this.PropertiesApplied))
             {
                 resourceType.SetEpmValue(attributeSegment, element, attribValue, this);
             }
         }
     }
 }
        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
        }
        protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind, DataServiceProviderWrapper provider)
#endif
        {
            if (targetSegment.IsAttribute)
            {
                this.WriteAttribute(targetSegment);
            }
            else
            {
#if ASTORIA_CLIENT
                this.WriteElement(targetSegment);
#else
                this.WriteElement(targetSegment, provider);
#endif
            }
        }
Example #20
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)
#endif
        {
            if (targetSegment.IsAttribute)
            {
                this.WriteAttribute(targetSegment);
            }
            else
            {
#if ASTORIA_CLIENT
                this.WriteElement(targetSegment);
#else
                this.WriteElement(targetSegment, provider);
#endif
            }
        }
Example #21
0
        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);
        }
        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
            }
        }
    }
        private void PopulateData(EpmTargetPathSegment segment, object element)
        {
            if (segment.EpmInfo != null)
            {
                Object propertyValue;

                try
                {
                    propertyValue = segment.EpmInfo.PropValReader.DynamicInvoke(element);
                }
                catch
                (System.Reflection.TargetInvocationException)
                {
                    throw;
                }

                this.Data = propertyValue == null ? String.Empty : ClientConvert.ToString(propertyValue, false);
            }
        }
Example #24
0
        private void WriteElement(EpmTargetPathSegment targetSegment)
        {
            EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment];

            currentContent.XmlContentWriter.WriteStartElement(
                targetSegment.SegmentNamespacePrefix,
                targetSegment.SegmentName,
                targetSegment.SegmentNamespaceUri);

            base.Serialize(targetSegment, EpmSerializationKind.Attributes);

            if (targetSegment.HasContent)
            {
                Debug.Assert(currentContent.Data != null, "Must always have non-null data content value");
                currentContent.XmlContentWriter.WriteString(currentContent.Data);
            }

            base.Serialize(targetSegment, EpmSerializationKind.Elements);

            currentContent.XmlContentWriter.WriteEndElement();
        }
        private void WriteElement(EpmTargetPathSegment targetSegment)
        {
            EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment];

            currentContent.XmlContentWriter.WriteStartElement(
                targetSegment.SegmentNamespacePrefix,
                targetSegment.SegmentName,
                targetSegment.SegmentNamespaceUri);

            base.Serialize(targetSegment, EpmSerializationKind.Attributes);

            if (targetSegment.HasContent)
            {
                Debug.Assert(currentContent.Data != null, "Must always have non-null data content value");
                currentContent.XmlContentWriter.WriteString(currentContent.Data);
            }

            base.Serialize(targetSegment, EpmSerializationKind.Elements);

            currentContent.XmlContentWriter.WriteEndElement();
        }
Example #26
0
        protected virtual void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
        {
            IEnumerable<EpmTargetPathSegment> segmentsToSerialize;
            switch (kind)
            {
                case EpmSerializationKind.Attributes:
                    segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == true);
                    break;
                case EpmSerializationKind.Elements:
                    segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == false);
                    break;
                default:
                    Debug.Assert(kind == EpmSerializationKind.All, "Must serialize everything");
                    segmentsToSerialize = targetSegment.SubSegments;
                    break;
            }

            foreach (EpmTargetPathSegment segment in segmentsToSerialize)
            {
                this.Serialize(segment, kind);
            }
        }
        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
        }
 /// <summary>
 /// Given a segment, writes the element to xml writer corresponding to it, works recursively to write child elements/attributes
 /// </summary>
 /// <param name="targetSegment">Segment being written</param>
 private void WriteElement(EpmTargetPathSegment targetSegment)
        protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
        {
            if (targetSegment.HasContent)
            {
                EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo;
                Object propertyValue;

                try
                {
                    propertyValue = epmInfo.ReadPropertyValue(this.Element);
                }
                catch (System.Reflection.TargetInvocationException)
                {
                    throw;
                }

                String contentType;
                Action<String> contentWriter;

                switch (epmInfo.Attribute.TargetTextContentKind)
                {
                    case SyndicationTextContentKind.Html:
                        contentType = "html";
                        contentWriter = this.Target.WriteString;
                        break;
                    case SyndicationTextContentKind.Xhtml:
                        contentType = "xhtml";
                        contentWriter = this.Target.WriteRaw;
                        break;
                    default:
                        contentType = "text";
                        contentWriter = this.Target.WriteString;
                        break;
                }

                Action<String, bool, bool> textSyndicationWriter = (c, nonTextPossible, atomDateConstruct) =>
                {
                    this.Target.WriteStartElement(c, XmlConstants.AtomNamespace);
                    if (nonTextPossible)
                    {
                        this.Target.WriteAttributeString(XmlConstants.AtomTypeAttributeName, String.Empty, contentType);
                    }

                    String textPropertyValue = 
                        propertyValue != null   ? ClientConvert.ToString(propertyValue, atomDateConstruct) :
                        atomDateConstruct       ? ClientConvert.ToString(DateTime.MinValue, atomDateConstruct) : 
                        String.Empty;

                    contentWriter(textPropertyValue);
                    this.Target.WriteEndElement();
                };

                switch (epmInfo.Attribute.TargetSyndicationItem)
                {
                    case SyndicationItemProperty.AuthorEmail:
                    case SyndicationItemProperty.ContributorEmail:
                        textSyndicationWriter(XmlConstants.AtomEmailElementName, false, false);
                        break;
                    case SyndicationItemProperty.AuthorName:
                    case SyndicationItemProperty.ContributorName:
                        textSyndicationWriter(XmlConstants.AtomNameElementName, false, false);
                        this.authorNamePresent = true;
                        break;
                    case SyndicationItemProperty.AuthorUri:
                    case SyndicationItemProperty.ContributorUri:
                        textSyndicationWriter(XmlConstants.AtomUriElementName, false, false);
                        break;
                    case SyndicationItemProperty.Updated:
                        textSyndicationWriter(XmlConstants.AtomUpdatedElementName, false, true);
                        this.updatedPresent = true;
                        break;
                    case SyndicationItemProperty.Published:
                        textSyndicationWriter(XmlConstants.AtomPublishedElementName, false, true);
                        break;
                    case SyndicationItemProperty.Rights:
                        textSyndicationWriter(XmlConstants.AtomRightsElementName, true, false);
                        break;
                    case SyndicationItemProperty.Summary:
                        textSyndicationWriter(XmlConstants.AtomSummaryElementName, true, false);
                        break;
                    case SyndicationItemProperty.Title:
                        textSyndicationWriter(XmlConstants.AtomTitleElementName, true, false);
                        break;
                    default:
                        Debug.Assert(false, "Unhandled SyndicationItemProperty enum value - should never get here.");
                        break;
                }
            }
            else
            {
                if (targetSegment.SegmentName == XmlConstants.AtomAuthorElementName)
                {
                    this.CreateAuthor(false);
                    base.Serialize(targetSegment, kind);
                    this.FinishAuthor();
                }
                else if (targetSegment.SegmentName == XmlConstants.AtomContributorElementName)
                {
                    this.Target.WriteStartElement(XmlConstants.AtomContributorElementName, XmlConstants.AtomNamespace);
                    base.Serialize(targetSegment, kind);
                    this.Target.WriteEndElement();
                }
                else
                {
                    Debug.Assert(false, "Only authors and contributors have nested elements");
                }
            }
        }
Example #30
0
 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;
 }
 internal EpmCustomContentWriterNodeData(EpmCustomContentWriterNodeData parentData, EpmTargetPathSegment segment, object element)
        private void PopulateData(EpmTargetPathSegment segment, object element)
        {
            if (segment.EpmInfo != null)
            {
                Object propertyValue;

                try
                {
                   propertyValue = segment.EpmInfo.PropValReader.DynamicInvoke(element);

                }
                catch
                (System.Reflection.TargetInvocationException)
                {
                    throw;
                }

               this.Data = propertyValue == null ? String.Empty : ClientConvert.ToString(propertyValue, false );

            }
        }
Example #33
0
        /// <summary>Used for deserializing each of syndication specific content nodes</summary>
        /// <param name="currentRoot">Node in the target path being processed</param>
        /// <param name="resourceType">ResourceType</param>
        /// <param name="element">object being deserialized</param>
        private void DeSerialize(EpmTargetPathSegment currentRoot, ResourceType resourceType, object element)
        {
            foreach (EpmTargetPathSegment newRoot in currentRoot.SubSegments)
            {
                if (newRoot.HasContent)
                {
                    if (!EpmContentDeSerializerBase.Match(newRoot, this.PropertiesApplied))
                    {
                        switch (newRoot.EpmInfo.Attribute.TargetSyndicationItem)
                        {
                        case SyndicationItemProperty.AuthorEmail:
                            if (this.Item.Authors.Count > 0)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Authors[0].Email, this);
                            }

                            break;

                        case SyndicationItemProperty.AuthorName:
                            if (this.Item.Authors.Count > 0)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Authors[0].Name, this);
                            }

                            break;

                        case SyndicationItemProperty.AuthorUri:
                            if (this.Item.Authors.Count > 0)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Authors[0].Uri, this);
                            }

                            break;

                        case SyndicationItemProperty.ContributorEmail:
                            if (this.Item.Contributors.Count > 0)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Contributors[0].Email, this);
                            }

                            break;

                        case SyndicationItemProperty.ContributorName:
                            if (this.Item.Contributors.Count > 0)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Contributors[0].Name, this);
                            }

                            break;

                        case SyndicationItemProperty.ContributorUri:
                            if (this.Item.Contributors.Count > 0)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Contributors[0].Uri, this);
                            }

                            break;

                        case SyndicationItemProperty.Updated:
                            // If this.Item.LastUpdatedTime == DateTimeOffset.MinValue we assume that the date has not been provided
                            // by the user. This is the same assumption Syndication Api does (see Atom10FeedFormatter.WriteItemContents()).
                            // If the date was not provided by the user we should not touch it - otherwise the response will not be
                            // compatible with response sent for the same request and the same resource type but having KeepInContent set to true
                            if (this.Item.LastUpdatedTime > DateTimeOffset.MinValue)
                            {
                                resourceType.SetEpmValue(newRoot, element, XmlConvert.ToString(this.Item.LastUpdatedTime), this);
                            }

                            break;

                        case SyndicationItemProperty.Published:
                            if (this.Item.PublishDate > DateTimeOffset.MinValue)
                            {
                                resourceType.SetEpmValue(newRoot, element, XmlConvert.ToString(this.Item.PublishDate), this);
                            }

                            break;

                        case SyndicationItemProperty.Rights:
                            if (this.Item.Copyright != null)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Copyright.Text, this);
                            }

                            break;

                        case SyndicationItemProperty.Summary:
                            if (this.Item.Summary != null)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Summary.Text, this);
                            }

                            break;

                        case SyndicationItemProperty.Title:
                            if (this.Item.Title != null)
                            {
                                resourceType.SetEpmValue(newRoot, element, this.Item.Title.Text, this);
                            }

                            break;

                        default:
                            Debug.Fail("Unhandled SyndicationItemProperty enum value - should never get here.");
                            break;
                        }
                    }
                }
                else
                {
                    this.DeSerialize(newRoot, resourceType, element);
                }
            }
        }
 /// <summary>Initialize the visitor content for all of root's grandchildren and beyond</summary>
 /// <param name="subSegment">One of root's children</param>
 /// <param name="nullValuedProperties">Null valued properties found during serialization</param>
 /// <param name="provider">Data Service provider used for rights verification.</param>
 private void InitializeSubSegmentVisitorContent(EpmTargetPathSegment subSegment, EpmContentSerializer.EpmNullValuedPropertyTree nullValuedProperties, DataServiceProviderWrapper provider)
 {
     foreach (EpmTargetPathSegment segment in subSegment.SubSegments)
     {
         this.visitorContent.Add(segment, new EpmCustomContentWriterNodeData(this.visitorContent[subSegment], segment, this.Element, nullValuedProperties, provider));
         this.InitializeSubSegmentVisitorContent(segment, nullValuedProperties, provider);
     }
 }
 internal EpmCustomContentWriterNodeData(EpmCustomContentWriterNodeData parentData, EpmTargetPathSegment segment, object element)
 {
     this.XmlContentStream = parentData.XmlContentStream;
     this.XmlContentWriter = parentData.XmlContentWriter;
     this.PopulateData(segment, element);
 }
        /// <summary>Used for deserializing each of syndication specific content nodes</summary>
        /// <param name="currentRoot">Node in the target path being processed</param>
        /// <param name="resourceType">ResourceType</param>
        /// <param name="element">object being deserialized</param>
        private void DeSerialize(EpmTargetPathSegment currentRoot, ResourceType resourceType, object element)
        {
            foreach (EpmTargetPathSegment newRoot in currentRoot.SubSegments)
            {
                if (newRoot.HasContent)
                {
                    if (!EpmContentDeSerializerBase.Match(newRoot, this.PropertiesApplied))
                    {
                        switch (newRoot.EpmInfo.Attribute.TargetSyndicationItem)
                        {
                            case SyndicationItemProperty.AuthorEmail:
                                if (this.Item.Authors.Count > 0)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Authors[0].Email, this);
                                }

                                break;
                            case SyndicationItemProperty.AuthorName:
                                if (this.Item.Authors.Count > 0)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Authors[0].Name, this);
                                }

                                break;
                            case SyndicationItemProperty.AuthorUri:
                                if (this.Item.Authors.Count > 0)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Authors[0].Uri, this);
                                }

                                break;
                            case SyndicationItemProperty.ContributorEmail:
                                if (this.Item.Contributors.Count > 0)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Contributors[0].Email, this);
                                }

                                break;
                            case SyndicationItemProperty.ContributorName:
                                if (this.Item.Contributors.Count > 0)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Contributors[0].Name, this);
                                }

                                break;
                            case SyndicationItemProperty.ContributorUri:
                                if (this.Item.Contributors.Count > 0)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Contributors[0].Uri, this);
                                }

                                break;
                            case SyndicationItemProperty.Updated:
                                // If this.Item.LastUpdatedTime == DateTimeOffset.MinValue we assume that the date has not been provided 
                                // by the user. This is the same assumption Syndication Api does (see Atom10FeedFormatter.WriteItemContents()).
                                // If the date was not provided by the user we should not touch it - otherwise the response will not be  
                                // compatible with response sent for the same request and the same resource type but having KeepInContent set to true
                                if (this.Item.LastUpdatedTime > DateTimeOffset.MinValue)
                                {
                                    resourceType.SetEpmValue(newRoot, element, XmlConvert.ToString(this.Item.LastUpdatedTime), this);
                                }

                                break;
                            case SyndicationItemProperty.Published:
                                if (this.Item.PublishDate > DateTimeOffset.MinValue)
                                {
                                    resourceType.SetEpmValue(newRoot, element, XmlConvert.ToString(this.Item.PublishDate), this);
                                }

                                break;
                            case SyndicationItemProperty.Rights:
                                if (this.Item.Copyright != null)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Copyright.Text, this);
                                }

                                break;
                            case SyndicationItemProperty.Summary:
                                if (this.Item.Summary != null)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Summary.Text, this);
                                }

                                break;
                            case SyndicationItemProperty.Title:
                                if (this.Item.Title != null)
                                {
                                    resourceType.SetEpmValue(newRoot, element, this.Item.Title.Text, this);
                                }

                                break;
                            default:
                                Debug.Fail("Unhandled SyndicationItemProperty enum value - should never get here.");
                                break;
                        }
                    }
                }
                else
                {
                    this.DeSerialize(newRoot, resourceType, element);
                }
            }
        }
        /// <summary>Called internally to deserialize each <see cref="SyndicationElementExtension"/></summary>
        /// <param name="reader">XmlReader for current extension</param>
        /// <param name="currentRoot">Node in the target path being processed</param>
        /// <param name="resourceType">ResourceType</param>
        /// <param name="element">object being deserialized</param>
        private void DeSerialize(XmlReader reader, EpmTargetPathSegment currentRoot, ResourceType resourceType, object element)
        {
            EpmValueBuilder currentValue = new EpmValueBuilder();

            do
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.Element:
                    if (currentRoot.HasContent)
                    {
                        // Throw an exception that we hit mixed-content.
                        // <contentElement>value<someElement /></contentElement>
                        // <contentElement><someElement />value</contentElement>
                        throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                    }

                    String elementName           = reader.LocalName;
                    String namespaceUri          = reader.NamespaceURI;
                    EpmTargetPathSegment newRoot = currentRoot.SubSegments
                                                   .SingleOrDefault(s => s.SegmentNamespaceUri == namespaceUri && s.SegmentName == elementName);
                    if (newRoot == null)
                    {
                        WebUtil.SkipToEnd(reader, elementName, namespaceUri);
                        continue;
                    }

                    currentRoot = newRoot;

                    this.DeserializeAttributes(reader, currentRoot, element, resourceType);

                    if (currentRoot.HasContent)
                    {
                        if (reader.IsEmptyElement)
                        {
                            if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                            {
                                resourceType.SetEpmValue(currentRoot, element, String.Empty, this);
                            }

                            currentRoot = currentRoot.ParentSegment;
                        }
                    }

                    break;

                case XmlNodeType.CDATA:
                case XmlNodeType.Text:
                case XmlNodeType.SignificantWhitespace:
                    if (!currentRoot.HasContent)
                    {
                        // Throw an exception that we hit mixed-content.
                        // <noContentElement>value<contentElement>value</contentElement></noContentElement>
                        // <noContentElement><contentElement>value</contentElement>value</noContentElement>
                        throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                    }

                    currentValue.Append(reader.Value);
                    break;

                case XmlNodeType.EndElement:
                    if (currentRoot.HasContent)
                    {
                        if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                        {
                            resourceType.SetEpmValue(currentRoot, element, currentValue.Value, this);
                        }
                    }

                    currentRoot = currentRoot.ParentSegment;
                    currentValue.Reset();
                    break;

                case XmlNodeType.Comment:
                case XmlNodeType.Whitespace:
                    break;

                case XmlNodeType.None:
                case XmlNodeType.XmlDeclaration:
                case XmlNodeType.Attribute:
                case XmlNodeType.EndEntity:
                case XmlNodeType.EntityReference:
                case XmlNodeType.Entity:
                case XmlNodeType.Document:
                case XmlNodeType.DocumentType:
                case XmlNodeType.DocumentFragment:
                case XmlNodeType.Notation:
                case XmlNodeType.ProcessingInstruction:
                    throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_InvalidXmlEntity);
                }
            }while (currentRoot.ParentSegment != null && reader.Read());
        }
 /// <summary>
 /// Deserializes the attributes from the <paramref name="reader"/> and sets values on <paramref name="element"/>
 /// </summary>
 /// <param name="reader">Current content reader.</param>
 /// <param name="currentRoot">Segment which has child attribute segments.</param>
 /// <param name="element">Current object.</param>
 /// <param name="resourceType">Resource type of <paramref name="element"/></param>
 private void DeserializeAttributes(XmlReader reader, EpmTargetPathSegment currentRoot, object element, ResourceType resourceType)
 {
     foreach (var attributeSegment in currentRoot.SubSegments.Where(s => s.IsAttribute))
     {
         String attribValue = WebUtil.GetAttributeEx(reader, attributeSegment.SegmentName.Substring(1), attributeSegment.SegmentNamespaceUri);
         if (attribValue != null)
         {
             if (!EpmContentDeSerializerBase.Match(attributeSegment, this.PropertiesApplied))
             {
                 resourceType.SetEpmValue(attributeSegment, element, attribValue, this);
             }
         }
     }        
 }
Example #39
0
        internal void Add(EntityPropertyMappingInfo epmInfo)
        {
            String targetName = epmInfo.Attribute.TargetPath;
            bool isSyndication = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
            String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
            String namespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;

            EpmTargetPathSegment currentSegment = isSyndication ? this.SyndicationRoot : this.NonSyndicationRoot;
            IList<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];

                if (targetSegment.Length == 0)
                {
                    throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
                }

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

                EpmTargetPathSegment foundSegment = activeSubSegments.SingleOrDefault(
                                                        segment => segment.SegmentName == targetSegment &&
                                                        (isSyndication || 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.HasContent)
            {
                throw new ArgumentException(Strings.EpmTargetTree_DuplicateEpmAttrsWithSameTargetName(EpmTargetTree.GetPropertyNameFromEpmInfo(currentSegment.EpmInfo), currentSegment.EpmInfo.DefiningType.Name, currentSegment.EpmInfo.Attribute.SourcePath, epmInfo.Attribute.SourcePath));
            }

            if (!epmInfo.Attribute.KeepInContent)
            {
                this.countOfNonContentProperties++;
            }

            currentSegment.EpmInfo = epmInfo;
            
            if (EpmTargetTree.HasMixedContent(this.NonSyndicationRoot, false))
            {
                throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
            }
        }
        /// <summary>
        /// Given a segment, writes the element to xml writer corresponding to it, works recursively to write child elements/attributes
        /// </summary>
        /// <param name="targetSegment">Segment being written</param>
        /// <param name="provider">Data Service provider used for rights verification.</param>
        private void WriteElement(EpmTargetPathSegment targetSegment, DataServiceProviderWrapper provider)
#endif
        {
            // Content to be written in an element 
            EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment];

            currentContent.XmlContentWriter.WriteStartElement(
                targetSegment.SegmentNamespacePrefix,
                targetSegment.SegmentName,
                targetSegment.SegmentNamespaceUri);

#if ASTORIA_CLIENT
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Attributes);
#else
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Attributes, provider);
#endif

            if (targetSegment.HasContent)
            {
                Debug.Assert(currentContent.Data != null, "Must always have non-null data content value");
                currentContent.XmlContentWriter.WriteString(currentContent.Data);
            }

#if ASTORIA_CLIENT
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Elements);
#else
            // Serialize the attributes and children before serializing the data itself
            base.Serialize(targetSegment, EpmSerializationKind.Elements, provider);
#endif

            currentContent.XmlContentWriter.WriteEndElement();
        }
Example #41
0
 /// <summary>
 /// Internal interface to be overridden in the subclasses.
 /// Goes through each subsegments and invokes itself for the children
 /// </summary>
 /// <param name="targetSegment">Current root segment in the target tree</param>
 /// <param name="kind">Which sub segments to serialize</param>
 protected virtual void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
 /// <summary>Initialize the visitor content for all of root's grandchildren and beyond</summary>
 /// <param name="subSegment">One of root's children</param>
 private void InitializeSubSegmentVisitorContent(EpmTargetPathSegment subSegment)
 {
     foreach (EpmTargetPathSegment segment in subSegment.SubSegments)
     {
         this.visitorContent.Add(segment, new EpmCustomContentWriterNodeData(this.visitorContent[subSegment], segment, this.Element));
         this.InitializeSubSegmentVisitorContent(segment);
     }
 }
        protected virtual void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind, DataServiceProviderWrapper provider)
#endif
        {
            IEnumerable<EpmTargetPathSegment> segmentsToSerialize;
            switch (kind)
            {
                case EpmSerializationKind.Attributes:
                    segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == true);
                    break;
                case EpmSerializationKind.Elements:
                    segmentsToSerialize = targetSegment.SubSegments.Where(s => s.IsAttribute == false);
                    break;
                default:
                    Debug.Assert(kind == EpmSerializationKind.All, "Must serialize everything");
                    segmentsToSerialize = targetSegment.SubSegments;
                    break;
            }

            foreach (EpmTargetPathSegment segment in segmentsToSerialize)
            {
#if ASTORIA_CLIENT
                this.Serialize(segment, kind);
#else
                this.Serialize(segment, kind, provider);
#endif
            }
        }
 /// <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>
 protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
 protected virtual void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
 private void PopulateData(EpmTargetPathSegment segment, object element)
 /// <summary>
 /// Matches the targetSegment with properties already applied and if finds something already applied considers it a match
 /// </summary>
 /// <param name="targetSegment">Target segment for which existing property application is checked for</param>
 /// <param name="propertiesApplied">Properties already applied based on content</param>
 /// <returns>true if already the property for the current segment has been applied</returns>
 internal static bool Match(EpmTargetPathSegment targetSegment, EpmContentDeSerializer.EpmAppliedPropertyInfo propertiesApplied)
 {
     if (!targetSegment.EpmInfo.Attribute.KeepInContent)
     {
         return propertiesApplied.Lookup(targetSegment.EpmInfo.Attribute.SourcePath);
     }
     else
     {
         return true;
     }
 }
Example #48
0
 /// <summary>
 /// Given a segment, writes the element to xml writer corresponding to it, works recursively to write child elements/attributes
 /// </summary>
 /// <param name="targetSegment">Segment being written</param>
 private void WriteElement(EpmTargetPathSegment targetSegment)
        /// <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);
            }
        }
Example #50
0
        internal void Add(EntityPropertyMappingInfo epmInfo)
        {
            String targetName      = epmInfo.Attribute.TargetPath;
            bool   isSyndication   = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
            String namespaceUri    = epmInfo.Attribute.TargetNamespaceUri;
            String namespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;

            EpmTargetPathSegment         currentSegment    = isSyndication ? this.SyndicationRoot : this.NonSyndicationRoot;
            IList <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];

                if (targetSegment.Length == 0)
                {
                    throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
                }

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

                EpmTargetPathSegment foundSegment = activeSubSegments.SingleOrDefault(
                    segment => segment.SegmentName == targetSegment &&
                    (isSyndication || 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.HasContent)
            {
                throw new ArgumentException(Strings.EpmTargetTree_DuplicateEpmAttrsWithSameTargetName(EpmTargetTree.GetPropertyNameFromEpmInfo(currentSegment.EpmInfo), currentSegment.EpmInfo.DefiningType.Name, currentSegment.EpmInfo.Attribute.SourcePath, epmInfo.Attribute.SourcePath));
            }

            if (!epmInfo.Attribute.KeepInContent)
            {
                this.countOfNonContentProperties++;
            }

            currentSegment.EpmInfo = epmInfo;

            if (EpmTargetTree.HasMixedContent(this.NonSyndicationRoot, false))
            {
                throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
            }
        }
        /// <summary>Called internally to deserialize each <see cref="SyndicationElementExtension"/></summary>
        /// <param name="reader">XmlReader for current extension</param>
        /// <param name="currentRoot">Node in the target path being processed</param>
        /// <param name="resourceType">ResourceType</param>
        /// <param name="element">object being deserialized</param>
        private void DeSerialize(XmlReader reader, EpmTargetPathSegment currentRoot, ResourceType resourceType, object element)
        {
            EpmValueBuilder currentValue = new EpmValueBuilder();

            do
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (currentRoot.HasContent)
                        {
                            // Throw an exception that we hit mixed-content.
                            // <contentElement>value<someElement /></contentElement>
                            // <contentElement><someElement />value</contentElement>
                            throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                        }

                        String elementName = reader.LocalName;
                        String namespaceUri = reader.NamespaceURI;
                        EpmTargetPathSegment newRoot = currentRoot.SubSegments
                                                                  .SingleOrDefault(s => s.SegmentNamespaceUri == namespaceUri && s.SegmentName == elementName);
                        if (newRoot == null)
                        {
                            WebUtil.SkipToEnd(reader, elementName, namespaceUri);
                            continue;
                        }

                        currentRoot = newRoot;
                        
                        this.DeserializeAttributes(reader, currentRoot, element, resourceType);
                        
                        if (currentRoot.HasContent)
                        {
                            if (reader.IsEmptyElement)
                            {
                                if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                                {
                                    resourceType.SetEpmValue(currentRoot, element, String.Empty, this);
                                }

                                currentRoot = currentRoot.ParentSegment;
                            }
                        }
                        
                        break;

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                    case XmlNodeType.SignificantWhitespace:
                        if (!currentRoot.HasContent)
                        {
                            // Throw an exception that we hit mixed-content.
                            // <noContentElement>value<contentElement>value</contentElement></noContentElement>
                            // <noContentElement><contentElement>value</contentElement>value</noContentElement>
                            throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_MixedContent(resourceType.FullName));
                        }

                        currentValue.Append(reader.Value);
                        break;
                        
                    case XmlNodeType.EndElement:
                        if (currentRoot.HasContent)
                        {
                            if (!EpmContentDeSerializerBase.Match(currentRoot, this.PropertiesApplied))
                            {
                                resourceType.SetEpmValue(currentRoot, element, currentValue.Value, this);
                            }
                        }

                        currentRoot = currentRoot.ParentSegment;
                        currentValue.Reset();
                        break;

                    case XmlNodeType.Comment:
                    case XmlNodeType.Whitespace:
                        break;

                    case XmlNodeType.None:
                    case XmlNodeType.XmlDeclaration:
                    case XmlNodeType.Attribute:
                    case XmlNodeType.EndEntity:
                    case XmlNodeType.EntityReference:
                    case XmlNodeType.Entity:
                    case XmlNodeType.Document:
                    case XmlNodeType.DocumentType:
                    case XmlNodeType.DocumentFragment:
                    case XmlNodeType.Notation:
                    case XmlNodeType.ProcessingInstruction:
                        throw DataServiceException.CreateBadRequestError(Strings.EpmDeserialize_InvalidXmlEntity);
                }
            }
            while (currentRoot.ParentSegment != null && reader.Read());
        }
Example #52
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>
 protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
        /// <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>
        protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)
        {
            if (targetSegment.HasContent)
            {
                EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo;
                Object propertyValue;

                try
                {
                    propertyValue = epmInfo.ReadPropertyValue(this.Element);
                }
                catch (System.Reflection.TargetInvocationException)
                {
                    throw;
                }

                String contentType;
                Action<String> contentWriter;

                switch (epmInfo.Attribute.TargetTextContentKind)
                {
                    case SyndicationTextContentKind.Html:
                        contentType = "html";
                        contentWriter = this.Target.WriteString;
                        break;
                    case SyndicationTextContentKind.Xhtml:
                        contentType = "xhtml";
                        contentWriter = this.Target.WriteRaw;
                        break;
                    default:
                        contentType = "text";
                        contentWriter = this.Target.WriteString;
                        break;
                }

                Action<String, bool, bool> textSyndicationWriter = (c, nonTextPossible, atomDateConstruct) =>
                {
                    this.Target.WriteStartElement(c, XmlConstants.AtomNamespace);
                    if (nonTextPossible)
                    {
                        this.Target.WriteAttributeString(XmlConstants.AtomTypeAttributeName, String.Empty, contentType);
                    }

                    // As per atomPub spec dateConstructs must contain valid datetime. Therefore we need to fill atom:updated/atom:published 
                    // field with something (e.g. DateTimeOffset.MinValue) if the user wants to map null to either of these fields. This will 
                    // satisfy protocol requirements and Syndication API. Note that the content will still contain information saying that the 
                    // mapped property is supposed to be null - therefore the server will know that the actual value sent by the user is null.
                    // For all other elements we can use empty string since the content is not validated.
                    String textPropertyValue = 
                        propertyValue != null   ? ClientConvert.ToString(propertyValue, atomDateConstruct) :
                        atomDateConstruct       ? ClientConvert.ToString(DateTime.MinValue, atomDateConstruct) : 
                        String.Empty;

                    contentWriter(textPropertyValue);
                    this.Target.WriteEndElement();
                };

                switch (epmInfo.Attribute.TargetSyndicationItem)
                {
                    case SyndicationItemProperty.AuthorEmail:
                    case SyndicationItemProperty.ContributorEmail:
                        textSyndicationWriter(XmlConstants.AtomEmailElementName, false, false);
                        break;
                    case SyndicationItemProperty.AuthorName:
                    case SyndicationItemProperty.ContributorName:
                        textSyndicationWriter(XmlConstants.AtomNameElementName, false, false);
                        this.authorNamePresent = true;
                        break;
                    case SyndicationItemProperty.AuthorUri:
                    case SyndicationItemProperty.ContributorUri:
                        textSyndicationWriter(XmlConstants.AtomUriElementName, false, false);
                        break;
                    case SyndicationItemProperty.Updated:
                        textSyndicationWriter(XmlConstants.AtomUpdatedElementName, false, true);
                        this.updatedPresent = true;
                        break;
                    case SyndicationItemProperty.Published:
                        textSyndicationWriter(XmlConstants.AtomPublishedElementName, false, true);
                        break;
                    case SyndicationItemProperty.Rights:
                        textSyndicationWriter(XmlConstants.AtomRightsElementName, true, false);
                        break;
                    case SyndicationItemProperty.Summary:
                        textSyndicationWriter(XmlConstants.AtomSummaryElementName, true, false);
                        break;
                    case SyndicationItemProperty.Title:
                        textSyndicationWriter(XmlConstants.AtomTitleElementName, true, false);
                        break;
                    default:
                        Debug.Assert(false, "Unhandled SyndicationItemProperty enum value - should never get here.");
                        break;
                }
            }
            else
            {
                if (targetSegment.SegmentName == XmlConstants.AtomAuthorElementName)
                {
                    this.CreateAuthor(false);
                    base.Serialize(targetSegment, kind);
                    this.FinishAuthor();
                }
                else if (targetSegment.SegmentName == XmlConstants.AtomContributorElementName)
                {
                    this.Target.WriteStartElement(XmlConstants.AtomContributorElementName, XmlConstants.AtomNamespace);
                    base.Serialize(targetSegment, kind);
                    this.Target.WriteEndElement();
                }
                else
                {
                    Debug.Assert(false, "Only authors and contributors have nested elements");
                }
            }
        }