/// <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; }
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); }
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); }
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; }