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;
}
Другие вопросы по тегам