Skip to content

Commit

Permalink
bulk ops deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
ElizabethOkerio committed Oct 18, 2022
1 parent cda7e83 commit 22bd66b
Show file tree
Hide file tree
Showing 22 changed files with 2,283 additions and 1,097 deletions.
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.OData.Shared/DeltaSetOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.OData
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NonValidatingParameterBinding]
internal class DeltaSet<TStructuralType> : Collection<IDeltaSetItem>, IDeltaSet where TStructuralType : class
public class DeltaSet<TStructuralType> : Collection<IDeltaSetItem>, IDeltaSet where TStructuralType : class
{
private Type _clrType;
private IList<string> _keys;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ internal static bool CanWriteType(
ODataPayloadKind? payloadKind;

Type elementType;
if (typeof(IEdmObject).IsAssignableFrom(type) ||
if (typeof(IEdmObject).IsAssignableFrom(type) ||
typeof(IDeltaSet).IsAssignableFrom(type) ||
(TypeHelper.IsCollection(type, out elementType) && typeof(IEdmObject).IsAssignableFrom(elementType)))
{
payloadKind = GetEdmObjectPayloadKind(type, internalRequest);
Expand Down Expand Up @@ -156,7 +157,16 @@ internal static void WriteToStream(

ODataMessageWriterSettings writerSettings = internalRequest.WriterSettings;
writerSettings.BaseUri = baseAddress;
writerSettings.Version = version;

if (serializer.ODataPayloadKind == ODataPayloadKind.Delta)
{
writerSettings.Version = ODataVersion.V401;
}
else
{
writerSettings.Version = version;
}

writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

string metadataLink = internaUrlHelper.CreateODataLink(MetadataSegment.Instance);
Expand Down Expand Up @@ -207,6 +217,7 @@ internal static void WriteToStream(
writeContext.Path = path;
writeContext.MetadataLevel = metadataLevel;
writeContext.QueryOptions = internalRequest.Context.QueryOptions;
writeContext.Type = type;

//Set the SelectExpandClause on the context if it was explicitly specified.
if (selectExpandDifferentFromQueryOptions != null)
Expand Down Expand Up @@ -251,7 +262,7 @@ internal static void WriteToStream(
{
return ODataPayloadKind.ResourceSet;
}
else if (typeof(IEdmChangedObject).IsAssignableFrom(elementType))
else if (typeof(IDeltaSetItem).IsAssignableFrom(elementType) || typeof(IEdmChangedObject).IsAssignableFrom(elementType))
{
return ODataPayloadKind.Delta;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ internal ODataSerializer GetODataPayloadSerializerImpl(Type type, Func<IEdmModel
{
return _rootContainer.GetRequiredService<ODataMetadataSerializer>();
}
else if (TypeHelper.IsTypeAssignableFrom(typeof(IDeltaSet), type))
{
return _rootContainer.GetRequiredService<ODataDeltaFeedSerializer>();
}

// Get the model. Using a Func<IEdmModel> to delay evaluation of the model
// until after the above checks have passed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
//------------------------------------------------------------------------------

using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNet.OData.Builder;
Expand All @@ -25,6 +28,7 @@ namespace Microsoft.AspNet.OData.Formatter.Serialization
public class ODataDeltaFeedSerializer : ODataEdmTypeSerializer
{
private const string DeltaFeed = "deltafeed";
IEdmStructuredTypeReference _elementType;

/// <summary>
/// Initializes a new instance of <see cref="ODataDeltaFeedSerializer"/>.
Expand Down Expand Up @@ -60,6 +64,7 @@ public override void WriteObject(object graph, Type type, ODataMessageWriter mes
}

IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

Contract.Assert(feedType != null);

IEdmEntityTypeReference entityType = GetResourceType(feedType).AsEntity();
Expand Down Expand Up @@ -93,6 +98,7 @@ public override async Task WriteObjectAsync(object graph, Type type, ODataMessag
}

IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

Contract.Assert(feedType != null);

IEdmEntityTypeReference entityType = GetResourceType(feedType).AsEntity();
Expand Down Expand Up @@ -186,6 +192,7 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
Contract.Assert(feedType != null);

IEdmStructuredTypeReference elementType = GetResourceType(feedType);
_elementType = elementType;

if (elementType.IsComplex())
{
Expand Down Expand Up @@ -234,13 +241,9 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
}

lastResource = entry;
IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
if (edmChangedObject == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
}
EdmDeltaEntityKind deltaEntityKind = GetDeltaEntityKind(enumerable, entry, writeContext);

switch (edmChangedObject.DeltaKind)
switch (deltaEntityKind)
{
case EdmDeltaEntityKind.DeletedEntry:
WriteDeltaDeletedEntry(entry, writer, writeContext);
Expand All @@ -254,6 +257,7 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
case EdmDeltaEntityKind.Entry:
{
ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataResourceSerializer;

if (entrySerializer == null)
{
throw new SerializationException(
Expand Down Expand Up @@ -289,6 +293,7 @@ private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feed
Contract.Assert(feedType != null);

IEdmStructuredTypeReference elementType = GetResourceType(feedType);
_elementType = elementType;

if (elementType.IsComplex())
{
Expand Down Expand Up @@ -337,13 +342,9 @@ private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feed
}

lastResource = entry;
IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
if (edmChangedObject == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
}
EdmDeltaEntityKind deltaEntityKind = GetDeltaEntityKind(enumerable, entry, writeContext);

switch (edmChangedObject.DeltaKind)
switch (deltaEntityKind)
{
case EdmDeltaEntityKind.DeletedEntry:
await WriteDeltaDeletedEntryAsync(entry, writer, writeContext);
Expand Down Expand Up @@ -441,12 +442,25 @@ public virtual ODataDeltaResourceSet CreateODataDeltaFeed(IEnumerable feedInstan
/// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
public virtual void WriteDeltaDeletedEntry(object graph, ODataWriter writer, ODataSerializerContext writeContext)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph);
ODataResourceSerializer serializer = SerializerProvider.GetEdmTypeSerializer(_elementType) as ODataResourceSerializer;

if (deletedResource != null)
if (serializer == null)
{
throw new SerializationException(
Error.Format(SRResources.TypeCannotBeSerialized, _elementType.FullName()));
}
else
{
writer.WriteStart(deletedResource);
writer.WriteEnd();
ResourceContext resourceContext = serializer.GetResourceContext(graph, writeContext);
SelectExpandNode selectExpandNode = serializer.CreateSelectExpandNode(resourceContext);

if (selectExpandNode != null)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph, resourceContext, serializer, selectExpandNode, writeContext.IsUntyped);
writer.WriteStart(deletedResource);
serializer.WriteDeltaComplexProperties(selectExpandNode, resourceContext, writer);
writer.WriteEnd();
}
}
}

Expand All @@ -459,10 +473,22 @@ public virtual void WriteDeltaDeletedEntry(object graph, ODataWriter writer, ODa
/// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
public virtual async Task WriteDeltaDeletedEntryAsync(object graph, ODataWriter writer, ODataSerializerContext writeContext)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph);
if (deletedResource != null)
ODataResourceSerializer serializer = SerializerProvider.GetEdmTypeSerializer(_elementType) as ODataResourceSerializer;

if (serializer == null)
{
throw new SerializationException(
Error.Format(SRResources.TypeCannotBeSerialized, _elementType.FullName()));
}

ResourceContext resourceContext = serializer.GetResourceContext(graph, writeContext);
SelectExpandNode selectExpandNode = serializer.CreateSelectExpandNode(resourceContext);

if (selectExpandNode != null)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph, resourceContext, serializer, selectExpandNode, writeContext.IsUntyped);
await writer.WriteStartAsync(deletedResource);
await serializer.WriteDeltaComplexPropertiesAsync(selectExpandNode, resourceContext, writer);
await writer.WriteEndAsync();
}
}
Expand Down Expand Up @@ -531,22 +557,41 @@ public async Task WriteDeltaLinkAsync(object graph, ODataWriter writer, ODataSer
}
}

private ODataDeletedResource GetDeletedResource(object graph)
private ODataDeletedResource GetDeletedResource(object graph, ResourceContext resourceContext, ODataResourceSerializer serializer, SelectExpandNode selectExpandNode, bool isUntyped)
{
EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject;
if (edmDeltaDeletedEntity == null)
string navigationSource;
ODataDeletedResource deletedResource = serializer.CreateDeletedResource(selectExpandNode, resourceContext);

if (isUntyped)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject;
if (edmDeltaDeletedEntity == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
}

deletedResource.Id = StringToUri(edmDeltaDeletedEntity.Id ?? string.Empty);
deletedResource.Reason = edmDeltaDeletedEntity.Reason;
navigationSource = edmDeltaDeletedEntity.NavigationSource?.Name;
}
else
{
IDeltaDeletedEntityObject deltaDeletedEntity = graph as IDeltaDeletedEntityObject;
if (deltaDeletedEntity == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
}

Uri id = StringToUri(edmDeltaDeletedEntity.Id);
ODataDeletedResource deletedResource = new ODataDeletedResource(id, edmDeltaDeletedEntity.Reason);
deletedResource.Id = deltaDeletedEntity.Id;
deletedResource.Reason = deltaDeletedEntity.Reason;
navigationSource = deltaDeletedEntity.NavigationSource;
}

if (edmDeltaDeletedEntity.NavigationSource != null)
if (navigationSource != null)
{
ODataResourceSerializationInfo serializationInfo = new ODataResourceSerializationInfo
{
NavigationSourceName = edmDeltaDeletedEntity.NavigationSource.Name
NavigationSourceName = navigationSource
};
deletedResource.SetSerializationInfo(serializationInfo);
}
Expand Down Expand Up @@ -621,5 +666,35 @@ internal static Uri StringToUri(string uriString)

return uri;
}

private EdmDeltaEntityKind GetDeltaEntityKind(IEnumerable enumerable, object entry, ODataSerializerContext writeContext)
{
EdmDeltaEntityKind deltaEntityKind;

if (writeContext.IsUntyped)
{
IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;

if (edmChangedObject == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
}

deltaEntityKind = edmChangedObject.DeltaKind;
}
else
{
IDeltaSetItem deltaSetItem = entry as IDeltaSetItem;

if (deltaSetItem == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
}

deltaEntityKind = deltaSetItem.DeltaKind;
}

return deltaEntityKind;
}
}
}
Loading

0 comments on commit 22bd66b

Please sign in to comment.