# Your First Cup: An Introduction to the Java EE Platform

# 4.4 Modifying the Web Client

To add the correct functionality to the web client, you need to perform the following tasks:

- Modify the `DukesBDay` managed bean class

- Modify the Facelets pages

## 4.4.1 Modify the DukesBDay Managed Bean Class

`DukesBDay` is a CDI managed bean that acts as a backing bean. A managed bean is a lightweight container-managed object that supports a set of basic services. A backing bean is a managed bean that provides temporary data storage for the values of the components included on a particular JavaServer Faces page. The JavaServer Faces application instantiates the managed bean and stores it in scope. The section following this one describes more about managed beans and how to configure them.

This section describes how to modify the `DukesBDay` class.

### 4.4.1.1 Call the dukes-age Web Service to Retrieve Duke's Current Age

Now modify the `getAge` method of `DukesBDay` to call the `dukes-age` web service using the JAX-RS Client API. This will retrieve Duke's current age, so it can be compared to the user's age.

1. Expand the Source Packages node, expand the `firstcup.web` node, then double-click the `DukesBDay.java` file to open it in the editor window.

2. Find the `getAge` method and implement its functionality by copying and pasting the following code in bold:

           public int getAge() {
               try {
                   Client client = ClientBuilder.newClient();
                   WebTarget target =
                   client.target("http://localhost:8080/dukes-age/webapi/dukesAge");
                   String response = target.request().get(String.class);
                   age = Integer.parseInt(response);
               } catch (IllegalArgumentException | NullPointerException |
                        WebApplicationException ex) {
                   logger.severe("processing of HTTP response failed");
               }
               return age;
           }

3. In the editor window, right-click and select Format.

4. From the File menu, select Save.

### 4.4.1.2 Get the Age Difference from the DukesBirthdayBean Enterprise Bean

Now modify the `processBirthday` method to get the difference in age between the user's age and Duke's age from the `DukesBirthdayBean` EJB, set the `absAgeDiff` variable to the absolute value of the age difference, and set a result string that will forward the user to the display page.

1. Find the `processBirthday` method and implement the functionality by copying and pasting the following code in bold:

           public String processBirthday() {
               this.setAgeDiff(dukesBirthdayBean.getAgeDifference(yourBD));
               logger.log(Level.INFO, "age diff from dukesbday {0}", ageDiff);
               this.setAbsAgeDiff(Math.abs(this.getAgeDiff()));
               logger.log(Level.INFO, "absAgeDiff {0}", absAgeDiff);
           this.setAverageAgeDifference(dukesBirthdayBean.getAverageAgeDifference());
           logger.log(Level.INFO, "averageAgeDifference {0}", averageAgeDifference);
               return "/response.xhtml";
           }

   This method calls the `getAgeDifference` method of `DukesBirthdayBean` to get the age difference and store it in the `ageDiff` property, sets the absolute age difference stored in the `absAgeDiff` property, and sets the average age difference stored in the `averageAgeDifference` property. It returns the relative URL of the response page to which the user will be forwarded.

2. In the editor window, right-click and select Format.

3. From the File menu, select Save.

## 4.4.2 Creating the Facelets Client

The Facelets client consists of a resource library, a composite component, and two XHTML files.

### 4.4.2.1 Resource Libraries in firstcup-war

A JavaServer Faces resource library is a collection of user-created components collected in a standard location in a web application. Resource libraries are identified according to a resource identifier, a string that represents a particular resource within a web application. Resources can be packaged either at the root of the web application or on the web application's classpath.

A resource packaged in the web application root must be in a subdirectory of a `resources` directory at the web application root.

    resources/resource-identifier

A resource packaged in the web application classpath must be in a subdirectory of the `META-INF/resources` directory within a web application.

    META-INF/resources/resource-identifier

Resource identifiers are unique strings that conform to the following format:

    [locale-prefix/][library-name /][library-version/]resource-name [/resource-version]

Elements of the resource identifier in brackets (`[]`) are optional. A resource name, identifying a particular resource (a file or a graphic, for example), is required. In `firstcup-war`, a resource library with the name `components` is packaged in the web application root, and this library contains one resource, a file called `inputDate.xhtml`. The resource identifier for this resource is therefore `components/inputDate.xhtml`, and it is located in the web application root at `resources/components/inputDate.xhtml`.

### 4.4.2.2 The inputDate Composite Component

A composite component is a set of user-defined JavaServerFaces and Facelets components located in a resource. In `firstcup-war`, the `inputDate.xhtml` resource, located in the `components` resource library, is a composite component that contains tags for reading in a date the user enters in a form. Composite components consist of an interface definition and an implementation.

The interface definition is specified with the `<cc:interface>` tag to define which attributes are exposed to pages that use the composite component. Attributes are identified with the `<cc:attribute>` tag.

The `inputDate.xhtml` interface definition is as follows. It defines a single attribute, `date`, that must be specified in pages that use the `inputDate` composite component.

    <cc:interface>
        <cc:attribute name="date" />
    </cc:interface>

