Sun Java Solaris Communities My SDN Account Join SDN
 

The Java Studio Creator 2 Application Model

By David Botterill and edited by Beth Stearns, April 19, 2006  
The Sun Java Studio Creator 2 Integrated Development Environment (IDE) employs a conceptual reference, or application model, that describes the makeup of a Java Studio Creator 2 web application. This article describes that application model and shows how the model relates to specific parts of a Java Studio Creator 2 web application.
Contents
 
[spacer]
Introduction
What is an Application Model?
The JavaServer Faces Technology Application Model
The JavaServer Faces User Interface Model
The JavaServer Faces Navigation Model
The JavaServer Faces Backing Bean Model
The JavaServer Faces Page Life Cycle
The JavaStudio Creator 2 Application Model
User Interface Backing Beans
Page Beans
[spacer]
Page Bean UI Component Properties
Page Bean Life Cycle
Leveraging the Request Processing Life Cycle
Page Fragment Bean
Portlet Life Cycle
Data Backing Beans
User Interface Components
Applying the Application Model to a Web Application
Summary
 
Introduction
 
The application model encompasses both the IDE design-time environment and the application runtime environment. It is important to keep this full scope of the application model in mind as you read this article. You may be familiar with the application model from the earlier version of the IDE. However, the application model for Java Studio Creator 2 has gone through significant improvements from the earlier Java Studio Creator 2004Q2 (version 1). The article describes the current application model rather than the changes to the model.
 
All levels of software developers, from those getting started with the Java Studio Creator 2 IDE through advanced developers, should benefit from understanding the concepts of the application model. Developers who know the application model have a better understanding of the structure of web applications produced by the IDE. To get the most from this article, developers should have a general knowledge of the Java[tm] Platform and JavaServer[tm] Pages. Since the application model is based on the JavaServer Faces[tm] technology application model, it is also helpful to be familiar with the JavaServer Faces technology. However, the article does introduce the JavaServer Faces concepts necessary to understand the application model. This article:
  • Describes an application model and indicates why a model is important.
  • Provides an overview of the JavaServer Faces technology application model, which is the underlying model for the Java Studio Creator 2 application model.
  • Provides details of the Java Studio Creator 2 IDE application model for both design and runtime environments.

What is an Application Model?
 

Let's begin with the definition of the term model, since it can have many different meanings and applications. In this article, the phrase "to model" means to simulate or abstractly represent a system. Many different disciplines use models to depict the various parts of a system. For example, in weather forecasting, weather models represent known weather systems. In the mechanical realm, you have models of different types of engines, such as combustion and jet engines.

The model represents the basic required elements and how these elements are related to make the system work properly. For example, a model of a combustion engine might show a combustion chamber, a piston, some fuel, and a spark plug. The model description would explain how these different pieces interact to make the system "combustion engine" work. The web site http://auto.howstuffworks.com/engine7.htm shows a good example of this.

An application model is an abstract representation of the various parts that make up the software system known as an "application." This article narrows the focus to a particular type of application, a "web application."

The "client-server" application model is another type of application model. In this model, the server provides some resources over a network to clients. The client connects to the server and uses the resources offered. Figure 1 shows a simplified diagram of a client-server application. Database and email applications are example of client-server applications.
 

Figure 1: Client-Server Application
Figure 1: Client-Server Application
 
An application model gives the developer an abstract or high-level view of the system or application under development. Knowing the application model helps the developer to create the web application, particularly in terms of the application design, problem determination, and performance tuning. As you make the necessary design decisions, you can maximize the usage of the application model. Even if things do not work as expected, knowing the application model helps you determine what went wrong. 

The JavaServer Faces Technology Application Model
 

Since the Java Studio Creator 2 application model is built on the JavaServer Faces technology application model, let's start with an overview of key JavaServer Faces technology application model concepts. (See the JavaServer Faces Technology chapter in the J2EE 1.4 Tutorial, for more information on JavaServer Faces technology.)

The JavaServer Faces technology is based on a basic web application model: A client-server architecture where the client is typically a browser and the server is an application or web server. In this web application model, the client invokes a request for content and the server gives a response composed of either HTML or XHTML. The browser takes the response and renders it in a readable format.

The JavaServer Faces application model can be broken down into three smaller models:

  • User Interface Model
  • Navigation Model
  • Backing Bean Model

The article first examines these models and then explains the JavaServer Faces page life cycle.

The JavaServer Faces User Interface Model
 

