Aug
26
2013

Faces Flow

With version 2.2, JavaServer Faces has a new bean scope that is wider than request scope, narrower than session scope and different from view scope: Flow Scope

 

What is Flow?
In today’s web applications we see examples mostly about where user interaction is provided through a series of screens that related to each other. For example flight booking, shopping/ordering applications and so on.

In these examples, a “flow” concept is in question which represents a navigation to the pages between the points that are non-random and entry and exit points are specified.

By taking inspiration from Spring Web Flow and ADF Task Flows, JavaServer Faces version 2.2 provides support to the flow concept that I tried to explain here by the Faces Flow name and makes a standardization by taking the good aspects of Spring Web Flow, ADF Task Flows and Apace MyFaces CODI.

Each flow consists of a series pages and a Managed Bean which has aFlowScoped. Each flow has a starting point called start node and an exit point called return node. Now, the application flow is defined as a flow between the nodes.

 

What does it provide?

Faces Flow provides the encapsulation of defined flows and the packaging as a reusable module in other applications with the used sources.

The data in a flow can be accessed within the scope of that flow (but specifying the parameters can make a flow to pass the data to another flow). This allows you to use the same flow in a different tab or window in the same browser.

 

Encapsulation

In order to fully understand the encapsulation, let’s look closer to what happens in a usage scenario that is similar to the flows with a bean which has a session scope.

Assume that we have three pages in our hypothetical example called as Step1.xhtml, Step2.xhtml, Step3.xhtml. In Step1.xhtml page, information input is requested from the user and then output this information to the screen in the Step2.xhtml. In Step2.xhtml, information input is again requested from the user and both of this obtained information is output to the screen in Step3.xhtml.

Because the scope of the bean is session in this hypothetical example, for example in a first tab/window of safari browser, when we enter the information requested in Step1.xhtml page and pass to the Step2.xhtml page, and then make a new request in Step2.xhtml page after opening a new tab/window; we can see the outputting bean data in the other tab/window. This is because the same bean instance serves in the both tab/window. When we request to Step2.xhtml page from another browser (e.g. chrome), we won’t encounter any access error even though we don’t see the data that is seen in safari.

Screen Shot 2013-06-21 at 11.29.20 PM

When we develop this hypothetical example with Faces Flow, we cannot see the data in question on the 2. tab/window of the same browser. On the contrary, because not calling the flow with flow call action, we get a”No active contexts for scope type javax.faces.flow.FlowScoped” exception. The same situation applies to a call made from another browser. When a flow is called with flow call action, a new instance of flow bean is created, activated in Faces Context and then this instance stores its own data.

 

Packaging the Flow

Flows can be packaged in JAR files or in directories.

 

I- Packaging in JAR

When the flows are packaged in JAR files, flows must be declared in META-INF/faces-config.xml file. Flow nodes (pages) take place in META-INF/flows/. beans.xml file must exists under the META-INF directory.

 

II- Packaging in directory

If we base on Maven project directory structure, a directory that has the same name with flow can be used under the src/main/webapp for a packaging in directory in a maven web project (this is a good habit). Start node is the same with the flow name as a default and takes .xhtml suffix. You can configure the start node as to take a different name. There is not any essential naming convention in flow nodes.

Additional considerations to be aware of:

  • Every page in this directory is a view node of the flow (view node).
  • Navigation between the views(pages) in directory is considered to be within the flow.
  • Navigation to a view outside of that directory is considered to be an exit of the flow.

 

Configuration

Flows can be configured in xml configuration file or programmatically in java classes.

 

I- Configuration file

If you use xml configuration file to configure a flow, this file should be named as flowname-flow.xml and should be located in flow directory.For example, if a flow called as order is being configurated, the file name must be order-flow.xml. Flow configuration file is a faces configuration file that includes flow-definition element.

<flow-definition id="order">
   <flow-return id="returnFromOrderFlow">
     <from-outcome>#{orderBean.returnValue}</from-outcome>
   </flow-return>
</flow-definition>

Flow name of the flow-definition element must be defined by using id attribute. Again, under this element, there must be a flow-return element which defines the return point for the flow.

Any inbound parameter for flow is specified with inbound-parameter element. If a flow calls another flow, this is specified with call-flow element. Which flow will be called is specified by flow-reference element under the call-flow element and if a parameter is going to be passed to this called flow, this is specified by outbound-parameter element.

 

II- Programmatic

If a flow is going to be configured with Java class, the class name must be the flow name. For example, if we want to configure a flow named as customer, the class must be Customer.java.

public class Customer implements Serializable {
    
    @Produces
    @FlowDefinition
    public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) {
        String flowId = "customer";
        flowBuilder.id("", flowId);
        flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml").markAsStartNode();
        
        flowBuilder.returnNode("returnFromCustomerFlow")
                   .fromOutcome("#{customerBean.returnValue}");
        
        return flowBuilder.getFlow();
    }
}

Flow configuration class includes a single method called defineFlow. This method returns javax.faces.flow.Flow class.

DefineFlow method takes a FlowBuilder parameter that is passed from faces application. The method uses javax.faces.flow.Builder.FlowBuilder class methods in order to configure the flow.

First of all, the flow identity must be defined in a method. Id method of FlowBuilder class is called for this purpose. Then, start node and return node are defined for flow.

The argument that is passed to ReturnNode method sets the name of the return node and the argument that is passed to the fromOutcome method sets the value of the return node.

As a result, Faces Flow meets a big need for JavaServer Faces and provides an important innovation for Faces developers. I tried to deal with what need to be known about Faces flow as a beginning in this article. I hope to be with new articles dealing with the usage of flows with concrete examples.

Comment time



Yazı gönder
Yazı yayınlayarak Türkçe kaynak üretimine destek olabilirsin.

acikakademi
sirkethaberleri
  Yes We Kanban