Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add insert, update, delete restrictions #1770

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/CodeAnalysisDictionary.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
<Word>ModelName</Word>
<Word>BSON</Word>
<Word>Untyped</Word>
<Word>Insertable</Word>
<Word>Updatable</Word>
<Word>Deletable</Word>
</Recognized>
<Compound>
<Term CompoundAlternate="WebPage">WebPage</Term>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,38 @@ internal static class CapabilitiesVocabularyConstants

/// <summary>Property NonExpandableProperties of Org.OData.Capabilities.V1.ExpandRestrictions</summary>
public const string ExpandRestrictionsNonExpandableProperties = "NonExpandableProperties";

/// <summary>Org.OData.Capabilities.V1.InsertRestrictions</summary>
public const string InsertRestrictions = "Org.OData.Capabilities.V1.InsertRestrictions";

/// <summary>Property Insertable of Org.OData.Capabilities.V1.InsertRestrictions</summary>
public const string InsertRestrictionsInsertable = "Insertable";

/// <summary>Property NonInsertableProperties of Org.OData.Capabilities.V1.InsertRestrictions</summary>
public const string InsertRestrictionsNonInsertableProperties = "NonInsertableProperties";

/// <summary>Property NonInsertableNavigationProperties of Org.OData.Capabilities.V1.InsertRestrictions</summary>
public const string InsertRestrictionsNonInsertableNavigationProperties = "NonInsertableNavigationProperties";

/// <summary>Org.OData.Capabilities.V1.UpdateRestrictions</summary>
public const string UpdateRestrictions = "Org.OData.Capabilities.V1.UpdateRestrictions";

/// <summary>Property Updatable of Org.OData.Capabilities.V1.UpdateRestrictions</summary>
public const string UpdateRestrictionsUpdatable = "Updatable";

/// <summary>Property NonUpdatableProperties of Org.OData.Capabilities.V1.UpdateRestrictions</summary>
public const string UpdateRestrictionsNonUpdatableProperties = "NonUpdatableProperties";

/// <summary>Property NonUpdatableNavigationProperties of Org.OData.Capabilities.V1.UpdateRestrictions</summary>
public const string UpdateRestrictionsNonUpdatableNavigationProperties = "NonUpdatableNavigationProperties";

/// <summary>Org.OData.Capabilities.V1.DeleteRestrictions</summary>
public const string DeleteRestrictions = "Org.OData.Capabilities.V1.DeleteRestrictions";

/// <summary>Property Deletable of Org.OData.Capabilities.V1.DeleteRestrictions</summary>
public const string DeleteRestrictionsDeletable = "Deletable";

/// <summary>Property NonDeletableNavigationProperties of Org.OData.Capabilities.V1.DeleteRestrictions</summary>
public const string DeleteRestrictionsNonDeletableNavigationProperties = "NonDeletableNavigationProperties";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,125 @@ public static void SetExpandRestrictionsAnnotation(this EdmModel model, IEdmEnti
model.SetVocabularyAnnotation(target, properties, CapabilitiesVocabularyConstants.ExpandRestrictions);
}

/// <summary>
/// Set Org.OData.Capabilities.V1.InsertRestrictions to target.
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target entity set to set the inline annotation.</param>
/// <param name="isInsertable">This entity set can be inserted.</param>
/// <param name="nonInsertableProperties">These properties SHOULD be omitted from POST requests because the server will ignore their values.</param>
/// <param name="nonInsertableNavigationProperties">These navigation properties do not allow InsertLink requests.</param>
public static void SetInsertRestrictionsAnnotation(this EdmModel model, IEdmEntitySet target, bool isInsertable,
IEnumerable<IEdmProperty> nonInsertableProperties,
IEnumerable<IEdmNavigationProperty> nonInsertableNavigationProperties)
{
if (model == null)
{
throw Error.ArgumentNull("model");
}

if (target == null)
{
throw Error.ArgumentNull("target");
}

nonInsertableProperties = nonInsertableProperties ?? EmptyStructuralProperties;
nonInsertableNavigationProperties = nonInsertableNavigationProperties ?? EmptyNavigationProperties;

IList<IEdmPropertyConstructor> properties = new List<IEdmPropertyConstructor>
{
new EdmPropertyConstructor(CapabilitiesVocabularyConstants.InsertRestrictionsInsertable,
new EdmBooleanConstant(isInsertable)),

new EdmPropertyConstructor(CapabilitiesVocabularyConstants.InsertRestrictionsNonInsertableProperties,
new EdmCollectionExpression(
nonInsertableProperties.Select(p => new EdmPropertyPathExpression(p.Name)).ToArray())),

new EdmPropertyConstructor(CapabilitiesVocabularyConstants.InsertRestrictionsNonInsertableNavigationProperties,
new EdmCollectionExpression(
nonInsertableNavigationProperties.Select(p => new EdmNavigationPropertyPathExpression(p.Name)).ToArray()))
};

model.SetVocabularyAnnotation(target, properties, CapabilitiesVocabularyConstants.InsertRestrictions);
}

