Add the capabilities classes

This commit is contained in:
Sam Xu 2018-01-18 17:53:15 -08:00
parent fa06f7a962
commit 708ec7d5c7
17 changed files with 1709 additions and 0 deletions

View file

@ -0,0 +1,31 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.BatchSupported
/// </summary>
internal class BatchSupported : SupportedRestrictions
{
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.BatchSupported;
/// <summary>
/// Initializes a new instance of <see cref="BatchSupported"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The annotation target.</param>
public BatchSupported(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
}
}

View file

@ -0,0 +1,153 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// The base class of Capabilities
/// </summary>
internal abstract class CapabilitiesRestrictions
{
private bool _initialized;
/// <summary>
/// Gets the <see cref="IEdmModel"/>.
/// </summary>
public IEdmModel Model { get; }
/// <summary>
/// Gets the <see cref="IEdmVocabularyAnnotatable"/>.
/// </summary>
public IEdmVocabularyAnnotatable Target { get; }
/// <summary>
/// The Term qualified name.
/// </summary>
public virtual string QualifiedName { get; }
/// <summary>
/// Initializes a new instance of <see cref="CapabilitiesRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm vocabulary annotatable.</param>
public CapabilitiesRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
{
Model = model ?? throw Error.ArgumentNull(nameof(model));
Target = Target ?? throw Error.ArgumentNull(nameof(target));
}
protected void Initialize()
{
if (_initialized)
{
return;
}
IEdmVocabularyAnnotation annotation = Model.GetCapabilitiesAnnotation(Target, QualifiedName);
if (annotation == null)
{
IEdmNavigationSource navigationSource = Target as IEdmNavigationSource;
// if not, search the entity type.
IEdmEntityType entityType = navigationSource.EntityType();
annotation = Model.GetCapabilitiesAnnotation(entityType, QualifiedName);
}
Initialize(annotation);
_initialized = true;
}
protected abstract void Initialize(IEdmVocabularyAnnotation annotation);
protected static bool SetBoolProperty(IEdmRecordExpression record, string propertyName, bool defaultValue)
{
if (record == null || record.Properties == null)
{
return defaultValue;
}
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);
if (property != null)
{
IEdmBooleanConstantExpression value = property.Value as IEdmBooleanConstantExpression;
if (value != null)
{
return value.Value;
}
}
return defaultValue;
}
protected static bool? SetBoolProperty(IEdmRecordExpression record, string propertyName)
{
if (record == null || record.Properties == null)
{
return null;
}
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);
if (property != null)
{
IEdmBooleanConstantExpression value = property.Value as IEdmBooleanConstantExpression;
if (value != null)
{
return value.Value;
}
}
return null;
}
protected static IList<string> GetCollectProperty(IEdmRecordExpression record, string propertyName)
{
IList<string> properties = new List<string>();
if (record != null && record.Properties != null)
{
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null)
{
foreach (var a in value.Elements.Select(e => e as EdmPropertyPathExpression))
{
properties.Add(a.Path);
}
}
}
}
return properties;
}
public IList<string> GetCollectNavigationProperty(IEdmRecordExpression record, string propertyName)
{
IList<string> properties = new List<string>();
if (record != null && record.Properties != null)
{
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null)
{
foreach (var a in value.Elements.Select(e => e as EdmNavigationPropertyPathExpression))
{
properties.Add(a.Path);
}
}
}
}
return properties;
}
}
}

View file

