Exemple #1
0
        // For most of the time, we need source location for object that appear on XAML.
        // During debugging, however, we must not transform the internal activity to their origin to make sure it stop when the internal activity is about the execute
        // Therefore, in debugger scenario, translateInternalActivityToOrigin will be set to false.
        internal static Dictionary <object, SourceLocation> GetSourceLocations(Activity rootActivity, WorkflowSymbol symbol, bool translateInternalActivityToOrigin)
        {
            Activity workflowRoot = rootActivity.RootActivity ?? rootActivity;

            if (!workflowRoot.IsMetadataFullyCached)
            {
                IList <ValidationError> validationErrors = null;
                ActivityUtilities.CacheRootMetadata(workflowRoot, new ActivityLocationReferenceEnvironment(), ProcessActivityTreeOptions.ValidationOptions, null, ref validationErrors);
            }

            Dictionary <object, SourceLocation> newMapping = new Dictionary <object, SourceLocation>();

            // Make sure the qid we are using to TryGetElementFromRoot
            // are shifted appropriately such that the first digit that QID is
            // the same as the last digit of the rootActivity.QualifiedId.

            int[] rootIdArray = rootActivity.QualifiedId.AsIDArray();
            int   idOffset    = rootIdArray[rootIdArray.Length - 1] - 1;

            foreach (ActivitySymbol actSym in symbol.Symbols)
            {
                QualifiedId qid = new QualifiedId(actSym.QualifiedId);
                if (idOffset != 0)
                {
                    int[] idArray = qid.AsIDArray();
                    idArray[0] += idOffset;
                    qid         = new QualifiedId(idArray);
                }
                Activity activity;
                if (QualifiedId.TryGetElementFromRoot(rootActivity, qid, out activity))
                {
                    object origin = activity;
                    if (translateInternalActivityToOrigin && activity.Origin != null)
                    {
                        origin = activity.Origin;
                    }

                    newMapping.Add(origin,
                                   new SourceLocation(symbol.FileName, symbol.GetChecksum(), actSym.StartLine, actSym.StartColumn, actSym.EndLine, actSym.EndColumn));
                }
            }
            return(newMapping);
        }
