polish - added conventions as much as possible for flow moduarlization and naming

tweaked package structure
This commit is contained in:
Keith Donald
2007-08-21 02:57:32 +00:00
parent 638bb5094d
commit 6e9cb66ec5
30 changed files with 409 additions and 492 deletions

View File

@@ -4,7 +4,8 @@
<configExtension>xml</configExtension>
</configExtensions>
<configs>
<config>src/main/webapp/WEB-INF/webflow-config.xml</config>
<config>src/main/webapp/WEB-INF/config/application-layer-config.xml</config>
<config>src/main/webapp/WEB-INF/config/web-application-config.xml</config>
</configs>
<configSets>
<configSet>
@@ -12,7 +13,8 @@
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
<incomplete>false</incomplete>
<configs>
<config>src/main/webapp/WEB-INF/webflow-config.xml</config>
<config>src/main/webapp/WEB-INF/config/application-layer-config.xml</config>
<config>src/main/webapp/WEB-INF/config/web-application-config.xml</config>
</configs>
</configSet>
</configSets>

View File

@@ -2,8 +2,12 @@
<webflow-project-description>
<configs>
<config>
<file>src/main/webapp/WEB-INF/flows/booking-flow.xml</file>
<file>src/main/webapp/flows/booking/booking-flow.xml</file>
<name><![CDATA[booking-flow]]></name>
</config>
<config>
<file>src/main/webapp/flows/main/main-flow.xml</file>
<name><![CDATA[main-flow]]></name>
</config>
</configs>
</webflow-project-description>

View File

@@ -5,9 +5,9 @@
version="1.0">
<persistence-unit name="bookingDatabase">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.springframework.webflow.samples.booking.model.User</class>
<class>org.springframework.webflow.samples.booking.model.Booking</class>
<class>org.springframework.webflow.samples.booking.model.Hotel</class>
<class>org.springframework.webflow.samples.booking.app.User</class>
<class>org.springframework.webflow.samples.booking.app.Booking</class>
<class>org.springframework.webflow.samples.booking.app.Hotel</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />

View File