/// <summary>
/// Set Org.OData.Capabilities.V1.UpdateRestrictions to target.
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target entity set to set the inline annotation.</param>
/// <param name="isUpdatable">This entity set can be updated.</param>
/// <param name="nonUpdatableProperties">These properties SHOULD be omitted from PUT or PATCH requests because the server will ignore their values.These properties do not allow UpdateValue and DeleteValue requests.</param>
/// <param name="nonUpdatableNavigationProperties">These navigation properties do not allow UpdateLink requests.</param>
public static void SetUpdateRestrictionsAnnotation(this EdmModel model, IEdmEntitySet target, bool isUpdatable,
IEnumerable<IEdmProperty> nonUpdatableProperties,
IEnumerable<IEdmNavigationProperty> nonUpdatableNavigationProperties)
{
if (model == null)
{
throw Error.ArgumentNull("model");
}

if (target == null)
{
throw Error.ArgumentNull("target");
}

nonUpdatableProperties = nonUpdatableProperties ?? EmptyStructuralProperties;
nonUpdatableNavigationProperties = nonUpdatableNavigationProperties ?? EmptyNavigationProperties;

IList<IEdmPropertyConstructor> properties = new List<IEdmPropertyConstructor>
{
new EdmPropertyConstructor(CapabilitiesVocabularyConstants.UpdateRestrictionsUpdatable,
new EdmBooleanConstant(isUpdatable)),

new EdmPropertyConstructor(CapabilitiesVocabularyConstants.UpdateRestrictionsNonUpdatableProperties,
new EdmCollectionExpression(
nonUpdatableProperties.Select(p => new EdmPropertyPathExpression(p.Name)).ToArray())),

new EdmPropertyConstructor(CapabilitiesVocabularyConstants.UpdateRestrictionsNonUpdatableNavigationProperties,
new EdmCollectionExpression(
nonUpdatableNavigationProperties.Select(p => new EdmNavigationPropertyPathExpression(p.Name)).ToArray()))
};

model.SetVocabularyAnnotation(target, properties, CapabilitiesVocabularyConstants.UpdateRestrictions);
}

/// <summary>
/// Set Org.OData.Capabilities.V1.DeleteRestrictions to target.
/// </summary>
/// <param name="model">The model referenced to.</param>
/// <param name="target">The target entity set to set the inline annotation.</param>
/// <param name="isDeletable">This entity set can be deleted.</param>
/// <param name="nonDeletableNavigationProperties">These navigation properties do not allow DeleteLink requests.</param>
public static void SetDeleteRestrictionsAnnotation(this EdmModel model, IEdmEntitySet target, bool isDeletable,
IEnumerable<IEdmNavigationProperty> nonDeletableNavigationProperties)
{
if (model == null)
{
throw Error.ArgumentNull("model");
}

if (target == null)
{
throw Error.ArgumentNull("target");
}

nonDeletableNavigationProperties = nonDeletableNavigationProperties ?? EmptyNavigationProperties;

IList<IEdmPropertyConstructor> properties = new List<IEdmPropertyConstructor>
{
new EdmPropertyConstructor(CapabilitiesVocabularyConstants.DeleteRestrictionsDeletable,
new EdmBooleanConstant(isDeletable)),

new EdmPropertyConstructor(CapabilitiesVocabularyConstants.DeleteRestrictionsNonDeletableNavigationProperties,
new EdmCollectionExpression(
nonDeletableNavigationProperties.Select(p => new EdmNavigationPropertyPathExpression(p.Name)).ToArray()))
};

model.SetVocabularyAnnotation(target, properties, CapabilitiesVocabularyConstants.DeleteRestrictions);
}

private static void SetVocabularyAnnotation(this EdmModel model, IEdmVocabularyAnnotatable target,
IList<IEdmPropertyConstructor> properties, string qualifiedName)
{
Expand Down
100 changes: 100 additions & 0 deletions src/Microsoft.AspNet.OData.Shared/Builder/EdmModelHelperMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,106 @@ private static void AddCapabilitiesVocabularyAnnotations(this EdmModel model, IE
model.AddFilterRestrictionsAnnotation(entitySet, entitySetConfig, edmTypeMap);
model.AddSortRestrictionsAnnotation(entitySet, entitySetConfig, edmTypeMap);
model.AddExpandRestrictionsAnnotation(entitySet, entitySetConfig, edmTypeMap);
model.AddInsertRestrictionsAnnotation(entitySet, entitySetConfig, edmTypeMap);
model.AddUpdateRestrictionsAnnotation(entitySet, entitySetConfig, edmTypeMap);
model.AddDeleteRestrictionsAnnotation(entitySet, entitySetConfig, edmTypeMap);
}
}

