142 lines
5.4 KiB
C#
142 lines
5.4 KiB
C#
|
//----------------------------------------------------------------
|
|||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
//----------------------------------------------------------------
|
|||
|
|
|||
|
namespace System.Runtime.DurableInstancing
|
|||
|
{
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Collections.ObjectModel;
|
|||
|
using System.Runtime;
|
|||
|
using System.Xml.Linq;
|
|||
|
|
|||
|
static class InstancePersistence
|
|||
|
{
|
|||
|
static readonly XNamespace activitiesCommandNamespace = XNamespace.Get("urn:schemas-microsoft-com:System.Activities.Persistence/command");
|
|||
|
static readonly XNamespace activitiesEventNamespace = XNamespace.Get("urn:schemas-microsoft-com:System.Activities.Persistence/event");
|
|||
|
|
|||
|
internal static XNamespace ActivitiesCommandNamespace
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return InstancePersistence.activitiesCommandNamespace;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal static XNamespace ActivitiesEventNamespace
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return InstancePersistence.activitiesEventNamespace;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void ValidatePropertyBag(this IDictionary<XName, InstanceValue> bag)
|
|||
|
{
|
|||
|
bag.ValidatePropertyBag(false);
|
|||
|
}
|
|||
|
|
|||
|
public static void ValidatePropertyBag(this IDictionary<XName, InstanceValue> bag, bool allowDelete)
|
|||
|
{
|
|||
|
if (bag != null)
|
|||
|
{
|
|||
|
foreach (KeyValuePair<XName, InstanceValue> property in bag)
|
|||
|
{
|
|||
|
property.ValidateProperty(allowDelete);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void ValidateProperty(this KeyValuePair<XName, InstanceValue> property)
|
|||
|
{
|
|||
|
property.ValidateProperty(false);
|
|||
|
}
|
|||
|
|
|||
|
public static void ValidateProperty(this KeyValuePair<XName, InstanceValue> property, bool allowDelete)
|
|||
|
{
|
|||
|
if (property.Key == null)
|
|||
|
{
|
|||
|
throw Fx.Exception.AsError(new InvalidOperationException(SRCore.MetadataCannotContainNullKey));
|
|||
|
}
|
|||
|
if (property.Value == null)
|
|||
|
{
|
|||
|
throw Fx.Exception.AsError(new InvalidOperationException(SRCore.MetadataCannotContainNullValue(property.Key)));
|
|||
|
}
|
|||
|
if (!allowDelete && property.Value.IsDeletedValue)
|
|||
|
{
|
|||
|
throw Fx.Exception.AsError(new InvalidOperationException(SRCore.InitialMetadataCannotBeDeleted(property.Key)));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static bool IsOptional(this InstanceValue value)
|
|||
|
{
|
|||
|
return (value.Options & InstanceValueOptions.Optional) != 0;
|
|||
|
}
|
|||
|
|
|||
|
public static bool IsWriteOnly(this InstanceValue value)
|
|||
|
{
|
|||
|
return (value.Options & InstanceValueOptions.WriteOnly) != 0;
|
|||
|
}
|
|||
|
|
|||
|
public static ReadOnlyDictionaryInternal<XName, InstanceValue> ReadOnlyCopy(this IDictionary<XName, InstanceValue> bag, bool allowWriteOnly)
|
|||
|
{
|
|||
|
if (bag != null && bag.Count > 0)
|
|||
|
{
|
|||
|
Dictionary<XName, InstanceValue> copy = new Dictionary<XName, InstanceValue>(bag.Count);
|
|||
|
foreach (KeyValuePair<XName, InstanceValue> value in bag)
|
|||
|
{
|
|||
|
value.ValidateProperty();
|
|||
|
if (!value.Value.IsWriteOnly())
|
|||
|
{
|
|||
|
copy.Add(value.Key, value.Value);
|
|||
|
}
|
|||
|
else if (!allowWriteOnly)
|
|||
|
{
|
|||
|
throw Fx.Exception.AsError(new InvalidOperationException(SRCore.LoadedWriteOnlyValue));
|
|||
|
}
|
|||
|
}
|
|||
|
return new ReadOnlyDictionaryInternal<XName, InstanceValue>(copy);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static ReadOnlyDictionaryInternal<XName, InstanceValue> ReadOnlyMergeInto(this IDictionary<XName, InstanceValue> bag, IDictionary<XName, InstanceValue> existing, bool allowWriteOnly)
|
|||
|
{
|
|||
|
Fx.Assert(existing == null || existing is ReadOnlyDictionaryInternal<XName, InstanceValue>, "Should only be merging into other read-only dictionaries.");
|
|||
|
|
|||
|
if (bag != null && bag.Count > 0)
|
|||
|
{
|
|||
|
Dictionary<XName, InstanceValue> copy = existing == null ? new Dictionary<XName, InstanceValue>(bag.Count) : new Dictionary<XName, InstanceValue>(existing);
|
|||
|
foreach (KeyValuePair<XName, InstanceValue> value in bag)
|
|||
|
{
|
|||
|
value.ValidateProperty(true);
|
|||
|
if (value.Value.IsDeletedValue)
|
|||
|
{
|
|||
|
copy.Remove(value.Key);
|
|||
|
}
|
|||
|
else if (!value.Value.IsWriteOnly())
|
|||
|
{
|
|||
|
copy[value.Key] = value.Value;
|
|||
|
}
|
|||
|
else if (!allowWriteOnly)
|
|||
|
{
|
|||
|
throw Fx.Exception.AsError(new InvalidOperationException(SRCore.LoadedWriteOnlyValue));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
copy.Remove(value.Key);
|
|||
|
}
|
|||
|
}
|
|||
|
return new ReadOnlyDictionaryInternal<XName, InstanceValue>(copy);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return (ReadOnlyDictionaryInternal<XName, InstanceValue>)existing;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|