Barracuda Event Model - Sample Presentation Flows
barracuda.gif (11456 bytes) This document just describes the basic program flow for various presentation frameworks.
  1. Turbine
  2. Struts
  3. Lutris Base PO
  4. Statecharts

And here's how Barracuda does it...

  1. Barracuda

Turbine

Suppose we have a form which whose action is mapped to a URL that looks something like this http://<server>/servlet/Turbine/template/AddUser.wm/action/NewUser and whose form buttons might be named doSubmit, doCancel, etc. When the user presses a button, the following sequence would occur.

  • the /servlet portion of the path will cause the Turbine Servlet to handle the request
  • Turbine evaluates whether the user has a session - if not it either redirects them to a default page, or sends them to the requested page with a default session
  • If the user has a session, Turbine makes sure the user has logged in, validates the session, and gets / builds an ACL list. This information will be stored in the RunData structure.
  • Turbine then evaluates the /action portion of the path, causing it to instantiate and execute the NewUser implementation of the Action interface
  • Turbine then evaluates the button name (i.e. doSubmit) to determine which method to invoke in the NewUser class.
  • If there is no method matching the button name, the doPerform method specified in the Action interface will be invoked
  • The method which gets invoked is passed a copy of RunData (encapsulates HTTP information, as well as other data)
  • This method would typically load info from the underlying data model and store it as named messages (based on form name, field name) in a FormMessages storage structure provided by RunData
  • Turbine then evaluates the /template portion of the path, and invokes the AddUser.wm template.
  • The (in this case) WebMacro template receives a copy of the RunData structure, and the WebMacro scripting language can pull values out of the FormMessages structure to populate specific data items in the page.
  • The completed page is then returned to the client browser

Struts

Struts initially loads an ActionServlet which (as described in the javadoc) has the following responsibilities:

  • Identify, from the incoming request URI, the substring that will be used to select an action procedure.
  • Use this substring to map to the Java class name of the corresponding action class (an implementation of the Action interface).
  • If this is the first request for a particular action class, instantiate an instance of that class and cache it for future use.
  • Optionally populate the properties of an ActionForm bean associated with this mapping.
  • Call the perform() method of this action class, passing on a reference to the mapping that was used (thereby providing access to the underlying ActionServlet and ServletContext, as well as any specialized properties of the mapping itself), and the request and response that were passed to the controller by the servlet container.

For the example application all urls ending with a ".do" extension are mapped to this Action Servlet. At initialization time, the action servlet reads in a action.xml file which provides additional routing information that is used during request processing. The basic application flow runs something like this:

  • All GET and POST requests are routed to the protected void process(HttpServletRequest request, HttpServletResponse response) method of the ActionServlet.
  • This method first retrieves the process path of the incoming request. This is either the "request.getPathInfo()" if available or a substring of the full "request.getServletPath()" as returned from the servlet request API. This is determined based on the deployment specifications in the web.xml file. Path Info would be used if the application routes URLs based on a application prefix. The sub string of Servlet Path would be used if the application routes URLs based on application extensions. This is how the example app is configured and a request URL such as 'http://localhost:8080/struts-example/editRegistration.do' would be mapped to a path of '/editRegistration'.
  • The next thing that happens is an ActionMapping class is found for the request. Based on the path retrieved from the previous step, the action mapping class is instantiated and passed onto the following stages. This class encapsulated the routing information obtained from the action.xml file. For example, a path of '/editRegistration' can be associated with its own ActionMapping class or the default ActionMappingBase class (which can be specified in the web.xml file). A line read from the action.xml file such as <forward name="success" path="registration.jsp"> tell the action mapping class where to go when a findForward() call is made on it. An additional line may be specified such as <action path="/editRegistration" className="org.apache.struts.example.ApplicationMapping"> to designate a custom action mapping class for this path.
  • The next step to occur is to find a ActionForm class, if it exists, for the request. This action form attribute is retrieved from the action mapping class associated with this request and is specified in the action.xml file. If the action form exists, it is automagically populated with any cgi data submitted with the request. This is done using the JavaBean method signature patters such that a form field with the name 'passwd' would be associated with the bean property 'passwd' and can be accessed by getter and setter methods of 'getPasswd()' and 'setPasswd(String passwd)'.
  • The next step that occurs is to validate the action form if required. The validation criteria is left up to the action from class and the validate method will only be called if:
    1. A action form instance was found.
    2. The action form is a sub class of ValidatingActionForm
    3. The input form attribute exists, this attribute is also specified in the action.xml file.
    4. The cancel action button was not selected.
  • otherwise, the process() method of the Action Servlet continues on as normal.
  • If the validation method is invoked, the action form class validates the submitted form parameters and reports any errors into an instance of the ErrorMessages class. This class returns all the collected errors at the end of the validation process as an array of Strings. If there are no errors to report, the process() method of the Action Servlet continues on as normal. If there are errors to report, the input form attribute is retrieved from the action mapping class and control is forwarded to this location.
  • If validation was successful or it was not required by not meeting the stated criteria, the Action instance class associated with this request is called. The action instance class is also retrieved from the action mapping class associated with this request and is specified in the action.xml file. The perform() method is called on the action instance class and any additional work that is required to complete the request processing before generating a response is performed here. The return value for the perform() method tell the Action Servlet where to forward control on to.
  • The final stage after the perform() method is called on the Action instance is to forward control onto a servlet that will generate the view. This servlet will be determined by the return value of the perform() method and is typically a Java Server Page.

