org.requirementsascode.Flow Maven / Gradle / Ivy
Show all versions of requirementsascodecore Show documentation
package org.requirementsascode;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.requirementsascode.flowposition.FlowPosition;
/**
* A flow defines a sequence of steps that lead the user through a use case.
*
*
* A flow either ends with the user reaching her/his goal, or terminates before,
* usually because of an exception that occurred.
*
* @author b_muth
*/
public class Flow extends ModelElement{
private UseCase useCase;
/**
* Creates a flow with the specified name that belongs to the specified use
* case.
*
* @param name the name of the flow to be created
* @param useCase the use case that will contain the new flow
*/
Flow(String name, UseCase useCase) {
super(name, useCase.getModel());
this.useCase = useCase;
}
/**
* Returns the use case this flow is part of.
*
* @return the containing use case
*/
public UseCase getUseCase() {
return useCase;
}
/**
* Returns the steps contained in this flow. Do not modify the returned
* collection directly.
*
* @return a collection of the steps
*/
public List getSteps() {
List steps = getUseCase().getModifiableSteps().stream().filter(step -> isStepInThisFlow(step))
.map(step -> ((FlowStep)step)).collect(Collectors.toList());
return Collections.unmodifiableList(steps);
}
/**
* Returns the first step of the flow
*
* @return the first step of the flow, or an empty optional if the flow has no
* steps.
*/
public Optional getFirstStep() {
Collection steps = getUseCase().getModifiableSteps();
FlowStep firstStep = null;
for (Step step : steps) {
if(isStepInThisFlow(step)) {
firstStep = (FlowStep)step;
break;
}
}
return Optional.ofNullable(firstStep);
}
private boolean isStepInThisFlow(Step step) {
return step instanceof FlowStep && this.equals(((FlowStep)step).getFlow());
}
/**
* Convenience method that returns the position of the flow (as defined e.g. by
* "InsteadOf").
*
*
* Internally this calls the method of the same name of the first step in the
* flow.
*
* @return the flow position, or null if the flow is empty.
*/
public FlowPosition getFlowPosition() {
FlowPosition flowPosition = getFirstStep().map(step -> step.getFlowPosition()).orElse(null);
return flowPosition;
}
/**
* Convenience method that returns the condition of the flow.
*
*
* Internally this calls the method of the same name of the first step in the
* flow.
*
* @return the condition
*/
public Optional getCondition() {
Optional condition = getFirstStep().flatMap(step -> step.getCondition());
return condition;
}
}