/// <summary> /// Gets a media entity content description. /// </summary> /// <returns>The entity content description.</returns> protected IDictionary <string, OpenApiMediaType> GetContentDescription() { var content = new Dictionary <string, OpenApiMediaType>(); OpenApiSchema schema = new OpenApiSchema { Type = "string", Format = "binary" }; IEdmVocabularyAnnotatable annotatableElement = null; IEdmEntityType entityType = EntitySet != null?EntitySet.EntityType() : Singleton.EntityType(); ODataSegment lastSegmentStreamProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment); if (lastSegmentStreamProp != null) { // Get the annotatable stream property // The stream property can either be a structural type or navigation type property IEdmProperty property = GetStructuralProperty(entityType, lastSegmentStreamProp.Identifier); if (property == null) { property = GetNavigationProperty(entityType, lastSegmentStreamProp.Identifier); } annotatableElement = property; } else { annotatableElement = entityType; } // Fetch the respective AcceptableMediaTypes IEnumerable <string> mediaTypes = null; if (annotatableElement != null) { mediaTypes = Context.Model.GetCollection(annotatableElement, CapabilitiesConstants.AcceptableMediaTypes); } if (mediaTypes != null) { foreach (string item in mediaTypes) { content.Add(item, null); } } else { // Default content type content.Add(Constants.ApplicationOctetStreamMediaType, new OpenApiMediaType { Schema = schema }); }; return(content); }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet; IEdmVocabularyAnnotatable target = entitySet; if (target == null) { target = NavigationSource as IEdmSingleton; } string navigationPropertyPath = String.Join("/", Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier)); NavigationRestrictionsType navigation = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions); NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath); // verify using individual first if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None) { return; } if (restriction == null || restriction.Navigability == null) { // if the individual has not navigability setting, use the global navigability setting if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None) { // Default navigability for all navigation properties of the annotation target. // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. return; } } // So far, we only consider the non-containment Debug.Assert(!NavigationProperty.ContainsTarget); // Create the ref if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { ODataSegment penultimateSegment = Path.Segments.Reverse().Skip(1).First(); if (penultimateSegment is ODataKeySegment) { // Collection-valued: DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref AddDeleteOperation(item, restriction); } else { AddReadOperation(item, restriction); AddInsertOperation(item, restriction); } } else { AddReadOperation(item, restriction); AddUpdateOperation(item, restriction); AddDeleteOperation(item, restriction); } }
/// <inheritdoc/> protected override void Initialize(ODataContext context, ODataPath path) { base.Initialize(context, path); // get the last second segment int count = path.Segments.Count; LastSecondSegment = path.Segments.ElementAt(count - 1); }
/// <summary> /// Retrieves the operation Id for a media entity stream path. /// </summary> /// <param name="prefix">The http method identifier name.</param> /// <param name="identifier">The stream segment identifier name.</param> /// <returns></returns> protected string GetOperationId(string prefix, string identifier) { Utils.CheckArgumentNullOrEmpty(prefix, nameof(prefix)); Utils.CheckArgumentNullOrEmpty(identifier, nameof(identifier)); IList <string> items = new List <string> { NavigationSourceSegment.Identifier }; ODataSegment lastSegment = Path.Segments.Last(c => c is ODataStreamContentSegment || c is ODataStreamPropertySegment); foreach (ODataSegment segment in Path.Segments.Skip(1)) { if (segment == lastSegment) { if (!IsNavigationPropertyPath) { string typeName = NavigationSourceSegment.EntityType.Name; items.Add(typeName); items.Add(prefix + Utils.UpperFirstChar(identifier)); } else { // Remove the last navigation property segment for navigation property paths, // as this will be included within the prefixed name of the operation id items.Remove(NavigationProperty.Name); items.Add(prefix + Utils.UpperFirstChar(NavigationProperty.Name) + Utils.UpperFirstChar(identifier)); } break; } else { if (segment is ODataNavigationPropertySegment npSegment) { items.Add(npSegment.NavigationProperty.Name); } } } return(string.Join(".", items)); }
/// <summary> /// Gets the annotatable stream property from the path segments. /// </summary> /// <returns>The annotatable stream property.</returns> protected IEdmVocabularyAnnotatable GetAnnotatableElement() { // Only ODataStreamPropertySegment is annotatable if (!LastSegmentIsStreamPropertySegment) { return(null); } // Retrieve the entity type of the segment before the stream property segment var entityType = Path.Segments.ElementAtOrDefault(Path.Segments.Count - 2).EntityType; // The stream property can either be a structural type or a navigation property type ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment); IEdmProperty property = GetStructuralProperty(entityType, lastSegmentProp.Identifier); if (property == null) { property = GetNavigationProperty(entityType, lastSegmentProp.Identifier); } return(property); }