コード例 #1
0
        /// <summary>
        /// Constructor which creates an empty root.
        /// </summary>
        /// <param name="epmTargetTree">Target xml tree</param>
        internal EpmSourceTree(EpmTargetTree epmTargetTree)
        {
            DebugUtils.CheckNoExternalCallers();

            this.root          = new EpmSourcePathSegment();
            this.epmTargetTree = epmTargetTree;
        }
コード例 #2
0
ファイル: EpmSourceTree.cs プロジェクト: modulexcite/pash-1
 private static void Validate(EpmSourcePathSegment pathSegment, IEdmType type)
 {
     foreach (EpmSourcePathSegment segment in pathSegment.SubProperties)
     {
         IEdmTypeReference propertyType = GetPropertyType(type, segment.PropertyName);
         IEdmType          type2        = (propertyType == null) ? null : propertyType.Definition;
         Validate(segment, type2);
     }
 }
コード例 #3
0
        /// <summary>
        /// Validates the specified segment and all its subsegments.
        /// </summary>
        /// <param name="pathSegment">The path segment to validate.</param>
        /// <param name="type">The type of the property represented by this segment (null for open properties).</param>
        private static void Validate(EpmSourcePathSegment pathSegment, IEdmType type)
        {
            Debug.Assert(pathSegment != null, "pathSegment != null");

            foreach (EpmSourcePathSegment subSegment in pathSegment.SubProperties)
            {
                IEdmTypeReference subSegmentTypeReference = GetPropertyType(type, subSegment.PropertyName);
                IEdmType          subSegmentType          = subSegmentTypeReference == null ? null : subSegmentTypeReference.Definition;

                Validate(subSegment, subSegmentType);
            }
        }
コード例 #4
0
ファイル: EpmSourceTree.cs プロジェクト: modulexcite/pash-1
        internal void Add(EntityPropertyMappingInfo epmInfo)
        {
            List <EpmSourcePathSegment> list     = new List <EpmSourcePathSegment>();
            EpmSourcePathSegment        root     = this.Root;
            EpmSourcePathSegment        segment2 = null;
            IEdmType actualPropertyType          = epmInfo.ActualPropertyType;

            string[] strArray = epmInfo.Attribute.SourcePath.Split(new char[] { '/' });
            int      length   = strArray.Length;

            for (int i = 0; i < length; i++)
            {
                string propertyName = strArray[i];
                if (propertyName.Length == 0)
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath));
                }
                IEdmTypeReference propertyType = GetPropertyType(actualPropertyType, propertyName);
                IEdmType          type2        = (propertyType == null) ? null : propertyType.Definition;
                if ((type2 == null) && (i < (length - 1)))
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_OpenComplexPropertyCannotBeMapped(propertyName, actualPropertyType.ODataFullName()));
                }
                actualPropertyType = type2;
                segment2           = root.SubProperties.SingleOrDefault <EpmSourcePathSegment>(e => e.PropertyName == propertyName);
                if (segment2 != null)
                {
                    root = segment2;
                }
                else
                {
                    EpmSourcePathSegment item = new EpmSourcePathSegment(propertyName);
                    root.SubProperties.Add(item);
                    root = item;
                }
                list.Add(root);
            }
            if ((actualPropertyType != null) && !actualPropertyType.IsODataPrimitiveTypeKind())
            {
                throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_EndsWithNonPrimitiveType(root.PropertyName));
            }
            if (segment2 != null)
            {
                if (segment2.EpmInfo.DefiningTypesAreEqual(epmInfo))
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_DuplicateEpmAttributesWithSameSourceName(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath));
                }
                this.epmTargetTree.Remove(segment2.EpmInfo);
            }
            epmInfo.SetPropertyValuePath(list.ToArray());
            root.EpmInfo = epmInfo;
            this.epmTargetTree.Add(epmInfo);
        }