Lutris Base PO

Suppose we have a form which whose action is mapped to a URL that looks something like this http://<server>/servlet/Welcome and whose form buttons might be named OneButton, TwoButton, etc. When the user presses a button, the following sequence would occur.

  • client javascript catches the action and adds a hidden parameter like event=one to the form
  • the request is routed to the Welcome servlet which extends BaseServletApplication.
  • the servlet (optionally) implements handleDefault and handleError methods along with additional methods like handleOne that correspond to button names
  • The BaseServletApplication starts by initializing the session data..
    • gets a HttpSession object, and if it doesn't exist creates it
    • gets the PresentationSessionData object, again creating it if it doesn't exist, and placing it in the HttpSession structure
  • Next it performs any preprocessing by invoking the preProcess method. Tasks like auto-login might be handled here.
  • Now it dispatches the "event" to the appropriate handler by invoking the getPage method (which the developer could override to provide custom dispatching functionality)...
    • the handleOne method would be invoked using reflection (if the method exists)
    • if the method does not exist, the handleDefault method is invoked
    • all of these methods return an XMLObject structure that represents an XMLC page
  • If a page throws a RedirectException the servlet catches and redirects
  • If any other error is encountered the handleError method is invoked
  • The servlet performs post-processing by invoking either postProcess or errorPostProcess (if there were errors)
  • Finally, the XMLC page is rendered, sending the new view back to the client

Statecharts

When a request is made to the server, the statechart approach would have the following sequence of events happen. The important thing to note here is that the Statechart engine is directly configured from the actual statechart diagram representing the application. This can be accomplished using a UML editing tool that supports XML. The statechart engine only determines what the appropriate transition should be, the controllers execute that transition:

  • Requests are always made to a controller servlet. Each controller servlet is considered to be a high level state composed of one or more sub-states. The mapping of URLs in the static storyboard to the corresponding controller servlets are done through the use of the web application deployment descriptor.
  • Once in the controller servlet, the request is wrapped in a very generic BarracudaRequest object. This is done to hide the semantics of a GET verses POST verses multi-part mime requests.
  • The controller would then pass the BarracudaRequest object off to a Statechart engine which would determine:
    • Does the user have an active session? If not, initialize a new session and direct the controller to transition to its start state.
    • If there is an active session, determine based on the clients history if the request made is a valid transition. If not, direct the controller to return to a valid state.
    • If the request is a valid transition, determine, based upon transition criteria specified by the statechart specification, what the appropriate state or sub-state is and direct the controller there.
    • Repeat this last step until a response is generated.

A typical flow through a controller's sub-states might be something like this:

  • Check that the user is logged in.
  • Check that the user is properly authorized.
  • Encapsulate request data into a type safe BarracudaRequest object.
  • Commit to persistent storage all request data.
  • Generate the appropriate response.

This example assumes no errors occur in each sub-state. If errors are encountered, the statechart engine would instruct the controller of the proper transition to make and the normal application flow would be redirected.


Barracuda

The Barracuda presentation flow is detailed here, in the Event Delivery Flow.

For all the latest information on Barracuda, please refer to http://barracudamvc.org
Questions, comments, feedback? Let us know...