walkthrough of carstore jsf sample...
TRANSCRIPT
1
1
Walkthrough ofCarStore JSF Sample
Application
In our previous class, we have gone though a simple JSF application called guessNumber.
In this presentation, we will walk through a more complex JSF application, carstore, which also comes with J2EE 1.4 SDK.
04/29/2004
3
3
Disclaimer & Acknowledgments? Even though Sang Shin is a full-time employee of Sun
Microsystems, the contents here is created as his own personal endeavor and thus does not reflect any official stance of Sun Microsystems.
? Sun Microsystems is not responsible for any inaccuracies in the contents.
? Acknowledgments: – Many slides and speaker notes are created from JSF tutorial– Source code examples are from sample codes that are shipped with JSF
beta
04/29/2004
4
4
Revision History? 12/28/2003: version 1: created by Sang Shin? 04/03/2004: version 2: updated with JSF version 1.0 that
comes with J2EE 1.4 SDK ? Things to do
– speaker notes need to be polished a bit
04/29/2004
5
5
CarStoreSample Application
04/29/2004
6
6
Sample JSP Application we are going to build? CarStore application that comes with
J2EE 1.4 SDK– <install>/samples/jsf/carstore– Windows: C:\Sun\AppServer1\samples\jsf\carstore
? Simulates online car dealership– select a locale– select a car model– add options– get an updated price– buy the car
The carstore application simulates a simple online car dealership through which a user can select a locale, select a car model, add options, and then get updated price, and finally buy the car.
04/29/2004
7
7
Page Flow
Here's a quick diagram of page flow through the application. Each box corresponds to a JSP page. The arrows correspond to the supported flow from page to page, either with buttons in the page, or with the browser navigation buttons.
04/29/2004
8
8
Backing Beans (Model Objects)
We then overlay the beans required to back the JSP pages. These beans are called backing beans. In MVC pattern, they correspond to model objects.
04/29/2004
9
9
Beans
Data
Finally, we add the back end data. In this simple application, the data is read from java.util.ResourceBundle instances, but it could just as well come from a database.
04/29/2004
10
10
Page Flow of CarStore Application
So let' go over the page flow of carstore application.
04/29/2004
11
11
JSP Pages used for End UserPresentation? chooseLocale.jsp? storeFront.jsp? carDetail.jsp? confirmChoices.jsp? finish.jsp? customerInfo.jsp
This slide shows the list of JSP pages in the carstore application. In the following slides, we will go over each of this pages and how they are presented in the browser.
04/29/2004
12
12
JSP Pages Included in OtherJSP Pages? optionsPanel.jsp
– included in carDetails.jsp? bottomMatter.jsp
– footer page– included in carDetails.jsp, chooseLocale.jsp,
confirmChoices.jsp, finish.jsp, storeFront.jsp
The carstore application also has two JSP pages which are included in the other JSP pages. The optionsPanel.jsp is included in the carDetails.jsp while the bottomMatter.jsp is included in the bottom of all the displayed JSP pages.
04/29/2004
13
13
chooseLocale.jsp
The chooseLocale.jsp page is the first page that gets displayed and allows you to select a locale.
04/29/2004
14
14
chooseLocale.jsp (page 1)
1 <html>2 <head>3 <title>CarStore</title>4 <link rel="stylesheet" type="text/css"5 href='<%= request.getContextPath() + "/stylesheet.css" %>'>6 </head>7 8 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>9 <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>10 <%@ taglib uri="http://java.sun.com/jsf/demo/components" prefix="d" %>11 12 <f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
This is the first part of the chooseLocale.jsp page. Here we see the declaration of JSF tag libraries, html and core. Since this application also has its own custom tag library called components, it also needs to be declared.
Please also note the <f:loadBundle> element through which a resource bundle is specified. The value of the “var” attribute, “bundle”, in this example, is used as a prefix when any localized message is refered to in this page.
04/29/2004
15
15
chooseLocale.jsp (page 2)
1 <f:view>2 <h:form>3 4 <h:panelGrid columns="1" 5 footerClass="form-footer"6 headerClass="form-header"7 styleClass="main-background"8 columnClasses="single-column"9 summary="#{bundle.chooseLocale}" 10 title="#{bundle.chooseLocale}" >11 12 <h:graphicImage url="/images/cardemo.jpg" /> 13 14 <h:outputText styleClass="maintitle"15 value="#{bundle.chooseLocale}" />16 17 <h:graphicImage id="mapImage" url="/images/world.jpg" 18 alt="#{bundle.chooseLocale}"19 usemap="#worldMap" />
This is the continuation of the chooseLocale.jsp. Here we are using <h:panelGrid> to have a table format. (This might not be obvious since things are displayed in graphics.)
The first <h:graphicImage> displays the carstore.jpg on the top. The <h:outputText> then display the main title. Then the <h:graphicImage> is used to display the world map.
04/29/2004
16
16
chooseLocale.jsp (page 3)
1 <d:map id="worldMap" current="NAmericas" immediate="true"2 action="storeFront"3 actionListener="#{carstore.chooseLocaleFromMap}">4 <d:area id="NAmerica" value="#{NA}" 5 onmouseover="/images/world_namer.jpg" 6 onmouseout="/images/world.jpg" 7 targetImage="mapImage" />8 <d:area id="SAmerica" value="#{SA}" 9 onmouseover="/images/world_samer.jpg"10 onmouseout="/images/world.jpg" 11 targetImage="mapImage" />12 <d:area id="Germany" value="#{gerA}" 13 onmouseover="/images/world_germany.jpg" 14 onmouseout="/images/world.jpg" 15 targetImage="mapImage" />16 <d:area id="France" value="#{fraA}" 17 onmouseover="/images/world_france.jpg" 18 onmouseout="/images/world.jpg" 19 targetImage="mapImage" />20 </d:map>21
Here we are using custom UI component called <d:map> in which 4 different world image files are refered to depending on which locale a user selected.
04/29/2004
17
17
chooseLocale.jsp (page 4) 1 <h:form>2 <!-- For non graphical browsers -->3 <h:panelGrid id="links" columns="4" 4 summary="#{bundle.chooseLocale}" 5 title="#{bundle.chooseLocale}" >6 <h:commandLink id="NAmerica" action="storeFront"7 actionListener="#{carstore.chooseLocaleFromLink}">8 <h:outputText value="#{bundle.english}" />9 </h:commandLink>10 <h:commandLink id="Germany" action="storeFront"11 actionListener="#{carstore.chooseLocaleFromLink}">12 <h:outputText value="#{bundle.german}" />13 </h:commandLink>14 <h:commandLink id="France" action="storeFront"15 actionListener="#{carstore.chooseLocaleFromLink}">16 <h:outputText value="#{bundle.french}" />17 </h:commandLink>18 <h:commandLink id="SAmerica" action="storeFront"19 actionListener="#{carstore.chooseLocaleFromLink}">20 <h:outputText value="#{bundle.spanish}" />21 </h:commandLink>22 </h:panelGrid> 23 </h:form>
This is the continuation of chooseLocale.jsp. The elements in this slide are used for non-graphical browsers.
04/29/2004
18
18
storeFront.jsp
This is how storeFront.jsp page is displayed. Now let's see the contents of the storeFront.jsp from the next slide.
04/29/2004
19
19
storeFront.jsp (page 1)
1 <HTML>2 3 <HEAD>4 <TITLE>Welcome to CarStore</TITLE>5 <link rel="stylesheet" type="text/css"6 href='<%= request.getContextPath() + "/stylesheet.css" %>'>7 </HEAD>8 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>9 <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>10 11 <BODY BGCOLOR="white">12 13 <f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
This is the first part of the storeFront.jsp. Since this part is the common for all the the JSP pages, I will move on. I included it here for the sake of completeness.
04/29/2004
20
20
storeFront.jsp (page 2)
1 <f:view> 2 <h:form>3 <h:graphicImage url="/images/cardemo.jpg" /> 4 <h:panelGrid columns="2" 5 footerClass="form-footer"6 headerClass="form-header"7 styleClass="top-table"8 columnClasses="single-column"9 summary="#{bundle.chooseCar}" 10 title="#{bundle.chooseCar}" >11 12 <h:panelGrid columns="2"13 styleClass="storeFrontCar">14 ...next page...15 </h:panelGrid>16 <h:panelGrid columns="2"17 styleClass="storeFrontCar">18 ...19 </h:panelGrid>20 </h:panelGrid>21 </h:form>
column 1 column 2
This is the continuation of the storeFront.jsp page. Here we are using nested <h:panelGrid> elements. The outmost <h:panelGrid> element has two columns as illustrated in the picture on the right side of the slide. The inside <h:panelGrid> element also has two columns which we will see in the following slide.
04/29/2004
21
21
storeFront.jsp (page 3)
<h:panelGrid columns="2" styleClass="storeFrontCar"> <!-- Jalopy --> <h:graphicImage binding="#{carstore.models.Jalopy.components.imageSmall}" /> <h:outputText styleClass="subtitlebig" value="#{carstore.models.Jalopy.attributes.title}" /> <h:outputText value="#{carstore.models.Jalopy.attributes.description}"/> <h:commandButton action="#{carstore.storeFrontJalopyPressed}"
10 value="#{bundle.moreButton}" >11 </h:commandButton>12 <!-- Roadster -->13 <h:graphicImage binding="#{carstore.models.Roadster.components.imageSmall}" />14 <h:outputText styleClass="subtitlebig"15 value="#{carstore.models.Roadster.attributes.title}" />16 <h:outputText 17 value="#{carstore.models.Roadster.attributes.description}" /> 18 <h:commandButton 19 action="#{carstore.storeFrontRoadsterPressed}" 20 value="#{bundle.moreButton}" >21 </h:commandButton>22 </h:panelGrid>
This slide shows the contents of the inside <h:grid_panel> elements of the previous slide. Here 8 UI components are displayed in two columns. Please see the UI component and its corresponding display by following through the arrows.
04/29/2004
22
22
carDetails.jsp (upper)
Now once a user selects a car mode, the carDetails.jsp page gets displayed . This page allows you to choose the options for a particular car model. Since this page is too long to display in a single slide, I divided it into two slides. This slide shows the upper part of the page while the next slide shows the lower part of the page.
04/29/2004
23
23
carDetails.jsp (lower)
This slide shows the lower part of the carDetails.jsp page. Now let's go over the actual contents of the carDetails.jsp page from the following slide.
04/29/2004
24
24
carDetails.jsp (page 1)
1 <f:view>2 <h:form>3 4 <!-- non-option details -->5 <h:panelGrid columns="1"6 summary="#{bundle.carDetails}"7 title="#{bundle.carDetails}">8 9 <h:graphicImage url="/images/cardemo.jpg" /> 10 11 <h:graphicImage 12 binding="#{carstore.currentModel.components.image}" />13 14 <h:outputText styleClass="subtitlebig"15 binding="#{carstore.currentModel.components.title}" />16 17 <h:outputText 18 binding="#{carstore.currentModel.components.description}" />
This part of the carDetails.jsp page shows the header, car model image, car model's title, and car model description. Please note JSF EL expression “#{carstore.currentModel.components.title}”.
The “carstore” is the main bean for the carstore application. It maintains a Map of CarBean instances, keyed by model name, and a Map of CarCustomizer instances, keyed by package name. The “currentModel” property of the “carstore” bean contains the CarBean instance of the selected car model. A CarBean instance contains a Map of UI components.
04/29/2004
25
25
carDetails.jsp (page 2)
1 <h:panelGrid columns="2">2 3 <h:outputText styleClass="subtitle"4 value="#{bundle.basePriceLabel}" />5 6 <h:outputText 7 binding="#{carstore.currentModel.components.basePrice}" />8 9 <h:outputText styleClass="subtitle"10 value="#{bundle.yourPriceLabel}" />11 12 <h:outputText value="#{carstore.currentModel.currentPrice}" />13 14 </h:panelGrid>15 16 <h:commandButton action="#{carstore.buyCurrentCar}"17 value="#{bundle.buy}" />18 19 </h:panelGrid>
This is continuation of carDetails.jsp page. Here “Best Price” label and the corresponding value of the selected car model and “Your Price” label and the corresponding value of the selected car model are displayed in a table form.
04/29/2004
26
26
carDetails.jsp (page 3)
1 <jsp:include page="optionsPanel.jsp"/>2 3 <h:commandButton value="#{bundle.recalculate}" 4 action="#{carstore.currentModel.updatePricing}" 5 immediate="true" />6 7 <h:commandButton action="#{carstore.buyCurrentCar}"8 value="#{bundle.buy}" />9 10 </h:form>11 12 <jsp:include page="bottomMatter.jsp"/>13 14 </f:view>
The carDetails.jsp page includes optionsPanel.jsp. The things that are displayed by optionsPanel.jsp page is inside the box on the right side of the slide.
The "Recalculate" and "Buy" buttons are then displayed.
04/29/2004
27
27
optionsPanel.jsp (page 1)
1 <!--2 Copyright 2003 Sun Microsystems, Inc. All rights reserved.3 SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.4 -->5 <%@ page contentType="text/html" language="java" %>6 <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>7 <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>8 <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>9 10 <f:subview id="optionsPanel">11 12 <h:panelGrid>13 14 <h:outputText value="#{bundle.OptionsPackages}" />
This slide shows the beginning part of the contents of the optionsPanel.jsp. Please note the <f:subview> element. If you want to include a JavaServer Faces page within another JavaServer Faces page or another JSP page, you must enclose the entire nested page in a <f:subview> tag.
04/29/2004
28
28
optionsPanel.jsp (page 2)
1 <h:panelGrid columns="4"> 2 3 <h:commandButton id="Custom" value="#{bundle.Custom}" immediate="true"4 styleClass="#{carstore.customizers.Custom.buttonStyle}"5 actionListener="#{carstore.choosePackage}" />6 7 <h:commandButton id="Standard" value="#{bundle.Standard}" immediate="true"8 styleClass="#{carstore.customizers.Standard.buttonStyle}"9 actionListener="#{carstore.choosePackage}" />10 11 <h:commandButton id="Performance" value="#{bundle.Performance}" immediate="true"12 styleClass="#{carstore.customizers.Performance.buttonStyle}"13 actionListener="#{carstore.choosePackage}" />14 15 <h:commandButton id="Deluxe" value="#{bundle.Deluxe}" immediate="true"16 styleClass="#{carstore.customizers.Deluxe.buttonStyle}"17 actionListener="#{carstore.choosePackage}" />18 19 </h:panelGrid>
This is the continuation of optionsPanel.jsp page. Here the four packaging options - Custom, Standard, Performance, and Deluxe - are displayed via <h:commandButton> elements.
04/29/2004
29
29
optionsPanel.jsp (page 3)
1 <h:panelGrid columns="2">2 3 <h:outputText value="#{bundle.Engine}" 4 styleClass="optionLabel"/>5 6 <h:selectOneMenu styleClass="optionValue"7 binding="#{carstore.currentModel.components.engine}"/>8 9 <h:outputText value="#{bundle.Brakes}" 10 styleClass="optionLabel" />11 12 <h:selectone_radio styleClass="optionValue"13 binding="#{carstore.currentModel.components.brake}"/>14 ...
This is continuation of the optionsPanel.jsp page. Here Engine and Brake selections are displayed as top down menu and radio button selection.
04/29/2004
30
30
optionsPanel.jsp (page 4)
1 <h:outputText value="#{bundle.OtherOptions}" 2 styleClass="optionLabel"/>3 4 <h:panelGrid columns="6">5 6 <h:selectboolean_checkbox title="#{bundle.sunroofLabel}" 7 alt="#{bundle.sunroofLabel}" 8 binding="#{carstore.currentModel.components.sunroof}">9 </h:selectboolean_checkbox> 10 <h:outputText value="#{bundle.sunroofLabel}" /> 11 12 <h:selectboolean_checkbox title="#{bundle.cruiseLabel}" 13 binding="#{carstore.currentModel.components.cruisecontrol}" >14 </h:selectboolean_checkbox>15 <h:outputText value="#{bundle.cruiseLabel}" /> 16 . .17 <h:selectboolean_checkbox title="#{bundle.towPkgLabel}" 18 alt="#{bundle.towPkgLabel}" 19 binding="#{carstore.currentModel.components.towPackage}" >20 </h:selectboolean_checkbox>21 <h:outputText value="#{bundle.towPkgLabel}" /> 22 . .
This is the continuation of the optionsPanel.jsp page. Here other options can be selected as a table which has 6 columns. The odd columns display the checkbox for each option and even columns display the labels of the options.
04/29/2004
31
31
confirmChoices.jsp
This slide shows the options currently chosen for a particular car model.
04/29/2004
32
32
confirmChoices.jsp (page 1)
1 <f:view> 2 <h:form>3 4 <h:panelGrid id="mainPanel" columns="1" footerClass="subtitle"5 styleClass="medium" columnClasses="medium">6 7 <h:graphicImage url="/images/cardemo.jpg" />8 <h:outputText binding="#{carstore.currentModel.components.title}" />
This is the beginning part of the confirmChoices.jsp page. There cardemo.jpg and the title of a car model gets displayed first.
04/29/2004
33
33
confirmChoices.jsp (page 2)
1 <h:panelGrid columns="2" footerClass="subtitle"2 headerClass="subtitlebig" styleClass="medium" columnClasses="subtitle,medium">3 4 <f:facet name="header">5 <h:outputText value="#{bundle.buyTitle}" />6 </f:facet>7 8 <h:outputText value="#{bundle.Engine}" />9 <h:outputText value="#{carstore.currentModel.attributes.engine}" />10 11 <h:outputText value="#{bundle.Brakes}" />12 <h:outputText value="#{carstore.currentModel.attributes.brake}" />13 14 ...
This is continuation of the confirmChoices.jsp page. Here we are displaying a table which has two columns. The first column displays the localized text of each option and the second column displays the value chosen by the buyer.
04/29/2004
34
34
confirmChoices.jsp (page 3)
1 <h:panelGroup>2 <h:commandButton value="#{bundle.buy}" action="customerInfo" 3 title="#{bundle.buy}" />4 <h:commandButton value="#{bundle.back}" action="carDetail" 5 title="#{bundle.back}"/>6 </h:panelGroup>7 8 </h:panelGrid>9 </h:form>10 <jsp:include page="bottomMatter.jsp"/>11 </f:view>
This slide shows the “Buy” and “Back” buttons.
04/29/2004
35
35
customerInfo.jsp
This slide shows how customerInfo.jsp gets displayed so that customer information such as name and address can be entered by the buyer.
04/29/2004
36
36
customerInfo.jsp (page 1)
1 <h:form >2 3 <h:panelGrid id="mainPanel" columns="1" footerClass="subtitle"4 headerClass="subtitlebig" styleClass="medium" columnClasses="medium">5 6 <h:graphicImage url="/images/cardemo.jpg" />7 8 <h:outputText value="#{bundle.customerTitle}" />
This is the beginning part of the customerInfo.jsp page. Here the cardemo.jpg and customerTitle text get displayed first.
04/29/2004
37
37
customerInfo.jsp (page 2)
1 <h:panelGrid id="subPanel" columns="3" footerClass="medium"2 headerClass="subtitlebig" styleClass="medium" columnClasses="medium">3 4 <h:outputText value="#{bundle.titleLabel}" />5 <h:selectOneMenu id="title" value="#{customer.currentTitle}">6 <f:selectItems value="#{customer.titleOptions}" />7 </h:selectOneMenu>8 <h:outputText value=""/>
This is the continuation of the customerInfo.jsp page.
04/29/2004
38
38
customerInfo.jsp (page 3)
1 <h:outputText value="#{bundle.firstLabel}" />2 <h:inputText id="firstName" value="#{customer.firstName}" required="true"> 3 <f:valueChangeListener type="carstore.FirstNameChanged" />4 </h:inputText>5 <h:messages styleClass="validationMessage" for="firstName"/>6 7 <h:outputText value="#{bundle.middleLabel}" />8 <h:inputText id="middleInitial" size="1" maxlength="1" 9 value="#{customer.middleInitial}" > 10 </h:inputText>11 <h:messages styleClass="validationMessage" for="middleInitial"/>
T
04/29/2004
39
39
customerInfo.jsp (page 4)
1 <h:outputText value="#{bundle.lastLabel}" />2 <h:inputText value="#{customer.lastName}" />3 <h:outputText value=""/>4 5 <h:outputText value="#{bundle.mailingLabel}"/>6 <h:inputText value="#{customer.mailingAddress}" />7 <h:outputText value=""/>8 9 <h:outputText value="#{bundle.cityLabel}" />10 <h:inputText value="#{customer.city}" />11 <h:outputText value=""/>
T
04/29/2004
40
40
customerInfo.jsp (page 5) 1 <h:outputText value="#{bundle.stateLabel}" />2 <h:selectOneMenu value="#{customer.state}" >3 4 <f:selectItem itemValue="AL" itemLabel="AL" />5 <f:selectItem itemValue="AK" itemLabel="AK"/>6 <f:selectItem itemValue="AZ" itemLabel="AZ"/>7 <f:selectItem itemValue="AR" itemLabel="AR"/>8 <f:selectItem itemValue="CA" itemLabel="CA"/>9 ...10 </h:selectOneMenu>11 <h:outputText value=""/>
T
04/29/2004
41
41
customerInfo.jsp (page 6) 1 <h:outputText value="#{bundle.zipLabel}" />2 <h:inputText id="zip" 3 value="#{customer.zip}"4 size="10" required="true">5 <cs:format_validator formatPatterns="99999|99999-9999|### ###"/> 6 </h:inputText>7 <h:messages styleClass="validationMessage" for="zip" />
T
04/29/2004
42
42
customerInfo.jsp (page 7) 1 <h:outputText value="#{bundle.ccNumberLabel}" />2 <h:inputText id="ccno" size="16"3 converter="#{creditCardConverter}" required="true">4 <cs:format_validator 5 formatPatterns="9999999999999999|9999 9999 9999 9999|9999-9999-9999-9999"/>6 </h:inputText>7 <h:messages styleClass="validationMessage" for="ccno"/>
T
04/29/2004
43
43
customerInfo.jsp (page 8) 1 <h:outputText value="#{bundle.monthLabel}" />2 3 <h:panelGrid id="monthYearPanel" columns="2" footerClass="medium"4 headerClass="medium" styleClass="medium" columnClasses="medium">5 6 <h:selectOneMenu value="#{customer.month}">7 <f:selectItem itemValue="01" itemLabel="01"/>8 <f:selectItem itemValue="02" itemLabel="02"/>9 ...10 <f:selectItem itemValue="11" itemLabel="11"/>11 <f:selectItem itemValue="12" itemLabel="12"/>12 </h:selectOneMenu>13 <h:selectOneMenu value="#{customer.year}" >14 <f:selectItem itemValue="2002" itemLabel="2002"/>15 <f:selectItem itemValue="2003" itemLabel="2003"/>16 ...17 <f:selectItem itemValue="2008" itemLabel="2008"/>18 </h:selectOneMenu>19 20 </h:panelGrid>21 22 <h:outputText value=""/>
T
04/29/2004
44
44
customerInfo.jsp (page 9) 1 <h:commandButton value="#{bundle.finishButton}" action="finish" />2 <h:graphicImage id="duke" url="/images/duke.gif" />3 <h:outputText value="#{bundle.buyLabel}" />4 5 </h:panelGrid>6 </h:form>7 </f:view>
T
04/29/2004
45
45
finish.jsp
The final page that thanks you for ordering the car
04/29/2004
46
46
finish.jsp (page 1) 1 <f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>2 <f:view> 3 <h:form>4 <h:graphicImage url="/images/cardemo.jpg" />5 6 <h:panelGrid id="thanksPanel" columns="1" footerClass="subtitle"7 headerClass="subtitlebig" styleClass="medium" columnClasses="subtitle,medium">8 <f:facet name="header">9 <h:outputMessage value="#{bundle.thanksLabel}">10 <f:parameter value="#{sessionScope.firstName}"/>11 </h:outputMessage>12 </f:facet>13 </h:panelGrid>14 15 </h:form>16 <jsp:include page="bottomMatter.jsp"/>17 </f:view>
This is the finish.jsp page. Please note the first name is inserted as a parameter to #{bundle.thanksLabel} message.
04/29/2004
47
47
Backing Beans
04/29/2004
48
48
Beans (repeat)
The beans we will look into are colored in blue. There are three beans: CarStore bean, CarBean, and CustomerBean.
04/29/2004
49
49
Backing Beans? CarStore bean
– Main bean for the application– Maintains a map of CarBean instances, keyed by
model name– Maintains a map of CarCustomizer instances,
keyed by package name? CarBean bean
– Encapsulates a car model, including pricing and package choices
? CustomerBean bean– Represents a customer
The CarStore bean is the main bean for this application. It maintains a map of CarBean instances keyed by model name. It also maintains a map of CarCustomer instances keyed by package name.
The CarBean bean encaptulates a car model including pricing and package options.
The CustomerBean bean represents the customer.
04/29/2004
50
50
CarStore Bean (page 1)
? Several pages in the application use this bean as the target of method reference and value reference expressions.
– "chooseLocale.jsp" page uses actionListener attributes to point to the chooseLocaleFromMap(javax.faces.event.ActionEvent) and chooseLocaleFromLink(javax.faces.event.ActionEvent) methods.
– "storeFront.jsp" page uses value binding expressions to pull information about four of the known car models in the store.
(read slide)
04/29/2004
51
51
CarStore Bean (page 2)
? Several pages in the application use this bean as the target of method reference and value reference expressions.
– "carDetail" page uses value binding expressions to pull information about the currently chosen model. It also uses the action attribute to convey the user's package choices.
– "confirmChoices" page uses value binding expressions to pull the user's choices from the currently chosen model.
(read slide)
04/29/2004
52
52
chooseLocale.jsp
1 <d:map id="worldMap" current="NAmericas" immediate="true"2 action="storeFront"3 actionListener="#{carstore.chooseLocaleFromMap}">4 <d:area id="NAmerica" value="#{NA}" 5 onmouseover="/images/world_namer.jpg" 6 onmouseout="/images/world.jpg" 7 targetImage="mapImage" />8 <d:area id="SAmerica" value="#{SA}" 9 onmouseover="/images/world_samer.jpg"10 onmouseout="/images/world.jpg" 11 targetImage="mapImage" />12 <d:area id="Germany" value="#{gerA}" 13 onmouseover="/images/world_germany.jpg" 14 onmouseout="/images/world.jpg" 15 targetImage="mapImage" />16 <d:area id="France" value="#{fraA}" 17 onmouseover="/images/world_france.jpg" 18 onmouseout="/images/world.jpg" 19 targetImage="mapImage" />20 </d:map>21
So you have seen this part of chooseLocale.jsp page. Here you see the actionListener attribute of <d:map> element is set to chooseLocaleFromMap() method of the carstore bean. (It is highlighted in blue color.) When a user selects a locale by pressing one of the 4 areas, an action event is generated and the chooseLocaleFromMap() method gets called.
04/29/2004
53
53
catStore.java 1 public class CarStore extends Object {2 ...3 public void chooseLocaleFromMap(ActionEvent actionEvent) {4 AreaSelectedEvent event = (AreaSelectedEvent) actionEvent;5 String current = event.getMapComponent().getCurrent();6 FacesContext context = FacesContext.getCurrentInstance();7 context.getViewRoot().setLocale((Locale) locales.get(current));8 resetMaps();9 } 10 ...11 private void resetMaps() {12 if (null != carModels) {13 carModels.clear();14 carModels = null;15 }16 if (null != carCustomizers) {17 carCustomizers.clear();18 carCustomizers = null;19 }20 }
This slide shows the chooseLocaleFromMap() method of the carstore bean. It first casts the ActionEvent type to AreaSelectedEvent type. From the event, it gets UI component that generates the event – getMapComponent() method. It then gets information on what the current selection is – getCurrent() method. It then saves it in the context object.
04/29/2004
54
54
storeFront.jsp
<h:panelGrid columns="2" styleClass="storeFrontCar"> <!-- Jalopy --> <h:graphicImage binding="#{carstore.models.Jalopy.components.imageSmall}" /> <h:outputText styleClass="subtitlebig" value=" #{carstore.models.Jalopy.attributes.title} " /> <h:outputText value=" #{carstore.models.Jalopy.attributes.description}"/> <h:commandButton action=" #{carstore.storeFrontJalopyPressed} "
10 value="#{bundle.moreButton}" >11 </h:commandButton>12 <!-- Roadster -->13 <h:graphicImage binding="#{carstore.models.Roadster.components.imageSmall} " />14 <h:outputText styleClass="subtitlebig"15 value=" #{carstore.models.Roadster.attributes.title}" />16 <h:outputText 17 value=" #{carstore.models.Roadster.attributes.description} " /> 18 <h:commandButton 19 action=" #{carstore.storeFrontRoadsterPressed}" 20 value="#{bundle.moreButton}" >21 </h:commandButton>22 </h:panelGrid>
This part of storeFront.jsp page shows value bindings of outputText component and action binding of the commandButton component. And the values of value and action binding attributes refers to carstore bean.
Note that the “carstore.models” will result in calling getModels() method of the carstore bean as we will see in the next slide.
04/29/2004
55
55
catStore.java 1 public class CarStore extends Object {2 ...3 // Car models we offer. Key=name of package, Value=CarBean instances4 private Map carModels = null;5 public Map getModels() {6 if (null == carModels) {7 carModels = new HashMap();8 if (log.isDebugEnabled()) {9 log.debug("Populating carModel map");10 }11 carModels.put(DEFAULT_MODEL, 12 new CarBean(DEFAULT_MODEL_PROPERTIES));13 carModels.put("Roadster", 14 new CarBean(CARSTORE_PREFIX + ".bundles.Roadster"));15 carModels.put("Luxury", new CarBean(CARSTORE_PREFIX + 16 ".bundles.Luxury"));17 carModels.put("SUV", new CarBean(CARSTORE_PREFIX + 18 ".bundles.SUV"));19 }20 return carModels;21 }
This is the getModels() method of the carStore bean. In this mode, a map object in which model sring values such as “Roadster”, “Luxury”, or “SUV” are used as keys and CarBean object is saved as values.
04/29/2004
56
56
carDetails.jsp (page 1)
1 <f:view>2 <h:form>3 4 <!-- non-option details -->5 <h:panelGrid columns="1"6 summary="#{bundle.carDetails}"7 title="#{bundle.carDetails}">8 9 <h:graphicImage url="/images/cardemo.jpg" /> 10 11 <h:graphicImage 12 binding="#{carstore.currentModel.components.image}" />13 14 <h:outputText styleClass="subtitlebig"15 binding="#{carstore.currentModel.components.title}" />16 17 <h:outputText 18 binding="#{carstore.currentModel.components.description}" />
This is carDetailes.jsp page in which currentModel field of the carstore bean is referenced. Again, we expect to see getCurrentModel() method in the carstore bean.
04/29/2004
57
57
carDetails.jsp (page 2)
1 <h:panelGrid columns="2">2 3 <h:outputText styleClass="subtitle"4 value="#{bundle.basePriceLabel}" />5 6 <h:outputText 7 binding="#{carstore.currentModel.components.basePrice}" />8 9 <h:outputText styleClass="subtitle"10 value="#{bundle.yourPriceLabel}" />11 12 <h:outputText value="#{carstore.currentModel.currentPrice}" />13 14 </h:panelGrid>15 16 <h:commandButton action="#{carstore.buyCurrentCar}"17 value="#{bundle.buy}" />18 19 </h:panelGrid>
This is the continuation of the carDetails.jsp page. Here we see action attribute of <h:commandButton> also refer to buyCurrentCar() method of the carstore bean.
04/29/2004
58
58
carDetails.jsp (page 3)
1 <jsp:include page="optionsPanel.jsp"/>2 3 <h:commandButton value="#{bundle.recalculate}" 4 action="#{carstore.currentModel.updatePricing}" 5 immediate="true" />6 7 <h:commandButton action="#{carstore.buyCurrentCar}"8 value="#{bundle.buy}" />9 10 </h:form>11 12 <jsp:include page="bottomMatter.jsp"/>13 14 </f:view>
This is the continuation of carDetails.jsp page.
04/29/2004
59
59
CarStore.java 1 public class CarStore extends Object {2 ...3 4 5 public String buyCurrentCar() {6 getCurrentModel().getCurrentPrice();7 return "confirmChoices";8 } 9 10 public CarBean getCurrentModel() {11 CarBean result = (CarBean) carModels.get(getCurrentModelName());12 return result;13 }14 15 ...16 }
This slide shows the two methods mentioned in the previous slides. The buyCurrentCar() method is a action listener method while the getCurrentModel() is an accessor method of a property field of the Carstore bean.
04/29/2004
60
60
CarBean
? Encapsulates a car model, including pricing and package choices
? The system allows the user to customize the properties of this bean with the help of the CarCustomizer
? Only bean in the application that has access to the persistent store of data
– In the present implementation, this persistent store is in ResourceBundle instances
(read the slide)
04/29/2004
61
61
components & attributes in CarBean
1 public class CarBean extends Object {2 ...3 /**4 * Keys: String attribute name, such as engine. Values: UIComponent5 * for the attribute6 */7 private Map components = null;8 ...9 public Map getAttributes() {10 return attributes;11 }12 ...13 /**14 * Keys: String attribute name, such as engine. Values: String value15 * of the component named by key in our components Map.16 */17 private Map attributes = null;18 ...19 public Map getAttributes() {20 return attributes;21 }22 ...
Where key is the name of an attribute of this car. For example, basePrice, or description. key_componentType is the component type of the UIComponent subclass to be used to represent this attribute in the page, for example SelectManyMenu. key_valueType is the data type of the value of the UIComponent, for example java.lang.Integer. For all non-String valueTypes.
When the bean is instantiated, we load both of the above properties files and iterate over the keys in each one. For each key, we look at the componentType and ask the Application to create a component of that type. We store that UIComponent instance in our components Map under the name key. We look at the valueType for the key. For non java.lang.String types, we ask the Application for a Converter instance for that class. If found, we use it to convert the value for the key to the appropriate type and store that as the value of the UIComponent instance.
04/29/2004
62
62
Where CarBean is Referenced?? chooseLocale.jsp
– uses actionListener attributes to point to the chooseLocaleFromMap(ActionEvent) and chooseLocaleFromLink(ActionEvent) methods
? storeFront.jsp – uses value binding expressions to pull information
about four of the known car models in the store
Several pages in the application use this bean as the target of method reference and value reference expressions.
04/29/2004
63
63
Where CarBean is Referenced?
? carDetail.jsp– uses value binding expressions to pull information
about the currently chosen model – also uses the action attribute to convey the user's
package choices? confirmChoices.jsp
– uses value binding expressions to pull the user's choices from the currently chosen model
(read the slide)
04/29/2004
64
64
Reference of CarBean instance in carDetails.jsp
1 <jsp:include page="optionsPanel.jsp"/>2 3 <h:commandButton value="#{bundle.recalculate}" 4 action="#{carstore.currentModel .updatePricing}" 5 immediate="true" />6 7 <h:commandButton action="#{carstore.buyCurrentCar}"8 value="#{bundle.buy}" />9 10 </h:form>11 12 <jsp:include page="bottomMatter.jsp"/>13 14 </f:view>
The circled part of carDetails.jsp page shows how updatePricing() method of the CarBean instance will get invoked when a buyer clicks the “Recalculate” botton. Typically an action method should return an outcome so that navigation handler can select a next page to display. However, as you will see in the next slide, the updatePricing() method returns null. It is because the goal of this action method is to recalculate the price and the same page needs to be displayed but with updated price. (Sang: I need to find out why action listener tag is not used in this case.)
04/29/2004
65
65
updatePricing() method in CarBean
1 public class CarBean extends Object {2 ...3 public String updatePricing() {4 getCurrentPrice();5 return null;6 }7 8 public Integer getCurrentPrice() {9 // go through our options and try to get the prices10 int sum = ((Integer)((ValueHolder)getComponents().get("basePrice")).11 getValue()).intValue();12 Iterator iter = getComponents().keySet().iterator();13 String key = null;14 Object value = null;15 UIComponent component = null;16 while (iter.hasNext()) {17 key = (String) iter.next();18 component = (UIComponent) getComponents().get(key);19 value = ((ValueHolder)component).getValue();20 if (null == value || (!(component instanceof UIInput))) {21 continue;22 }23
The cod above shows the updatePricing() method in the CarBean that is invoked as an action method as shown in the previous slide.
The getCurrentPrice() method that is invoked inside updatePricing()method does the following:(1) get the base price of the car(2) go through the iterator of options and for each option, get the price of it and add it to the base price of the car(3) the result will be saved as “currentPrice”
This currentPrice will be displayed next time carDetails.jsp page is displayed.
04/29/2004
66
66
Reference to CarBean in confirmChoices.jsp
1 <h:panelGrid columns="2" footerClass="subtitle"2 headerClass="subtitlebig" styleClass="medium" columnClasses="subtitle,medium">3 4 <f:facet name="header">5 <h:outputText value="#{bundle.buyTitle}" />6 </f:facet>7 8 <h:outputText value="#{bundle.Engine}" />9 <h:outputText value="#{carstore.currentModel.attributes.engine}" />10 11 <h:outputText value="#{bundle.Brakes}" />12 <h:outputText value=" #{carstore.currentModel.attributes.brake}" />13 14 ...
This is continuation of the confirmChoices.jsp page. Here we are displaying a table which has two columns. The first column displays the localized text of each option and the second column displays the value chosen by the buyer.
04/29/2004
67
67
Supporting Class to Backing Beans
? CarCustomizer.java– Customizes a CarBean for a set of options in an
options package
The CarCustomizer class is not a backing bean itself but a supporting class. It is used to customize a CarBean for a set of options in a option package.
04/29/2004
68
68
Bundles asData Source
04/29/2004
69
69
Beans
Data (repeat)
Finally, we add the back end data. In this simple application, the data is read from java.util.ResourceBundle instances, but it could just as well come from a database.
04/29/2004
70
70
Data Source Resource Bundles
? <ModelName>.properties– Contains the localized content for this model– There is a variant of this file for each supported locale,
for example, Jalopy_de.properties? Common_options.properties
– Contains the localized content common to all models? <ModelName_options>
– Contains the non-localized content for this model, including the non-localized options
– There is only one variant of this file for all locales for example, Jalopy_options.properties
In this application, this persistent store is in the form of ResourceBundle instances.
There are three data source ResourceBundle files used:
1.<ModelName>:This contains the localized content for this model. There is a variant of this file for each supported locale, for example, Jalopy_de.properties
2.<Common_properties>: This contains the localized content common to all models.
3.<ModelName_options>:This contains the non-localized content for this model, including the non-localized options. There is only one variant of this file for all locales for example, Jalopy_options.properties
04/29/2004
71
71
Key Convention
? Convention– key– key_componentType– key_valueType
D
04/29/2004
72
72
Bundles
? Common_options.properties? Custom.properties? Deluxe.properties? Jalopy.properties, Jalopy_de.properties,
Jalopy_es.properties, Jalopy_fr.properties? ...
D
04/29/2004
73
73
Bundles
? Common_options.properties? Custom.properties? Deluxe.properties? Jalopy.properties, Jalopy_de.properties,
Jalopy_es.properties, Jalopy_fr.properties? ...
D
04/29/2004
74
74
Common_options.properties
1 # this file contains the non-localized set of options common to all cars2 3 sunroof=false4 sunroof_componentType=SelectBooleanCheckbox5 sunroof_valueType=java.lang.Boolean6 cruisecontrol=false7 cruisecontrol_componentType=SelectBooleanCheckbox8 cruisecontrol_valueType=java.lang.Boolean9 keylessentry=false10 keylessentry_componentType=SelectBooleanCheckbox11 keylessentry_valueType=java.lang.Boolean12 securitySystem=false13 securitySystem_componentType=SelectBooleanCheckbox14 securitySystem_valueType=java.lang.Boolean15 skiRack=false16 skiRack_componentType=SelectBooleanCheckbox17 skiRack_valueType=java.lang.Boolean18 towPackage=false19 towPackage_componentType=SelectBooleanCheckbox20 towPackage_valueType=java.lang.Boolean21 gps=false22 gps_componentType=SelectBooleanCheckbox23 gps_valueType=java.lang.Boolean
T
04/29/2004
75
75
Custom.properties
1 # false represents unselected, true represents selected2 # other values represent the currently selected option3 sunroof=false4 sunroof_disabled=false5 cruisecontrol=false6 cruisecontrol_disabled=false7 keylessentry=false8 keylessentry_disabled=false9 securitySystem=false10 securitySystem_disabled=false11 skirack=false12 skirack_disabled=false13 towPackage=false14 towPackage_disabled=false15 gps=false16 gps_disabled=false17 18 engine=V419 brake=Disc20 suspension=Regular21 speaker=422 audio=Standard23 transmission=Manual
T
04/29/2004
76
76
Deluxe.properties
1 # false represents unselected, true represents selected2 # other values represent the currently selected option3 sunroof=true4 sunroof_disabled=false5 cruisecontrol=true6 cruisecontrol_disabled=false7 keylessentry=true8 keylessentry_disabled=false9 securitySystem=true10 securitySystem_disabled=false11 skirack=true12 skirack_disabled=false13 towPackage=true14 towPackage_disabled=false15 gps=true16 gps_disabled=false17 18 engine=V819 brake=Drum20 suspension=Regular21 speaker=622 audio=Premium23 transmission=Auto
T
04/29/2004
77
77
Jalopy.properties
1 # this file contains the localized content for the Jalopy 2 3 title=Duke's Stripped-Down Jalopy4 title_componentType=OutputText5 title_valueType=java.lang.String6 description=If you're the type who doesn't care what anyone thinks, this 7 is the car for you. Strictly for point-a-to-point-b types.8 description_componentType=OutputText9 description_valueType=java.lang.String
T
04/29/2004
78
78
Jalopy_de.properties
1 # this file contains the localized content for the Jalopy 2 3 title=Dukes alte Kiste4 title_componentType=OutputText5 title_valueType=java.lang.String6 description=Wenn Sie der Typ von Mensch sind, den es nicht k\u00fcmmert, 7 was jeder denkt, dann ist dies genau der richtige Wagen 8 f\u00fcr Sie! Gedacht f\u00fcr Punkt-A-Nach-Punkt-B Typen. 9 description_componentType=OutputText10 description_valueType=java.lang.String
T
04/29/2004
79
79
Event Handler
04/29/2004
80
80
Event Handler
? FirstNameChanged class– ValueChangeListener type– Handles the event of entering a value in the First
Name field on the customerInfo.jsp page? LocaleChanged class
– ActionListener type– Handles the event of a user selecting a locale
D
04/29/2004
81
81
ProcessValueChange() method in FirstNameChanged.Java
1 public class FirstNameChanged extends Object implements ValueChangeListener {2 3 public void processValueChange (ValueChangeEvent event)4 throws AbortProcessingException {5 if (null != event.getNewValue()) {6 FacesContext.getCurrentInstance().7 getExternalContext().8 getSessionMap().9 put("firstName", event.getNewValue());10 }11 }12 13 public PhaseId getPhaseId() {14 return PhaseId.ANY_PHASE;15 }16 17 }18
This is FirstNameChanged class which implements ValueChangeListener interface.
The processValueChange() method of the listener stores the first name that the user enters into session scope map. When the finish page is loaded, this first name information will be retrieved and inserted inside the message, "Thanks {0} for using cardemo. Your car will ship soon."
04/29/2004
82
82
Example: customerInfo.jsp (CarStore)
<h:inputText id="firstName" value="#{customer.firstName}" required="true"> <f:valueChangeListener type="carstore.FirstNameChanged" /></h:inputText>
The FirstNameChanged listener implementation is registered on the firstName UIInput component on the customerInfo.jsp page.
04/29/2004
83
83
Example: LocaleChange Listener(CarStore) ...public class LocaleChange extends Object implements ActionListener {
public void processAction(ActionEvent event) throws AbortProcessingException { String current = event.getComponent().getId(); FacesContext context = FacesContext.getCurrentInstance(); context.getViewRoot().setLocale((Locale) locales.get(current)); resetMaps(); } }
The carstore application does not use any ActionListener implementations. Instead, it uses actionListener expressions that point to bean methods that handle events. This section explains how to turn one of these methods into an ActionListener implementation.
The chooseLocale page allows the user to select a locale for the application by clicking on one of a set of hyperlinks. When the user clicks one of the hyperlinks, an ActionEvent is generated, and the chooseLocaleFromLink(ActionEvent) method of the CarStore bean is invoked. Instead of implementing a bean method to handle this event, you can create a listener implementation to handle it. To do this, you need to:
* Move the chooseLocaleFromLink(ActionEvent) method to a class that implements ActionListener * Rename the method to processAction(ActionEvent)
The listener implementation would look something like above.
04/29/2004
84
84
Example: chooseLocale.jsp if it uses <f:actionListener> <h:commandLink id="NAmerica" action="storeFront"> <f:actionListener type="carstore.LocaleChange" /></h:commandLink>
Here is one of the commandLink tags on the chooseLocale page, changed to reference an ActionListener implementation rather than a bean method:
04/29/2004
85
85
Validator
04/29/2004
86
86
Validator
? FormatValidator.java– Defines a custom Validator
D
04/29/2004
87
87
Example: Custom validator used for zip code in customerInfo.jsp (CarStore)
T
04/29/2004
88
88
Example: validate() method of FormatValidator (CarStore)–page1
public void validate(FacesContext context, UIInput component) { boolean valid = false; String value = null; if ((context == null) || (component == null)) { throw new NullPointerException(); } if (!(component instanceof UIOutput)) { return; } if ( formatPatternsList == null ) { component.setValid(true); return; }
This method gets the local value of the component and converts it to a String. It then iterates over the formatPatternsList list, which is the list of acceptable patterns as specified in the formatPatterns attribute of the format_validator tag.
04/29/2004
89
89
Example: validate() method of FormatValidator (CarStore)-page2
Object input = ((UIOutput)component).getValue(); if(input != null) { value = input.toString(); //validate the value against the list of valid patterns. Iterator patternIt = formatPatternsList.iterator(); while (patternIt.hasNext()) { valid = isFormatValid( ((String)patternIt.next()), value); if (valid) { break; } }
While iterating over the list, this method checks the pattern of the local value against the patterns in the list. If the pattern of the local value does not match any pattern in the list, this method: marks the component's local value invalid by calling component.setValid(false), generates an error message, and queues the error message to the FacesContext so that the message is displayed on the page during the Render Response phase.
04/29/2004
90
90
Example: validate() method of FormatValidator (CarStore)-page3
if ( valid ) { component.setValid(true); } else { component.setValid(false); FacesMessage errMsg = MessageFactory.getMessage(context, FORMAT_INVALID_MESSAGE_ID, (new Object[] {formatPatterns})); context.addMessage(component.getClientId(context)), errMsg); } }}
The error messages are retrieved from the Application instance by MessageFactory. An application that creates its own custom messages must provide a class, like MessageFactory, that retrieves the messages from the Application instance. When creating your own application, you can simply copy the MessageFactory class from the cardemo application to your application.
The getMessage method of MessageFactory takes a FacesContext, a static String that represents the key into the Properties file, and the format pattern as an Object. The key corresponds to the static message ID in the FormatValidator class:
public static final String FORMAT_INVALID_MESSAGE_ID = "cardemo.Format_Invalid";}
When the error message is displayed, the format pattern will be substituted for the {0} in the error message, which, in English, is:
Input must match one of the following patterns {0}
04/29/2004
91
91
Example: Registering Error Messages through App. Conf. File (CarStore)
<application> <message-bundle>carstore.bundles.Messages</message-bundle> <locale-config> <default-locale>en</default-locale> <supported-locale>de</supported-locale> <supported-locale>fr</supported-locale> <supported-locale>es</supported-locale> </locale-config></application>
Here is the part of the file that registers the error messages for the cardemo application:
04/29/2004
92
92
faces-config.xml 1 <!-- Validator -->2 <validator>3 <description>4 Registers the concrete Validator implementation,5 carstore.FormatValidator with the validator6 identifier, FormatValidator.7 </description>8 <validator-id>FormatValidator</validator-id>9 <validator-class>carstore.FormatValidator</validator-class>10 <attribute>11 <description>12 List of format patterns separated by '|'. The validator13 compares these patterns against the data entered in a 14 component that has this validator registered on it.15 </description>16 <attribute-name>formatPatterns</attribute-name>17 <attribute-class>java.lang.String</attribute-class>18 </attribute>19 </validator>
T
04/29/2004
93
93
Converter
04/29/2004
94
94
Converter
? CreditCardConverter.java– Accepts a Credit Card Number of type String and
strips blanks and "-" if any from it
D
04/29/2004
95
95
CreditCardConverter in CarStore
Sometimes you might want to convert a component's data to a type other than a standard type, or you might want to convert the format of the data. To facilitate this, JavaServer Faces technology allows you to register a Converter implementation on UIOutput components and components whose classes subclass UIOutput.
04/29/2004
96
96
Example: getAsString() in CreditCardConverter (CarStore)
public String getAsString(FacesContext context, UIComponent component,Object value) throws ConverterException { String inputVal = null; if ( value == null ) { return null; } try { inputVal = (String)value; } catch (ClassCastException ce) { throw new ConverterException(Util.getExceptionMessage( Util.CONVERSION_ERROR_MESSAGE_ID)); } char[] input = inputVal.toCharArray(); StringBuffer buffer = new StringBuffer(50); for ( int i = 0; i < input.length; ++i ) { if ( (i % 4) == 0 && i != 0) { if (input[i] != ' ' || input[i] != '-'){ buffer.append(" "); } else if (input[i] == '-') { buffer.append(" "); } } buffer.append(input[i]);
Here is the implementation of getAsString() method from CreditCardConverter class.
04/29/2004
97
97
faces-config.xml 1 <!-- converter -->2 <converter>3 <description>4 Registers the concrete Converter implementation,5 carstore.CreditCardConverter using the ID, 6 creditcard.7 </description>8 <converter-id>creditcard</converter-id>9 <converter-class>carstore.CreditCardConverter</converter-class>10 </converter>
T
04/29/2004
98
98
Custom Components &Renderer
04/29/2004
99
99
Custom Component
? AreaComponent.java– The class that defines the component
corresponding to the area custom tag
D
04/29/2004
100
100
Renderer
? AreaRenderer.java– This Renderer performs the delegated rendering
for the UIArea component
D
04/29/2004
101
101
Custom Tag Files,TLD files
04/29/2004
102
102
Custom Tag Classes
? AreaTag– tag handler that implements the area custom tag
? ImageArea– bean that stores the shape and coordinates of the
hot spots? MapComponent
– class that defines the component orresponding to the map custom tag
? MapTag– tag handler that implements the map custom tag
D
04/29/2004
103
103
TLD file
? carstore.tld– Defines carstore.FormatValidatorTag
D
04/29/2004
104
104
Stylesheet
04/29/2004
105
105
Stylesheet
? stylesheet.css
D
04/29/2004
106
106
storeFront.jsp (page 1)
1 <HTML>2 3 <HEAD>4 <TITLE>Welcome to CarStore</TITLE>5 <link rel="stylesheet" type="text/css"6 href='<%= request.getContextPath() + "/stylesheet.css" %>'>7 </HEAD>8 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>9 <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>10 11 <BODY BGCOLOR="white">12 13 <f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
This is the first part of the storeFront.jsp. Since this part is the common for all the the JSP pages, I will move on. I included it here for the sake of completeness.
04/29/2004
107
107
storeFront.jsp (page 2)
1 <f:view> 2 <h:form>3 <h:graphicImage url="/images/cardemo.jpg" /> 4 <h:panelGrid columns="2" 5 footerClass="form-footer"6 headerClass="form-header"7 styleClass="top-table"8 columnClasses="single-column"9 summary="#{bundle.chooseCar}" 10 title="#{bundle.chooseCar}" >11 12 <h:panelGrid columns="2"13 styleClass="storeFrontCar">14 ...15 </h:panelGrid>16 <h:panelGrid columns="2"17 styleClass="storeFrontCar">18 ...19 </h:panelGrid>20 </h:panelGrid>21 </h:form>
column 1 column 2
T
04/29/2004
108
108
stylesheet.css (page 1)
1 ...2 .top-table { 3 padding: 0;4 border: 0;5 width: 660px;6 }7 8 .storeFrontCar { 9 padding: 010 border: 011 }12 ...
This is the first part of the storeFront.jsp. Since this part is the common for all the the JSP pages, I will move on. I included it here for the sake of completeness.
04/29/2004
109
109
catStore.java 1 public class CarStore extends Object {2 ...3 public void choosePackage(String packageName) {4 CarCustomizer packageCustomizer = (CarCustomizer) carCustomizers.get(packageName);5 packageCustomizer.customizeCar(getCurrentModel());6 getCurrentModel().getCurrentPrice();7 8 // HERE IS WHERE WE UPDATE THE BUTTON STYLE!9 String curName;10 Iterator iter = carCustomizers.keySet().iterator();11 // go through all the available packages and set the button style accordingly.12 while (iter.hasNext()) {13 curName = (String) iter.next();14 packageCustomizer = (CarCustomizer) carCustomizers.get(curName);15 if (curName.equals(packageName)) {16 packageCustomizer.setButtonStyle("package-selected");17 }18 else {19 packageCustomizer.setButtonStyle("package-unselected");20 }21 }22 }23 ...24 }
T
04/29/2004
110
110
stylesheet.css (page 2)
1 ...2 .package-selected {3 background-color: #93B629;4 }5 6 .package-unselected {7 background-color: #C0C0C0;8 }9 ...
This is the first part of the storeFront.jsp. Since this part is the common for all the the JSP pages, I will move on. I included it here for the sake of completeness.
04/29/2004
111
111
Configuration Files
04/29/2004
112
112
faces-config.xml 1
2 <faces-config>3 <application>...</application>4 <validator>...</validator>5 <converter>...</converter>6 <managed-bean>...</managed-bean>7 ...8 <managed-bean>...</managed-bean>9 <navigation-rule>...</navigation-rule>10 ...11 <navigation-rule>...</navigation-rule>12 </faces-config>
T
04/29/2004
113
113
faces-config.xml (page2) 1 <application>2 <message-bundle>carstore.bundles.Messages</message-bundle>3 <locale-config>4 <default-locale>en</default-locale>5 <supported-locale>de</supported-locale>6 <supported-locale>fr</supported-locale>7 <supported-locale>es</supported-locale>8 </locale-config>9 </application>
T
04/29/2004
114
114
Images
04/29/2004
115
115
?
D
04/29/2004
116
116
? duke.gif
D
04/29/2004
117
117
?
D
04/29/2004
118
118
?
D
04/29/2004
119
119
Passion!
04/29/2004