Exemple #2
0
        // rootIdSpace is optional.  if it's null, result.NewActivity will be null
        internal UpdatedActivity GetUpdatedActivity(QualifiedId oldQualifiedId, IdSpace rootIdSpace)
        {
            UpdatedActivity result = new UpdatedActivity();

            int[]            oldIdSegments  = oldQualifiedId.AsIDArray();
            int[]            newIdSegments  = null;
            IdSpace          currentIdSpace = rootIdSpace;
            DynamicUpdateMap currentMap     = this;

            Fx.Assert(!this.IsForImplementation, "This method is never supposed to be called on an implementation map.");

            for (int i = 0; i < oldIdSegments.Length; i++)
            {
                if (currentMap == null || currentMap.Entries.Count == 0)
                {
                    break;
                }

                DynamicUpdateMapEntry entry;
                if (!currentMap.TryGetUpdateEntry(oldIdSegments[i], out entry))
                {
                    // UpdateMap should contain entries for all old activities in the IdSpace
                    int[] subIdSegments = new int[i + 1];
                    Array.Copy(oldIdSegments, subIdSegments, subIdSegments.Length);
                    throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidUpdateMap(
                                                                                    SR.MapEntryNotFound(new QualifiedId(subIdSegments)))));
                }

                if (entry.IsIdChange)
                {
                    if (newIdSegments == null)
                    {
                        newIdSegments = new int[oldIdSegments.Length];
                        Array.Copy(oldIdSegments, newIdSegments, oldIdSegments.Length);
                    }

                    newIdSegments[i] = entry.NewActivityId;
                }

                Activity currentActivity = null;
                if (currentIdSpace != null && !entry.IsRemoval)
                {
                    currentActivity = currentIdSpace[entry.NewActivityId];
                    if (currentActivity == null)
                    {
                        // New Activity pointed to by UpdateMap should exist
                        string activityId = currentIdSpace.Owner.Id + "." + entry.NewActivityId.ToString(CultureInfo.InvariantCulture);
                        throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidUpdateMap(
                                                                                        SR.ActivityNotFound(activityId))));
                    }
                    currentIdSpace = currentActivity.ParentOf;
                }

                if (i == oldIdSegments.Length - 1)
                {
                    result.Map         = currentMap;
                    result.MapEntry    = entry;
                    result.NewActivity = currentActivity;
                }
                else if (entry.IsRuntimeUpdateBlocked || entry.IsUpdateBlockedByUpdateAuthor)
                {
                    currentMap = null;
                }
                else
                {
                    currentMap = entry.ImplementationUpdateMap;
                }
            }

            result.IdChanged = newIdSegments != null;
            result.NewId     = result.IdChanged ? new QualifiedId(newIdSegments) : oldQualifiedId;

            return(result);
        }
        // targetDefinition argument is optional.
        private IList <InstanceListNeedingUpdate> GetInstanceListsNeedingUpdate(DynamicUpdateMap updateMap, Activity targetDefinition, List <ActivityInstance> secondaryRootInstances, ref Collection <ActivityBlockingUpdate> updateErrors)
        {
            IList <InstanceListNeedingUpdate> instanceListsToUpdate = new List <InstanceListNeedingUpdate>();

            if (this.rawDeserializedLists == null)
            {
                // This instance doesn't have any active instances (it is complete).
                return(instanceListsToUpdate);
            }

            IdSpace rootIdSpace = null;

            if (targetDefinition != null)
            {
                rootIdSpace = targetDefinition.MemberOf;
            }

            for (int i = 0; i < this.rawDeserializedLists.Length; i++)
            {
                InstanceList list           = this.rawDeserializedLists[i];
                QualifiedId  oldQualifiedId = new QualifiedId(list.ActivityId);

                if (updateMap.IsImplementationAsRoot)
                {
                    int[] oldIdArray = oldQualifiedId.AsIDArray();
                    if (oldIdArray.Length == 1 && oldIdArray[0] != 1)
                    {
                        throw FxTrace.Exception.AsError(new InstanceUpdateException(SR.InvalidImplementationAsWorkflowRootForRuntimeState));
                    }
                }

                string error;
                InstanceListNeedingUpdate        update;
                DynamicUpdateMap.UpdatedActivity updatedActivity = updateMap.GetUpdatedActivity(oldQualifiedId, rootIdSpace);

                if (CanCompensationOrConfirmationHandlerReferenceAddedSymbols(list, updateMap, rootIdSpace, secondaryRootInstances, ref updateErrors))
                {
                    update = null;
                }
                else if (updatedActivity.MapEntry == null)
                {
                    if (updatedActivity.IdChanged)
                    {
                        // this newQualifiedId is the new id for those InstanceLists whose IDs shifted by their parents' ID change
                        update = new InstanceListNeedingUpdate
                        {
                            InstanceList = list,
                            NewId        = updatedActivity.NewId
                        };
                    }
                    else
                    {
                        // nothing changed, no map, no mapEntry
                        update = new InstanceListNeedingUpdate
                        {
                            InstanceList = list,
                            NewId        = null,
                        };
                    }
                }
                else if (updatedActivity.MapEntry.IsParentRemovedOrBlocked)
                {
                    update = null;
                }
                else if (IsRemovalOrRTUpdateBlockedOrBlockedByUser(updatedActivity, oldQualifiedId, out error))
                {
                    string instanceId = null;
                    for (int j = 0; j < list.Count; j++)
                    {
                        ActivityInstance activityInstance = list[j] as ActivityInstance;
                        if (activityInstance != null)
                        {
                            instanceId = activityInstance.Id;
                            break;
                        }
                    }
                    AddBlockingActivity(ref updateErrors, updatedActivity, oldQualifiedId, error, instanceId);

                    update = null;
                }
                else if (IsInvalidEnvironmentUpdate(list, updatedActivity, ref updateErrors))
                {
                    update = null;
                }
                else
                {
                    // no validation error for this InstanceList
                    // add it to the list of InstanceLists to be updated
                    update = new InstanceListNeedingUpdate
                    {
                        InstanceList = list,
                        NewId        = updatedActivity.NewId,
                        UpdateMap    = updatedActivity.Map,
                        MapEntry     = updatedActivity.MapEntry,
                        NewActivity  = updatedActivity.NewActivity
                    };
                }

                if (update != null)
                {
                    update.OriginalId = list.ActivityId;
                    instanceListsToUpdate.Add(update);
                }
            }

            return(instanceListsToUpdate);
        }
        // For most of the time, we need source location for object that appear on XAML.
        // During debugging, however, we must not transform the internal activity to their origin to make sure it stop when the internal activity is about the execute
        // Therefore, in debugger scenario, translateInternalActivityToOrigin will be set to false.
        internal static Dictionary<object, SourceLocation> GetSourceLocations(Activity rootActivity, WorkflowSymbol symbol, bool translateInternalActivityToOrigin)
        {
            Activity workflowRoot = rootActivity.RootActivity ?? rootActivity;
            if (!workflowRoot.IsMetadataFullyCached)
            {
                IList<ValidationError> validationErrors = null;
                ActivityUtilities.CacheRootMetadata(workflowRoot, new ActivityLocationReferenceEnvironment(), ProcessActivityTreeOptions.ValidationOptions, null, ref validationErrors);
            }

            Dictionary<object, SourceLocation> newMapping = new Dictionary<object, SourceLocation>();

            // Make sure the qid we are using to TryGetElementFromRoot
            // are shifted appropriately such that the first digit that QID is
            // the same as the last digit of the rootActivity.QualifiedId.

            int[] rootIdArray = rootActivity.QualifiedId.AsIDArray();
            int idOffset = rootIdArray[rootIdArray.Length - 1] - 1;

            foreach (ActivitySymbol actSym in symbol.Symbols)
            {
                QualifiedId qid = new QualifiedId(actSym.QualifiedId);
                if (idOffset != 0)
                {
                    int[] idArray = qid.AsIDArray();
                    idArray[0] += idOffset;
                    qid = new QualifiedId(idArray);
                }
                Activity activity;
                if (QualifiedId.TryGetElementFromRoot(rootActivity, qid, out activity))
                {
                    object origin = activity;
                    if (translateInternalActivityToOrigin && activity.Origin != null)
                    {
                        origin = activity.Origin;
                    }

                    newMapping.Add(origin,
                        new SourceLocation(symbol.FileName, symbol.GetChecksum(), actSym.StartLine, actSym.StartColumn, actSym.EndLine, actSym.EndColumn));
                }
            }
            return newMapping;
        }