@ -0,0 +1,112 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.CountRestrictions
/// </summary>
internal class CountRestrictions : CapabilitiesRestrictions
{
private bool _countable = true;
private IList<string> _nonCountableProperties;
private IList<string> _nonCountableNavigationProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.CountRestrictions;
/// <summary>
/// Gets the Countable value.
/// <Property Name="Countable" Type="Edm.Boolean" DefaultValue="true">
/// </summary>
public bool Countable
{
get
{
Initialize();
return _countable;
}
}
/// <summary>
/// Gets the properties which do not allow /$count segments.
/// </summary>
public IList<string> NonCountableProperties
{
get
{
Initialize();
return _nonCountableProperties;
}
}
/// <summary>
/// Gets the navigation properties which do not allow /$count segments.
/// </summary>
public IList<string> NonCountableNavigationProperties
{
get
{
Initialize();
return _nonCountableNavigationProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="CountRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public CountRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input property which do not allow /$count segments.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsNonCountableNavigationProperty(IEdmProperty property)
{
return NonCountableProperties.Any(a => a == property.Name);
}
/// <summary>
/// Test the input navigation property which do not allow /$count segments.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsNonCountableNavigationProperty(IEdmNavigationProperty property)
{
return NonCountableNavigationProperties.Any(a => a == property.Name);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_countable = SetBoolProperty(record, "Countable", true);
_nonCountableProperties = GetCollectProperty(record, "NonCountableProperties");
_nonCountableNavigationProperties = GetCollectNavigationProperty(record, "NonCountableNavigationProperties");
}
}
}

View file

@ -0,0 +1,86 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.DeleteRestrictions
/// </summary>
internal class DeleteRestrictions : CapabilitiesRestrictions
{
private bool _deletable = true;
private IList<string> _nonDeletableNavigationProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.DeleteRestrictions;
/// <summary>
/// Gets the Deletable value.
/// </summary>
public bool Deletable
{
get
{
Initialize();
return _deletable;
}
}
/// <summary>
/// Gets the navigation properties which do not allow DeleteLink requests.
/// </summary>
public IList<string> NonDeletableNavigationProperties
{
get
{
Initialize();
return _nonDeletableNavigationProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="DeleteRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public DeleteRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input navigation property do not allow DeleteLink requests.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool NonDeletableNavigationProperty(IEdmNavigationProperty property)
{
return NonDeletableNavigationProperties.Any(a => a == property.Name);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_deletable = SetBoolProperty(record, "Deletable", true);
_nonDeletableNavigationProperties = GetCollectNavigationProperty(record, "NonDeletableNavigationProperties");
}
}
}

View file

@ -0,0 +1,391 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Linq;
using System.Collections.Generic;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
namespace Microsoft.OpenApi.OData.Capabilities
{
internal static class EdmModelCapabilitiesHelper
{
public static IEnumerable<string> GetAscendingOnlyProperties(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
IEdmRecordExpression record = model.GetSortRestrictionsAnnotation(target);
if (record != null)
{
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == "AscendingOnlyProperties");
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null)
{
foreach(var a in value.Elements.Select(e => e as EdmPropertyPathExpression))
{
yield return a.Path;
}
}
}
}
yield return null;
}
public static IEnumerable<string> GetDescendingOnlyProperties(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
IEdmRecordExpression record = model.GetSortRestrictionsAnnotation(target);
if (record != null)
{
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == "DescendingOnlyProperties");
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null)
{
foreach (var a in value.Elements.Select(e => e as EdmPropertyPathExpression))
{
yield return a.Path;
}
}
}
}
yield return null;
}
public static IEnumerable<string> GetNonSortableProperties(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
IEdmRecordExpression record = model.GetSortRestrictionsAnnotation(target);
if (record != null)
{
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == "NonSortablePropeties");
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null)
{
foreach (var a in value.Elements.Select(e => e as EdmPropertyPathExpression))
{
yield return a.Path;
}
}
}
}
yield return null;
}
/// <summary>
/// Gets description for term Org.OData.Core.V1.Description from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Description for term Org.OData.Core.V1.Description</returns>
public static IEdmVocabularyAnnotation GetCapabilitiesAnnotation(this IEdmModel model, IEdmVocabularyAnnotatable target, string qualifiedName)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
Utils.CheckArgumentNull(qualifiedName, nameof(qualifiedName));
IEdmTerm term = model.FindTerm(qualifiedName);
if (term != null)
{
IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
if (annotation != null)
{
return annotation;
}
}
return null;
}
/// <summary>
/// Gets description for term Org.OData.Core.V1.Description from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Description for term Org.OData.Core.V1.Description</returns>
public static IEdmVocabularyAnnotation GetCapabilitiesAnnotation(this IEdmModel model, IEdmVocabularyAnnotatable target, IEdmTerm term)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
Utils.CheckArgumentNull(term, nameof(term));
IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
if (annotation != null)
{
return annotation;
}
return null;
}
/// <summary>
/// Gets description for term Org.OData.Core.V1.Description from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Description for term Org.OData.Core.V1.Description</returns>
public static IEdmRecordExpression GetSortRestrictionsAnnotation(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
if (model == null)
{
throw Error.ArgumentNull(nameof(model));
}
if (target == null)
{
throw Error.ArgumentNull(nameof(target));
}
IEdmTerm term = model.FindTerm(CapabilitiesConstants.SortRestrictions);
if (term == null)
{
return null;
}
IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
if (annotation != null)
{
IEdmRecordExpression recordExpression = annotation.Value as IEdmRecordExpression;
if (recordExpression != null)
{
return recordExpression;
}
}
return null;
}
/// <summary>
/// Gets description for term Org.OData.Core.V1.Description from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Description for term Org.OData.Core.V1.Description</returns>
public static IEdmRecordExpression GetFilterRestrictionsAnnotation(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
if (model == null)
{
throw Error.ArgumentNull(nameof(model));
}
if (target == null)
{
throw Error.ArgumentNull(nameof(target));
}
var a = model.FindDeclaredVocabularyAnnotations(target);
IEdmTerm term = model.FindTerm("Org.OData.Capabilities.V1.FilterRestrictions");
if (term == null)
{
return null;
}
IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
if (annotation != null)
{
IEdmRecordExpression recordExpression = annotation.Value as IEdmRecordExpression;
if (recordExpression != null)
{
return recordExpression;
}
}
return null;
}
/// <summary>
/// Gets bool value for term Org.OData.Core.V1.TopSupported from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Boolean value for term Org.OData.Core.V1.TopSupported</returns>
public static bool IsTopSupported(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
IEdmTerm term = model.FindTerm(CapabilitiesConstants.TopSupported);
if (term != null)
{
bool? boolValue = model.GetBoolean(target, term);
if (boolValue != null)
{
return boolValue.Value;
}
}
// by default, it supports $top.
return true;
}
/// <summary>
/// Gets bool value for term Org.OData.Core.V1.SkipSupported from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Boolean value for term Org.OData.Core.V1.SkipSupported</returns>
public static bool IsSkipSupported(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
IEdmTerm term = model.FindTerm(CapabilitiesConstants.SkipSupported);
if (term != null)
{
bool? boolValue = model.GetBoolean(target, term);
if (boolValue != null)
{
return boolValue.Value;
}
}
// by default, it supports $skip.
return true;
}
/// <summary>
/// Gets Sortable value for term Org.OData.Core.V1.SortRestrictions from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Boolean value for term Org.OData.Core.V1.SortRestrictions</returns>
public static bool IsSortable(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
IEdmTerm term = model.FindTerm(CapabilitiesConstants.SortRestrictions);
if (term != null)
{
bool? boolValue = model.GetBoolean(target, term, "Sortable");
if (boolValue != null)
{
return boolValue.Value;
}
}
return true; // by default, it's sortable.
}
/// <summary>
/// Gets Searchable property value for term Org.OData.Core.V1.SearchRestritions from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Boolean value for term Org.OData.Core.V1.SearchRestritions</returns>
public static bool IsSearchable(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
IEdmTerm term = model.FindTerm(CapabilitiesConstants.SearchRestrictions);
if (term != null)
{
bool? boolValue = model.GetBoolean(target, term, "Searchable");
if (boolValue != null)
{
return boolValue.Value;
}
}
// by default, it supports $search.
return true;
}
/// <summary>
/// Gets Countable property value for term Org.OData.Core.V1.CountRestrictions from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Boolean value for term Org.OData.Core.V1.CountRestrictions</returns>
public static bool IsCountable(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
IEdmTerm term = model.FindTerm(CapabilitiesConstants.CountRestrictions);
if (term != null)
{
bool? boolValue = model.GetBoolean(target, term, "Countable");
if (boolValue != null)
{
return boolValue.Value;
}
}
// by default, it supports $count.
return true;
}
/// <summary>
/// Gets Filterable property value for term Org.OData.Core.V1.FilterRestrictions from a target annotatable
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target Annotatable to find annotation</param>
/// <returns>Boolean value for term Org.OData.Core.V1.FilterRestrictions</returns>
public static bool IsFilterable(this IEdmModel model, IEdmVocabularyAnnotatable target)
{
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
IEdmTerm term = model.FindTerm(CapabilitiesConstants.FilterRestrictions);
if (term != null)
{
bool? boolValue = model.GetBoolean(target, term, "Filterable");
if (boolValue != null)
{
return boolValue.Value;
}
}
// by default, it supports $filter.
return true;
}
private static bool? GetBoolean(this IEdmModel model, IEdmVocabularyAnnotatable target, IEdmTerm term, string propertyName = null)
{
IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
if (annotation != null)
{
switch (annotation.Value.ExpressionKind)
{
case EdmExpressionKind.Record:
IEdmRecordExpression recordExpression = (IEdmRecordExpression)annotation.Value;
if (recordExpression != null)
{
IEdmPropertyConstructor property = recordExpression.Properties.FirstOrDefault(e => e.Name == propertyName);
if (property != null)
{
IEdmBooleanConstantExpression value = property.Value as IEdmBooleanConstantExpression;
if (value != null)
{
return value.Value;
}
}
}
break;
case EdmExpressionKind.BooleanConstant:
IEdmBooleanConstantExpression boolConstant = (IEdmBooleanConstantExpression)annotation.Value;
if (boolConstant != null)
{
return boolConstant.Value;
}
break;
}
}
return null;
}
}
}

