I should be a bit clearer
I'm writing a VoiceXML banking application, and I'm evaluating the use of WebFlow as our state machine. It looks like a good fit so far since voice interactions are highly sequential and there are no browser navigation surprises.
I have some cases where global handling of events is necessary - I'd rather not duplicate the handling of these events in every flow. The two main cases I have in mind are user authorisation, and help handling. Authorisation should be checked before each flow is begun, but I'd like to define that behaviour in one place, then reuse it for every flow in the system (more than 100 flows I'm guessing). Next, I'd like to handle that event in one place - (e.g transition to a logon flow), then return to the original flow and resume.
The solution I had in mind is similar to the <bean parent="parentBean"> syntax we are familar with - but modified for flows. There is a problem with start-state semantics that needs to be thought through. The basic idea is that all states from the parent are just "copied down" to the child - then the child flow can transition to any parent flow. The child can also redefine any parent state.
Here is a possible flow defn for a "parent" whose _flowId=authorisation:
Code:
<flow start-state="check">
<action-state id="check">
<action bean="action"/>
<transition on="yes" to="finish"/>
<transition on="no" to="logon"/>
</action-state>
<subflow-state id="logon" flow="logon">
<transition on="yes" to="finish"/>
<transition on="no" to="exit"/>
</subflow-state>
<end-state id="finish"/>
<end-state id="exit"/>
<import resource="beans.xml"/>
</flow>
And here is a "child" flow (_flowId=balance). My expectation is that the parent's start-state happens first, then one of it's end-state's (in this case "finish") is mapped to the child's start-state.
Code:
<flow parent="authorisation" map-event="finish" start-state="displaySelect">
<view-state id="displaySelect" view="balance/select">
<transition on="submit" to="process">
<action bean="formAction" method="bind"/>
</transition>
</view-state>
<action-state id="process">
<action bean="formAction"/>
<transition on="success" to="displayBalance"/>
<transition on="error" to="finish"/>
</action-state>
<view-state id="displayBalance" view="balance/balance">
<transition on="submit" to="finish"/>
</view-state>
<end-state id="finish"/>
<import resource="beans.xml"/>
</flow>
These semantics are similar to VoiceXML <catch> tags that are copied from application scope, to form scope, then finally to field scope.
However, instead of all this extra syntactic sugar - can I do this with an exception handling mechanism? - so that I throw a StateException when the user tries to access flow functions - perhaps by using AOP pointcuts to advise all action beans with the authorisation-check, then handle the exception by initiating the logon sub-flow, then resume in the state where the exception occurred. Or can exceptions only be handled in the flow that generated them?
As a final unrelated point, VoiceXML doesn't like the _underscore at the start of it's ECMA script variables. What is the best way to redefine the parameter names for _flowExecutionKey and _eventId?
Regards,
Jamie