We're trying to use some of the newer inheritance features of SWF in both flow definition/model registries and flows. I'm making certain assumptions about how things should work since the documentation in this area is somewhat sparse, so if someone can point out any false assumptions (or that we're just not getting the concepts) I would really appreciate it.
The app being worked on is a voice application where the call flow may vary according to the caller's area code and the number he's calling. The flows can support multiple languages and the choice of language can affect the not only the language resources used, but the flow itself. A flexible way of setting up flows and re-using parts across all the flow variations is essential for us.
What we wanted to achieve (and we have partially gotten there) is a runtime selection of a flow definition registry hierarchy based on the criteria above (caller's area code/DNIS). In other words, for any one caller one flow definition hierarchy is chosen and in this hierarchy the flows and subflows could be related by flow (and possibly state) inheritance that can span the flow definition registry hierarchy.
We implemented this using a few simple aspects that advise the SWF code (this seems more maintainable than modifying SWF source directly, but we would welcome this type of functionality to be built in) and by implementing FlowDefinitionRegistry in a proxy that is set as the registry specified for the executor in the SWF configuration. When a request comes in and a flow definition has to be located, this proxy provides the proper (based on a mapping to caller area code/called number) FlowDefinitionRegistry to SWF. The registry provided is a leaf in the flow definition hierarchy and forms an inheritance path to a root flow definition registry.
Our first problem was in assuming that everything related to inheritance is working (not just a work-in-progress) in SWF 2.0.2. This seems not to be the case as the first problem we hit is that flow inheritance didn't work (flow was not found) when the parent flow definition was located in an ancestor flow definition registry relative to the location of the child flow. I found the problem to be that when the FlowModel is resolved at runtime starting from the child flow, the FlowModelRegistry it belongs to did not have its parent set, so SWF did not search up the FlowModelRegistry hierarchy.
What I see is that in FlowRegistryFactoryBean, a FlowDefinitionRegistrImpl and FlowModelRegistryImpl are created as a pair, but only the former has the parent set to form the hierarchy specified in the SWF configuration. With additional hacking through aspects, I modified SWF behaviour such that the FlowModelRegistry hierarchy mirrors the hierarchy of the FlowDefinitionRegistry hierarchy by appropriately setting the parent property in a FlowModelRegistry. I can see that this symmetry should not necessarily be the case, but until more documentation is available on the intended current and future use of FlowModelRegistries, this suits us and produces a flow hierarchy in which flows can successfully inherit from flows in immediate or distant parent flow definition registries (but not in child flow definition registries, as detailed below).
With one problem solved, we moved on and hit another obstacle. My (mistaken) assumption was that a flow of a given name would "override" a flow of a similar name in an ancestor flow definition registry. The documentation points out that "A child flow cannot override an element from a parent flow.", but the overriding I'm talking about is not between parent-child flows, but between unrelated, but like-named flows. This causes problems in that when a flow calls a subflow, the search for the subflow is started in the flow definition registry of the caller flow and proceeds up the hierarchy. The result is that the correct subflow is not found if it is in a child flow definition registry, or that the wrong (same name, but in a higher up flow definition registry) is returned.
My gut reaction would be that the search space, when resolving flow definitions, should include the complete path from the leaf to the root of the flow definition registry hierarchy and should start in the "most derived", i.e leaf flow definition registry proceeding upwards. With the current state of things in SWF, I get the feeling the complete picture surrounding flow definition resolution has not been formed et (is this true? - even a future hint at a direction would be welcome so that we could hack constructively to work around current limitations. If this post gets no attention, we'll proceed in this direction until SpringSource clears things up.
In trying to understand the SWF code, there seem to be so many possible "degrees of freedom" in defining and resolving flows with static and dynamic flow definitions possibly being used through the FlowDefinitionRegistry, FlowDefinitionHolder, FlowFlowModelRegistry, FlowModelHolder, etc., that it gets somewhat confusing trying to think of the possibilities. Keith, or whomever is working on this area, it would be really helpful to get your thoughts wrt the relationship between the flow definition and model registries and how they could/should be used.
I suppose I've exceeded the acceptable size limit of a post, but hopefully a reply to these questions will help many others to take advantage of some of the amazing potential available now or coming soon to a SWF version near you.