コード例 #5
0
ファイル: EpmSourceTree.cs プロジェクト: nickchal/pash
 internal void Add(EntityPropertyMappingInfo epmInfo)
 {
     List<EpmSourcePathSegment> list = new List<EpmSourcePathSegment>();
     EpmSourcePathSegment root = this.Root;
     EpmSourcePathSegment segment2 = null;
     IEdmType actualPropertyType = epmInfo.ActualPropertyType;
     string[] strArray = epmInfo.Attribute.SourcePath.Split(new char[] { '/' });
     int length = strArray.Length;
     for (int i = 0; i < length; i++)
     {
         string propertyName = strArray[i];
         if (propertyName.Length == 0)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath));
         }
         IEdmTypeReference propertyType = GetPropertyType(actualPropertyType, propertyName);
         IEdmType type2 = (propertyType == null) ? null : propertyType.Definition;
         if ((type2 == null) && (i < (length - 1)))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_OpenComplexPropertyCannotBeMapped(propertyName, actualPropertyType.ODataFullName()));
         }
         actualPropertyType = type2;
         segment2 = root.SubProperties.SingleOrDefault<EpmSourcePathSegment>(e => e.PropertyName == propertyName);
         if (segment2 != null)
         {
             root = segment2;
         }
         else
         {
             EpmSourcePathSegment item = new EpmSourcePathSegment(propertyName);
             root.SubProperties.Add(item);
             root = item;
         }
         list.Add(root);
     }
     if ((actualPropertyType != null) && !actualPropertyType.IsODataPrimitiveTypeKind())
     {
         throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_EndsWithNonPrimitiveType(root.PropertyName));
     }
     if (segment2 != null)
     {
         if (segment2.EpmInfo.DefiningTypesAreEqual(epmInfo))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_DuplicateEpmAttributesWithSameSourceName(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath));
         }
         this.epmTargetTree.Remove(segment2.EpmInfo);
     }
     epmInfo.SetPropertyValuePath(list.ToArray());
     root.EpmInfo = epmInfo;
     this.epmTargetTree.Add(epmInfo);
 }
