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); }
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 + "'"); } }
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); }
public static string GetTransientPath(WorkStep expandedWorkStep, WorkItem workItem) { return(WorkflowPath.CombinePath(expandedWorkStep.Path, workItem.Id)); }
public WorkStep UpdatePath(string path) { var parentPath = WorkflowPath.GetParentPath(path); return(new WorkStep(path, parentPath, _ordinal, Type, WorkItemClass, Title, WipLimit)); }