The JavaServer Faces user interface model contains component Java classes, a rendering model, an event and listener model, a validation model, and a conversion model.

  • Component Java Classes. JavaServer Faces technology provides a set of Java classes that represent common user interface components, such as buttons, output fields, input fields, and so forth. Components are organized in a tree-like structure, with more generic components towards the top of the tree and more specific components descending from them.

    There are two important classes in the user interface model:
    • The UIViewRoot component class represents the root of the tree of all components for a particular page.
    • The FacesContext class serves as the access point for per-request information and other helper classes.

  • Rendering Model. The JavaServer Faces rendering (or user interface) model separates the component definition from the component rendering. This division of responsibility allows the same component definition to be rendered in different ways. For example, a password field can be rendered in a web browser as an input field that hides the characters typed. The same component in a PDA application might be rendered with the word ?-assigned-? displayed in the input field to hide the password.

    A render kit defines how a component maps to component tags in the JavaServer Pages tag language. The JavaServer Faces reference implementation comes with a standard HTML render kit.


  • Event and Listener Model. The JavaServer Faces event and listener model lets developers register listeners on user interface (UI) components to handle events such as button presses. This model follows the standard Java Foundation Classes (JFC)/Swing model based on the Observer software design pattern. (According to the Gang of Four Design Patterns book, the Observer design pattern defines a one-to-many dependency among objects so that when one object changes state, all dependent objects are notified and updated automatically.) This design pattern allows components to register as observers on other components that generate events. When a component does something that constitutes an event, it notifies all registered listeners (that is, observers) with the event. The listening component has the responsibility of reacting to the event. In the JavaServer Faces event model, there are two types of events: an action event and a value-change event.
    • Action event: An action event is fired when a user does something, such as pressing a button or clicking a hyperlink.
    • Value-change event: A value-change event is fired when a user changes a component's value, such as by clicking a checkbox or entering a value in a text field. A value-change event only fires if there are no validation errors on the component.

    The JavaServer Faces application model provides two ways to specify an event handler:

    1. Implement an event listener class like ActionListener or ValueChangeListener, then add an actionListener or valueChangeListener to the JSP tag for the component.
    2. Define a method on the backing bean (see Backing Bean Model) and use a method-binding expression to bind the method to the component.
  • Conversion Model. The JavaServer Faces conversion model allows for converting between data types. When a JavaBean server-side object (backing bean) is associated as a converter with a UI component, the JavaBean object controls the presentation type and model type of the data. For example, the JavaBean object could choose to show a Boolean model type as a String with a value of true.


  • Validation Model. The JavaServer Faces validation model provides a means to define custom validation for components. For example, date validation ensures a date is input correctly.


The JavaServer Faces Navigation Model
 

The JavaServer Faces navigation model defines how a web application moves from one page to another. The navigation model consists of a handler that uses a navigation configuration file containing navigation rules. The handler responds to action events executed by action sources, such as buttons or hyperlinks.

There are two types of navigation: static and dynamic. With static navigation, the navigation rules are determined before runtime using the navigation configuration file and hard-coded return values from action methods. Figure 2 shows an example of a navigation configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
    <navigation-rule>
        <from-view-id>/Page1.jsp</from-view-id>
        <navigation-case>
            <from-outcome>case1</from-outcome>
            <to-view-id>/Page2.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/Page2.jsp</from-view-id>
        <navigation-case>
            <from-outcome>back</from-outcome>
            <to-view-id>/Page1.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
</faces-config>
     

Figure 2: Navigation Configuration File With Static Navigation Rules

The navigation configuration determines static configuration by mapping a JavaServer Pages action method return value to a <to-view-id> tag identifying the page to navigate to. Figure 3 shows an action method that causes the web application to navigate to Page2.jsp, according to the rules in the navigation configuration file shown in Figure 2.

public String button1_action() {

        return "case1";
    }
     

Figure 3: Action Method Return Value

Dynamic navigation allows the developer to change the navigation based on runtime conditions. The navigation model allows the developer to define a set of navigation rules that point from one page to many pages. The return value of an action method determines the navigation route, and program logic deduces the next page. Figure 4 shows a navigation configuration file with multiple navigation cases for Page1.jsp. These multiple navigation cases for the same page allow the navigation to be determined logically in the action method. Figure 5 shows a method triggered by a drop-down list value change. The action method dynamically determines which page to navigate to.

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
    <navigation-rule>
        <from-view-id>/Page1.jsp</from-view-id>
        <navigation-case>
            <from-outcome>case1</from-outcome>
            <to-view-id>/Page2.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
           <from-outcome>case2</from-outcome>
            <to-view-id>/Page3.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-outcome>case3</from-outcome>
            <to-view-id>/Page4.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/Page2.jsp</from-view-id>
        <navigation-case>
            <from-outcome>back</from-outcome>
            <to-view-id>/Page1.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
</faces-config>
	 

Figure 4: Navigation Configuration File With Dynamic Navigation Rules

      public void dropDown1_processValueChange(ValueChangeEvent vce) {
      if(dropDown1.getSelected().equals("one")) {
         return case1;
      } else if(dropDown1.getSelected().equals("two")) {
         return case2;
      } else if(dropDown1.getSelected().equals("three")) {
         return case3;
      } else return null;
}
	 

Figure 5: Value Change Action Method for Dynamic Navigation

The JavaServer Faces Backing Bean Model
 

The JavaServer Faces application model separates the user interface from the back-end objects that represent the data model. The server-side, or back-end objects that represent data and state, are called backing beans. Usually a JavaServer Faces application has at least one backing bean.
The backing bean is a JavaBean component and can contain:

  • User interface component properties
  • Event handling methods
  • Validation methods
  • Converter initialization code
You can bind a user interface component's value to a backing bean property. You can also bind a component's instance to a backing bean property. The backing beans are bound to the user interface components in the JavaServer Pages using the JavaServer Faces Expression Language (EL). The JavaServer Faces EL is denoted by the #{} syntax.

Value Binding

If a component's value is bound to a backing bean property, the value of the component is wired to the getter and setter methods of the associated backing bean property. Figure 6 shows the Java code in the backing bean to bind a property called firstName to a user interface component.