コード例 #6
0
        /// <summary>
        /// Adds a path to the source and target tree which is obtained by looking at the EntityPropertyMappingAttribute in the <paramref name="epmInfo"/>
        /// </summary>
        /// <param name="epmInfo">EnitityPropertyMappingInfo holding the source path</param>
        internal void Add(EntityPropertyMappingInfo epmInfo)
        {
            DebugUtils.CheckNoExternalCallers();

            List <EpmSourcePathSegment> pathToCurrentSegment = new List <EpmSourcePathSegment>();
            EpmSourcePathSegment        currentSourceSegment = this.Root;
            EpmSourcePathSegment        foundSourceSegment   = null;
            IEdmType currentType = epmInfo.ActualPropertyType;

            Debug.Assert(!string.IsNullOrEmpty(epmInfo.Attribute.SourcePath), "Invalid source path");
            string[] propertyPath = epmInfo.Attribute.SourcePath.Split('/');

            int propertyPathLength = propertyPath.Length;

            Debug.Assert(propertyPathLength > 0, "Must have been validated during EntityPropertyMappingAttribute construction");
            for (int sourcePropertyIndex = 0; sourcePropertyIndex < propertyPathLength; sourcePropertyIndex++)
            {
                string propertyName = propertyPath[sourcePropertyIndex];

                if (propertyName.Length == 0)
                {
                    throw new ODataException(ODataErrorStrings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath));
                }

                IEdmTypeReference nextPropertyTypeReference = GetPropertyType(currentType, propertyName);
                IEdmType          nextPropertyType          = nextPropertyTypeReference == null ? null : nextPropertyTypeReference.Definition;

                // If we don't find a property type this is an open property; check whether this is the last segment in the path
                // since otherwise this would not be an open primitive property and only open primitive properties are allowed.
                if (nextPropertyType == null && sourcePropertyIndex < propertyPathLength - 1)
                {
                    throw new ODataException(ODataErrorStrings.EpmSourceTree_OpenComplexPropertyCannotBeMapped(propertyName, currentType.ODataFullName()));
                }

                currentType        = nextPropertyType;
                foundSourceSegment = currentSourceSegment.SubProperties.SingleOrDefault(e => e.PropertyName == propertyName);
                if (foundSourceSegment != null)
                {
                    currentSourceSegment = foundSourceSegment;
                }
                else
                {
                    EpmSourcePathSegment newSourceSegment = new EpmSourcePathSegment(propertyName);
                    currentSourceSegment.SubProperties.Add(newSourceSegment);
                    currentSourceSegment = newSourceSegment;
                }

                pathToCurrentSegment.Add(currentSourceSegment);
            }

            // The last segment is the one being mapped from by the user specified attribute.
            // It must be a primitive type - we don't allow mappings of anything else than primitive properties directly.
            // Note that we can only verify this for non-open properties, for open properties we must assume it's a primitive type
            // and we will make this check later during serialization again when we actually have the value of the property.
            if (currentType != null)
            {
                if (!currentType.IsODataPrimitiveTypeKind())
                {
                    throw new ODataException(ODataErrorStrings.EpmSourceTree_EndsWithNonPrimitiveType(currentSourceSegment.PropertyName));
                }
            }

            Debug.Assert(foundSourceSegment == null || foundSourceSegment.EpmInfo != null, "Can't have a leaf node in the tree without EpmInfo.");

            // Two EpmAttributes with same PropertyName in the same type, this could be a result of inheritance
            if (foundSourceSegment != null)
            {
                Debug.Assert(object.ReferenceEquals(foundSourceSegment, currentSourceSegment), "currentSourceSegment variable should have been updated already to foundSourceSegment");

                // Check for duplicates on the same entity type
                Debug.Assert(foundSourceSegment.SubProperties.Count == 0, "If non-leaf, it means we allowed complex type to be a leaf node");
                if (foundSourceSegment.EpmInfo.DefiningTypesAreEqual(epmInfo))
                {
                    throw new ODataException(ODataErrorStrings.EpmSourceTree_DuplicateEpmAttributesWithSameSourceName(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath));
                }

                // In case of inheritance, we need to remove the node from target tree which was mapped to base type property
                this.epmTargetTree.Remove(foundSourceSegment.EpmInfo);
            }

            epmInfo.SetPropertyValuePath(pathToCurrentSegment.ToArray());
            currentSourceSegment.EpmInfo = epmInfo;

            this.epmTargetTree.Add(epmInfo);
        }
