示例#1
0
        public static WorkStep New(string path)
        {
            ThrowIfIllegalPath(path, "path");
            var parentPath = WorkflowPath.GetParentPath(path);

            ThrowIfIllegalPath(parentPath, "parentPath");

            return(new WorkStep(path, parentPath));
        }
        public void MoveWorkStep(WorkStep stepToMove, WorkStep toStep)
        {
            if (stepToMove.WorkItemClass != toStep.WorkItemClass)
            {
                throw new InvalidOperationException("Cannot move work step. Work item classes are not compatible");
            }

            var siblings = _workflowRepository.GetChildWorkSteps(toStep.Path);

            if (siblings.Where(ws => ws.Ordinal == stepToMove.Ordinal).Count() > 0)
            {
                throw new InvalidOperationException("Cannot move work step. Conflicting ordinals");
            }

            if (_workflowRepository.IsWithinTransientStep(stepToMove))
            {
                throw new InvalidOperationException("Cannot move transient work step or step within transient work step");
            }

            var commonRoot = WorkflowPath.FindCommonRoot(stepToMove.Path, toStep.Path);

            foreach (var path in WorkflowPath.GetPathsBetween(commonRoot, stepToMove.Path))
            {
                if (path == commonRoot || path == stepToMove.Path)
                {
                    continue;
                }

                if (_workflowRepository.GetWorkStep(path).Type == WorkStepType.Expand)
                {
                    throw new InvalidOperationException("Cannot move work step within expand step outside expand step");
                }

                if (_workflowRepository.GetWorkStep(path).Type == WorkStepType.Parallel)
                {
                    throw new InvalidOperationException("Cannot move work step within expand step outside parallel step");
                }
            }

            var wipLimitChecker = new WipLimitChecker(_workflowRepository);

            if (!wipLimitChecker.CanAcceptWorkStep(toStep, stepToMove))
            {
                throw new InvalidOperationException("Cannot move work step when WIP limit of new ancestors are violated");
            }



            MoveWorkStepRecursively(stepToMove, toStep);
        }
示例#3
0
        private static void ThrowIfIllegalPath(string path, string paramName)
        {
            if (path == null)
            {
                throw new ArgumentNullException(paramName);
            }

            bool isValid = WorkflowPath.IsValidPath(path);

            if (!isValid)
            {
                throw new ArgumentException(paramName, "Path must start with '/' but was '" + path + "'");
            }
        }