String firstName = null;

String getFirstName(){
  return firstName;
}

void setFirstName(String inFirstName){
   firstname = inFirstName;
}

Figure 6: Backing Bean Code to Bind a Property

Figure 7 shows the JavaServer Faces EL necessary to bind the user interface component to the backing bean.

<h:outputText value="#{MyBean.firstName}" />

Figure 7: JavaServer Faces EL to Bind a Component to a Backing Bean

Component Instance Binding

Binding a component instance to a backing bean is useful if an event handler in the backing bean dynamically needs to change anything about the component. When a component's instance is bound to a backing bean, thebinding attribute of the component is used to specify the backing bean attribute to associate with the component instance. For example, Figure 8 shows the JavaServer Faces EL necessary to bind the user interface component to the backing bean.

<h:outputText binding="#{MyBean.outputText1}" id="outputText1" 
value="Hello World" />

Figure 8: Binding a Component to a Backing Bean

After the binding, the backing bean has getter and setter methods for the component instance outputText1. Figure 9 shows how the backing bean source might look.

HtmlOutputText outputText1 = new HtmlOutputText();

HtmlOutputText getOutputText1(){
  if(showLabel) {
    outputText1.setRendered(true);
  } else {
    outputText1.setRendered(false);
  }
  return outputText1;
}

void setOutputText1(HtmlOutputText inOutputText){
   outputText1 = inOutputText;
}

Figure 9: Backing Bean Code With Instance Binding

Notice that the backing bean includes logic to dynamically set the component rendering to true or false. Instance binding makes it much easier to effect dynamic changes to UI components in the backing beans. If you did not use instance binding, you would have to write code to get the UI component every time you needed to make a change. Figure 10 illustrates what that code might look like.

HTMLOutputText outputText1 = getFacesContext().getViewRoot()
.findComponent(":form:outputText1");

if(null != outputText1) {
  //dynamically change UI component
} else {
  //deal with UI component not found condition
}

Figure 10: Hypothetical Backing Bean Code Without Instance Binding

Managed Backing Beans

JavaServer Faces technology provides a managed bean facility to manage backing beans. The managed bean facility manages the creation and persistence of the backing beans. To have JavaServer Faces bind user interface component data to backing beans, the backing beans must be managed and declared in the managed bean facility configuration file. You also must provide an XML configuration file with the starting tag <managed-bean>, which indicates that you are using the managed bean facility.

Figure 11 shows a managed bean facility configuration file called managed-beans.xml. When an application references a bean, the facility creates, initializes, and stores the bean in the request, session or application scope.

<managed-bean>
<managed-bean-name>UserNumberBean</managed-bean-name>
<managed-bean-class>guessNumber.UserNumberBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>minimum</property-name>
<property-class>long</property-class>
<value>0</value>
</managed-property>
<managed-property>
<property-name>maximum</property-name>
<property-class>long</property-class><value>10</value>
</managed-property>
</managed-bean>

Figure 11: Managed Bean Facility Configuration File

The JavaServer Faces Page Life Cycle
 

A JavaServer Faces page follows a defined life cycle. A browser displays a JavaServer Faces page and an end user action, such as pressing a button or clicking a hyperlink, generates a servlet request. The request follows a set logic path and eventually a response is generated and returned. The process of handling the request and generating the response is referred to in the JavaServer Faces documentation as the life cycle.

Please see the J2EE 1.4 tutorial The Life Cycle of a JavaServer Faces Page for an in-depth explanation of the JavaServer Faces life cycle. There are four basic types of request/response events.

  1. JavaServer Faces request ? A servlet request sent from a previously generated JavaServer Faces response.
  2. Non-JavaServer Faces request ? A servlet request sent to a server-side component such as a servlet or a JSP page. A non-JavaServer Faces request starts a JavaServer Faces application by making a request to a JavaServer Faces JSP page, which in turn generates a JavaServer Faces response.
  3. JavaServer Faces response ? A servlet response generated by calling the render response phase of the JavaServer Faces life cycle.
  4. Non-JavaServer Faces response ? A servlet response generated from a server-side component, such as a servlet or a JSP page, that does not contain JavaServer Faces components.
Handling a JavaServer Faces request and generating a JavaServer Faces response is know as the standard request processing life cycle for JavaServer Faces. Figure 12 shows this life cycle.

 
Figure 12: JavaServer Faces Standard Request Processing Life Cycle
Figure 12: JavaServer Faces Standard Request Processing Life Cycle


The JavaStudio Creator 2 Application Model
 

The Java Studio Creator 2 application model is based on the JavaServer Faces application model. The Java Studio Creator development team has significantly enhanced the application model to make it both easier for developers to understand and usable within the IDE.

This section covers the parts of the application model that are specific to Java Studio Creator 2, particularly exploring the differences and specializations made to the backing beans and the user interface component model. Unless otherwise noted, the term application model in this section refers to the Java Studio Creator 2 application model rather than the JavaServer Faces application model.


User Interface Backing Beans
 

Let's first look at the backing beans. The application model has a category of backing beans for handling user interface details. This backing bean category, called user interface backing beans, handles user interface properties and events. There are two backing beans in this category: page bean and page fragment bean.


