|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.DynamicUpdate
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime;
using System.Runtime.Serialization;
using System.ComponentModel;
[DataContract(IsReference = true)]
internal class DynamicUpdateMapEntry
{
static DynamicUpdateMapEntry dummyMapEntry = new DynamicUpdateMapEntry(-1, -1);
DynamicUpdateMap implementationUpdateMap;
int oldActivityId;
int newActivityId;
public DynamicUpdateMapEntry(int oldActivityId, int newActivityId)
{
this.OldActivityId = oldActivityId;
this.NewActivityId = newActivityId;
}
// this is a dummy map entry to be used for creating a NativeActivityUpdateContext
// for calling UpdateInstance() on activities without map entries.
// the OldActivityId and NewActivityId of this dummy map entry are invalid,
// and should not be used anywhere except for creating NativeActivityUpdateContext.
internal static DynamicUpdateMapEntry DummyMapEntry
{
get { return dummyMapEntry; }
}
public int OldActivityId
{
get
{
return this.oldActivityId;
}
private set
{
this.oldActivityId = value;
}
}
public int NewActivityId
{
get
{
return this.newActivityId;
}
private set
{
this.newActivityId = value;
}
}
[DataMember(EmitDefaultValue = false)]
public DynamicUpdateMapEntry Parent
{
get;
set;
}
// Only set when IsRemoval == true && IsParentRemovedOrBlock == false
[DataMember(EmitDefaultValue = false)]
public string DisplayName
{
get;
set;
}
[DataMember(EmitDefaultValue = false)]
public UpdateBlockedReason BlockReason { get; set; }
[DataMember(EmitDefaultValue = false)]
public string BlockReasonMessage { get; set; }
public bool IsRuntimeUpdateBlocked
{
get
{
return BlockReason != UpdateBlockedReason.NotBlocked;
}
}
[DataMember(EmitDefaultValue = false)]
public bool IsUpdateBlockedByUpdateAuthor { get; set; }
public bool IsParentRemovedOrBlocked
{
get
{
for (DynamicUpdateMapEntry parent = this.Parent; parent != null; parent = parent.Parent)
{
if (parent.IsRemoval || parent.IsRuntimeUpdateBlocked || parent.IsUpdateBlockedByUpdateAuthor)
{
return true;
}
}
return false;
}
}
[DataMember(EmitDefaultValue = false)]
public IDictionary<string, object> SavedOriginalValues { get; set; }
[DataMember(EmitDefaultValue = false)]
public object SavedOriginalValueFromParent { get; set; }
[DataMember(EmitDefaultValue = false)]
public EnvironmentUpdateMap EnvironmentUpdateMap
{
get;
set;
}
public DynamicUpdateMap ImplementationUpdateMap
{
get
{
return this.implementationUpdateMap;
}
internal set
{
this.implementationUpdateMap = value;
}
}
[DataMember(EmitDefaultValue = false, Name = "implementationUpdateMap")]
internal DynamicUpdateMap SerializedImplementationUpdateMap
{
get { return this.implementationUpdateMap; }
set { this.implementationUpdateMap = value; }
}
[DataMember(EmitDefaultValue = false, Name = "OldActivityId")]
internal int SerializedOldActivityId
{
get { return this.OldActivityId; }
set { this.OldActivityId = value; }
}
[DataMember(EmitDefaultValue = false, Name = "NewActivityId")]
internal int SerializedNewActivityId
{
get { return this.NewActivityId; }
set { this.NewActivityId = value; }
}
internal bool IsIdChange
{
get
{
return this.NewActivityId > 0 && this.OldActivityId > 0 && this.NewActivityId != this.OldActivityId;
}
}
internal bool IsRemoval
{
get
{
return this.NewActivityId <= 0 && this.OldActivityId > 0;
}
}
internal bool HasEnvironmentUpdates
{
get
{
return this.EnvironmentUpdateMap != null;
}
}
internal static DynamicUpdateMapEntry Merge(DynamicUpdateMapEntry first, DynamicUpdateMapEntry second,
DynamicUpdateMapEntry newParent, DynamicUpdateMap.MergeErrorContext errorContext)
{
Fx.Assert(first.NewActivityId == second.OldActivityId, "Merging mismatched entries");
Fx.Assert((first.Parent == null && second.Parent == null) || (first.Parent.NewActivityId == second.Parent.OldActivityId), "Merging mismatched parents");
DynamicUpdateMapEntry result = new DynamicUpdateMapEntry(first.OldActivityId, second.NewActivityId)
{
Parent = newParent
};
if (second.IsRemoval)
{
if (!result.IsParentRemovedOrBlocked)
{
result.DisplayName = second.DisplayName;
}
}
else
{
result.SavedOriginalValues = Merge(first.SavedOriginalValues, second.SavedOriginalValues);
result.SavedOriginalValueFromParent = first.SavedOriginalValueFromParent ?? second.SavedOriginalValueFromParent;
if (first.BlockReason == UpdateBlockedReason.NotBlocked)
{
result.BlockReason = second.BlockReason;
result.BlockReasonMessage = second.BlockReasonMessage;
}
else
{
result.BlockReason = first.BlockReason;
result.BlockReasonMessage = second.BlockReasonMessage;
}
result.IsUpdateBlockedByUpdateAuthor = first.IsUpdateBlockedByUpdateAuthor || second.IsUpdateBlockedByUpdateAuthor;
errorContext.PushIdSpace(result.NewActivityId);
result.EnvironmentUpdateMap = EnvironmentUpdateMap.Merge(first.EnvironmentUpdateMap, second.EnvironmentUpdateMap, errorContext);
if (!result.IsRuntimeUpdateBlocked && !result.IsUpdateBlockedByUpdateAuthor && !result.IsParentRemovedOrBlocked)
{
result.ImplementationUpdateMap = DynamicUpdateMap.Merge(first.ImplementationUpdateMap, second.ImplementationUpdateMap, errorContext);
}
errorContext.PopIdSpace();
};
return result;
}
internal static IDictionary<string, object> Merge(IDictionary<string, object> first, IDictionary<string, object> second)
{
if (first == null || second == null)
{
return first ?? second;
}
Dictionary<string, object> result = new Dictionary<string, object>(first);
foreach (KeyValuePair<string, object> pair in second)
{
if (!result.ContainsKey(pair.Key))
{
result.Add(pair.Key, pair.Value);
}
}
return result;
}
internal DynamicUpdateMapEntry Clone(DynamicUpdateMapEntry newParent)
{
return new DynamicUpdateMapEntry(this.OldActivityId, this.NewActivityId)
{
DisplayName = this.DisplayName,
EnvironmentUpdateMap = this.EnvironmentUpdateMap,
ImplementationUpdateMap = this.ImplementationUpdateMap,
BlockReason = this.BlockReason,
BlockReasonMessage = this.BlockReasonMessage,
IsUpdateBlockedByUpdateAuthor = this.IsUpdateBlockedByUpdateAuthor,
Parent = newParent,
SavedOriginalValues = this.SavedOriginalValues,
SavedOriginalValueFromParent = this.SavedOriginalValueFromParent
};
}
}
}
|