private static void AddInsertRestrictionsAnnotation(this EdmModel model, IEdmEntitySet target,
EntitySetConfiguration entitySetConfiguration, EdmTypeMap edmTypeMap)
{
EntityTypeConfiguration entityTypeConfig = entitySetConfiguration.EntityType;

IEnumerable<PropertyConfiguration> notInsertableProperties = entityTypeConfig.Properties.Where(property => property.NotInsertable);

IList<IEdmProperty> nonInsertableProperties = new List<IEdmProperty>();
IList<IEdmNavigationProperty> nonInsertableNavigationProperties = new List<IEdmNavigationProperty>();
foreach (PropertyConfiguration property in notInsertableProperties)
{
IEdmProperty value;
if (edmTypeMap.EdmProperties.TryGetValue(property.PropertyInfo, out value))
{
if (value != null)
{
if (value.PropertyKind == EdmPropertyKind.Navigation)
{
nonInsertableNavigationProperties.Add((IEdmNavigationProperty)value);
}
else
{
nonInsertableProperties.Add(value);
}
}
}
}

if (entitySetConfiguration.NotInsertable || nonInsertableProperties.Any() || nonInsertableNavigationProperties.Any())
{
model.SetInsertRestrictionsAnnotation(target, !entitySetConfiguration.NotInsertable, nonInsertableProperties, nonInsertableNavigationProperties);
}
}

private static void AddUpdateRestrictionsAnnotation(this EdmModel model, IEdmEntitySet target,
EntitySetConfiguration entitySetConfiguration, EdmTypeMap edmTypeMap)
{
EntityTypeConfiguration entityTypeConfig = entitySetConfiguration.EntityType;

IEnumerable<PropertyConfiguration> notUpdatableProperties = entityTypeConfig.Properties.Where(property => property.NotUpdatable);

IList<IEdmProperty> nonUpdatableProperties = new List<IEdmProperty>();
IList<IEdmNavigationProperty> nonUpdatableNavigationProperties = new List<IEdmNavigationProperty>();
foreach (PropertyConfiguration property in notUpdatableProperties)
{
IEdmProperty value;
if (edmTypeMap.EdmProperties.TryGetValue(property.PropertyInfo, out value))
{
if (value != null)
{
if (value.PropertyKind == EdmPropertyKind.Navigation)
{
nonUpdatableNavigationProperties.Add((IEdmNavigationProperty)value);
}
else
{
nonUpdatableProperties.Add(value);
}
}
}
}

if (entitySetConfiguration.NotUpdatable || nonUpdatableProperties.Any() || nonUpdatableNavigationProperties.Any())
{
model.SetUpdateRestrictionsAnnotation(target, !entitySetConfiguration.NotUpdatable, nonUpdatableProperties, nonUpdatableNavigationProperties);
}
}

private static void AddDeleteRestrictionsAnnotation(this EdmModel model, IEdmEntitySet target,
EntitySetConfiguration entitySetConfiguration, EdmTypeMap edmTypeMap)
{
EntityTypeConfiguration entityTypeConfig = entitySetConfiguration.EntityType;

IEnumerable<PropertyConfiguration> notDeletableProperties = entityTypeConfig.Properties.Where(property => property.NotDeletable);

IList<IEdmNavigationProperty> nonDeletableNavigationProperties = new List<IEdmNavigationProperty>();
foreach (PropertyConfiguration property in notDeletableProperties)
{
IEdmProperty value;
if (edmTypeMap.EdmProperties.TryGetValue(property.PropertyInfo, out value))
{
if (value != null)
{
if (value.PropertyKind == EdmPropertyKind.Navigation)
{
nonDeletableNavigationProperties.Add((IEdmNavigationProperty)value);
}
}
}
}

if (entitySetConfiguration.NotDeletable || nonDeletableNavigationProperties.Any())
{
model.SetDeleteRestrictionsAnnotation(target, !entitySetConfiguration.NotDeletable, nonDeletableNavigationProperties);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,5 +574,74 @@ private static Type VerifyBindingSegment(Type current, MemberInfo info)

return propertyInfo.PropertyType;
}

/// <summary>
/// Gets or sets whether the entity set is not insertable. Default is false.
/// </summary>
public bool NotInsertable { get; set; }

/// <summary>
/// Gets or sets whether the entity set is not updatable. Default is false.
/// </summary>
public bool NotUpdatable { get; set; }

/// <summary>
/// Gets or sets whether the entity set is not deletable. Default is false.
/// </summary>
public bool NotDeletable { get; set; }

/// <summary>
/// Sets the entity set as not insertable.
/// </summary>
public virtual NavigationSourceConfiguration IsNotInsertable()
{
NotInsertable = true;
return this;
}

/// <summary>
/// Sets the entity set as insertable.
/// </summary>
public virtual NavigationSourceConfiguration IsInsertable()
{
NotInsertable = false;
return this;
}

/// <summary>
/// Sets the entity set as not updatable.
/// </summary>
public virtual NavigationSourceConfiguration IsNotUpdatable()
{
NotUpdatable = true;
return this;
}

/// <summary>
/// Sets the entity set as updatable.
/// </summary>
public virtual NavigationSourceConfiguration IsUpdatable()
{
NotUpdatable = false;
return this;
}

/// <summary>
/// Sets the entity set as not deletable.
/// </summary>
public virtual NavigationSourceConfiguration IsNotDeletable()
{
NotDeletable = true;
return this;
}

/// <summary>
/// Sets the entity set as deletable.
/// </summary>
public virtual NavigationSourceConfiguration IsDeletable()
{
NotDeletable = false;
return this;
}
}
}
Loading