/// <summary> /// Validate NavigationPath for given ODataContextUrlInfo for entry or feed /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateNavigationPath(ODataContextUrlInfo contextUrlInfo) { if (string.IsNullOrEmpty(contextUrlInfo.NavigationPath)) { throw new ODataException(Strings.ODataContextUriBuilder_NavigationSourceMissingForEntryAndFeed); } }
/// <summary> /// Validate TypeName for given ODataContextUrlInfo for collection. /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateCollectionType(ODataContextUrlInfo contextUrlInfo) { if (string.IsNullOrEmpty(contextUrlInfo.TypeName)) { throw new ODataException(Strings.ODataContextUriBuilder_TypeNameMissingForTopLevelCollection); } }
/// <summary> /// Validate TypeName for given ODataContextUrlInfo for property. /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateType(ODataContextUrlInfo contextUrlInfo) { if (string.IsNullOrEmpty(contextUrlInfo.TypeName)) { throw new ODataException(Strings.ODataContextUriBuilder_TypeNameMissingForProperty); } }
/// <summary> /// Create context URL from ODataPayloadKind and ODataContextUrlInfo. /// should make the context uri correct for null primitive / null enum value / normal enum value /// ODataEnumValue is allowed to have null or arbitrary TypeName, but the output ContextUri must have correct type name. /// </summary> /// <param name="payloadKind">The ODataPayloadKind for the context URI.</param> /// <param name="contextInfo">The ODataContextUrlInfo to be used.</param> /// <returns>The generated context url.</returns> internal Uri BuildContextUri(ODataPayloadKind payloadKind, ODataContextUrlInfo contextInfo = null) { if (this.baseContextUrl == null) { return null; } Action<ODataContextUrlInfo> verifyAction; if (ValidationDictionary.TryGetValue(payloadKind, out verifyAction)) { if (verifyAction != null && throwIfMissingInfo) { Debug.Assert(contextInfo != null, "contextInfo != null"); verifyAction(contextInfo); } } else { throw new ODataException(Strings.ODataContextUriBuilder_UnsupportedPayloadKind(payloadKind.ToString())); } switch (payloadKind) { case ODataPayloadKind.ServiceDocument: return this.baseContextUrl; case ODataPayloadKind.EntityReferenceLink: return new Uri(this.baseContextUrl, ODataConstants.SingleEntityReferencesContextUrlSegment); case ODataPayloadKind.EntityReferenceLinks: return new Uri(this.baseContextUrl, ODataConstants.CollectionOfEntityReferencesContextUrlSegment); } return CreateFromContextUrlInfo(contextInfo); }
/// <summary> /// Validate ResourcePath for given ODataContextUrlInfo for individual property. /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateResourcePath(ODataContextUrlInfo contextUrlInfo) { if (string.IsNullOrEmpty(contextUrlInfo.ResourcePath)) { throw new ODataException(Strings.ODataContextUriBuilder_ODataUriMissingForIndividualProperty); } }
/// <summary> /// Validate NavigationSource for given ODataContextUrlInfo for entry or feed. /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateNavigationSource(ODataContextUrlInfo contextUrlInfo) { // For navigation property without navigation target, navigation path should be null so // validate its navigation source (should be the name of the navigation property) which // at least requires EdmUnknownEntitySet to be present; otherwise validate its navigation // path as before. if (!contextUrlInfo.IsUnknownEntitySet && string.IsNullOrEmpty(contextUrlInfo.NavigationPath) || contextUrlInfo.IsUnknownEntitySet && string.IsNullOrEmpty(contextUrlInfo.NavigationSource)) { throw new ODataException(Strings.ODataContextUriBuilder_NavigationSourceMissingForEntryAndFeed); } }
/// <summary> /// Determine whether current contextUrlInfo could be determined from parent contextUrlInfo. /// </summary> /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param> /// <returns>Whether current contextUrlInfo could be determined from parent contextUrlInfo.</returns> internal bool IsHiddenBy(ODataContextUrlInfo parentContextUrlInfo) { if (parentContextUrlInfo == null) { return(false); } if (parentContextUrlInfo.NavigationPath == NavigationPath && parentContextUrlInfo.DeltaKind == ODataDeltaKind.Feed && this.DeltaKind == ODataDeltaKind.Entry) { return(true); } return(false); }
/// <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> /// Create context URL from ODataPayloadKind and ODataContextUrlInfo. /// BUG 1659341: should make the context uri correct for null primitive / null enum value / normal enum value /// ODataEnumValue is allowed to have null or arbitrary TypeName, but the output ContextUri must have correct type name. /// </summary> /// <param name="payloadKind">The ODataPayloadKind for the context URI.</param> /// <param name="contextInfo">The ODataContextUrlInfo to be used.</param> /// <returns>The generated context url.</returns> internal Uri BuildContextUri(ODataPayloadKind payloadKind, ODataContextUrlInfo contextInfo = null) { if (this.baseContextUrl == null) { return(null); } Action <ODataContextUrlInfo> verifyAction; if (ValidationDictionary.TryGetValue(payloadKind, out verifyAction)) { if (verifyAction != null && throwIfMissingInfo) { Debug.Assert(contextInfo != null, "contextInfo != null"); verifyAction(contextInfo); } } else { throw new ODataException(Strings.ODataContextUriBuilder_UnsupportedPayloadKind(payloadKind.ToString())); } switch (payloadKind) { case ODataPayloadKind.ServiceDocument: return(this.baseContextUrl); case ODataPayloadKind.EntityReferenceLink: return(new Uri(this.baseContextUrl, ODataConstants.SingleEntityReferencesContextUrlSegment)); case ODataPayloadKind.EntityReferenceLinks: return(new Uri(this.baseContextUrl, ODataConstants.CollectionOfEntityReferencesContextUrlSegment)); } return(CreateFromContextUrlInfo(contextInfo)); }
/// <summary> /// Create context URL from ODataContextUrlInfo. /// </summary> /// <param name="info">The ODataContextUrlInfo to be used.</param> /// <returns>The generated context url.</returns> private Uri CreateFromContextUrlInfo(ODataContextUrlInfo info) { StringBuilder builder = new StringBuilder(); // # builder.Append(ODataConstants.ContextUriFragmentIndicator); if (!string.IsNullOrEmpty(info.ResourcePath)) { builder.Append(info.ResourcePath); } else if (!string.IsNullOrEmpty(info.NavigationPath)) { // #ContainerName.NavigationSourceName builder.Append(info.NavigationPath); if (info.DeltaKind == ODataDeltaKind.None || info.DeltaKind == ODataDeltaKind.Feed || info.DeltaKind == ODataDeltaKind.Entry) { // #ContainerName.NavigationSourceName ==> #ContainerName.NavigationSourceName/Namespace.DerivedTypeName if (!string.IsNullOrEmpty(info.TypeCast)) { builder.Append(ODataConstants.UriSegmentSeparatorChar); builder.Append(info.TypeCast); } // #ContainerName.NavigationSourceName ==> #ContainerName.NavigationSourceName(selectedPropertyList) if (!string.IsNullOrEmpty(info.QueryClause)) { builder.Append(info.QueryClause); } } switch (info.DeltaKind) { case ODataDeltaKind.None: case ODataDeltaKind.Entry: if (info.IncludeFragmentItemSelector) { // #ContainerName.NavigationSourceName ==> #ContainerName.NavigationSourceName/$entity builder.Append(ODataConstants.ContextUriFragmentItemSelector); } break; case ODataDeltaKind.Feed: builder.Append(ODataConstants.ContextUriDeltaFeed); break; case ODataDeltaKind.DeletedEntry: builder.Append(ODataConstants.ContextUriDeletedEntry); break; case ODataDeltaKind.Link: builder.Append(ODataConstants.ContextUriDeltaLink); break; case ODataDeltaKind.DeletedLink: builder.Append(ODataConstants.ContextUriDeletedLink); break; } } else if (!string.IsNullOrEmpty(info.TypeName)) { // #TypeName builder.Append(info.TypeName); } else { return null; } return new Uri(this.baseContextUrl, builder.ToString()); }
/// <summary> /// Create context URL from ODataContextUrlInfo. /// </summary> /// <param name="info">The ODataContextUrlInfo to be used.</param> /// <returns>The generated context url.</returns> private Uri CreateFromContextUrlInfo(ODataContextUrlInfo info) { StringBuilder builder = new StringBuilder(); // # builder.Append(ODataConstants.ContextUriFragmentIndicator); if (!string.IsNullOrEmpty(info.ResourcePath)) { builder.Append(info.ResourcePath); } else if (!string.IsNullOrEmpty(info.NavigationPath)) { // #ContainerName.NavigationSourceName builder.Append(info.NavigationPath); if (info.DeltaKind == ODataDeltaKind.None || info.DeltaKind == ODataDeltaKind.Feed || info.DeltaKind == ODataDeltaKind.Entry) { // #ContainerName.NavigationSourceName ==> #ContainerName.NavigationSourceName/Namespace.DerivedTypeName if (!string.IsNullOrEmpty(info.TypeCast)) { builder.Append(ODataConstants.UriSegmentSeparatorChar); builder.Append(info.TypeCast); } // #ContainerName.NavigationSourceName ==> #ContainerName.NavigationSourceName(selectedPropertyList) if (!string.IsNullOrEmpty(info.QueryClause)) { builder.Append(info.QueryClause); } } switch (info.DeltaKind) { case ODataDeltaKind.None: case ODataDeltaKind.Entry: if (info.IncludeFragmentItemSelector) { // #ContainerName.NavigationSourceName ==> #ContainerName.NavigationSourceName/$entity builder.Append(ODataConstants.ContextUriFragmentItemSelector); } break; case ODataDeltaKind.Feed: builder.Append(ODataConstants.ContextUriDeltaFeed); break; case ODataDeltaKind.DeletedEntry: builder.Append(ODataConstants.ContextUriDeletedEntry); break; case ODataDeltaKind.Link: builder.Append(ODataConstants.ContextUriDeltaLink); break; case ODataDeltaKind.DeletedLink: builder.Append(ODataConstants.ContextUriDeletedLink); break; } } else if (!string.IsNullOrEmpty(info.TypeName)) { // #TypeName builder.Append(info.TypeName); } else { return(null); } return(new Uri(this.baseContextUrl, builder.ToString())); }
/// <summary> /// Validate the given ODataContextUrlInfo for delta /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateDelta(ODataContextUrlInfo contextUrlInfo) { Debug.Assert(contextUrlInfo.DeltaKind != ODataDeltaKind.None, "contextUrlInfo.DeltaKind != ODataDeltaKind.None"); }
/// <summary> /// Validate NavigationSource for given ODataContextUrlInfo for entry or feed. /// </summary> /// <param name="contextUrlInfo">The ODataContextUrlInfo to evaluate on.</param> private static void ValidateNavigationSource(ODataContextUrlInfo contextUrlInfo) { // For navigation property without navigation target, navigation path should be null so // validate its navigation source (should be the name of the navigation property) which // at least requires EdmUnknownEntitySet to be present; otherwise validate its navigation // path as before. if (!contextUrlInfo.IsUnknownEntitySet && string.IsNullOrEmpty(contextUrlInfo.NavigationPath) || contextUrlInfo.IsUnknownEntitySet && string.IsNullOrEmpty(contextUrlInfo.NavigationSource) && string.IsNullOrEmpty(contextUrlInfo.TypeName)) { throw new ODataException(Strings.ODataContextUriBuilder_NavigationSourceMissingForEntryAndFeed); } }
/// <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; }
/// <summary> /// Determine whether current contextUrlInfo could be determined from parent contextUrlInfo. /// </summary> /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param> /// <returns>Whether current contextUrlInfo could be determined from parent contextUrlInfo.</returns> internal bool IsHiddenBy(ODataContextUrlInfo parentContextUrlInfo) { if (parentContextUrlInfo == null) { return false; } if (parentContextUrlInfo.NavigationPath == NavigationPath && parentContextUrlInfo.DeltaKind == ODataDeltaKind.Feed && this.DeltaKind == ODataDeltaKind.Entry) { return true; } return false; }