The implementation of the composite component is specified with the `<cc:implementation>` tag. The tags within the `<cc:implementation>` are the actual component tags that will be added to pages that use the composite component. They can be any HTML render kit, JavaServer Faces, or Facelets tags. The `#{cc.attrs.``attribute-name``}` expression is used to get the value of the specified attribute from the page or component that is using the composite component.

The implementation of the `inputDate` composite component is as follows. An HTML input text component will store the entered text into the `date` attribute, accessed by the `#{cc.attrs.date}` expression. A JavaServer Faces `convertDateTime` component will convert the entered text to a date with the form of `MM/dd/yyyy` (04/13/2014, for example).

    <cc:implementation>
        <h:inputText id="getdate" value="#{cc.attrs.date}">
            <f:convertDateTime pattern="MM/dd/yyyy" />
        </h:inputText>
        <p/>
        <h:message for="getdate" style="color:red" />
    </cc:implementation>

If there's an error with the input of the `inputText` component, the form submission is unsuccessful, and a warning message is displayed. The message output is specified by the `<h:message>` tag, which is connected to the `inputText` component that has the id `getdate`.

### 4.4.2.3 Implement the inputDate Composite Component

Modify the `inputDate` composite component in the `components` resource library.

1. Expand Web Pages, then `resources`, then `components`, and open `inputDate.xhtml`.

2. Add the composite component interface definition between the opening and closing `<cc:interface>` tags in `inputDate.xhtml`:

           <cc:interface>
               <cc:attribute name="date" />
           </cc:interface>

3. Add the composite component implementation between the opening and closing `cc:implementation` tags:

           <cc:implementation>
               <h:inputText id="getdate" value="#{cc.attrs.date}">
                   <f:convertDateTime pattern="MM/dd/yyyy" />
               </h:inputText>
               <p/>
               <h:message for="getdate" style="color:red" />
           </cc:implementation>

4. In the editor window, right-click and select Format.

5. From the File menu, select Save.

### 4.4.2.4 The Facelets Web Interface

The `firstcup-war` web application interface has two XHTML files. The `greeting.xhtml` file displays Duke's current age and the form where the user can enter a birthday. The `response.xhtml` file displays the age difference between the user and Duke.

The `greeting.xhtml` file contains several pieces of the `firstcup-war` application detailed previously. It uses the localized strings contained in `WebMessages.properties` and `WebMessages_es.properties`. It uses the `DukesBDay` managed bean to call both the `DukesAgeResource` JAX-RS web service and the `DukesBirthdayBean` enterprise bean. It uses the `inputDate` composite component to create the input for the user to enter a birthday.

Here's the content of the `greeting.xhtml` file.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html
          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
          xmlns:h="http://xmlns.jcp.org/jsf/html"
          xmlns:fc="http://xmlns.jcp.org/jsf/composite/components">
        <h:head>
            <title>Firstcup Greeting Page</title>
        </h:head>
        <h:body>
            <h:form>
                <h2>
                    <h:outputText value="#{bundle.Welcome}"/>
                </h2>
                <h:outputText value="#{bundle.DukeIs} "/>
                <h:outputText value="#{dukesBDay.age} #{bundle.YearsOldToday}"/>
                <p/>
                <h:outputText value="#{bundle.Instructions}"/>
                <p/>
                <h:outputText value="#{bundle.YourBD} "/>
                <fc:inputDate id="userBirthday" date="#{dukesBDay.yourBD}" />
                <p/>
                <h:commandButton value="#{bundle.Submit}"
                                 action="#{dukesBDay.processBirthday}"/>
            </h:form>

        </h:body>
    </html>

The `greeting.xhtml` file uses the HTML RenderKit and the `components` resource library tag libraries. The `components` tag library has a prefix of `fc`, and is used to specify the `inputDate` composite component in the form below. The `<fc:inputDate id="userBirthday" date="#{dukesBDay.yourBD}" />` tag has the required `date` attribute, and it stores the value in the `yourBD` property in the `DukesBDay` managed bean by using the EL expression `#{dukesBDay.yourBD}`.

The localized strings are referenced by the EL expressions `#{bundle.``property-name``}`. For example, the `<h:outputText value="#{bundle.Welcome}"/>` tag will display the following string in English locales:

    Hi. I'm Duke. Let's find out who's older -- you or I.

The `<h:commandButton>` tag creates a Submit button and specifies that a successful submission should render the `response.xhtml` file by setting the `action` attribute to `#{dukesBDay.processBirthday}`. The `processBirthday` method returns the value `"/response.xhtml"`. The `action` attribute is used to define navigation rules for forms in Facelets pages.

The `response.xhtml` file displays the age difference between the user and Duke and the average age difference of all users so far. Different strings are displayed based on whether the user is the same age, younger, or older than Duke. The text can be displayed or not based on the conditions specified by the `rendered` attribute of the `<h:outputText>` tag. The conditions used in the `rendered` attribute are Expression Language (EL) alternatives to the Java programming language conditional operators to allow XML parsing of the XHTML file.

Table 4-1 Conditional Operator EL Language Alternatives

Logical Condition | Java Programming Language Conditional Operator | EL Alternative
--- | --- | ---
AND | `&&` | `&&`
EQUALS | `==` | `==`
LESS THAN | `<` | `lt`
GREATER THAN | `>` | `gt`