Page Beans
 

A page bean represents one JavaServer Pages page. The page bean contains all implementation logic to manage the server-side aspect of a web page. It does not contain validation and conversion logic.

User interface components are bound to backing beans on the server. The JavaServer Faces specification places no restrictions on the cardinality between the JavaServer Pages pages and the backing beans. For example, a web application might have five JSP pages all bound to the same backing bean.

However, the Java Studio Creator application model is different. The application model specifies a one-to-one relationship between the JavaServer Page page and the page bean backing bean. That is, for every JSP page there is a single page bean to which the JavaServer Page components are bound. For example, the Visual Designer window in the IDE is a visual view of the JSP page. Figure 13 depicts the relationship between the IDE's Visual Designer, the JSP page, and the page bean.  

Figure 13: JSP Page and Page Bean Relationship
Figure 13: JSP Page and Page Bean Relationship

The application model also supports backing beans that do not have a JSP page associated with them. The section Data Backing Beans discusses these types of backing beans.

Let's examine the anatomy of a page bean. The page bean contains everything necessary to manage the server-side logic for a web page. This logic can be grouped into two major categories: UI component properties and events. In the Java Studio Creator application model, standalone classes outside the scope of the page bean handle validation and conversion.

Page Bean UI Component Properties
 

Let's first look at the backing beans. The application model has a category of backing beans for handling user interface details. This backing bean category, called user interface backing beans, handles user interface properties and events. There are two backing beans in this category: page bean and page fragment bean.

Since there is a one-to-one relationship between a JSP page and a page bean, each time a UI component is added to the IDE Visual Designer, a property is added to the associated page bean for the UI component. Because the application model uses both value binding and component instance binding, the IDE implements the application model by creating getters and setters for the component instance binding and assigning a default value binding. Figure 14 shows the JavaServer Page script created by the IDE when a basic Static Text component is dropped on the Visual Designer view of Page1. Notice the bindings created on the ui:statictext component to #{Page1.staticText1}.

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2" xmlns:f="http://java.sun.com/jsf/core" 
xmlns:h="http://java.sun.com/jsf/html" 
 xmlns:jsp="http://java.sun.com/JSP/Page" 
 xmlns:ui="http://www.sun.com/web/ui">
    <jsp:directive.page contentType="text/html;charset=UTF-8" 
	pageEncoding="UTF-8"/>
    <f:view>
        <ui:page binding="#{Page1.page1}" id="page1">
            <ui:html binding="#{Page1.html1}" id="html1">
                <ui:head binding="#{Page1.head1}" id="head1">
                    <ui:link binding="#{Page1.link1}" id="link1" 
					url="/resources/stylesheet.css"/>
                </ui:head>
                <ui:body binding="#{Page1.body1}" id="body1"" 
				style="-rave-layout: grid">
                    <ui:form binding="#{Page1.form1}" id="form1">
                        <ui:staticText binding="#{Page1.staticText1}" 
						id="staticText1" style="position: 
                         absolute; left: 96px; top: 24px"/>
                    </ui:form>
                </ui:body>
            </ui:html>
        </ui:page>
    </f:view>
</jsp:root>
	 

Figure 14: Page1 Bindings

Figure 15 shows the setters and getters created for the ui:statictext component in the page bean. Notice that since the binding type is component instance (binding=), and both the return value and the value passed to the setter are component types and not Java primitive types. This means you can do things in the backing bean with the UI component, such as setRendered(false), to hide the static text field.

    private StaticText staticText1 = new StaticText();

    public StaticText getStaticText1() {
        return staticText1;
    }

    public void setStaticText1(StaticText st) {
        this.staticText1 = st;
    }
	 

Figure 15: Getters and Setters in a Page Bean

Events

The Java Studio Creator 2 application model supports the JavaServer Faces action and value-change events. Java Studio Creator 2 components that allow values to be changed, such as drop down list or text box, support the value-change event. Components that cause an action, such as hyperlink or button, support the action event.

The IDE provides several ways to define a value-change or an action event. The easiest way to define event handling is to double click the component. The Visual Designer creates the necessary entries in the JSP page and the page bean to support handling the event.

Figure 16 shows the JSP page code created for a button.

<ui:button action="#{Page1.button1_action}" binding="#{Page1.button1}" 
id="button1" style="position: absolute; left: 120px; top: 360px" 
text="go"/>
	 

Figure 16: JSP code for a Button

Figure 17 shows the page bean method created to support an action event.

    public String button1_action() {
        // TODO: Process the button click action. Return value is a navigation
        // case name where null will return to the same page.        
        return null;
    }
	 

Figure 17: Page Bean Method for Action Event

Notice that the method name in Figure 17 matches the method binding expression method name in Figure 16.

A value-change event is handled a bit differently from an action event solely because the JavaServer Page attribute name is different. Notice in Figure 18 that a value-change event uses the attribute valueChangeListener.

<ui:textField binding="#{Page1.textField1}" id="textField1" 
style="position: absolute; left: 120px; top:
144px" valueChangeListener="#{Page1.textField1_processValueChange}"/>
	 

Figure 18: Value-Change Event Attribute

Figure 19 shows the corresponding value-change event method in the page bean. These event methods are called on the page bean during the invoke application phase of the JavaServer Faces life cycle. The next section discusses the page bean life cycle.

    public void textField1_processValueChange(ValueChangeEvent event) {
        // TODO: Replace with your code
        
    }
	

