Walkthrough of CarStore JSF Sample Application

Transcription

Walkthrough of CarStore JSF Sample Application
04/29/2004
Walkthrough of
CarStore JSF Sample
Application
1
04/29/2004
Sang Shin
[email protected]
www.javapassion.com
Java ™ Technology Evangelist
Sun Microsystems, Inc.
2
04/29/2004
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
3
04/29/2004
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
4
04/29/2004
CarStore
Sample Application
5
04/29/2004
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
6
04/29/2004
Page Flow
7
04/29/2004
Backing Beans (Model
Objects)
8
04/29/2004
Data
Beans
9
04/29/2004
Page Flow of
CarStore Application
10
04/29/2004
JSP Pages used for End User
Presentation
?
?
?
?
?
?
chooseLocale.jsp
storeFront.jsp
carDetail.jsp
confirmChoices.jsp
finish.jsp
customerInfo.jsp
11
04/29/2004
JSP Pages Included in Other
JSP Pages
?
optionsPanel.jsp
–
?
included in carDetails.jsp
bottomMatter.jsp
–
–
footer page
included in carDetails.jsp, chooseLocale.jsp,
confirmChoices.jsp, finish.jsp, storeFront.jsp
12
04/29/2004
chooseLocale.jsp
13
04/29/2004
chooseLocale.jsp (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<title>CarStore</title>
<link rel="stylesheet" type="text/css"
href='<%= request.getContextPath() + "/stylesheet.css" %>'>
</head>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/demo/components" prefix="d" %>
<f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
14
04/29/2004
chooseLocale.jsp (page 2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<f:view>
<h:form>
<h:panelGrid columns="1"
footerClass="form-footer"
headerClass="form-header"
styleClass="main-background"
columnClasses="single-column"
summary="#{bundle.chooseLocale}"
title="#{bundle.chooseLocale}" >
<h:graphicImage url="/images/cardemo.jpg" />
<h:outputText styleClass="maintitle"
value="#{bundle.chooseLocale}" />
<h:graphicImage id="mapImage" url="/images/world.jpg"
alt="#{bundle.chooseLocale}"
usemap="#worldMap" />
15
04/29/2004
chooseLocale.jsp (page 3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<d:map id="worldMap" current="NAmericas" immediate="true"
action="storeFront"
actionListener="#{carstore.chooseLocaleFromMap}">
<d:area id="NAmerica" value="#{NA}"
onmouseover="/images/world_namer.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
<d:area id="SAmerica" value="#{SA}"
onmouseover="/images/world_samer.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
<d:area id="Germany" value="#{gerA}"
onmouseover="/images/world_germany.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
<d:area id="France" value="#{fraA}"
onmouseover="/images/world_france.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
</d:map>
16
04/29/2004
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>
17
04/29/2004
storeFront.jsp
18
04/29/2004
storeFront.jsp (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
<HTML>
<HEAD>
<TITLE>Welcome to CarStore</TITLE>
<link rel="stylesheet" type="text/css"
href='<%= request.getContextPath() + "/stylesheet.css" %>'>
</HEAD>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<BODY BGCOLOR="white">
<f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
19
04/29/2004
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"
column 1
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 2
20
04/29/2004
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}"
value="#{bundle.moreButton}" >
</h:commandButton>
<!-- Roadster -->
<h:graphicImage binding="#{carstore.models.Roadster.components.imageSmall}" />
<h:outputText styleClass="subtitlebig"
value="#{carstore.models.Roadster.attributes.title}" />
<h:outputText
value="#{carstore.models.Roadster.attributes.description}" />
<h:commandButton
action="#{carstore.storeFrontRoadsterPressed}"
value="#{bundle.moreButton}" >
</h:commandButton>
</h:panelGrid>
21
04/29/2004
carDetails.jsp (upper)
22
04/29/2004
carDetails.jsp (lower)
23
04/29/2004
carDetails.jsp (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<f:view>
<h:form>
<!-- non-option details -->
<h:panelGrid columns="1"
summary="#{bundle.carDetails}"
title="#{bundle.carDetails}">
<h:graphicImage url="/images/cardemo.jpg" />
<h:graphicImage
binding="#{carstore.currentModel.components.image}" />
<h:outputText styleClass="subtitlebig"
binding="#{carstore.currentModel.components.title}" />
<h:outputText
binding="#{carstore.currentModel.components.description}" />
24
04/29/2004
carDetails.jsp (page 2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h:panelGrid columns="2">
<h:outputText styleClass="subtitle"
value="#{bundle.basePriceLabel}" />
<h:outputText
binding="#{carstore.currentModel.components.basePrice}" />
<h:outputText styleClass="subtitle"
value="#{bundle.yourPriceLabel}" />
<h:outputText value="#{carstore.currentModel.currentPrice}" />
</h:panelGrid>
<h:commandButton action="#{carstore.buyCurrentCar}"
value="#{bundle.buy}" />
</h:panelGrid>
25
04/29/2004
carDetails.jsp (page 3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<jsp:include page="optionsPanel.jsp"/>
<h:commandButton value="#{bundle.recalculate}"
action="#{carstore.currentModel.updatePricing}"
immediate="true" />
<h:commandButton action="#{carstore.buyCurrentCar}"
value="#{bundle.buy}" />
</h:form>
<jsp:include page="bottomMatter.jsp"/>
</f:view>
26
04/29/2004
optionsPanel.jsp (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-Copyright 2003 Sun Microsystems, Inc. All rights reserved.
SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->
<%@ page contentType="text/html" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<f:subview id="optionsPanel">
<h:panelGrid>
<h:outputText value="#{bundle.OptionsPackages}" />
27
04/29/2004
optionsPanel.jsp (page 2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h:panelGrid columns="4">
<h:commandButton id="Custom" value="#{bundle.Custom}" immediate="true"
styleClass="#{carstore.customizers.Custom.buttonStyle}"
actionListener="#{carstore.choosePackage}" />
<h:commandButton id="Standard" value="#{bundle.Standard}" immediate="true"
styleClass="#{carstore.customizers.Standard.buttonStyle}"
actionListener="#{carstore.choosePackage}" />
<h:commandButton id="Performance" value="#{bundle.Performance}" immediate="true"
styleClass="#{carstore.customizers.Performance.buttonStyle}"
actionListener="#{carstore.choosePackage}" />
<h:commandButton id="Deluxe" value="#{bundle.Deluxe}" immediate="true"
styleClass="#{carstore.customizers.Deluxe.buttonStyle}"
actionListener="#{carstore.choosePackage}" />
</h:panelGrid>
28
04/29/2004
optionsPanel.jsp (page 3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h:panelGrid columns="2">
<h:outputText value="#{bundle.Engine}"
styleClass="optionLabel"/>
<h:selectOneMenu styleClass="optionValue"
binding="#{carstore.currentModel.components.engine}"/>
<h:outputText value="#{bundle.Brakes}"
styleClass="optionLabel" />
<h:selectone_radio styleClass="optionValue"
binding="#{carstore.currentModel.components.brake}"/>
...
29
0
1
2
3
4
5
6
7
8
9
0
1
2
04/29/2004
optionsPanel.jsp (page 4)
<h:outputText value="#{bundle.OtherOptions}"
styleClass="optionLabel"/>
<h:panelGrid columns="6">
<h:selectboolean_checkbox title="#{bundle.sunroofLabel}"
alt="#{bundle.sunroofLabel}"
binding="#{carstore.currentModel.components.sunroof}">
</h:selectboolean_checkbox>
<h:outputText value="#{bundle.sunroofLabel}" />
<h:selectboolean_checkbox title="#{bundle.cruiseLabel}"
binding="#{carstore.currentModel.components.cruisecontrol}" >
</h:selectboolean_checkbox>
<h:outputText value="#{bundle.cruiseLabel}" />
..
<h:selectboolean_checkbox title="#{bundle.towPkgLabel}"
alt="#{bundle.towPkgLabel}"
binding="#{carstore.currentModel.components.towPackage}" >
</h:selectboolean_checkbox>
<h:outputText value="#{bundle.towPkgLabel}" />
..
30
04/29/2004
confirmChoices.jsp
31
04/29/2004
confirmChoices.jsp (page 1)
1
2
3
4
5
6
7
8
<f:view>
<h:form>
<h:panelGrid id="mainPanel" columns="1" footerClass="subtitle"
styleClass="medium" columnClasses="medium">
<h:graphicImage url="/images/cardemo.jpg" />
<h:outputText binding="#{carstore.currentModel.components.title}" />
32
04/29/2004
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
...
33
04/29/2004
confirmChoices.jsp (page 3)
1
2
3
4
5
6
7
8
9
10
11
<h:panelGroup>
<h:commandButton value="#{bundle.buy}" action="customerInfo"
title="#{bundle.buy}" />
<h:commandButton value="#{bundle.back}" action="carDetail"
title="#{bundle.back}"/>
</h:panelGroup>
</h:panelGrid>
</h:form>
<jsp:include page="bottomMatter.jsp"/>
</f:view>
34
04/29/2004
customerInfo.jsp
35
04/29/2004
customerInfo.jsp (page 1)
1
2
3
4
5
6
7
8
<h:form >
<h:panelGrid id="mainPanel" columns="1" footerClass="subtitle"
headerClass="subtitlebig" styleClass="medium" columnClasses="medium">
<h:graphicImage url="/images/cardemo.jpg" />
<h:outputText value="#{bundle.customerTitle}" />
36
04/29/2004
customerInfo.jsp (page 2)
1
2
3
4
5
6
7
8
<h:panelGrid id="subPanel" columns="3" footerClass="medium"
headerClass="subtitlebig" styleClass="medium" columnClasses="medium">
<h:outputText value="#{bundle.titleLabel}" />
<h:selectOneMenu id="title" value="#{customer.currentTitle}">
<f:selectItems value="#{customer.titleOptions}" />
</h:selectOneMenu>
<h:outputText value=""/>
37
04/29/2004
customerInfo.jsp (page 3)
1
2
3
4
5
6
7
8
9
10
11
<h:outputText value="#{bundle.firstLabel}" />
<h:inputText id="firstName" value="#{customer.firstName}" required="true">
<f:valueChangeListener type="carstore.FirstNameChanged" />
</h:inputText>
<h:messages styleClass="validationMessage" for="firstName"/>
<h:outputText value="#{bundle.middleLabel}" />
<h:inputText id="middleInitial" size="1" maxlength="1"
value="#{customer.middleInitial}" >
</h:inputText>
<h:messages styleClass="validationMessage" for="middleInitial"/>
38
04/29/2004
customerInfo.jsp (page 4)
1
2
3
4
5
6
7
8
9
10
11
<h:outputText value="#{bundle.lastLabel}" />
<h:inputText value="#{customer.lastName}" />
<h:outputText value=""/>
<h:outputText value="#{bundle.mailingLabel}"/>
<h:inputText value="#{customer.mailingAddress}" />
<h:outputText value=""/>
<h:outputText value="#{bundle.cityLabel}" />
<h:inputText value="#{customer.city}" />
<h:outputText value=""/>
39
04/29/2004
customerInfo.jsp (page 5)
1
2
3
4
5
6
7
8
9
10
11
<h:outputText value="#{bundle.stateLabel}" />
<h:selectOneMenu value="#{customer.state}" >
<f:selectItem itemValue="AL" itemLabel="AL" />
<f:selectItem itemValue="AK" itemLabel="AK"/>
<f:selectItem itemValue="AZ" itemLabel="AZ"/>
<f:selectItem itemValue="AR" itemLabel="AR"/>
<f:selectItem itemValue="CA" itemLabel="CA"/>
...
</h:selectOneMenu>
<h:outputText value=""/>
40
04/29/2004
customerInfo.jsp (page 6)
1
2
3
4
5
6
7
<h:outputText value="#{bundle.zipLabel}" />
<h:inputText id="zip"
value="#{customer.zip}"
size="10" required="true">
<cs:format_validator formatPatterns="99999|99999-9999|### ###"/>
</h:inputText>
<h:messages styleClass="validationMessage" for="zip" />
41
04/29/2004
customerInfo.jsp (page 7)
1
2
3
4
5
6
7
<h:outputText value="#{bundle.ccNumberLabel}" />
<h:inputText id="ccno" size="16"
converter="#{creditCardConverter}" required="true">
<cs:format_validator
formatPatterns="9999999999999999|9999 9999 9999 9999|9999-9999-9999-9999
</h:inputText>
<h:messages styleClass="validationMessage" for="ccno"/>
42
0
1
2
3
4
5
6
7
8
9
0
1
2
04/29/2004
customerInfo.jsp (page 8)
<h:outputText value="#{bundle.monthLabel}" />
<h:panelGrid id="monthYearPanel" columns="2" footerClass="medium"
headerClass="medium" styleClass="medium" columnClasses="medium">
<h:selectOneMenu value="#{customer.month}">
<f:selectItem itemValue="01" itemLabel="01"/>
<f:selectItem itemValue="02" itemLabel="02"/>
...
<f:selectItem itemValue="11" itemLabel="11"/>
<f:selectItem itemValue="12" itemLabel="12"/>
</h:selectOneMenu>
<h:selectOneMenu value="#{customer.year}" >
<f:selectItem itemValue="2002" itemLabel="2002"/>
<f:selectItem itemValue="2003" itemLabel="2003"/>
...
<f:selectItem itemValue="2008" itemLabel="2008"/>
</h:selectOneMenu>
</h:panelGrid>
<h:outputText value=""/>
43
04/29/2004
customerInfo.jsp (page 9)
1
2
3
4
5
6
7
<h:commandButton value="#{bundle.finishButton}" action="finish" />
<h:graphicImage id="duke" url="/images/duke.gif" />
<h:outputText value="#{bundle.buyLabel}" />
</h:panelGrid>
</h:form>
</f:view>
44
04/29/2004
finish.jsp
45
04/29/2004
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,med
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>
46
04/29/2004
Backing Beans
47
04/29/2004
Beans (repeat)
48
04/29/2004
Backing Beans
?
CarStore bean
–
–
–
?
CarBean 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
Encapsulates a car model, including pricing and
package choices
CustomerBean bean
–
Represents a customer
49
04/29/2004
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.
50
04/29/2004
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.
51
04/29/2004
chooseLocale.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<d:map id="worldMap" current="NAmericas" immediate="true"
action="storeFront"
actionListener="#{carstore.chooseLocaleFromMap}">
<d:area id="NAmerica" value="#{NA}"
onmouseover="/images/world_namer.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
<d:area id="SAmerica" value="#{SA}"
onmouseover="/images/world_samer.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
<d:area id="Germany" value="#{gerA}"
onmouseover="/images/world_germany.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
<d:area id="France" value="#{fraA}"
onmouseover="/images/world_france.jpg"
onmouseout="/images/world.jpg"
targetImage="mapImage" />
</d:map>
52
04/29/2004
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
}
53
04/29/2004
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}"
value="#{bundle.moreButton}" >
</h:commandButton>
<!-- Roadster -->
<h:graphicImage binding="#{carstore.models.Roadster.components.imageSmall}" />
<h:outputText styleClass="subtitlebig"
value="#{carstore.models.Roadster.attributes.title}" />
<h:outputText
value="#{carstore.models.Roadster.attributes.description}" />
<h:commandButton
action="#{carstore.storeFrontRoadsterPressed}"
value="#{bundle.moreButton}" >
</h:commandButton>
</h:panelGrid>
54
04/29/2004
catStore.java
1 public class CarStore extends Object {
2
...
3
// Car models we offer. Key=name of package, Value=CarBean instances
4
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 }
55
04/29/2004
carDetails.jsp (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<f:view>
<h:form>
<!-- non-option details -->
<h:panelGrid columns="1"
summary="#{bundle.carDetails}"
title="#{bundle.carDetails}">
<h:graphicImage url="/images/cardemo.jpg" />
<h:graphicImage
binding="#{carstore.currentModel.components.image}" />
<h:outputText styleClass="subtitlebig"
binding="#{carstore.currentModel.components.title}" />
<h:outputText
binding="#{carstore.currentModel.components.description}" />
56
04/29/2004
carDetails.jsp (page 2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h:panelGrid columns="2">
<h:outputText styleClass="subtitle"
value="#{bundle.basePriceLabel}" />
<h:outputText
binding="#{carstore.currentModel.components.basePrice}" />
<h:outputText styleClass="subtitle"
value="#{bundle.yourPriceLabel}" />
<h:outputText value="#{carstore.currentModel.currentPrice}" />
</h:panelGrid>
<h:commandButton action="#{carstore.buyCurrentCar}"
value="#{bundle.buy}" />
</h:panelGrid>
57
04/29/2004
carDetails.jsp (page 3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<jsp:include page="optionsPanel.jsp"/>
<h:commandButton value="#{bundle.recalculate}"
action="#{carstore.currentModel.updatePricing}"
immediate="true" />
<h:commandButton action="#{carstore.buyCurrentCar}"
value="#{bundle.buy}" />
</h:form>
<jsp:include page="bottomMatter.jsp"/>
</f:view>
58
04/29/2004
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 }
59
04/29/2004
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
60
04/29/2004
components & attributes in CarBean
1 public class CarBean extends Object {
2
...
3
/**
4
* Keys: String attribute name, such as engine. Values: UIComponent
5
* for the attribute
6
*/
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 value
15
* 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
...
61
04/29/2004
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
62
04/29/2004
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
63
04/29/2004
Reference of CarBean instance
in carDetails.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<jsp:include page="optionsPanel.jsp"/>
<h:commandButton value="#{bundle.recalculate}"
action="#{carstore.currentModel.updatePricing}"
immediate="true" />
<h:commandButton action="#{carstore.buyCurrentCar}"
value="#{bundle.buy}" />
</h:form>
<jsp:include page="bottomMatter.jsp"/>
</f:view>
64
04/29/2004
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 prices
10
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
65
04/29/2004
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
...
66
04/29/2004
Supporting Class to Backing Beans
?
CarCustomizer.java
–
Customizes a CarBean for a set of options in an
options package
67
04/29/2004
Bundles as
Data Source
68
04/29/2004
Data (repeat)
Beans
69
04/29/2004
Data Source Resource Bundles
?
<ModelName>.properties
–
–
?
Common_options.properties
–
?
Contains the localized content for this model
There is a variant of this file for each supported locale,
for example, Jalopy_de.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
70
04/29/2004
Key Convention
?
Convention
–
–
–
key
key_componentType
key_valueType
71
04/29/2004
Bundles
?
?
?
?
?
Common_options.properties
Custom.properties
Deluxe.properties
Jalopy.properties, Jalopy_de.properties,
Jalopy_es.properties, Jalopy_fr.properties
...
72
04/29/2004
Bundles
?
?
?
?
?
Common_options.properties
Custom.properties
Deluxe.properties
Jalopy.properties, Jalopy_de.properties,
Jalopy_es.properties, Jalopy_fr.properties
...
73
04/29/2004
Common_options.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# this file contains the non-localized set of options common to all cars
sunroof=false
sunroof_componentType=SelectBooleanCheckbox
sunroof_valueType=java.lang.Boolean
cruisecontrol=false
cruisecontrol_componentType=SelectBooleanCheckbox
cruisecontrol_valueType=java.lang.Boolean
keylessentry=false
keylessentry_componentType=SelectBooleanCheckbox
keylessentry_valueType=java.lang.Boolean
securitySystem=false
securitySystem_componentType=SelectBooleanCheckbox
securitySystem_valueType=java.lang.Boolean
skiRack=false
skiRack_componentType=SelectBooleanCheckbox
skiRack_valueType=java.lang.Boolean
towPackage=false
towPackage_componentType=SelectBooleanCheckbox
towPackage_valueType=java.lang.Boolean
gps=false
gps_componentType=SelectBooleanCheckbox
gps_valueType=java.lang.Boolean
74
04/29/2004
Custom.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# false represents unselected, true represents selected
# other values represent the currently selected option
sunroof=false
sunroof_disabled=false
cruisecontrol=false
cruisecontrol_disabled=false
keylessentry=false
keylessentry_disabled=false
securitySystem=false
securitySystem_disabled=false
skirack=false
skirack_disabled=false
towPackage=false
towPackage_disabled=false
gps=false
gps_disabled=false
engine=V4
brake=Disc
suspension=Regular
speaker=4
audio=Standard
transmission=Manual
75
04/29/2004
Deluxe.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# false represents unselected, true represents selected
# other values represent the currently selected option
sunroof=true
sunroof_disabled=false
cruisecontrol=true
cruisecontrol_disabled=false
keylessentry=true
keylessentry_disabled=false
securitySystem=true
securitySystem_disabled=false
skirack=true
skirack_disabled=false
towPackage=true
towPackage_disabled=false
gps=true
gps_disabled=false
engine=V8
brake=Drum
suspension=Regular
speaker=6
audio=Premium
transmission=Auto
76
04/29/2004
Jalopy.properties
1
2
3
4
5
6
7
8
9
# this file contains the localized content for the Jalopy
title=Duke's Stripped-Down Jalopy
title_componentType=OutputText
title_valueType=java.lang.String
description=If you're the type who doesn't care what anyone thinks, this
is the car for you. Strictly for point-a-to-point-b types.
description_componentType=OutputText
description_valueType=java.lang.String
77
04/29/2004
Jalopy_de.properties
1
2
3
4
5
6
7
8
9
10
# this file contains the localized content for the Jalopy
title=Dukes alte Kiste
title_componentType=OutputText
title_valueType=java.lang.String
description=Wenn Sie der Typ von Mensch sind, den es nicht k\u00fcmmert,
was jeder denkt, dann ist dies genau der richtige Wagen
f\u00fcr Sie! Gedacht f\u00fcr Punkt-A-Nach-Punkt-B Typen.
description_componentType=OutputText
description_valueType=java.lang.String
78
04/29/2004
Event Handler
79
04/29/2004
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
80
04/29/2004
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
81
04/29/2004
Example: customerInfo.jsp (CarStore)
<h:inputText id="firstName" value="#{customer.firstName}"
required="true">
<f:valueChangeListener type="carstore.FirstNameChanged" />
</h:inputText>
82
04/29/2004
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();
}
}
83
04/29/2004
Example: chooseLocale.jsp if it uses
<f:actionListener>
<h:commandLink id="NAmerica" action="storeFront">
<f:actionListener type="carstore.LocaleChange" />
</h:commandLink>
84
04/29/2004
Validator
85
04/29/2004
Validator
?
FormatValidator.java
–
Defines a custom Validator
86
04/29/2004
Example: Custom validator used for zip
code in customerInfo.jsp (CarStore)
87
04/29/2004
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;
}
88
04/29/2004
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;
}
}
89
04/29/2004
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);
}
}
}
90
04/29/2004
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>
91
04/29/2004
faces-config.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- Validator -->
<validator>
<description>
Registers the concrete Validator implementation,
carstore.FormatValidator with the validator
identifier, FormatValidator.
</description>
<validator-id>FormatValidator</validator-id>
<validator-class>carstore.FormatValidator</validator-class>
<attribute>
<description>
List of format patterns separated by '|'. The validator
compares these patterns against the data entered in a
component that has this validator registered on it.
</description>
<attribute-name>formatPatterns</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
</validator>
92
04/29/2004
Converter
93
04/29/2004
Converter
?
CreditCardConverter.java
–
Accepts a Credit Card Number of type String and
strips blanks and "-" if any from it
94
04/29/2004
CreditCardConverter in CarStore
95
04/29/2004
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]);
}
96
04/29/2004
faces-config.xml
<!-- 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>
1
97
04/29/2004
Custom Components &
Renderer
98
04/29/2004
Custom Component
?
AreaComponent.java
–
The class that defines the component
corresponding to the area custom tag
99
04/29/2004
Renderer
?
AreaRenderer.java
–
This Renderer performs the delegated rendering
for the UIArea component
100
04/29/2004
Custom Tag Files,
TLD files
101
04/29/2004
Custom Tag Classes
?
AreaTag
–
?
ImageArea
–
?
bean that stores the shape and coordinates of the
hot spots
MapComponent
–
?
tag handler that implements the area custom tag
class that defines the component orresponding to
the map custom tag
MapTag
–
tag handler that implements the map custom tag
102
04/29/2004
TLD file
?
carstore.tld
–
Defines carstore.FormatValidatorTag
103
04/29/2004
Stylesheet
104
04/29/2004
Stylesheet
?
stylesheet.css
105
04/29/2004
storeFront.jsp (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
<HTML>
<HEAD>
<TITLE>Welcome to CarStore</TITLE>
<link rel="stylesheet" type="text/css"
href='<%= request.getContextPath() + "/stylesheet.css" %>'>
</HEAD>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<BODY BGCOLOR="white">
<f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
106
04/29/2004
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"
column 1
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 2
107
04/29/2004
stylesheet.css (page 1)
1
2
3
4
5
6
7
8
9
10
11
12
...
.top-table {
padding: 0;
border: 0;
width: 660px;
}
.storeFrontCar {
padding: 0
border: 0
}
...
108
04/29/2004
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 }
109
04/29/2004
stylesheet.css (page 2)
1
2
3
4
5
6
7
8
9
...
.package-selected {
background-color: #93B629;
}
.package-unselected {
background-color: #C0C0C0;
}
...
110
04/29/2004
Configuration Files
111
04/29/2004
faces-config.xml
1
2
3
4
5
6
7
8
9
10
11
12
<faces-config>
<application>...</application>
<validator>...</validator>
<converter>...</converter>
<managed-bean>...</managed-bean>
...
<managed-bean>...</managed-bean>
<navigation-rule>...</navigation-rule>
...
<navigation-rule>...</navigation-rule>
</faces-config>
112
04/29/2004
faces-config.xml (page2)
1
2
3
4
5
6
7
8
9
<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>
113
04/29/2004
Images
114
04/29/2004
?
115
04/29/2004
?
duke.gif
116
04/29/2004
?
117
04/29/2004
?
118
04/29/2004
Passion!
119

Similar documents