View file

@ -0,0 +1,86 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.ExpandRestrictions
/// </summary>
internal class ExpandRestrictions : CapabilitiesRestrictions
{
private bool _expandable = true;
private IList<string> _nonExpandableProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.ExpandRestrictions;
/// <summary>
/// Gets the Expandable value.
/// </summary>
public bool Expandable
{
get
{
Initialize();
return _expandable;
}
}
/// <summary>
/// Gets the properties which cannot be used in $expand expressions.
/// </summary>
public IList<string> NonExpandableProperties
{
get
{
Initialize();
return _nonExpandableProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="ExpandRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="entityStargetet">The Edm annotation target.</param>
public ExpandRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input property cannot be used in $orderby expressions.
/// </summary>
/// <param name="property">The input property name.</param>
/// <returns>True/False.</returns>
public bool IsNonExpandableProperty(string property)
{
return NonExpandableProperties.Any(a => a == property);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_expandable = SetBoolProperty(record, "Expandable", true);
_nonExpandableProperties = GetCollectNavigationProperty(record, "NonExpandableProperties");
}
}
}

View file

@ -0,0 +1,126 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.FilterRestrictions
/// </summary>
internal class FilterRestrictions : CapabilitiesRestrictions
{
private bool _filterable = true;
private bool? _requiresFilter;
private IList<string> _requiredProperties;
private IList<string> _nonFilterableProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.FilterRestrictions;
/// <summary>
/// Gets the Filterable value.
/// </summary>
public bool Filterable
{
get
{
Initialize();
return _filterable;
}
}
/// <summary>
/// Gets the RequiresFilter value.
/// </summary>
public bool? RequiresFilter
{
get
{
Initialize();
return _requiresFilter;
}
}
/// <summary>
/// Gets the properties which must be specified in the $filter clause.
/// </summary>
public IList<string> RequiredProperties
{
get
{
Initialize();
return _requiredProperties;
}
}
/// <summary>
/// Gets the properties which cannot be used in $filter expressions.
/// </summary>
public IList<string> NonFilterableProperties
{
get
{
Initialize();
return _nonFilterableProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="FilterRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public FilterRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input property which must be specified in the $filter clause.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsRequiredProperty(IEdmProperty property)
{
return RequiredProperties.Any(a => a == property.Name);
}
/// <summary>
/// Test the input property which cannot be used in $filter expressions.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsNonFilterableProperty(IEdmProperty property)
{
return NonFilterableProperties.Any(a => a == property.Name);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_filterable = SetBoolProperty(record, "Filterable", true);
_requiresFilter = SetBoolProperty(record, "RequiresFilter");
_requiredProperties = GetCollectProperty(record, "RequiredProperties");
_nonFilterableProperties = GetCollectNavigationProperty(record, "NonFilterableProperties");
}
}
}

View file

@ -0,0 +1,31 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.IndexableByKey
/// </summary>
internal class IndexableByKey : SupportedRestrictions
{
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.IndexableByKey;
/// <summary>
/// Initializes a new instance of <see cref="IndexableByKey"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public IndexableByKey(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
}
}

View file

@ -0,0 +1,86 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.InsertRestrictions
/// </summary>
internal class InsertRestrictions : CapabilitiesRestrictions
{
private bool _insertable = true;
private IList<string> _nonInsertableNavigationProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.InsertRestrictions;
/// <summary>
/// Gets the Insertable value.
/// </summary>
public bool Insertable
{
get
{
Initialize();
return _insertable;
}
}
/// <summary>
/// Gets the navigation properties which do not allow deep inserts.
/// </summary>
public IList<string> NonInsertableNavigationProperties
{
get
{
Initialize();
return _nonInsertableNavigationProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="InsertRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public InsertRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input navigation property do not allow deep insert.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsNonINsertableNavigationProperty(IEdmNavigationProperty property)
{
return NonInsertableNavigationProperties.Any(a => a == property.Name);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_insertable = SetBoolProperty(record, "Insertable", true);
_nonInsertableNavigationProperties = GetCollectNavigationProperty(record, "NonInsertableNavigationProperties");
}
}
}

View file

@ -0,0 +1,144 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Enumerates the navigation type can apply on navigation restrictions.
/// </summary>
internal enum NavigationType
{
/// <summary>
/// Navigation properties can be recursively navigated.
/// </summary>
Recursive,
/// <summary>
/// Navigation properties can be navigated to a single level.
/// </summary>
Single,
/// <summary>
/// Navigation properties are not navigable.
/// </summary>
None
}
/// <summary>
/// Org.OData.Capabilities.V1.NavigationRestrictions
/// </summary>
internal class NavigationRestrictions : CapabilitiesRestrictions
{
/// <summary>
/// Complex type name = NavigationPropertyRestriction
/// </summary>
public class NavigationPropertyRestriction
{
/// <summary>
/// Navigation properties can be navigated
/// </summary>
public string NavigationProperty { get; set; }
/// <summary>
/// Navigation properties can be navigated to this level.
/// </summary>
public NavigationType Navigability { get; set; }
}
private NavigationType _navigability = NavigationType.Single;
private IList<NavigationPropertyRestriction> _restrictedProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.NavigationRestrictions;
/// <summary>
/// Gets the Navigability value.
/// </summary>
public NavigationType Navigability
{
get
{
Initialize();
return _navigability;
}
}
/// <summary>
/// Gets the navigation properties which has navigation restrictions.
/// </summary>
public IList<NavigationPropertyRestriction> RestrictedProperties
{
get
{
Initialize();
return _restrictedProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="NavigationRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public NavigationRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input property cannot be used in $orderby expressions.
/// </summary>
/// <param name="property">The input property name.</param>
/// <returns>True/False.</returns>
public bool IsNonNavigationProperty(IEdmNavigationProperty property)
{
return RestrictedProperties
.Where(a => a.NavigationProperty == property.Name)
.Any(a => a.Navigability == NavigationType.None);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == "Navigability");
if (property != null)
{
IEdmEnumMemberExpression value = property.Value as IEdmEnumMemberExpression;
if (value != null)
{
// Expandable = value.EnumMembers.First().Value.Value;
}
}
property = record.Properties.FirstOrDefault(e => e.Name == "RestrictedProperties");
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null)
{
foreach (var a in value.Elements.Select(e => e as EdmNavigationPropertyPathExpression))
{
//NonExpandableProperties.Add(a.Path);
}
}
}
}
}
}