コード例 #7
0
        /// <summary>
        /// Write the content of the given entry.
        /// </summary>
        /// <param name="entry">The entry for which to write properties.</param>
        /// <param name="entryType">The <see cref="IEdmEntityType"/> of the entry (or null if not metadata is available).</param>
        /// <param name="propertiesValueCache">The cache of properties.</param>
        /// <param name="rootSourcePathSegment">The root of the EPM source tree, if there's an EPM applied.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        private void WriteEntryContent(
            ODataEntry entry,
            IEdmEntityType entryType, 
            EntryPropertiesValueCache propertiesValueCache, 
            EpmSourcePathSegment rootSourcePathSegment,
            ProjectedPropertiesAnnotation projectedProperties)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(propertiesValueCache != null, "propertiesValueCache != null");

            ODataStreamReferenceValue mediaResource = entry.MediaResource;
            if (mediaResource == null)
            {
                // <content type="application/xml">
                this.atomOutputContext.XmlWriter.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomContentElementName,
                    AtomConstants.AtomNamespace);

                this.atomOutputContext.XmlWriter.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    MimeConstants.MimeApplicationXml);

                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();
                this.atomEntryAndFeedSerializer.WriteProperties(
                    entryType,
                    propertiesValueCache.EntryProperties,
                    false /* isWritingCollection */,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd,
                    this.DuplicatePropertyNamesChecker,
                    propertiesValueCache,
                    rootSourcePathSegment,
                    projectedProperties);
                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();

                // </content>
                this.atomOutputContext.XmlWriter.WriteEndElement();
            }
            else
            {
                WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true);

                this.atomEntryAndFeedSerializer.WriteEntryMediaEditLink(mediaResource);

                if (mediaResource.ReadLink != null)
                {
                    // <content type="type" src="src">
                    this.atomOutputContext.XmlWriter.WriteStartElement(
                        AtomConstants.AtomNamespacePrefix,
                        AtomConstants.AtomContentElementName,
                        AtomConstants.AtomNamespace);

                    Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now. If we have a read link we must have a non-empty content type as well.");
                    this.atomOutputContext.XmlWriter.WriteAttributeString(
                        AtomConstants.AtomTypeAttributeName,
                        mediaResource.ContentType);

                    this.atomOutputContext.XmlWriter.WriteAttributeString(
                        AtomConstants.MediaLinkEntryContentSourceAttributeName,
                        this.atomEntryAndFeedSerializer.UriToUrlAttributeValue(mediaResource.ReadLink));

                    // </content>
                    this.atomOutputContext.XmlWriter.WriteEndElement();
                }

                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();
                this.atomEntryAndFeedSerializer.WriteProperties(
                    entryType,
                    propertiesValueCache.EntryProperties, 
                    false /* isWritingCollection */,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd,
                    this.DuplicatePropertyNamesChecker,
                    propertiesValueCache,
                    rootSourcePathSegment,
                    projectedProperties);
                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();
            }
        }
コード例 #8
0
ファイル: ODataAtomWriter.cs プロジェクト: nickchal/pash
 private void WriteEntryContent(ODataEntry entry, IEdmEntityType entryType, EntryPropertiesValueCache propertiesValueCache, EpmSourcePathSegment rootSourcePathSegment, ProjectedPropertiesAnnotation projectedProperties)
 {
     ODataStreamReferenceValue mediaResource = entry.MediaResource;
     if (mediaResource == null)
     {
         this.atomOutputContext.XmlWriter.WriteStartElement("", "content", "http://www.w3.org/2005/Atom");
         this.atomOutputContext.XmlWriter.WriteAttributeString("type", "application/xml");
         this.atomEntryAndFeedSerializer.WriteProperties(entryType, propertiesValueCache.EntryProperties, false, new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart), new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd), base.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties);
         this.atomOutputContext.XmlWriter.WriteEndElement();
     }
     else
     {
         WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true);
         this.atomEntryAndFeedSerializer.WriteEntryMediaEditLink(mediaResource);
         if (mediaResource.ReadLink != null)
         {
             this.atomOutputContext.XmlWriter.WriteStartElement("", "content", "http://www.w3.org/2005/Atom");
             this.atomOutputContext.XmlWriter.WriteAttributeString("type", mediaResource.ContentType);
             this.atomOutputContext.XmlWriter.WriteAttributeString("src", this.atomEntryAndFeedSerializer.UriToUrlAttributeValue(mediaResource.ReadLink));
             this.atomOutputContext.XmlWriter.WriteEndElement();
         }
         this.atomEntryAndFeedSerializer.WriteProperties(entryType, propertiesValueCache.EntryProperties, false, new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart), new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd), base.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties);
     }
 }
コード例 #9
0
ファイル: EpmSourceTree.cs プロジェクト: nickchal/pash
 private static void Validate(EpmSourcePathSegment pathSegment, IEdmType type)
 {
     foreach (EpmSourcePathSegment segment in pathSegment.SubProperties)
     {
         IEdmTypeReference propertyType = GetPropertyType(type, segment.PropertyName);
         IEdmType type2 = (propertyType == null) ? null : propertyType.Definition;
         Validate(segment, type2);
     }
 }