Figure 19: Value-Change Event Page Bean Method

Page Bean Life Cycle
 

The application model uses the JavaServer Faces standard request processing life cycle for the page bean life cycle. The Java Studio Creator 2 application model, however, simplifies the life cycle by leveraging part of the JavaServer Faces architecture known as phase listeners. Phase listeners allow applications to inject logic into the JavaServer Faces standard request processing life cycle shown in figure 12.

The application model defines the following injection points into this request processing life cycle.

  • init
  • preprocess
  • prerender
  • destroy
These injection points are available as methods on the page bean. With these methods, an IDE developer can utilize the JavaServer Faces standard request processing life cycle to better control the web application logic. Figure 20 shows the Java Studio Creator 2 application model life cycle overlaid on the JavaServer Faces life cycle when a non-JavaServer Faces request generates a JavaServer Faces response.
Figure 20: Java Studio Creator 2 Application Model Life Cycle Example 1
Figure 20: Java Studio Creator 2 Application Model Life Cycle Example 1

Figure 21 shows the Java Studio Creator 2 application model life cycle overlaid on the standard request processing life cycle when a JavaServer Faces request generates a JavaServer Faces response. In both figures 20 and 21, the yellow boxes represent the application model injected life cycle methods.

Figure 21: Java Studio Creator 2 Application Model Life Cycle Example 2
Figure 21: Java Studio Creator 2 Application Model Life Cycle Example 2

The init method is invoked at the end of the restore view phase, after the page bean constructor completes. The init method is used to get resources that the page bean later uses in the preprocess and prerender methods. Within the init method you might, for example, establish database connections and acquire a hibernate session, among other operations.

The preprocess method is invoked at the beginning of the apply request values phase, after the component tree has been restored but before any event processing. You might put logic in the preprocess method to set the required attribute of a UI Component. The required attribute allows the developer to dynamically turn validation on or off for a given UI component. Figure 22 is an example of such code.

public void preprocess() {
   FacesContext context = FacesContext.getCurrentInstance();
   Map map = context.getExternalContext().getRequestParameterMap();
   // see if the "next" button was sent in the request which would tell us the 
   // "next" button was pressed.
   if (map.containsKey(nextButton.getClientId(context))) {
      shippingMethodDropDown.setRequired(true);
   } else {
      shippingMethodDropDown.setRequired(false);
   }
}

Figure 22: The preprocess Method

The prerender method, called at the beginning of the render response phase, is invoked for the page that is about to be rendered just before the actual page rendering occurs. The prerender method is a good place to put logic that needs to happen before a page is rendered. For example, you might include logic in this method to ensure that bound data providers are positioned at the correct row within a table.

The destroy method, invoked at the end of the render response phase, releases resources acquired for processing the page. This method is a good place to clean up resources allocated during the other life cycle methods.

Leveraging the Request Processing Life Cycle
 

To take advantage of the Java Studio Creator 2 application model life cycle, you should understand what each phase does in the JavaServer Faces standard request processing life cycle. This section provides a brief description of each phase in the standard life cycle. For a more detailed explanation, please refer to the JavaServer Faces specification.

The standard request processing life cycle phases are as follows:

  • Restore view phase ? The restore view phase performs the following tasks:
    • If a UIViewRoot exists in the FacesContext:
      • Sets the locale on the UIViewRoot.
      • For each component in the UIViewRoot, if component instance binding is used, calls the setValue method on each binding.
      • Processing ends for this phase.
    • If no UIViewRoot exists for this FacesContext, then this phase derives a view identifier. If it cannot determine a view identifier, it throws an exception and processing ends for this phase.
    • Calls viewHandler.restoreView with the derived view identifier to get the UIViewRoot. If no UIViewRoot can be found, creates a UIViewRoot.
    • Stores the restored or created UIViewRoot in the FacesContext.
    • For each component in the UIViewRoot, if component instance binding is used, calls the setValue method on each binding.
  • Apply request values phase ? The following operations happen in the apply request values phase:
    • For components that implement ActionSource, such as Button and Hyperlink, creates an ActionEvent when they are activated. These components are activated when a user clicks the button or selects the hyperlink. If the immediate property is set to true for the component, delivers the ActionEvent at the end of the apply request values phase. Otherwise, delivers the ActionEvent at the end of the invoke application phase.
    • Performs validation and conversion on components that implement EditableValueHolder, such as Text Field, if they also have the immediate property set to true.
    • By the end of this phase, updates all EditableValueHolder components from the submitted values in the request.
  • Process validations phase ? The following operations happen in the process validations phase:
    • Performs all component validations unless the component's immediate property is set to true, in which case the validation already happened in the apply request values phase.
    • Does all component conversions.
    • If a validation or conversion fails, queues the appropriate events. When the phase ends and the events are processed, control is passed directly to the render response phase, which handles the errors.
    • Terminates life cycle processing if responseComplete is called in a validate method.
    • Passes control to the render response phase if renderResponse is called in the validate method.
  • Update model values phase ? The following operations happen in the update model values phase:
    • Updates the application's model data by calling the updateModel method on all the components. This method call updates the model with each component's local data.
    • Clears the component's local data.
    • Terminates the life cycle processing if the method responseComplete is called in a updateModel method.
    • Passes control to the render response phase if the renderResponse method is called in the updateModel method.
  • Invoke application phase ? The following operations occur in the invoke application phase:
    • Broadcasts any queued events. For the Java Studio Creator 2 application model, this phase invokes the action methods, such as a button action.
    • This phase also interacts with the JavaServer Faces page navigation facility to check on return values of action methods and possibly to navigate to a different page. If navigating to another page, adheres to the non-JavaServer Faces page to JavaServer Faces page request type scenario, as show in Figure 20.
  • Render response phase ? The render response phase operations are as follows:
    • Causes the response to be rendered to the client.
    • Saves the state of the response for subsequent requests.


