Beispiel #1
0
        /// <summary>
        /// Create contextUrlInfo for delta
        /// </summary>
        /// <param name="typeContext">The ODataResourceTypeContext to be used.</param>
        /// <param name="version">The OData version of the response.</param>
        /// <param name="kind">The delta kind.</param>
        /// <param name="odataUri">The odata uri info for current query.</param>
        /// <returns>The generated ODataContextUrlInfo.</returns>
        internal static ODataContextUrlInfo Create(ODataResourceTypeContext typeContext, ODataVersion version, ODataDeltaKind kind, ODataUri odataUri = null)
        {
            Debug.Assert(typeContext != null, "typeContext != null");

            ODataContextUrlInfo contextUriInfo = new ODataContextUrlInfo()
            {
                IsUnknownEntitySet          = typeContext.NavigationSourceKind == EdmNavigationSourceKind.UnknownEntitySet,
                NavigationSource            = typeContext.NavigationSourceName,
                TypeCast                    = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedResourceTypeName ? null : typeContext.ExpectedResourceTypeName,
                TypeName                    = typeContext.NavigationSourceEntityTypeName,
                IncludeFragmentItemSelector = kind == ODataDeltaKind.Resource && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton,
                DeltaKind                   = kind,
                NavigationPath              = ComputeNavigationPath(typeContext.NavigationSourceKind, null, typeContext.NavigationSourceName),
            };

            // Only use odata uri in with model case.
            if (typeContext is ODataResourceTypeContext.ODataResourceTypeContextWithModel)
            {
                contextUriInfo.NavigationPath = ComputeNavigationPath(typeContext.NavigationSourceKind, odataUri,
                                                                      typeContext.NavigationSourceName);
                contextUriInfo.ResourcePath = ComputeResourcePath(odataUri);
                contextUriInfo.QueryClause  = ComputeQueryClause(odataUri, version);
                contextUriInfo.IsUndeclared = ComputeIfIsUndeclared(odataUri);
            }

            return(contextUriInfo);
        }
        /// <summary>
        /// Create contextUrlInfo for delta
        /// </summary>
        /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param>
        /// <param name="kind">The delta kind.</param>
        /// <param name="odataUri">The odata uri info for current query.</param>
        /// <returns>The generated ODataContextUrlInfo.</returns>
        internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataUri odataUri = null)
        {
            Debug.Assert(typeContext != null, "typeContext != null");

            ODataContextUrlInfo contextUriInfo = new ODataContextUrlInfo()
            {
                isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet,
                IsUnknownEntitySet = typeContext.NavigationSourceKind == EdmNavigationSourceKind.UnknownEntitySet,
                navigationSource = typeContext.NavigationSourceName,
                TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName,
                TypeName = typeContext.NavigationSourceEntityTypeName,
                IncludeFragmentItemSelector = kind == ODataDeltaKind.Entry && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton,
                DeltaKind = kind,
            };

            // Only use odata uri in with model case.
            if (typeContext is ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel)
            {
                contextUriInfo.odataUri = odataUri;
            }

            return contextUriInfo;
        }
Beispiel #3
0
        private Uri CreateDeltaResponseContextUri(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind)
        {
            ODataContextUrlInfo info = ODataContextUrlInfo.Create(typeContext, kind);
            Uri contextUrl           = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.Delta, info);

            contextUrl.Should().NotBeNull();
            return(contextUrl);
        }
        /// <summary>
        /// Create contextUrlInfo for delta
        /// </summary>
        /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param>
        /// <param name="kind">The delta kind.</param>
        /// <param name="odataUri">The odata uri info for current query.</param>
        /// <returns>The generated ODataContextUrlInfo.</returns>
        internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataUri odataUri = null)
        {
            Debug.Assert(typeContext != null, "typeContext != null");

            ODataContextUrlInfo contextUriInfo = new ODataContextUrlInfo()
            {
                isContained                 = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet,
                navigationSource            = typeContext.NavigationSourceName,
                TypeCast                    = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName,
                TypeName                    = typeContext.NavigationSourceEntityTypeName,
                IncludeFragmentItemSelector = kind == ODataDeltaKind.Entry && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton,
                DeltaKind                   = kind,
            };

            // Only use odata uri in with model case.
            if (typeContext is ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel)
            {
                contextUriInfo.odataUri = odataUri;
            }

            return(contextUriInfo);
        }
 /// <summary>
 /// Writes the context uri for a delta (deleted) link.
 /// </summary>
 /// <param name="kind">The delta kind of link.</param>
 private void WriteDeltaLinkContextUri(ODataDeltaKind kind)
 {
     Debug.Assert(kind == ODataDeltaKind.Link || kind == ODataDeltaKind.DeletedLink, "kind must be either DeltaLink or DeltaDeletedLink.");
     this.jsonLightEntryAndFeedSerializer.WriteDeltaContextUri(this.CurrentDeltaLinkScope.GetOrCreateTypeContext(this.jsonLightOutputContext.Model), kind);
 }
