コード例 #1
0
ファイル: ActivityInstanceMap.cs プロジェクト: wforney/corewf
        private static bool IsInvalidEnvironmentUpdate(InstanceList instanceList, DynamicUpdateMap.UpdatedActivity updatedActivity, ref Collection <ActivityBlockingUpdate> updateErrors)
        {
            if (updatedActivity.MapEntry == null || !updatedActivity.MapEntry.HasEnvironmentUpdates)
            {
                return(false);
            }

            for (int j = 0; j < instanceList.Count; j++)
            {
                ActivityInstance activityInstance = instanceList[j] as ActivityInstance;
                if (activityInstance != null)
                {
                    string error = null;
                    if (activityInstance.SubState == ActivityInstance.Substate.ResolvingVariables)
                    {
                        // if the entry has Environment update to do when the instance is in the
                        // middle of resolving variable, it is an error.
                        error = SR.CannotUpdateEnvironmentInTheMiddleOfResolvingVariables;
                    }
                    else if (activityInstance.SubState == ActivityInstance.Substate.ResolvingArguments)
                    {
                        // if the entry has Environment update to do when the instance is in the
                        // middle of resolving arguments, it is an error.
                        error = SR.CannotUpdateEnvironmentInTheMiddleOfResolvingArguments;
                    }

                    if (error != null)
                    {
                        AddBlockingActivity(ref updateErrors, updatedActivity, new QualifiedId(instanceList.ActivityId), error, activityInstance.Id);
                        return(true);
                    }
                }
                else
                {
                    LocationEnvironment environment = instanceList[j] as LocationEnvironment;
                    if (environment != null)
                    {
                        // environment that is referenced by a secondary root Adding a variable or
                        // argument that requires expression scheduling to this instanceless
                        // environment is not allowed.
                        List <int>           dummyIndexes;
                        EnvironmentUpdateMap envMap = updatedActivity.MapEntry.EnvironmentUpdateMap;

                        if ((envMap.HasVariableEntries && TryGatherSchedulableExpressions(envMap.VariableEntries, out dummyIndexes)) ||
                            (envMap.HasPrivateVariableEntries && TryGatherSchedulableExpressions(envMap.PrivateVariableEntries, out dummyIndexes)) ||
                            (envMap.HasArgumentEntries && TryGatherSchedulableExpressions(envMap.ArgumentEntries, out dummyIndexes)))
                        {
                            AddBlockingActivity(ref updateErrors, updatedActivity, new QualifiedId(instanceList.ActivityId), SR.VariableOrArgumentAdditionToReferencedEnvironmentNoDUSupported, null);
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
コード例 #2
0
        private static bool IsRemovalOrRTUpdateBlockedOrBlockedByUser(DynamicUpdateMap.UpdatedActivity updatedActivity, QualifiedId oldQualifiedId, out string error)
        {
            error = null;
            if (updatedActivity.MapEntry.IsRemoval)
            {
                //

                error = SR.CannotRemoveExecutingActivityUpdateError(oldQualifiedId, updatedActivity.MapEntry.DisplayName);
            }
            else if (updatedActivity.MapEntry.IsRuntimeUpdateBlocked)
            {
                error = updatedActivity.MapEntry.BlockReasonMessage ?? UpdateBlockedReasonMessages.Get(updatedActivity.MapEntry.BlockReason);
            }
            else if (updatedActivity.MapEntry.IsUpdateBlockedByUpdateAuthor)
            {
                error = SR.BlockedUpdateInsideActivityUpdateByUserError;
            }

            return(error != null);
        }
コード例 #3
0
        private static bool IsRemovalOrRTUpdateBlockedOrBlockedByUser(DynamicUpdateMap.UpdatedActivity updatedActivity, QualifiedId oldQualifiedId, out string error)
        {
            error = null;
            if (updatedActivity.MapEntry.IsRemoval)
            {
                // TODO, 190894, this will prevent us from removing a completed activity whose
                // completion callback has not been called.
                error = SR.CannotRemoveExecutingActivityUpdateError(oldQualifiedId, updatedActivity.MapEntry.DisplayName);
            }
            else if (updatedActivity.MapEntry.IsRuntimeUpdateBlocked)
            {
                error = updatedActivity.MapEntry.BlockReasonMessage ?? UpdateBlockedReasonMessages.Get(updatedActivity.MapEntry.BlockReason);
            }
            else if (updatedActivity.MapEntry.IsUpdateBlockedByUpdateAuthor)
            {
                error = SR.BlockedUpdateInsideActivityUpdateByUserError;
            }

            return(error != null);
        }
コード例 #4
0
 private static void AddBlockingActivity(ref Collection <ActivityBlockingUpdate> updateErrors, DynamicUpdateMap.UpdatedActivity updatedActivity, QualifiedId originalId, string reason, string activityInstanceId)
 {
     if (updatedActivity.NewActivity != null)
     {
         ActivityBlockingUpdate.AddBlockingActivity(ref updateErrors, updatedActivity.NewActivity, originalId.ToString(), reason, activityInstanceId);
     }
     else
     {
         string updatedId = updatedActivity.MapEntry.IsRemoval ? null : updatedActivity.NewId.ToString();
         ActivityBlockingUpdate.AddBlockingActivity(ref updateErrors, updatedId, originalId.ToString(), reason, activityInstanceId);
     }
 }
コード例 #5
0
        // 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);
        }
コード例 #6
0
        private static bool CanCompensationOrConfirmationHandlerReferenceAddedSymbols(InstanceList instanceList, DynamicUpdateMap rootUpdateMap, IdSpace rootIdSpace, List <ActivityInstance> secondaryRootInstances, ref Collection <ActivityBlockingUpdate> updateErrors)
        {
            for (int j = 0; j < instanceList.Count; j++)
            {
                ActivityInstance activityInstance = instanceList[j] as ActivityInstance;
                if (activityInstance == null || !IsNonDefaultSecondaryRoot(activityInstance, secondaryRootInstances))
                {
                    continue;
                }

                // here, find out if the given non-default secondary root references an environment to which a symbol is to be added via DU.
                // we start from a secondary root instead of starting from the enviroment with the already completed owner that was added symbols.
                // It is becuase for the case of adding symbols to noSymbols activities, the environment doesn't even exist from which we can start looking for referencing secondary root.

                int[] secondaryRootOriginalQID = new QualifiedId(instanceList.ActivityId).AsIDArray();

                Fx.Assert(secondaryRootOriginalQID != null && secondaryRootOriginalQID.Length > 1,
                          "CompensationParticipant is always an implementation child of a CompensableActivity, therefore it's IdSpace must be at least one level deep.");

                int[] parentOfSecondaryRootOriginalQID = new int[secondaryRootOriginalQID.Length - 1];
                Array.Copy(secondaryRootOriginalQID, parentOfSecondaryRootOriginalQID, secondaryRootOriginalQID.Length - 1);

                List <int> currentQIDBuilder = new List <int>();
                for (int i = 0; i < parentOfSecondaryRootOriginalQID.Length; i++)
                {
                    //
                    // for each iteration of this for-loop,
                    //  we are finding out if at every IdSpace level the map has any map entry whose activity has the CompensableActivity as an implementation decendant.
                    //  The map may not exist for every IdSpace between the root and the CompensableActivity.
                    //  If the matching map and the entry is found, then we find out if that matching entry's activity is a public decendant of any NoSymbols activity DU is to add variables or arguments to.
                    //
                    // This walk on the definition activity tree determines the hypothetical execution-time chain of instances and environments.
                    // The ultimate goal is to prevent adding variables or arguments to a NoSymbols activity which has already completed,
                    //  but its decendant CompensableActivity's compensation or confirmation handlers in the future may need to reference the added variables or arguments.

                    currentQIDBuilder.Add(parentOfSecondaryRootOriginalQID[i]);

                    DynamicUpdateMap.UpdatedActivity updatedActivity = rootUpdateMap.GetUpdatedActivity(new QualifiedId(currentQIDBuilder.ToArray()), rootIdSpace);
                    if (updatedActivity.MapEntry != null)
                    {
                        // the activity of this entry either has the CompensableActivity as an implementation decendant, or is the CompensableActivity itself.

                        // walk the same-IdSpace-parent chain of the entry,
                        // look for an entry whose EnvironmentUpdateMap.IsAdditionToNoSymbols is true.
                        DynamicUpdateMapEntry entry = updatedActivity.MapEntry;
                        do
                        {
                            if (!entry.IsRemoval && entry.HasEnvironmentUpdates && entry.EnvironmentUpdateMap.IsAdditionToNoSymbols)
                            {
                                int[] noSymbolAddActivityIDArray = currentQIDBuilder.ToArray();
                                noSymbolAddActivityIDArray[noSymbolAddActivityIDArray.Length - 1] = entry.OldActivityId;
                                QualifiedId noSymbolAddActivityQID = new QualifiedId(noSymbolAddActivityIDArray);
                                DynamicUpdateMap.UpdatedActivity noSymbolAddUpdatedActivity = rootUpdateMap.GetUpdatedActivity(noSymbolAddActivityQID, rootIdSpace);

                                AddBlockingActivity(ref updateErrors, noSymbolAddUpdatedActivity, noSymbolAddActivityQID, SR.VariableOrArgumentAdditionToReferencedEnvironmentNoDUSupported, null);
                                return(true);
                            }

                            entry = entry.Parent;
                        } while (entry != null);
                    }
                }
            }

            return(false);
        }