Page Fragment Bean
 

The page fragment bean is identical to the page bean except for the injected methods. The page fragment bean has only init and destroy life cycle methods. Refer to Figure 21 to see how these two injected methods overlay the JavaServer Faces standard request processing life cycle.

Portlet Life Cycle
 

In the Java Studio Creator 2 application model, a portlet page is the same as a web application page except for differences in the page life cycle. To best understand these life cycle differences, you should first understand how a portal interacts with a portlet. The JSR-168 Portlet specification defines the interaction between portals and portlets.

Typically, a portal display in the web browser shows multiple portlets. That is, when the browser displays the portal page, multiple portlets actually display or render their content. The portal manages the displayed portlets. Internally, the portal is responsible for two things:

  1. It tells the portlet when to display itself.
  2. It tells the portlet if an action, such as a button press, was performed inside that portlet.
When a portal wants its portlets to display their contents, the portal sends a render request to each portlet appearing in the portal. If a portlet appearing in the portal has a button tied to an action request, when that button is pushed the portal queues an action request for that portlet. In addition, the portal generates a render request for that portlet and all other portlets on the page. You should note that the portal queues both action and render requests for each action method on a portlet appearing in the portal.

This interaction means that the portlet page being rendered cannot make assumptions about the state of the values to be shown. Unlike a web application page, a portlet page cannot assume that the page to be rendered in the render response phase is the same page built in the restore view phase. A portlet that wants to maintain state across repeated render requests must use the session bean to store stateful information.

Figure 23 shows the life cycle of a portlet page when an action (postback) is invoked and the same portlet page is to be rendered. Notice that two separate instances of Page1 are created. Also notice that instance 1 of Page1 never goes through the render response phase, which means the component values are never saved for the UIViewRoot. Thus, when instance 2 of Page1 is created and goes through the restore view phase, the component tree pointed to by UIViewRoot does NOT have the values entered in instance 1 of Page1. It is important to remember that a portlet page must always be prepared to render it's values from scratch or session data. This implies you should never bind portlet page UI components to page bean properties or request bean properties. Also, you should never rely on page bean instance variables that might be set during an action event.

Figure 23: Portlet Page Life Cycle
Figure 23: Portlet Page Life Cycle

Let's look at an illustration of the portlet life cycle to see how it affects page rendering. Suppose you have a page bean that includes a static text field and a button as shown in Figure 24.

Figure 24: Page Bean with Button and Static Text Field
Figure 24: Page Bean with Button and Static Text Field

Let's say you also define a property called myString on the page bean and bind the static text field to this property. If the button action method contains the code shown in Figure 25, when you run the portlet application and press the button, the static text field is blank.

public String button1_action() { 
    this.myString = "Hello World";
    return null;
}

Figure 25: Value-Change Event Page Bean Method

Normally, you expect the static text field to contain the phrase Hello World. But here's what happens. When you press the button, the button action method sets the myString property that is on instance 1 of PageBean1. When the portlet container sends the render request to the portlet, this creates instance 2 of PageBean1 and the myString property on instance 2 is blank.

Data Backing Beans
 

Data backing beans are different from user interface backing beans. Data backing beans are used to manage data and are not associated with any JSP pages. Request beans, session beans, and application beans are data backing beans.

Data Backing Bean Scope and Life Cycle

Because a data backing bean is not associated to a JSP page, a data backing bean has a different life cycle from a page bean. You need to understand the scope of these backing beans since they are used to manage data. The Java Studio Creator 2 application model defines three scopes for data backing beans: application, session, and request scope.

  • Application scope?Objects in application scope are created at the application level and available to all users, sessions, and requests. A good example of using application scope is having a drop down list hold data that needs to be shared by all users.
  • Session scope?Objects in session scope are created at the user session level. They are available to the session and to all requests in the session. ession scope is useful for sharing data resources, such as RowSets and data providers.
  • Request scope?Objects in request scope are created for each request and are only available during the request. Request scope is useful for passing information between two pages. For example, you might have a set of web pages that act as a wizard to gather information about an order. On each press of a continue button, you store the current page's values in request scope and navigate to the next page in the wizard.

All data backing beans are managed by the JavaServer Faces managed bean facility. The facility creates the data backing bean only when it needs to, an approach called lazy instantiation. Here's how this lazy instantiation works.

The JavaServer Faces managed bean facility creates a data backing bean, if it doesn't already exist, during the restore view life cycle phase when the method setValue is invoked. The setValue method is called if the data backing bean has a property from a UI component bound to it. The newly created data backing bean is placed into the appropriate scope. The managed bean facility also creates a data backing bean and places it into the appropriate scope if the backing bean is referenced from another backing bean.