Beispiel #6
0
        private ODataPayloadKind ParseContextUriFragment(string fragment, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict, out bool isUndeclared)
        {
            bool           hasItemSelector = false;
            ODataDeltaKind kind            = ODataDeltaKind.None;

            isUndeclared = false;

            // Deal with /$entity
            if (fragment.EndsWith(ODataConstants.ContextUriFragmentItemSelector, StringComparison.Ordinal))
            {
                hasItemSelector = true;
                fragment        = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriFragmentItemSelector.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeltaResourceSet, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.ResourceSet;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeltaResourceSet.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeletedEntry, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.DeletedEntry;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeletedEntry.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeltaLink, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.Link;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeltaLink.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeletedLink, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.DeletedLink;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeletedLink.Length);
            }

            this.parseResult.DeltaKind = kind;

            // Deal with query option
            if (fragment.EndsWith(")", StringComparison.Ordinal))
            {
                int index = fragment.Length - 2;
                for (int rcount = 1; rcount > 0 && index > 0; --index)
                {
                    switch (fragment[index])
                    {
                    case '(':
                        rcount--;
                        break;

                    case ')':
                        rcount++;
                        break;
                    }
                }

                if (index == 0)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                string previous = fragment.Substring(0, index + 1);

                // Don't treat Collection(Edm.Type) as SelectExpand segment
                if (!previous.Equals("Collection"))
                {
                    string selectExpandStr = fragment.Substring(index + 2);
                    selectExpandStr = selectExpandStr.Substring(0, selectExpandStr.Length - 1);

                    // Do not treat Key as SelectExpand segment
                    if (KeyPattern.IsMatch(selectExpandStr))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_LastSegmentIsKeySegment(UriUtils.UriToString(this.parseResult.ContextUri)));
                    }

                    this.parseResult.SelectQueryOption = ExtractSelectQueryOption(selectExpandStr);
                    fragment = previous;
                }
            }

            ODataPayloadKind detectedPayloadKind = ODataPayloadKind.Unsupported;
            EdmTypeResolver  edmTypeResolver     = new EdmTypeReaderResolver(this.model, clientCustomTypeResolver);

            if (!fragment.Contains(ODataConstants.UriSegmentSeparator) && !hasItemSelector && kind == ODataDeltaKind.None)
            {
                // Service document: no fragment
                if (fragment.Length == 0)
                {
                    detectedPayloadKind = ODataPayloadKind.ServiceDocument;
                }
                else if (fragment.Equals(ODataConstants.CollectionPrefix + "(" + ODataConstants.EntityReferenceSegmentName + ")"))
                {
                    detectedPayloadKind = ODataPayloadKind.EntityReferenceLinks;
                }
                else if (fragment.Equals(ODataConstants.EntityReferenceSegmentName))
                {
                    detectedPayloadKind = ODataPayloadKind.EntityReferenceLink;
                }
                else
                {
                    var foundNavigationSource = this.model.FindDeclaredNavigationSource(fragment);

                    if (foundNavigationSource != null)
                    {
                        // Resource Set: {schema.entity-container.entity-set} or Singleton: {schema.entity-container.singleton}
                        this.parseResult.NavigationSource = foundNavigationSource;
                        this.parseResult.EdmType          = edmTypeResolver.GetElementType(foundNavigationSource);
                        detectedPayloadKind = foundNavigationSource is IEdmSingleton ? ODataPayloadKind.Resource : ODataPayloadKind.ResourceSet;
                    }
                    else
                    {
                        // Property: {schema.type} or Collection({schema.type}) where schema.type is primitive or complex.
                        detectedPayloadKind = this.ResolveType(fragment, clientCustomTypeResolver, throwIfMetadataConflict);
                        Debug.Assert(
                            this.parseResult.EdmType.TypeKind == EdmTypeKind.Primitive || this.parseResult.EdmType.TypeKind == EdmTypeKind.Enum || this.parseResult.EdmType.TypeKind == EdmTypeKind.TypeDefinition || this.parseResult.EdmType.TypeKind == EdmTypeKind.Complex || this.parseResult.EdmType.TypeKind == EdmTypeKind.Collection || this.parseResult.EdmType.TypeKind == EdmTypeKind.Entity || this.parseResult.EdmType.TypeKind == EdmTypeKind.Untyped,
                            "The first context URI segment must be a set or a non-entity type.");
                    }
                }
            }
            else
            {
                Debug.Assert(this.parseResult.MetadataDocumentUri.IsAbsoluteUri, "this.parseResult.MetadataDocumentUri.IsAbsoluteUri");

                string metadataDocumentStr = UriUtils.UriToString(this.parseResult.MetadataDocumentUri);

                if (!metadataDocumentStr.EndsWith(ODataConstants.UriMetadataSegment, StringComparison.Ordinal))
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                Uri serviceRoot = new Uri(metadataDocumentStr.Substring(0, metadataDocumentStr.Length - ODataConstants.UriMetadataSegment.Length));

                ODataUriParser odataUriParser = new ODataUriParser(this.model, serviceRoot, new Uri(serviceRoot, fragment));

                ODataPath path;
                try
                {
                    path = odataUriParser.ParsePath();
                }
                catch (ODataException)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                if (path.Count == 0)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                this.parseResult.Path = path;

                parseResult.NavigationSource = path.NavigationSource();
                parseResult.EdmType          = path.LastSegment.EdmType;

                ODataPathSegment lastSegment = path.TrimEndingTypeSegment().LastSegment;
                if (lastSegment is EntitySetSegment || lastSegment is NavigationPropertySegment)
                {
                    if (kind != ODataDeltaKind.None)
                    {
                        detectedPayloadKind = ODataPayloadKind.Delta;
                    }
                    else
                    {
                        detectedPayloadKind = hasItemSelector ? ODataPayloadKind.Resource : ODataPayloadKind.ResourceSet;
                    }

                    if (this.parseResult.EdmType is IEdmCollectionType)
                    {
                        var collectionTypeReference = this.parseResult.EdmType.ToTypeReference().AsCollection();
                        if (collectionTypeReference != null)
                        {
                            this.parseResult.EdmType = collectionTypeReference.ElementType().Definition;
                        }
                    }
                }
                else if (lastSegment is SingletonSegment)
                {
                    detectedPayloadKind = ODataPayloadKind.Resource;
                }
                else if (path.IsIndividualProperty())
                {
                    isUndeclared        = path.IsUndeclared();
                    detectedPayloadKind = ODataPayloadKind.Property;
                    IEdmComplexType complexType = parseResult.EdmType as IEdmComplexType;
                    if (complexType != null)
                    {
                        detectedPayloadKind = ODataPayloadKind.Resource;
                    }
                    else
                    {
                        IEdmCollectionType collectionType = parseResult.EdmType as IEdmCollectionType;

                        if (collectionType != null)
                        {
                            if (collectionType.ElementType.IsComplex())
                            {
                                this.parseResult.EdmType = collectionType.ElementType.Definition;
                                detectedPayloadKind      = ODataPayloadKind.ResourceSet;
                            }
                            else
                            {
                                detectedPayloadKind = ODataPayloadKind.Collection;
                            }
                        }
                    }
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }
            }

            return(detectedPayloadKind);
        }
 /// <summary>
 /// Writes the context uri for a delta (deleted) entry.
 /// </summary>
 /// <param name="kind">The kind of delta entry.</param>
 private void WriteDeltaEntryContextUri(ODataDeltaKind kind)
 {
     Debug.Assert(kind == ODataDeltaKind.Entry || kind == ODataDeltaKind.DeletedEntry, "kind must be either DeltaEntry or DeltaDeletedEntry.");
     this.jsonLightEntryAndFeedSerializer.WriteDeltaContextUri(
         this.CurrentDeltaEntryScope.GetOrCreateTypeContext(this.jsonLightOutputContext.Model),
         kind,
         this.GetParentDeltaFeedScope().ContextUriInfo);
 }
        /// <summary>
        /// Tries to writes the context URI property for delta resource/resource set/link into the payload if one is available.
        /// </summary>
        /// <param name="typeContext">The context object to answer basic questions regarding the type of the resource.</param>
        /// <param name="kind">The delta kind to write.</param>
        /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param>
        /// <returns>The created context uri info.</returns>
        internal ODataContextUrlInfo WriteDeltaContextUri(ODataResourceTypeContext typeContext, ODataDeltaKind kind, ODataContextUrlInfo parentContextUrlInfo = null)
        {
            ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri;

            return(this.WriteContextUriProperty(ODataPayloadKind.Delta, () => ODataContextUrlInfo.Create(typeContext, this.MessageWriterSettings.Version ?? ODataVersion.V4, kind, odataUri), parentContextUrlInfo));
        }
 /// <summary>
 /// Tries to writes the context URI property for delta entry/feed/link into the payload if one is available.
 /// </summary>
 /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param>
 /// <param name="kind">The delta kind to write.</param>
 /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param>
 /// <returns>The created context uri info.</returns>
 internal ODataContextUrlInfo WriteDeltaContextUri(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataContextUrlInfo parentContextUrlInfo = null)
 {
     ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri;
     return this.WriteContextUriProperty(ODataPayloadKind.Delta, () => ODataContextUrlInfo.Create(typeContext, kind, odataUri), parentContextUrlInfo);
 }
Beispiel #10
0
        private Uri CreateDeltaResponseContextUri(ODataResourceTypeContext typeContext, ODataDeltaKind kind, ODataVersion version)
        {
            ODataContextUrlInfo info = ODataContextUrlInfo.Create(typeContext, version, kind);
            Uri contextUrl           = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.Delta, info);

            contextUrl.Should().NotBeNull();
            return(contextUrl);
        }
 private Uri CreateDeltaResponseContextUri(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind)
 {
     ODataContextUrlInfo info = ODataContextUrlInfo.Create(typeContext, kind);
     Uri contextUrl = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.Delta, info);
     contextUrl.Should().NotBeNull();
     return contextUrl;
 }