View file

@ -0,0 +1,112 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Enumerates the search expressions.
/// </summary>
[Flags]
internal enum SearchExpressions
{
/// <summary>
/// none.
/// </summary>
none = 0,
/// <summary>
/// AND.
/// </summary>
AND = 1,
/// <summary>
/// OR.
/// </summary>
OR = 2,
/// <summary>
/// NOT.
/// </summary>
NOT = 4,
/// <summary>
/// phrase.
/// </summary>
phrase = 8,
/// <summary>
/// group.
/// </summary>
group = 16
}
/// <summary>
/// Org.OData.Capabilities.V1.SearchRestrictions
/// </summary>
internal class SearchRestrictions : CapabilitiesRestrictions
{
private bool _searchable = true;
private SearchExpressions _searchExpressions;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.SearchRestrictions;
/// <summary>
/// Gets the Searchable value.
/// </summary>
public bool Searchable
{
get
{
Initialize();
return _searchable;
}
}
/// <summary>
/// Gets the search expressions which can is supported in $search.
/// </summary>
public SearchExpressions SearchExpressions
{
get
{
Initialize();
return _searchExpressions;
}
}
/// <summary>
/// Initializes a new instance of <see cref="SearchRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public SearchRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_searchable = SetBoolProperty(record, "Searchable", true);
// add the enum
}
}
}