With lazy instantiation such as this, a developer using the application model should not rely on the instantiation of a data backing bean. Even though a particular scope is created, it does not mean that the backing beans associated with that scope are also created. As a result, you should avoid placing any necessary initialization code in data backing bean constructors. Instead, you should place all initialization code in a backing bean's init method.

Application Bean

The application bean, created in the application scope, is used for managing data at the application level. The application bean has two life cycle methods: init and destroy.

The init method is called when the application bean is added as an attribute to the servlet context. The application bean is added as an attribute when the application bean name is evaluated in a value-binding expression.

The destroy method is called when the application bean is removed as an attribute from the servlet context. The JavaServer Faces managed bean facility, when it determines the managed bean scope is application, controls adding and removing the application bean to and from the servlet context. The managed bean facility can remove the application bean for the following reasons:

  • The application logic explicitly removes the application bean.
  • The application is undeployed from the application or web container.

Session Bean

The session bean is created in the session scope and is used for managing data at the session level. The session bean has four life cycle methods: init, passivate, activate, and destroy.

The init method is called when the session bean is added as an attribute to the session, which occurs when the session bean name is evaluated in a value-binding expression.

The passivate method is called when the session is passivated (that is, its state is temporarily saved to a data store). The servlet container typically passivates and activates a session so that it can pass the session to a remote servlet container. Passing a session to a remote container implies that every class attribute on the session bean should be serializable or marked transient. The passivate method is used to do any special serialization of class attributes. Class attributes dealt with in the passivate method also need to be reconstituted in the activate method. Also, if it needs to be marked transient, the class attribute is probably a good candidate to recreate in the activate method.

The activate method is called when the session is activated. This method is used to reconstitute information that cannot be serialized in a standard way.

The destroy method is called when the session bean is removed as an attribute from the session. The JavaServer Faces managed bean facility controls adding and removing the session bean to and from the session when it determines the managed bean scope is session. It can remove the session bean for the following reasons;

  • The application logic explicitly removes the session bean.
  • The session is invalidated, such as when the user logs out.
  • The session times out.

Request Bean

The request bean is created in the request scope and it has two life cycle methods init and destroy.

The init method is called from the restore view phase of the JavaServer Faces standard request processing life cycle if a UI component attribute is bound to a request bean.

The destroy method is called at the end of the render response phase of the JavaServer Faces standard request processing life cycle.

 
User Interface Components
 

The Java Studio Creator 2 application model includes four groups of user interface components: basic components, JavaServer Faces standard components, custom components, and non-visual components.

  • Basic components?Basic components, which are based on the JavaServer Faces components, use the Java Studio Creator 2 Design-Time Application Programming Interface (API).
  • Because they implement this design-time API, the IDE is able to provide a richer visual design environment than with the JavaServer Faces standard components. (The Java Studio Creator 2 Design-Time API has been submitted for standardization through the Java Community Process (JCP) as Java Specification Request (JSR) 273 Design-Time API for JavaBeans[tm] JBDT.) The basic components are a comprehensive set of components that include, but are not limited to, the following:
    • Static text
    • Text field
    • Button
    • Calendar with popup date picker
    • Tab Set
    • Tree
  • JavaServer Faces standard components?The JavaServer Faces standard components are the components that come with the reference implementation of JavaServer Faces. If you are familiar with the earlier Java Studio Creator 2004Q2 IDE, these were the standard components.
  • Custom Components?Because the IDE component model is extensible, it provides an infrastructure for adding custom components. The component model specifies how to define the runtime and design-time aspects of each component, allowing third party component vendors to plug-in custom components to the Java Studio Creator 2 application model.
  • Non-visual Components?The application model permits you to define and use nonvisual components. Examples of nonvisual components are converters, validators, and data providers.
 

Applying the Application Model to a Web Application

 The best way to understand the Java Studio Creator 2 application model is to look at a working example. The sample application, Corporate Travel Center, can help you understand the application model. Download the sample. Unzip the file in a CorporateTravelCenter directory and open this project from within the Java Studio Creator 2 IDE. Once the project is open in the IDE, look at the Projects window. See Figure 26.

Figure 26: Projects Window for Corporate Travel Center
Figure 26: Projects Window for Corporate Travel Center

Notice the files with the .jsp file extension that appear beneath the Web Pages node. These files are the JSP pages for the user interface. Double click Page1.jsp to open Page1 in the Visual Designer. When it opens, you should see three buttons (Design, JSP, and Java) on the Visual Designer editing toolbar. See Figure 27. Click the Java button and the Java Editor opens and displays the source code for the Page1 page bean. Remember, in a Java Studio Creator 2 web application, there is one page bean for every JavaServer Pages page.

Figure 27: Visual Designer Editing Toolbar
Figure 27: Visual Designer Editing Toolbar
Now let's look at the page life cycle methods. While the Page1 page bean is open in the Java Editor, you can see the four life cycle methods for the page bean:
  • init
  • preprocess
  • prerender
  • destroy

The init method contains the code shown in Figure 28.

