Thought it might be worth sharing my implementation of a breadcrumb trail based on flow hierarchy. This FlowExecutionListenerAdapter builds a List of strings (one per crumb) and places it into the request context under the key "breadcrumbs".
Note that flow names don't always provide the most meaningful breadcrumb text. I'm using a MessageSource to lookup localized breadcrumb strings.
A flow can be omitted from the breadcrumb trail by assigning it an empty name in the message source.
Code:
public class BreadcrumbFlowExecutionListener extends FlowExecutionListenerAdapter {
protected MessageSource messageSource;
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
public void stateEntering(RequestContext ctx, State state) throws EnterStateVetoException {
if (state instanceof ViewState) {
FlowSession session = ctx.getFlowExecutionContext().getActiveSession();
List crumbs = new ArrayList();
Map scopeMap = session.getScope().getAttributeMap();
crumbs.add(getLocalizedFlowName(scopeMap, session.getFlow().getId()));
while (session.getParent() != null) {
session = session.getParent();
scopeMap = session.getScope().getAttributeMap();
String flowName = getLocalizedFlowName(scopeMap, session.getFlow().getId());
if (flowName != null && !flowName.equals(""))
crumbs.add(0, flowName);
}
ctx.getRequestScope().setAttribute("breadcrumbs", crumbs);
}
}
public String getLocalizedFlowName(Map attributeMap, String flowId) {
return attributeMap, messageSource.getMessage(flowId, new String[0], flowId, Locale.getDefault());
}
}