View file

@ -0,0 +1,31 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.SkipSupported
/// </summary>
internal class SkipSupported : SupportedRestrictions
{
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.SkipSupported;
/// <summary>
/// Initializes a new instance of <see cref="SkipSupported"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public SkipSupported(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
}
}

View file

@ -0,0 +1,11 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
{
public class SkipSupportedTests
{
}
}

View file

@ -0,0 +1,136 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.SortRestrictions
/// </summary>
internal class SortRestrictions : CapabilitiesRestrictions
{
private bool _sortable = true;
private IList<string> _ascendingOnlyProperties;
private IList<string> _descendingOnlyProperties;
private IList<string> _nonSortableProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.SortRestrictions;
/// <summary>
/// Gets the Sortable value.
/// </summary>
public bool Sortable
{
get
{
Initialize();
return _sortable;
}
}
/// <summary>
/// Gets the properties which can only be used for sorting in Ascending order.
/// </summary>
public IList<string> AscendingOnlyProperties
{
get
{
Initialize();
return _ascendingOnlyProperties;
}
}
/// <summary>
/// Gets the properties which can only be used for sorting in Descending order.
/// </summary>
public IList<string> DescendingOnlyProperties
{
get
{
Initialize();
return _descendingOnlyProperties;
}
}
/// <summary>
/// Gets the properties which cannot be used in $orderby expressions.
/// </summary>
public IList<string> NonSortableProperties
{
get
{
Initialize();
return _nonSortableProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="SortRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public SortRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input property is Ascending only.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsAscendingOnlyProperty(IEdmProperty property)
{
return AscendingOnlyProperties.Any(a => a == property.Name);
}
/// <summary>
/// Test the input property is Descending only.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsDescendingOnlyProperty(IEdmProperty property)
{
return DescendingOnlyProperties.Any(a => a == property.Name);
}
/// <summary>
/// Test the input property cannot be used in $orderby expressions.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsNonsortableProperty(IEdmProperty property)
{
return NonSortableProperties.Any(a => a == property.Name);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_sortable = SetBoolProperty(record, "Sortable", true);
_ascendingOnlyProperties = GetCollectProperty(record, "AscendingOnlyProperties");
_descendingOnlyProperties = GetCollectProperty(record, "DescendingOnlyProperties");
_nonSortableProperties = GetCollectProperty(record, "NonSortablePropeties");
}
}
}

View file

@ -0,0 +1,56 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Base class the supported restrictions.
/// </summary>
internal abstract class SupportedRestrictions : CapabilitiesRestrictions
{
private bool _supported = true;
/// <summary>
/// Get the Supported boolean value.
/// </summary>
public bool Supported
{
get
{
Initialize();
return _supported;
}
}
/// <summary>
/// Initializes a new instance of <see cref="SupportedRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public SupportedRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.BooleanConstant)
{
return;
}
IEdmBooleanConstantExpression boolConstant = (IEdmBooleanConstantExpression)annotation.Value;
if (boolConstant != null)
{
_supported = boolConstant.Value;
}
}
}
}