@@ -1,4 +1,4 @@
insert into Customer (username, password, name) values ('springuser', 'barfoo', 'Spring User')
insert into Customer (username, password, name) values ('springer', 'springrocks', 'Spring User')
insert into Customer (username, password, name) values ('demo', 'demo', 'Demo User')
insert into Hotel (id, price, name, address, city, state, zip, country) values (1, 199, 'Westin Diplomat', '3555 S. Ocean Drive', 'Hollywood', 'FL', '33019', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (2, 120, 'Marriott Courtyard', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')

View File

@@ -1,46 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.List;
import org.springframework.webflow.action.MultiAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.samples.booking.model.Booking;
import org.springframework.webflow.samples.booking.model.Hotel;
import org.springframework.webflow.samples.booking.model.User;
import org.springframework.webflow.samples.booking.service.BookingService;
public class SearchAction extends MultiAction {
BookingService bookingService;
public Event findHotels(RequestContext context) {
HotelSearch search = (HotelSearch) context.getFlowScope().get("hotelSearch");
List<Hotel> hotels = bookingService
.findHotels(search.getSearchString(), search.getPageSize(), search.getPage());
if (hotels != null) {
SerializableListDataModel model = new SerializableListDataModel(hotels);
int test = model.getRowCount();
context.getFlowScope().put("hotels", new SerializableListDataModel(hotels));
} else {
context.getFlowScope().put("hotels", null);
}
return success();
}
public Event findBookings(RequestContext context) {
User user = (User) context.getConversationScope().get("user");
List<Booking> bookings = bookingService.findBookings(user);
if (bookings != null) {
context.getFlowScope().put("bookings", new SerializableListDataModel(bookings));
} else {
context.getFlowScope().put("bookings", null);
}
return success();
}
public void setBookingService(BookingService bookingService) {
this.bookingService = bookingService;
}
}

View File

@@ -1,4 +1,4 @@
package org.springframework.webflow.samples.booking.model;
package org.springframework.webflow.samples.booking.app;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -19,15 +19,25 @@ import javax.persistence.Transient;
@Entity
public class Booking implements Serializable {
private Long id;
private User user;
private Hotel hotel;
private Date checkinDate;
private Date checkoutDate;
private String creditCard;
private String creditCardName;
private int creditCardExpiryMonth;
private int creditCardExpiryYear;
private boolean smoking;
private int beds;
public Booking() {
@@ -36,7 +46,6 @@ public class Booking implements Serializable {
public Booking(Hotel hotel, User user) {
this.hotel = hotel;
this.user = user;
Calendar calendar = Calendar.getInstance();
setCheckinDate(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 1);

View File

@@ -0,0 +1,16 @@
package org.springframework.webflow.samples.booking.app;
import java.util.List;
public interface BookingService {
public List<Booking> findBookings(String username);
public List<Hotel> findHotels(String searchString, int pageSize, int page);
public Hotel findHotelById(Long id);
public Booking bookHotel(Hotel hotel, User user);
public void cancelBooking(Long id);
}

View File

@@ -1,4 +1,4 @@
package org.springframework.webflow.samples.booking.model;
package org.springframework.webflow.samples.booking.app;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -11,12 +11,19 @@ import javax.persistence.Id;
@Entity
public class Hotel implements Serializable {
private Long id;
private String name;
private String address;
private String city;
private String state;
private String zip;
private String country;
private BigDecimal price;
@Id

View File

@@ -1,4 +1,4 @@
package org.springframework.webflow.samples.booking.service;
package org.springframework.webflow.samples.booking.app;
import java.util.List;
@@ -8,20 +8,22 @@ import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.webflow.samples.booking.model.Booking;
import org.springframework.webflow.samples.booking.model.Hotel;
import org.springframework.webflow.samples.booking.model.User;
@Repository
public class JpaBookingService implements BookingService {
private EntityManager em;
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Booking> findBookings(User user) {
public List<Booking> findBookings(String username) {
return em.createQuery("select b from Booking b where b.user.username = :username order by b.checkinDate")
.setParameter("username", user.getUsername()).getResultList();
.setParameter("username", username).getResultList();
}
@Transactional(readOnly = true)
@@ -36,7 +38,7 @@ public class JpaBookingService implements BookingService {
}
@Transactional(readOnly = true)
public Hotel readHotelById(Long id) {
public Hotel findHotelById(Long id) {
return em.find(Hotel.class, id);
}
@@ -54,10 +56,4 @@ public class JpaBookingService implements BookingService {
em.remove(booking);
}
}
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
}

View File

@@ -1,4 +1,4 @@
package org.springframework.webflow.samples.booking.model;
package org.springframework.webflow.samples.booking.app;
import java.io.Serializable;
@@ -10,18 +10,20 @@ import javax.persistence.Table;
@Table(name = "Customer")
public class User implements Serializable {
private String username;
private String password;
private String name;
public User() {
}
public User(String name, String password, String username) {
this.name = name;
this.password = password;
this.username = username;
}
public User() {
}
public String getName() {
return name;
}

View File

@@ -1,4 +1,4 @@
package org.springframework.webflow.samples.booking;
package org.springframework.webflow.samples.booking.flow.booking;
import java.util.Calendar;
@@ -8,7 +8,7 @@ import javax.faces.context.FacesContext;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.samples.booking.model.Booking;
import org.springframework.webflow.samples.booking.app.Booking;
public class ValidateBookingAction extends AbstractAction {

View File

@@ -0,0 +1,51 @@
package org.springframework.webflow.samples.booking.flow.main;
import java.util.List;
import org.springframework.webflow.action.MultiAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.samples.booking.app.Booking;
import org.springframework.webflow.samples.booking.app.BookingService;
import org.springframework.webflow.samples.booking.app.Hotel;
import org.springframework.webflow.samples.booking.app.User;
import org.springframework.webflow.samples.booking.web.util.SerializableListDataModel;
public class MainActions extends MultiAction {
private BookingService bookingService;
public MainActions(BookingService bookingService) {
this.bookingService = bookingService;
}
public Event initCurrentUser(RequestContext context) {
User user = new User("springer", "springrocks", "Spring User");
context.getConversationScope().put("user", user);
return success();
}
public Event findCurrentUserBookings(RequestContext context) {
User user = (User) context.getConversationScope().get("user");
List<Booking> bookings = bookingService.findBookings(user.getName());
if (bookings != null) {
context.getFlowScope().put("bookings", new SerializableListDataModel(bookings));
} else {
context.getFlowScope().put("bookings", null);
}
return success();
}
public Event findHotels(RequestContext context) {
SearchCriteria search = (SearchCriteria) context.getFlowScope().get("hotelSearch");
List<Hotel> hotels = bookingService
.findHotels(search.getSearchString(), search.getPageSize(), search.getPage());
if (hotels != null) {
context.getFlowScope().put("hotels", new SerializableListDataModel(hotels));
} else {
context.getFlowScope().put("hotels", null);
}
return success();
}
}

View File

@@ -1,10 +1,10 @@
package org.springframework.webflow.samples.booking;
package org.springframework.webflow.samples.booking.flow.main;
import java.io.Serializable;
import javax.faces.event.ActionEvent;
public class HotelSearch implements Serializable {
public class SearchCriteria implements Serializable {
private static final long serialVersionUID = 1L;

View File

@@ -1,20 +0,0 @@
package org.springframework.webflow.samples.booking.service;
import java.util.List;
import org.springframework.webflow.samples.booking.model.Booking;
import org.springframework.webflow.samples.booking.model.Hotel;
import org.springframework.webflow.samples.booking.model.User;
public interface BookingService {
public List<Booking> findBookings(User user);
public List<Hotel> findHotels(String searchString, int pageSize, int page);
public Hotel readHotelById(Long id);
public Booking bookHotel(Hotel hotel, User user);
public void cancelBooking(Long id);
}

View File

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="jpaConversationListener" class="org.springframework.webflow.persistence.JpaFlowExecutionListener">
<constructor-arg>
<ref bean="entityManagerFactory"/>
</constructor-arg>
<constructor-arg>
<ref bean="txManager"/>
</constructor-arg>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="bookingService"
class="org.springframework.webflow.samples.booking.service.JpaBookingService" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="inMemoryDataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>
<bean id="inMemoryDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:Booking" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="txManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>

View File

@@ -1,41 +0,0 @@
package org.springframework.webflow.samples.booking.util;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class DebuggingPhaseListener implements PhaseListener {
private static final long serialVersionUID = 1L;
Log logger = LogFactory.getLog(DebuggingPhaseListener.class);
public void afterPhase(PhaseEvent event) {
// No-op
}
public void beforePhase(PhaseEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("Entering JSF Phase: " + event.getPhaseId());
if (event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES) {
Map input = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
for (Object key : input.keySet())
logger.debug(key + " : " + input.get(key));
}
}
}
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}

View File

@@ -1,4 +1,4 @@
package org.springframework.webflow.samples.booking;
package org.springframework.webflow.samples.booking.web.util;
import java.io.Serializable;
import java.util.List;

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="bookingService" class="org.springframework.webflow.samples.booking.app.JpaBookingService" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:booking" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>

View File

@@ -7,8 +7,4 @@
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
<lifecycle>
<phase-listener>org.springframework.webflow.samples.booking.util.DebuggingPhaseListener</phase-listener>
</lifecycle>
</faces-config>

View File

@@ -7,8 +7,7 @@
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:org/springframework/webflow/samples/booking/service/services-config-jpa.xml
/WEB-INF/webflow-config.xml
/WEB-INF/config/web-application-config.xml
</param-value>
</context-param>
@@ -18,12 +17,6 @@
<param-value>.xhtml</param-value>
</context-param>
<!-- Special Debug Output for Development -->
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
<!-- Bootstraps the root Spring Web Application Context, responsible for deploying managed beans
defined in the configuration files above. These beans represent the services used by the JSF application. -->
<listener>
@@ -59,6 +52,7 @@
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.spring</url-pattern>

View File

@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<flow:enable-scopes/>
<bean id="user" class="org.springframework.webflow.samples.booking.model.User" scope="conversation">
<property name="username" value="springuser"/>
<property name="password" value="barfoo"/>
<property name="name" value="Spring User"/>
</bean>
<bean id="searchAction" class="org.springframework.webflow.samples.booking.SearchAction">
<property name="bookingService" ref="bookingService"/>
</bean>
<bean id="validateBookingAction" class="org.springframework.webflow.samples.booking.ValidateBookingAction"/>
<!-- Launches new flow executions and resumes existing executions -->
<flow:executor id="flowExecutor" registry-ref="flowRegistry">
<flow:execution-attributes>
<flow:alwaysRedirectOnPause value="false"/>
</flow:execution-attributes>
<flow:execution-listeners>
<flow:listener ref="jpaConversationListener"/>
</flow:execution-listeners>
</flow:executor>
<!-- Creates the registry of flow definitions for this application -->
<bean id="flowRegistry" class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean">
<property name="expressionParser" ref="jsfExpressionParser"/>
<property name="flowLocations">
<list>
<value>/flows/main/main-flow.xml</value>
<value>/flows/booking/bookHotel-flow.xml</value>
</list>
</property>
</bean>
<bean id="jsfExpressionParser" class="org.springframework.faces.el.Jsf12ELExpressionParser">
<constructor-arg >
<bean class="org.jboss.el.ExpressionFactoryImpl"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="validateBookingAction" class="org.springframework.webflow.samples.booking.web.booking.ValidateBookingAction"/>
</beans>

View File

@@ -9,34 +9,35 @@
<input-mapper>
<input-attribute name="id" scope="flow"/>
</input-mapper>
<start-actions>
<bean-action method="findHotelById" bean="bookingService">
<method-arguments>
<argument expression="id"/>
</method-arguments>
<method-result name="hotel" scope="flow"/>
</bean-action>
</start-actions>
<start-state idref="displayHotel"/>
<view-state id="displayHotel" view="/flows/booking/hotel.xhtml">
<render-actions>
<bean-action bean="bookingService" method="readHotelById">
<method-arguments>
<argument expression="id"/>
</method-arguments>
<method-result name="hotel" scope="flow"/>
</bean-action>
</render-actions>
<transition on="bookHotel" to="bookHotel"/>
<view-state id="displayHotel" view="/flows/booking/hotelDetails.xhtml">
<transition on="book" to="bookHotel"/>
<transition on="cancel" to="cancel"/>
</view-state>
<action-state id="bookHotel">
<bean-action bean="bookingService" method="bookHotel">
<method-arguments>
<argument expression="hotel"/>
<argument expression="user"/>
</method-arguments>
<method-result name="booking" scope="flow"/>
<method-arguments>
<argument expression="hotel"/>
<argument expression="user"/>
</method-arguments>
<method-result name="booking" scope="flow"/>
</bean-action>
<transition to="enterBookingDetails"/>
</action-state>
<view-state id="enterBookingDetails" view="/flows/booking/book.xhtml">
<view-state id="enterBookingDetails" view="/flows/booking/bookDetails.xhtml">
<transition on="reviewDetails" to="validateBooking"/>
<transition on="cancel" to="cancel"/>
</view-state>
@@ -47,8 +48,8 @@
<transition on="error" to="enterBookingDetails"/>
</action-state>
<view-state id="confirmBooking" view="/flows/booking/confirm.xhtml">
<transition on="confirm" to="completeBooking"/>
<view-state id="confirmBooking" view="/flows/booking/confirmBooking.xhtml">
<transition on="confirm" to="authorizeBooking"/>
<transition on="revise" to="enterBookingDetails"/>
<transition on="cancel" to="cancel"/>
</view-state>
@@ -57,7 +58,7 @@
<attribute name="commit" value="false" type="boolean"/>
</end-state>
<end-state id="completeBooking">
<end-state id="authorizeBooking">
<attribute name="commit" value="true" type="boolean"/>
</end-state>

View File

@@ -0,0 +1,171 @@
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://springframework.org/faces"
template="/template.xhtml">
<ui:define name="content">
<div class="section">
<h1>Book Hotel</h1>
</div>
<div class="section">
<h:form id="booking">
<h:messages errorClass="errors" />
<fieldset>
<div class="entry">
<div class="label">Name:</div>
<div class="output">#{hotel.name}</div>
</div>
<div class="entry">
<div class="label">Address:</div>
<div class="output">#{hotel.address}</div>
</div>
<div class="entry">
<div class="label">City, State:</div>
<div class="output">#{hotel.city}, #{hotel.state}</div>
</div>
<div class="entry">
<div class="label">Zip:</div>
<div class="output">#{hotel.zip}</div>
</div>
<div class="entry">
<div class="label">Country:</div>
<div class="output">#{hotel.country}</div>
</div>
<div class="entry">
<div class="label">Nightly rate:</div>
<div class="output">
<h:outputText value="#{hotel.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="checkinDate">Check In Date:</h:outputLabel>
</div>
<div class="input">
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="checkoutDate">Check Out Date:</h:outputLabel>
</div>
<div class="input">
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="beds">Room Preference:</h:outputLabel>
</div>
<div class="input">
<h:selectOneMenu id="beds" value="#{booking.beds}">
<f:selectItem itemLabel="One king-size bed" itemValue="1"/>
<f:selectItem itemLabel="Two double beds" itemValue="2"/>
<f:selectItem itemLabel="Three beds" itemValue="3"/>
</h:selectOneMenu>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="smoking">Smoking Preference:</h:outputLabel>
</div>
<div id="radio" class="input">
<h:selectOneRadio id="smoking" value="#{booking.smoking}" layout="pageDirection">
<f:selectItem itemLabel="Smoking" itemValue="true"/>
<f:selectItem itemLabel="Non Smoking" itemValue="false"/>
</h:selectOneRadio>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="creditCard">Credit Card #:</h:outputLabel>
</div>
<div class="input">
<sf:clientNumberValidator allowBlank="false" allowNegative="false" allowDecimals="false" minLength="16" maxLength="16" msgDisplay="block" msgClass="errors">
<h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/>
</sf:clientNumberValidator>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="creditCardName">Credit Card Name:</h:outputLabel>
</div>
<div class="input">
<sf:clientTextValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/>
</sf:clientTextValidator>
</div>
</div>
<div class="entry">
<div class="label">
<h:outputLabel for="creditCardExpiryMonth">Credit Card Expiry:</h:outputLabel>
</div>
<div class="input">
<h:selectOneMenu id="creditCardExpiryMonth" value="#{booking.creditCardExpiryMonth}">
<f:selectItem itemLabel="Jan" itemValue="1"/>
<f:selectItem itemLabel="Feb" itemValue="2"/>
<f:selectItem itemLabel="Mar" itemValue="3"/>
<f:selectItem itemLabel="Apr" itemValue="4"/>
<f:selectItem itemLabel="May" itemValue="5"/>
<f:selectItem itemLabel="Jun" itemValue="6"/>
<f:selectItem itemLabel="Jul" itemValue="7"/>
<f:selectItem itemLabel="Aug" itemValue="8"/>
<f:selectItem itemLabel="Sep" itemValue="9"/>
<f:selectItem itemLabel="Oct" itemValue="10"/>
<f:selectItem itemLabel="Nov" itemValue="11"/>
<f:selectItem itemLabel="Dec" itemValue="12"/>
</h:selectOneMenu>
<h:selectOneMenu id="creditCardExpiryYear" value="#{booking.creditCardExpiryYear}">
<f:selectItem itemLabel="2005" itemValue="2005"/>
<f:selectItem itemLabel="2006" itemValue="2006"/>
<f:selectItem itemLabel="2007" itemValue="2007"/>
<f:selectItem itemLabel="2008" itemValue="2008"/>
<f:selectItem itemLabel="2009" itemValue="2009"/>
</h:selectOneMenu>
</div>
</div>
<div class="entry errors">
<h:messages globalOnly="true"/>
</div>
<div class="entry">
<div class="label">&#160;</div>
<div class="input">
<sf:validateAllOnClick>
<h:commandButton id="proceed" value="Proceed" action="reviewDetails"/>
</sf:validateAllOnClick>&#160;
<h:commandButton id="cancel" immediate="true" value="Cancel" action="cancel"/>
</div>
</div>
</fieldset>
</h:form>
</div>
</ui:define>
</ui:composition>

View File

@@ -5,11 +5,12 @@
xmlns:f="http://java.sun.com/jsf/core"
template="/template.xhtml">
<!-- content -->
<ui:define name="content">
<div class="section">
<h1>View Hotel</h1>
</div>
<div class="section">
<div class="entry">
<div class="label">Name:</div>
@@ -39,12 +40,12 @@
<div class="label">Nightly rate:</div>
<div class="output">
<h:outputText value="#{hotel.price}">
<f:convertNumber type="currency"
currencySymbol="$"/>
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</div>
</div>
</div>
<div class="section">
<h:form id="hotel">
<fieldset class="buttonBox">
@@ -55,4 +56,4 @@
</div>
</ui:define>
</ui:composition>
</ui:composition>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="mainActions" class="org.springframework.webflow.samples.booking.flow.main.MainActions">
<constructor-arg ref="bookingService" />
</bean>
</beans>

View File

@@ -3,32 +3,19 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a="https://ajax4jsf.dev.java.net/ajax"
template="/template.xhtml">
<!-- content -->
<ui:define name="content">
<h:form id="main">
<h:form id="main">
<div class="section">
<span class="errors">
<h:messages globalOnly="true"/>
</span>
<h1>Search Hotels</h1>
<fieldset>
<h:inputText id="searchString" value="#{hotelSearch.searchString}" style="width: 165px;"/>
&#160;
<h:commandButton id="findHotels" value="Find Hotels" actionListener="#{hotelSearch.findHotelsListener}"
action="findHotels" reRender="searchResults"/>
&#160;
<a:status>
<f:facet name="start">
<h:graphicImage value="/img/spinner.gif"/>
</f:facet>
</a:status>
<h:inputText id="searchString" value="#{hotelSearch.searchString}" style="width: 165px; height: 15px;"/>&#160;
<h:commandButton id="findHotels" value="Find Hotels" actionListener="#{hotelSearch.findHotelsListener}" action="findHotels"/>
<br/>
<h:outputLabel for="pageSize">Maximum results:</h:outputLabel>&#160;
<h:selectOneMenu value="#{hotelSearch.pageSize}" id="pageSize">
@@ -39,9 +26,9 @@
</fieldset>
</div>
<div class="section">
<div class="section">
<h:outputText value="No Hotels Found" rendered="#{hotels.rowCount==0}"/>
<h:dataTable id="hotels" value="#{hotels}" var="hotel" rendered="#{hotels.rowCount>0}">
<h:dataTable id="hotels" value="#{hotels}" var="hotel" rendered="#{hotels.rowCount > 0}">
<h:column>
<f:facet name="header">Name</f:facet>
#{hotel.name}
@@ -66,22 +53,20 @@
</h:column>
</h:dataTable>
<div class="prev">
<h:commandLink id="prevPageLink" value="Previous results" actionListener="#{hotelSearch.prevPageListener}"
action="findHotels" rendered="#{hotelSearch.page > 0}"/>
<h:commandLink id="prevPageLink" value="Previous results" actionListener="#{hotelSearch.prevPageListener}" action="findHotels" rendered="#{hotelSearch.page > 0}"/>
</div>
<div class="next">
<h:commandLink id="nextPageLink" value="More results" actionListener="#{hotelSearch.nextPageListener}"
action="findHotels" rendered="#{hotels != null and hotels.rowCount == hotelSearch.pageSize}"/>
<h:commandLink id="nextPageLink" value="More results" actionListener="#{hotelSearch.nextPageListener}" action="findHotels" rendered="#{hotels != null and hotels.rowCount == hotelSearch.pageSize}"/>
</div>
</div>
</div>
<div class="section">
<h1>Current Hotel Bookings</h1>
</div>
<div class="section">
<h:outputText value="No Bookings Found" rendered="#{bookings.rowCount==0}"/>
<h:dataTable id="bookings" value="#{bookings}" var="booking" rendered="#{bookings.rowCount>0}">
<div class="section">
<h:outputText value="No Bookings Found" rendered="#{bookings.rowCount == 0}"/>
<h:dataTable id="bookings" value="#{bookings}" var="booking" rendered="#{bookings.rowCount > 0}">
<h:column>
<f:facet name="header">Name</f:facet>
#{booking.hotel.name}
@@ -116,7 +101,5 @@
</div>
</h:form>
</ui:define>
</ui:composition>
</ui:composition>

View File

@@ -4,28 +4,26 @@
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
<var name="hotelSearch" class="org.springframework.webflow.samples.booking.HotelSearch" scope="flow"/>
<var name="user" bean="user"/> <!-- Can replace this when we can replace searchAction with bean-actions -->
<var name="searchCriteria" class="org.springframework.webflow.samples.booking.web.SearchCriteria" scope="flow" />
<start-state idref="findBookings"/>
<start-actions>
<action method="findCurrentUserBookings" bean="mainActions" />
</start-actions>
<action-state id="findBookings">
<action bean="searchAction"/>
<transition on="success" to="main"/>
</action-state>
<start-state idref="displayMain"/>
<view-state id="main" view="/flows/main/main.xhtml">
<transition on="findHotels" to="findHotels"/>
<transition on="selectHotel" to="bookHotel-flow"/>
<transition on="cancelBooking" to="cancelBooking"/>
<view-state id="displayMain" view="/flows/main/main.xhtml">
<transition on="findHotels" to="findHotels" />
<transition on="selectHotel" to="bookHotel" />
<transition on="cancelBooking" to="cancelBooking" />
</view-state>
<action-state id="findHotels">
<action bean="searchAction"/>
<transition to="main"/>
<action bean="searchAction" method="findHotels" />
<transition on="success" to="displayMain" />
</action-state>
<subflow-state flow="bookHotel-flow" id="bookHotel-flow">
<subflow-state id="bookHotel" flow="booking-flow">
<attribute-mapper>
<input-mapper>
<mapping source="param.hotelId" target="id" from="string" to="long"/>
@@ -37,12 +35,15 @@
<action-state id="cancelBooking">
<bean-action bean="bookingService" method="cancelBooking">
<method-arguments>
<argument expression="param.bookingId" parameter-type="long"/>
<argument expression="param.bookingId" parameter-type="long" />
</method-arguments>
</bean-action>
<transition on="success" to="findBookings"/>
<transition on="success" to="reloadCurrentUserBookings" />
</action-state>
<end-state id="loggedIn"/>
<action-state id="reloadCurrentUserBookings">
<action bean="searchAction" method="findCurrentUserBookings" />
<transition on="success" to="displayMain" />
</action-state>
</flow>

View File

@@ -1,162 +0,0 @@
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a="https://ajax4jsf.dev.java.net/ajax"
xmlns:sf="http://springframework.org/faces"
template="/template.xhtml">
<!-- content -->
<ui:define name="content">
<div class="section">
<h1>Book Hotel</h1>
</div>
<div class="section">
<h:form id="booking">
<h:messages errorClass="errors" />
<fieldset>
<div class="entry">
<div class="label">Name:</div>
<div class="output">#{hotel.name}</div>
</div>
<div class="entry">
<div class="label">Address:</div>
<div class="output">#{hotel.address}</div>
</div>
<div class="entry">
<div class="label">City, State:</div>
<div class="output">#{hotel.city}, #{hotel.state}</div>
</div>
<div class="entry">
<div class="label">Zip:</div>
<div class="output">#{hotel.zip}</div>
</div>
<div class="entry">
<div class="label">Country:</div>
<div class="output">#{hotel.country}</div>
</div>
<div class="entry">
<div class="label">Nightly rate:</div>
<div class="output">
<h:outputText value="#{hotel.price}">
<f:convertNumber type="currency"
currencySymbol="$"/>
</h:outputText>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="checkinDate">Check In Date:</h:outputLabel></div>
<div class="input">
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="checkoutDate">Check Out Date:</h:outputLabel></div>
<div class="input">
<sf:clientDateValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
<f:convertDateTime pattern="MM/dd/yy" timeZone="EST"/>
</h:inputText>
</sf:clientDateValidator>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="beds">Room Preference:</h:outputLabel></div>
<div class="input">
<h:selectOneMenu id="beds" value="#{booking.beds}">
<f:selectItem itemLabel="One king-size bed" itemValue="1"/>
<f:selectItem itemLabel="Two double beds" itemValue="2"/>
<f:selectItem itemLabel="Three beds" itemValue="3"/>
</h:selectOneMenu>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="smoking">Smoking Preference:</h:outputLabel></div>
<div id="radio" class="input">
<h:selectOneRadio id="smoking" value="#{booking.smoking}" layout="pageDirection">
<f:selectItem itemLabel="Smoking" itemValue="true"/>
<f:selectItem itemLabel="Non Smoking" itemValue="false"/>
</h:selectOneRadio>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="creditCard">Credit Card #:</h:outputLabel></div>
<div class="input">
<sf:clientNumberValidator allowBlank="false" allowNegative="false" allowDecimals="false"
minLength="16" maxLength="16" msgDisplay="block" msgClass="errors">
<h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/>
</sf:clientNumberValidator>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="creditCardName">Credit Card Name:</h:outputLabel></div>
<div class="input">
<sf:clientTextValidator allowBlank="false" msgDisplay="block" msgClass="errors">
<h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/>
</sf:clientTextValidator>
</div>
</div>
<div class="entry">
<div class="label"><h:outputLabel for="creditCardExpiryMonth">Credit Card Expiry:</h:outputLabel></div>
<div class="input">
<h:selectOneMenu id="creditCardExpiryMonth" value="#{booking.creditCardExpiryMonth}">
<f:selectItem itemLabel="Jan" itemValue="1"/>
<f:selectItem itemLabel="Feb" itemValue="2"/>
<f:selectItem itemLabel="Mar" itemValue="3"/>
<f:selectItem itemLabel="Apr" itemValue="4"/>
<f:selectItem itemLabel="May" itemValue="5"/>
<f:selectItem itemLabel="Jun" itemValue="6"/>
<f:selectItem itemLabel="Jul" itemValue="7"/>
<f:selectItem itemLabel="Aug" itemValue="8"/>
<f:selectItem itemLabel="Sep" itemValue="9"/>
<f:selectItem itemLabel="Oct" itemValue="10"/>
<f:selectItem itemLabel="Nov" itemValue="11"/>
<f:selectItem itemLabel="Dec" itemValue="12"/>
</h:selectOneMenu>
<h:selectOneMenu id="creditCardExpiryYear" value="#{booking.creditCardExpiryYear}">
<f:selectItem itemLabel="2005" itemValue="2005"/>
<f:selectItem itemLabel="2006" itemValue="2006"/>
<f:selectItem itemLabel="2007" itemValue="2007"/>
<f:selectItem itemLabel="2008" itemValue="2008"/>
<f:selectItem itemLabel="2009" itemValue="2009"/>
</h:selectOneMenu>
</div>
</div>
<div class="entry errors">
<h:messages globalOnly="true"/>
</div>
<div class="entry">
<div class="label">&#160;</div>
<div class="input">
<sf:validateAllOnClick>
<h:commandButton id="proceed" value="Proceed" action="reviewDetails"/>
</sf:validateAllOnClick>&#160;
<h:commandButton id="cancel" immediate="true" value="Cancel" action="cancel"/>
</div>
</div>
</fieldset>
</h:form>
</div>
</ui:define>
</ui:composition>