0

is it possible to determine the actual running flow in a spring mvc context and terminate it ?

The reason why I'm asking is, that in my shop web app the whole checkout process is a web flow but the header menu is still visible and now I experience the problem that if a menu link is klicked the flow is exited but I don't recognize it.

I hope it is understandable what I want and I appreciate any help to get through this issue :)

Thanks.

conscience
  • 463
  • 6
  • 21

2 Answers2

1

If I understood your problem correctly - you wanted to terminate the current flow but still have the menu click work - is that right?

If it is, have a global common flow that is inherited by all your subflows. Then, add this in the flow tag of each of your flows, where commonFlow is the name or ID of your global flow definition file.

parent="commonFlow"

In this global flow definition, define the transition for the menu option:

<global-transitions>
<!-- If Menus are triggered on flows, we end them first. -->
<transition on="menuClick" to="endCurrentFlowThenMenu"/>
</global-transitions>

And then define a redirect for the menu:

<end-state id="endCurrentFlowThenMenu" view="flowRedirect:menuView"></end-state>

However, this only works when current flow is a parent/top-level flow. If it is a subflow, it gets a little bit dirty - you need a work-around so that all subflows are ended first:

<global-transitions>
<!-- If Menus are triggered on flows and subflows, we end them first. -->
<transition on="menuClick" to="endCurrentFlowThenMenuLevel1"/>
    <transition on="endCurrentFlowThenMenuLevel1" to="endCurrentFlowThenMenuLevel2"/>
</global-transitions>

In which case you define the matching end states:

<end-state id="endCurrentFlowThenMenuLevel1" view="flowRedirect:newFlow">
</end-state>
<end-state id="endCurrentFlowThenMenuLevel2" view="flowRedirect:newFlow">
</end-state>

The reason why I repeat the view attribute on each end state is so that it could still work even if the current flow is a top-level flow. Depending on the maximum deepest subflow, you need have multiple transitions and end states to match them (i.e. if you max deepest functionality can have 2 subflows, repeat the above 3 times).

The trick here is, if the current flow is already a top level flow, SWF would not bubble up the parent and will just execute the flowRedirect.

If, however, the current flow is a subflow, SWF will not execute the redirect on the subflow, but instead will bubble up to the parent first, looking for a matching transition for the current subflow that just ended. It would continue doing this until it finds the top-level flow in which case it would execute the redirect, effectively ending all subflows in the process as well.

ailveen
  • 583
  • 3
  • 14
0

It's possible share global transition between flows and subflows, the way to do it's similar to above code.

Basically, you must define an abstract flow,commons-headers, setting abstract=true inside flow tag, then to define global-transitions which will be share among flow/subflow, these global-transitions can redirect to some kind of event, in this example to end-state.

Calling flow define, main flow, define subflow-state tag, here you must write returned transition from called flow,subflow, which must be the same id shared between transition and subflow's end-state tag, this is the way to finish subflow and return to the main flow. If you wish use some global transitions then you must define these transitions inside subflow-state tag setting same value for main flow's on attribute and global-flow's to attribute (in this example will be loginEnd and signEnd). Last step, main flow's to attribute must coincide with some global flow state id attribute (in this example loginEnd and signEnd again).

Commons-headers

<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
abstract="true">

<end-state id="loginEnd" view="flowRedirect:login" />

<end-state id="signupEnd" view="flowRedirect:signup" />

<global-transitions>
    <transition on="login" to="loginEnd" />
    <transition on="signup" to="signupEnd"/>
</global-transitions>

Main flow

<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://www.springframework.org/schema/webflow
    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
    parent="commons-header">


<view-state id="inicio" view="main.xhtml">
    <transition on="manageSpace" to="adminSpaces" />

    <transition on="goSpace" to="visitSpace" />
</view-state>

<subflow-state id="visitSpace" subflow="space">
    <on-entry>
         <evaluate expression="space.showSpace(requestParameters.idSpace,flowRequestContext)" result="conversationScope.visitedSpace" />
    </on-entry>

    <transition on="finishSubFlow" to="inicio" />

    <transition on="loginEnd" to="loginEnd" />
    <transition on="registerEnd" to="registerEnd" />
</subflow-state>

<end-state id="error" view="flowRedirect:error" />

Subflow

<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
parent="commons-header">


<view-state id="showPicture" view="space_pictures.xhtml">

    <on-entry>
         <evaluate expression="multimediaProvider.showPages('picture')" result="viewScope.pagesList"/>
     </on-entry>

    <transition on="goMain" to="finishSubFlow" />
    <transition on="visit" to="visitPicturePage" />
</view-state>

    <view-state id="visitPicturePage" view="show_picturePage.xthml">
        <on-entry>
            <set name="flowScope.code" value="requestParameters.code" />
        </on-entry>
        <on-render>
             <evaluate expression="multimediaProvider.loadPage(flowScope.code)" />
        </on-render>

        <transition on="goMain" to="finishSubFlow" />       
    </view-state>

<end-state id="finishSubFlow" />