/** 
     * <p>Callback method that is called whenever a page is navigated to,
     * either directly via a URL, or indirectly via page navigation.
     * Customize this method to acquire resources that will be needed
     * for event handlers and life cycle methods, whether or not this
     * page is performing post back processing.</p>
     * 
     * <p>Note that, if the current request is a postback, the property
     * values of the components do not represent any
     * values submitted with this request.  Instead, they represent the
     * property values that were saved for this view when it was rendered.</p>
     */
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialization code here

        // <editor-fold defaultstate="collapsed" desc="Creator-managed 
		Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("Page1 Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e: new 
			FacesException(e);
        }

        // 
        // Perform application initialization that must complete
        // *after* managed components are initialized
        // TODO - add your own initialization code here
    }
  

Figure 28: Page1 init Method Code

Notice that there are two comments (shown here in bold) that instruct the developer to put code before or after the managed components section. The code in the init method is called once for the page bean. Logic inside the init method should initialize resources for the page.

The preprocess method in this sample does not contain any specialized code.

The prerender method contains the code shown in Figure 29.

/** 
     *<p>Callback method that is called just before rendering takes place.
     * This method will <strong>only</strong> be called for the page that
     * will actually be rendered (and not, for example, on a page that
     * handled a postback and then navigated to a different page). Customize
     * this method to allocate resources that will be required for rendering
     * this page.</p>
     */
    public void prerender() {
        if (getSessionBean1().getPersonId() == null ) {
         try {
           personDataProvider.cursorFirst();
           getSessionBean1().getTripRowSet().setObject(1, 
		   personDataProvider.getValue("PERSON.PERSONID"));
           getSessionBean1().setPersonId((Integer)personDataProvider.getValue
		   ("PERSON.PERSONID"));
           tripDataProvider.refresh();
         } catch (Exception e) {
           error("Cannot switch to person " + 
		   personDataProvider.getValue("PERSON.PERSONID"));
           log("Cannot switch to person " + 
		   personDataProvider.getValue("PERSON.PERSONID"), e);
          }
       }else {
           dropDown1.setSelected(getSessionBean1().getPersonId());
        }
   }
  

Figure 29: Page1 prerender Method

The code in the prerender method illustrates some of the concepts previously discussed. Notice the getSessionBean1 method calls to get and set session bean data that has session scope. Notice also the reference to the instance binding of a drop down list (dropDown1) component. The statement dropdown1.setSelected(getSessionBean1().getPersonId()); dynamically changes the drop down list component's selected value.

The destroy method contains the code shown in Figure 30.

    /** 
     * <p>Callback method that is called after rendering is completed for
     * this request, if <code>init()</code> was called (regardless of whether
     * or not this was the page that was actually rendered). Customize this
     * method to release resources acquired in the <code>init()</code>,
     * <code>preprocess()</code>, or <code>prerender()</code> methods (or
     * acquired during execution of an event handler).</p>
     */
    public void destroy() {
        tripDataProvider.close();
        personDataProvider.close();
    }
  

Figure 30: Page1 destroy Method

Notice that the destroy method disposes of or closes resources used in the page bean. Specifically, this sample code closes two data providers for proper clean up.

Finally, let's examine the value binding in this example. Click the JSP button in the Visual Designer editing toolbar, as shown in Figure 27 to open the JavaServer Pages script for Page1.jsp. In particular, notice the binding definition for the drop down list ui:dropDown. See Figure 31.

<ui:dropDown binding="#{Page1.dropDown1}"
converter="#{Page1.dropDown1Converter}" id="dropDown1" 
items="#{Page1.personDataProvider.options['PERSON.PERSONID,PERSON.NAME']}"
onChange="common_timeoutSubmitForm(this.form, 'dropDown1');" 
style="left: 144px; top: 216px; position: absolute; width: 144px" 
valueChangeListener="#{Page1.dropDown1_processValueChange}"/>
  

Figure 31: Page1 JavaServer Pages Script

The definition supports instance binding because of the clause binding="#{Page1.dropDown1}. The UI component is bound to the Page1 backing bean (a page bean in Java Studio Creator 2) and the dropDown1Converter property. The converter code (shown in Figure 32) in the page bean is used by the JavaServer Faces binding.

    private IntegerConverter dropDown1Converter = new IntegerConverter();

    public IntegerConverter getDropDown1Converter() {
        return dropDown1Converter;
    }

    public void setDropDown1Converter(IntegerConverter ic) {
        this.dropDown1Converter = ic;
    }
	

Figure 32: Page1 Converter Methods

 
Summary
You should now have a good understanding of the Java Studio Creator 2 application model and how it was derived from the JavaServer Faces application model. You should understand the application model event life cycle and its methods, along with the event life cycle differences between web application pages and portlet application pages.
 
More Developer Resources

For more tech tips, articles, and expert advice for developers, visit the Java Studio Creator developer resources on the Sun Developer Network (SDN).

 
 
David Botterill has been software developer for the past 22 years, David has been active on the Java platform since version 1.0. As the lead for the portlet development feature effort in Java Studio Creator, he's using his blog to get feedback from portlet developers so he can improve the feature. David also specializes in the web services consumption capabilities of the IDE.
 
Beth Stearns has written numerous articles and books on Java-related technologies. She is most recently a co-author on the J2EE BluePrints book, "Designing Web Services with the J2EE 1.4 Platform".