View file

@ -0,0 +1,31 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.TopSupported
/// </summary>
internal class TopSupported : SupportedRestrictions
{
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.TopSupported;
/// <summary>
/// Initializes a new instance of <see cref="TopSupported"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public TopSupported(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
}
}

View file

@ -0,0 +1,86 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
namespace Microsoft.OpenApi.OData.Capabilities
{
/// <summary>
/// Org.OData.Capabilities.V1.UpdateRestrictions
/// </summary>
internal class UpdateRestrictions : CapabilitiesRestrictions
{
private bool _updatable = true;
private IList<string> _nonUpdatableNavigationProperties;
/// <summary>
/// The Term type name.
/// </summary>
public override string QualifiedName => CapabilitiesConstants.UpdateRestrictions;
/// <summary>
/// Gets the Updatable value.
/// </summary>
public bool Updatable
{
get
{
Initialize();
return _updatable;
}
}
/// <summary>
/// Gets the navigation properties which do not allow rebinding.
/// </summary>
public IList<string> NonUpdatableNavigationProperties
{
get
{
Initialize();
return _nonUpdatableNavigationProperties;
}
}
/// <summary>
/// Initializes a new instance of <see cref="UpdateRestrictions"/> class.
/// </summary>
/// <param name="model">The Edm model.</param>
/// <param name="target">The Edm annotation target.</param>
public UpdateRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
: base(model, target)
{
}
/// <summary>
/// Test the input navigation property do not allow rebinding.
/// </summary>
/// <param name="property">The input property.</param>
/// <returns>True/False.</returns>
public bool IsNonUpdatableNavigationProperty(IEdmNavigationProperty property)
{
return NonUpdatableNavigationProperties.Any(a => a == property.Name);
}
protected override void Initialize(IEdmVocabularyAnnotation annotation)
{
if (annotation == null ||
annotation.Value == null ||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
{
return;
}
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
_updatable = SetBoolProperty(record, "Updatable", true);
_nonUpdatableNavigationProperties = GetCollectNavigationProperty(record, "NonUpdatableNavigationProperties");
}
}
}