Skip to content

Commit 6839150

Browse files
committed
- fixes #129 a bug where odata count paths would be missing from the description
Signed-off-by: Vincent Biret <[email protected]>
1 parent d73da48 commit 6839150

File tree

2 files changed

+43
-26
lines changed

2 files changed

+43
-26
lines changed

src/Microsoft.OpenApi.OData.Reader/Edm/ODataDollarCountSegment.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ namespace Microsoft.OpenApi.OData.Edm
1212
/// </summary>
1313
public class ODataDollarCountSegment : ODataSegment
1414
{
15+
/// <summary>
16+
/// Get the static instance of $count segment.
17+
/// </summary>
18+
internal static ODataDollarCountSegment Instance = new();
1519
/// <inheritdoc />
1620
public override ODataSegmentKind Kind => ODataSegmentKind.DollarCount;
1721

src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ protected virtual void Initialize(IEdmModel model)
102102

103103
private IEnumerable<ODataPath> MergePaths()
104104
{
105-
List<ODataPath> allODataPaths = new List<ODataPath>();
105+
List<ODataPath> allODataPaths = new();
106106
foreach (var item in _allNavigationSourcePaths.Values)
107107
{
108108
allODataPaths.AddRange(item);
@@ -127,6 +127,7 @@ private void AppendPath(ODataPath path)
127127
ODataPathKind kind = path.Kind;
128128
switch(kind)
129129
{
130+
case ODataPathKind.DollarCount:
130131
case ODataPathKind.Entity:
131132
case ODataPathKind.EntitySet:
132133
case ODataPathKind.Singleton:
@@ -143,8 +144,7 @@ private void AppendPath(ODataPath path)
143144

144145
case ODataPathKind.NavigationProperty:
145146
case ODataPathKind.Ref:
146-
ODataNavigationPropertySegment navigationPropertySegment = path.Last(p => p is ODataNavigationPropertySegment)
147-
as ODataNavigationPropertySegment;
147+
ODataNavigationPropertySegment navigationPropertySegment = path.OfType<ODataNavigationPropertySegment>().Last();
148148

149149
if (!_allNavigationPropertyPaths.TryGetValue(navigationPropertySegment.EntityType, out IList<ODataPath> npList))
150150
{
@@ -174,15 +174,17 @@ private void RetrieveNavigationSourcePaths(IEdmNavigationSource navigationSource
174174
Debug.Assert(navigationSource != null);
175175

176176
// navigation source itself
177-
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(navigationSource));
177+
ODataPath path = new(new ODataNavigationSourceSegment(navigationSource));
178178
AppendPath(path.Clone());
179179

180180
IEdmEntitySet entitySet = navigationSource as IEdmEntitySet;
181181
IEdmEntityType entityType = navigationSource.EntityType();
182182

183-
// for entity set, create a path with key
183+
// for entity set, create a path with key and a $count path
184184
if (entitySet != null)
185185
{
186+
CreateCountPath(path);
187+
186188
path.Push(new ODataKeySegment(entityType));
187189
AppendPath(path.Clone());
188190
}
@@ -275,6 +277,13 @@ private void RetrieveNavigationPropertyPaths(IEdmNavigationProperty navigationPr
275277
if (restriction == null || restriction.IndexableByKey == true)
276278
{
277279
IEdmEntityType navEntityType = navigationProperty.ToEntityType();
280+
var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many;
281+
282+
if (targetsMany)
283+
{
284+
// ~/entityset/{key}/collection-valued-Nav/$count
285+
CreateCountPath(currentPath);
286+
}
278287

279288
if (!navigationProperty.ContainsTarget)
280289
{
@@ -283,7 +292,7 @@ private void RetrieveNavigationPropertyPaths(IEdmNavigationProperty navigationPr
283292
// Collection-valued: ~/entityset/{key}/collection-valued-Nav/$ref?$id ={navKey}
284293
CreateRefPath(currentPath);
285294

286-
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
295+
if (targetsMany)
287296
{
288297
// Collection-valued: DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref
289298
currentPath.Push(new ODataKeySegment(navEntityType));
@@ -296,7 +305,7 @@ private void RetrieveNavigationPropertyPaths(IEdmNavigationProperty navigationPr
296305
else
297306
{
298307
// append a navigation property key.
299-
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
308+
if (targetsMany)
300309
{
301310
currentPath.Push(new ODataKeySegment(navEntityType));
302311
AppendPath(currentPath.Clone());
@@ -318,7 +327,7 @@ private void RetrieveNavigationPropertyPaths(IEdmNavigationProperty navigationPr
318327
}
319328
}
320329

321-
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
330+
if (targetsMany)
322331
{
323332
currentPath.Pop();
324333
}
@@ -360,6 +369,16 @@ private void CreateRefPath(ODataPath currentPath)
360369
newPath.Push(ODataRefSegment.Instance); // $ref
361370
AppendPath(newPath);
362371
}
372+
/// <summary>
373+
/// Create $count paths.
374+
/// </summary>
375+
/// <param name="currentPath">The current OData path.</param>
376+
private void CreateCountPath(ODataPath currentPath) {
377+
if(currentPath == null) throw new ArgumentNullException(nameof(currentPath));
378+
var countPath = currentPath.Clone();
379+
countPath.Push(ODataDollarCountSegment.Instance);
380+
AppendPath(countPath);
381+
}
363382

364383
/// <summary>
365384
/// Retrieve all bounding <see cref="IEdmOperation"/>.
@@ -436,7 +455,11 @@ private void RetrieveBoundOperationPaths(OpenApiConvertSettings convertSettings)
436455
}
437456
}
438457
}
439-
458+
private static readonly HashSet<ODataPathKind> _oDataPathKindsToSkipForOperations = new HashSet<ODataPathKind>() {
459+
ODataPathKind.EntitySet,
460+
ODataPathKind.MediaEntity,
461+
ODataPathKind.DollarCount
462+
};
440463
private bool AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType)
441464
{
442465
bool found = false;
@@ -448,8 +471,7 @@ private bool AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperati
448471
foreach (var subPath in value)
449472
{
450473
if ((isCollection && subPath.Kind == ODataPathKind.EntitySet) ||
451-
(!isCollection && subPath.Kind != ODataPathKind.EntitySet &&
452-
subPath.Kind != ODataPathKind.MediaEntity))
474+
(!isCollection && !_oDataPathKindsToSkipForOperations.Contains(subPath.Kind)))
453475
{
454476
ODataPath newPath = subPath.Clone();
455477
newPath.Push(new ODataOperationSegment(edmOperation, isEscapedFunction));
@@ -461,21 +483,18 @@ private bool AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperati
461483

462484
return found;
463485
}
464-
486+
private static readonly HashSet<ODataPathKind> _pathKindToSkipForNavigationProperties = new () {
487+
ODataPathKind.Ref,
488+
};
465489
private bool AppendBoundOperationOnNavigationPropertyPath(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType)
466490
{
467491
bool found = false;
468492
bool isEscapedFunction = _model.IsUrlEscapeFunction(edmOperation);
469493

470494
if (_allNavigationPropertyPaths.TryGetValue(bindingEntityType, out IList<ODataPath> value))
471495
{
472-
foreach (var path in value)
496+
foreach (var path in value.Where(x => !_pathKindToSkipForNavigationProperties.Contains(x.Kind)))
473497
{
474-
if (path.Kind == ODataPathKind.Ref)
475-
{
476-
continue;
477-
}
478-
479498
ODataNavigationPropertySegment npSegment = path.Segments.Last(s => s is ODataNavigationPropertySegment) as ODataNavigationPropertySegment;
480499

481500
if (!npSegment.NavigationProperty.ContainsTarget)
@@ -596,15 +615,9 @@ private bool AppendBoundOperationOnDerivedNavigationPropertyPath(
596615
{
597616
if (_allNavigationPropertyPaths.TryGetValue(baseType, out IList<ODataPath> paths))
598617
{
599-
foreach (var path in paths)
618+
foreach (var path in paths.Where(x => !_pathKindToSkipForNavigationProperties.Contains(x.Kind)))
600619
{
601-
if (path.Kind == ODataPathKind.Ref)
602-
{
603-
continue;
604-
}
605-
606-
var npSegment = path.Segments.Last(s => s is ODataNavigationPropertySegment)
607-
as ODataNavigationPropertySegment;
620+
var npSegment = path.Segments.OfType<ODataNavigationPropertySegment>().LastOrDefault();
608621
if (npSegment == null)
609622
{
610623
continue;

0 commit comments

Comments
 (0)