FromOutcome для `Switch Node`, направляющий поток к`Method Call Node`, не будет работать
Я определил мой поток как:
builder.id("", PublisherBean.PUBLISHER_FLOW_NAME);
builder.viewNode("list", "/pages/publishers.xhtml");
builder.viewNode("details", "/pages/publishers-details.xhtml");
builder.viewNode("deleted", "/pages/publishers-deleted.xhtml");
builder.viewNode("form", "/pages/publishers-form.xhtml");
builder.viewNode("exit", "/index.xhtml");
builder.methodCallNode("invoke-update")
.expression("#{publisherBean.update()}")
.defaultOutcome("details");
builder.methodCallNode("switch-fail")
.defaultOutcome("invoke-publishers")
.expression("#{publisherBean.switchFail()}");
builder.switchNode("proceed-action-request")
.defaultOutcome("switch-fail")
.switchCase()
.condition("#{publisherBean.actionType.ifEdit()}").fromOutcome("form");
builder.switchNode("go-for-it")
.defaultOutcome("switch-fail")
.switchCase()
.switchCase()
.condition("#{publisherBean.actionType.ifEdit()}").fromOutcome("invoke-update");
как видите, есть два узла коммутатора. Первый направляет к View Nod
е, второй пытается направить к Method Call Node
,
Первый работает нормально, а второй вызывает головную боль. Второй дает мне ошибку
Unable to find matching navigation case with from-view-id '/pages/publishers-form.xhtml' for action '#{publisherBean.proceed()}' with outcome 'proceed-form'
,
функция продолжения просто
public String proceed() {
LOG.log(Level.OFF, "Form proceed in action type {0}", actionType);
return "go-for-it";
}
Зарегистрированная информация подтверждает, что publisherBean.actionType.ifEdit()
возвращает true, однако этот факт игнорируется. Если я изменю результат с invoke-update
в form
или любой другой View Node
идентификатор, то он "работает нормально".
Я что-то делаю не так или Method Call Node
не может быть использован в качестве результата для Switch Node
?
1 ответ
Я тоже столкнулся с этой проблемой. В моем случае проблема заключается в вызове узла вызова метода после другого узла вызова метода.
Я немного потрудился и нашел проблему в: com.sun.faces.application.NavigationHandlerImpl.synthesizeCaseStruct методе. Этот метод используется, чтобы определить, куда идти из methodCallNode или switchCallNode, и он смотрит только на viewNodes и returnNodes.
private CaseStruct synthesizeCaseStruct(FacesContext context, Flow flow, String fromAction, String outcome) {
CaseStruct result = null;
FlowNode node = flow.getNode(outcome);
if (null != node) {
if (node instanceof ViewNode) {
result = new CaseStruct();
result.viewId = ((ViewNode)node).getVdlDocumentId();
result.navCase = new MutableNavigationCase(fromAction,
fromAction, outcome, null, result.viewId,
flow.getDefiningDocumentId(), null, false, false);
} else if (node instanceof ReturnNode) {
String fromOutcome = ((ReturnNode)node).getFromOutcome(context);
FlowHandler flowHandler = context.getApplication().getFlowHandler();
try {
flowHandler.pushReturnMode(context);
result = getViewId(context, fromAction, fromOutcome, FlowHandler.NULL_FLOW);
// We are in a return node, but no result can be found from that
// node. Show the last displayed viewId from the preceding flow.
if (null == result) {
Flow precedingFlow = flowHandler.getCurrentFlow(context);
if (null != precedingFlow) {
String toViewId = flowHandler.getLastDisplayedViewId(context);
if (null != toViewId) {
result = new CaseStruct();
result.viewId = toViewId;
result.navCase = new MutableNavigationCase(context.getViewRoot().getViewId(),
fromAction,
outcome,
null,
toViewId,
FlowHandler.NULL_FLOW,
null,
false,
false);
}
}
} else {
result.newFlow = FlowImpl.SYNTHESIZED_RETURN_CASE_FLOW;
}
}
finally {
flowHandler.popReturnMode(context);
}
}
} else {
// See if there is an implicit match within this flow, using outcome
// to derive a view id within this flow.
String currentViewId = outcome;
// If the viewIdToTest needs an extension, take one from the currentViewId.
String currentExtension;
int idx = currentViewId.lastIndexOf('.');
if (idx != -1) {
currentExtension = currentViewId.substring(idx);
} else {
// PENDING, don't hard code XHTML here, look it up from configuration
currentExtension = ".xhtml";
}
String viewIdToTest = "/" + flow.getId() + "/" + outcome + currentExtension;
ViewHandler viewHandler = Util.getViewHandler(context);
viewIdToTest = viewHandler.deriveViewId(context, viewIdToTest);
if (null != viewIdToTest) {
result = new CaseStruct();
result.viewId = viewIdToTest;
result.navCase = new MutableNavigationCase(fromAction,
fromAction, outcome, null, result.viewId,
null, false, false);
}
}
return result;
}