A lot of the concepts are from Beehive Page Flow, but I'm being purposefully vague about the implementation details so we can choose a design that's clean and fits with the rest of the project.
See StrutsTi/ControllerMock for other controller features.
Basic State Management
Each page flow controller is itself a bean that is instantiated when a request is made for:
- the page flow URI, or
- any action in the page flow's module path, or
- any view element (e.g., a JSP) in the page flow's module path.
It contains state relevant to the navigational logic in the class. The basic rules are:
- The bean is stored in the session by default, although this needs to be configurable (per-webapp or per-controller).
- The bean is stored as the single "current page flow controller", except as noted below.
- The bean is removed when a request for another controller module is made, except as noted below.
Key concept. A "nested" page flow is one that can be brought to life temporarily, with the intention of returning to the current page flow. A nested page flow controller is a controller that:
- has some sort of indicator that it can be nested
- defines at least one exit point (all page flow controllers have at least one entry point)
It alters the basic rules as follows:
- When you hit a nested page flow (by any of the means for hitting a page flow, above), the current controller is pushed onto a stack, and the nested controller becomes the current controller.
- When you hit an exit point, the nested page flow is released, and the stack is popped. In Beehive, an exit point is a "return action", which is raised on the original page flow (along with any bean that's passed along). I like the simplicity of this, but I'm open to alternatives.
Long-Lived Page Flows
There are some page flows that shouldn't be destroyed when other page flows are hit. These are marked with some sort of "long-lived" indicator. If you leave a long-lived page flow and then come back to it, you'll get the same instance of the controller.
To support portals and also browser frames and multiple browser windows, page flows can be "scoped" into named areas within whatever entity is handling storage (user session, database, etc.).
Since controllers are stateful, the framework should synchronize on action method invocations. In Beehive this happens automatically... anyone think it should be optional in Ti?
There should be some sort of mechanism to ensure that altered controller instances are replicated in a cluster.
Page flow controllers should be Serializable, and the framework should take care of reinitializing transient state when appropriate (maybe with a hook?).