示例#4
0
        private IEnumerable <string> GetPathsToTraverseForParallelStep(WorkItemTransition transition)
        {
            IEnumerable <string> pathsBetweenRootAndTarget;
            WorkItem             parallelParent;

            if (IsMovedUnderneathParallelParent(transition, out parallelParent))
            {
                var commonRootStepPath = WorkflowPath.FindCommonRoot(parallelParent.Path, transition.WorkStep.Path);
                pathsBetweenRootAndTarget = WorkflowPath.GetPathsBetween(commonRootStepPath, transition.WorkStep.Path).Skip(1);
            }
            else
            {
                var commonRootStepPath = WorkflowPath.FindCommonRoot(transition.WorkItem.Path, transition.WorkStep.Path);
                pathsBetweenRootAndTarget = WorkflowPath.GetPathsBetween(commonRootStepPath, transition.WorkStep.Path);
            }

            return(pathsBetweenRootAndTarget);
        }
        private void MoveWorkStepRecursively(WorkStep stepToMove, WorkStep toStep)
        {
            var leafDirectory = WorkflowPath.GetLeafDirectory(stepToMove.Path);

            var newPath = WorkflowPath.CombinePath(toStep.Path, leafDirectory);

            var newStep = stepToMove.UpdatePath(newPath);

            _workflowRepository.CreateWorkStep(newStep);

            foreach (var workItem in _workflowRepository.GetWorkItems(stepToMove.Path))
            {
                _workflowRepository.UpdateWorkItem(workItem.MoveTo(newStep, _timeSource.GetTime()));
            }

            foreach (var childWorkStep in _workflowRepository.GetChildWorkSteps(stepToMove.Path))
            {
                MoveWorkStep(childWorkStep, newStep);
            }

            _workflowRepository.DeleteWorkStep(stepToMove.Path);
        }
        public void CreateWorkStep(WorkStep workStep)
        {
            if (workStep.ParentPath != WorkStep.Root.Path)
            {
                if (!WorkflowRepository.ExistsWorkStep(workStep.ParentPath))
                {
                    throw new InvalidOperationException("Parent does not exist");
                }
            }

            if (workStep.Type == WorkStepType.Transient)
            {
                throw new InvalidOperationException("Cannot create transient workstep");
            }

            WorkStep parent = null;

            if (workStep.ParentPath != WorkStep.Root.Path)
            {
                parent = WorkflowRepository.GetWorkStep(workStep.ParentPath);
            }

            if (workStep.WorkItemClass == null && parent != null && parent.Type != WorkStepType.Parallel)
            {
                workStep = workStep.UpdateWorkItemClass(parent.WorkItemClass);
            }

            if (parent != null && parent.Type == WorkStepType.Parallel)
            {
                var leaf          = WorkflowPath.GetLeafDirectory(workStep.Path);
                var workItemClass = parent.WorkItemClass + "-" + leaf;

                if (workStep.WorkItemClass == null)
                {
                    workStep = workStep.UpdateWorkItemClass(workItemClass);
                }
                else if (workStep.WorkItemClass != workItemClass)
                {
                    throw new InvalidOperationException("Invalid work item class for child of parallel step. Expected '" + workItemClass + "' but was '" + workStep.WorkItemClass + "'");
                }
            }

            var siblings     = WorkflowRepository.GetChildWorkSteps(workStep.ParentPath);
            var firstSibling = siblings.FirstOrDefault();

            if (workStep.WorkItemClass == null && firstSibling != null)
            {
                workStep = workStep.UpdateWorkItemClass(firstSibling.WorkItemClass);
            }

            if (!workStep.Ordinal.HasValue)
            {
                var last    = siblings.OrderBy(ws => ws.Ordinal).LastOrDefault();
                var ordinal = last == null ? 0 : last.Ordinal.Value + 1;
                workStep = workStep.UpdateOrdinal(ordinal);
            }

            if (siblings.Where(ws => ws.Ordinal == workStep.Ordinal).Count() > 0)
            {
                throw new InvalidOperationException("Cannot create workstep with same ordinal as sibling");
            }

            if (workStep.WorkItemClass == null)
            {
                throw new InvalidOperationException("Work item class missing and could not resolve one");
            }

            if (parent != null && parent.Type == WorkStepType.Expand && parent.WorkItemClass == workStep.WorkItemClass)
            {
                throw new InvalidOperationException("Child of expand step cannot have same workitem class as parent");
            }

            if (parent != null && parent.Type != WorkStepType.Expand && parent.Type != WorkStepType.Parallel && parent.WorkItemClass != workStep.WorkItemClass)
            {
                throw new InvalidOperationException("Incompatible work item class. Should be same as parent");
            }

            if (firstSibling != null && firstSibling.WorkItemClass != workStep.WorkItemClass)
            {
                if (parent == null || parent.Type != WorkStepType.Parallel)
                {
                    throw new InvalidOperationException("Incompatible work item class. Should be same as siblings");
                }
            }

            WorkflowRepository.CreateWorkStep(workStep);
        }
示例#7
0
 public static string GetTransientPath(WorkStep expandedWorkStep, WorkItem workItem)
 {
     return(WorkflowPath.CombinePath(expandedWorkStep.Path, workItem.Id));
 }
示例#8
0
        public WorkStep UpdatePath(string path)
        {
            var parentPath = WorkflowPath.GetParentPath(path);

            return(new WorkStep(path, parentPath, _ordinal, Type, WorkItemClass, Title, WipLimit));
        }