Here's the content of the `response.xhtml` file.

    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://xmlns.jcp.org/jsf/html">
        <h:head>
            <title>Response Page</title>
        </h:head>
        <h:body>
            <h:form>
                <h:outputText value="#{bundle.YouAre} "/>
                <h:outputText value="#{bundle.SameAge}"
                              rendered="#{dukesBDay.ageDiff == 0}"/>
                <h:outputText value="#{dukesBDay.absAgeDiff}"
                              rendered="#{dukesBDay.ageDiff lt 0}"/>
                <h:outputText value=" #{bundle.Year} "
                              rendered="#{dukesBDay.ageDiff == -1}"/>
                <h:outputText value=" #{bundle.Years} "
                              rendered="#{dukesBDay.ageDiff lt -1}"/>
                <h:outputText value="#{bundle.Younger}"
                              rendered="#{dukesBDay.ageDiff lt 0}"/>
                <h:outputText value="#{dukesBDay.absAgeDiff}"
                              rendered="#{dukesBDay.ageDiff gt 0}"/>
                <h:outputText value=" #{bundle.Year} "
                              rendered="#{dukesBDay.ageDiff == 1}"/>
                <h:outputText value=" #{bundle.Years} "
                              rendered="#{dukesBDay.ageDiff gt 1}"/>
                <h:outputText value="#{bundle.Older}"
                              rendered="#{dukesBDay.ageDiff gt 0}"/>
                <p/>
                <h:outputText
                    value="#{bundle.AverageAge} #{dukesBDay.averageAgeDifference}."/>
                <p/>
                <h:commandButton id="back" value="#{bundle.Back}" action="greeting"/>
            </h:form>
        </h:body>
    </html>

For example, the `#{bundle.SameAge}` string is displayed if the user and Duke have the same birthday, as specified by the condition `#{dukesBDay.ageDiff == 0}` in the `rendered` attribute. That is, the following string is displayed when the `ageDiff` property of `DukesBDay` equals `0`:

    You are the same age as Duke!

The form also contains a `<h:commandButton>` tag that creates a Back button, which directs the user back to the `greeting.xhtml` page, as specified in the `action` attribute.

### 4.4.2.5 Add the Form to greeting.xhtml

Add the form that provides the user interface for displaying Duke's age and specifying the user's birthday.

1. In the Projects tab, double-click `greeting.xhtml` in the `firstcup-war` project and, in the editor window, replace the text between the `<h:form>` and `</h:form>` tags with the following:

           <h2>
               <h:outputText value="#{bundle.Welcome}"/>
           </h2>
           <h:outputText value="#{bundle.DukeIs} "/>
           <h:outputText value="#{dukesBDay.age} #{bundle.YearsOldToday}"/>
           <p/>
           <h:outputText value="#{bundle.Instructions}"/>
           <p/>
           <h:outputText value="#{bundle.YourBD} "/>
           <fc:inputDate id="userBirthday" date="#{dukesBDay.yourBD}" />
           <p/>
           <h:commandButton value="#{bundle.Submit}"
                            action="#{dukesBDay.processBirthday}"/>

2. In the editor window, right-click and select Format.

3. From the File menu, select Save.

### 4.4.2.6 Add the Form to response.html

Add a form that displays the age difference between Duke and the user, displays the average age difference of all users, and allows the user to navigate back to `greeting.xhtml`.

1. In the Projects tab, double-click `response.xhtml` in the `firstcup-war` project and, in the editor window, replace the text between the `<h:form>` and `</h:form>` tags with the following:

           <h:outputText value="#{bundle.YouAre} "/>
           <h:outputText value="#{bundle.SameAge}"
                         rendered="#{dukesBDay.ageDiff == 0}"/>
           <h:outputText value="#{dukesBDay.absAgeDiff}"
                         rendered="#{DukesBDay.ageDiff lt 0}"/>
           <h:outputText value=" #{bundle.Year} "
                         rendered="#{dukesBDay.ageDiff == -1}"/>
           <h:outputText value=" #{bundle.Years} "
                         rendered="#{dukesBDay.ageDiff lt -1}"/>
           <h:outputText value="#{bundle.Younger}"
                         rendered="#{dukesBDay.ageDiff lt 0}"/>
           <h:outputText value="#{dukesBDay.absAgeDiff}"
                         rendered="#{dukesBDay.ageDiff gt 0}"/>
           <h:outputText value=" #{bundle.Year} "
                         rendered="#{dukesBDay.ageDiff == 1}"/>
           <h:outputText value=" #{bundle.Years} "
                         rendered="#{dukesBDay.ageDiff gt 1}"/>
           <h:outputText value="#{bundle.Older}"
                         rendered="#{dukesBDay.ageDiff gt 0}"/>
           <p/>
           <h:outputText
               value="#{bundle.AverageAge} #{dukesBDay.averageAgeDifference}." />
           <p/>
           <h:commandButton id="back" value="#{bundle.Back}" action="greeting"/>

2. In the editor window, right-click and select Format.

3. From the File menu, select Save.