Drop portlet samples

Preparation for upgrade to SFW 5.0 and SWF 2.5.
This commit is contained in:
Rossen Stoyanchev
2018-02-06 22:26:40 -05:00
parent 07b7fef830
commit a1889ad93f
66 changed files with 0 additions and 3246 deletions

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<pageflow:Pageflow xmlns:pageflow="http://www.sybase.com/suade/pageflow" id="pf12065550095160" configfile="/swf-booking-portlet-faces/src/main/webapp/WEB-INF/faces-config.xml"/>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="swf-booking-portlet-faces">
<property name="source.version" value="1.5"/>
<property name="ivy.cache.dir" value="${basedir}/../../ivy-cache"/>
<property name="integration.repo.dir" value="${basedir}/../../integration-repo"/>
<property name="ivy.settings.file" value="${basedir}/../../build-spring-webflow/ivysettings.xml"/>
<property file="${basedir}/../../build.properties"/>
<import file="${basedir}/../../spring-build/war/default.xml"/>
</project>

View File

@@ -1,125 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.webflow.samples</groupId>
<artifactId>booking-portlet-faces</artifactId>
<packaging>war</packaging>
<name>Hotel Booking : Spring Portlet MVC + Web Flow + JSF</name>
<version>1.0.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow-samples</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-faces</artifactId>
<version>${webflow.version}</version>
</dependency>
<!-- Servlet, Portlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- JSF -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>${mojarra.version}</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>${mojarra.version}</version>
</dependency>
<!-- Database, JPA -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- JSR 303 with Hibernate Validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- JAXB2 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
<build>
<finalName>booking-portlet-faces</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,8 +0,0 @@
Starting with version 2.2, Spring Web Flow provides support for JSF Portlets using its own internal
Portlet integration rather than a Portlet Bridge for JSF.
This sample demonstrates that support. It has been tested on Apache Pluto 2.0.1 with Portlet
API 2.0 and JSF 1.2 (both Mojarra and MyFaces).
See the reference documentation for more information.

View File

@@ -1,198 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
/**
* A Hotel Booking made by a User.
*/
@Entity
public class Booking implements Serializable {
private static final long serialVersionUID = 1171567558348174963L;
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() {
}
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);
setCheckoutDate(calendar.getTime());
}
@Transient
public BigDecimal getTotal() {
return hotel.getPrice().multiply(new BigDecimal(getNights()));
}
@Transient
public int getNights() {
return (int) (checkoutDate.getTime() - checkinDate.getTime()) / 1000 / 60 / 60 / 24;
}
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
@Temporal(TemporalType.DATE)
public Date getCheckinDate() {
return checkinDate;
}
public void setCheckinDate(Date datetime) {
this.checkinDate = datetime;
}
@ManyToOne
public Hotel getHotel() {
return hotel;
}
public void setHotel(Hotel hotel) {
this.hotel = hotel;
}
@ManyToOne
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Basic
@Temporal(TemporalType.DATE)
public Date getCheckoutDate() {
return checkoutDate;
}
public void setCheckoutDate(Date checkoutDate) {
this.checkoutDate = checkoutDate;
}
public String getCreditCard() {
return creditCard;
}
public void setCreditCard(String creditCard) {
this.creditCard = creditCard;
}
@Transient
public String getDescription() {
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
return hotel == null ? null : hotel.getName() + ", " + df.format(getCheckinDate()) + " to "
+ df.format(getCheckoutDate());
}
public boolean isSmoking() {
return smoking;
}
public void setSmoking(boolean smoking) {
this.smoking = smoking;
}
public int getBeds() {
return beds;
}
public void setBeds(int beds) {
this.beds = beds;
}
public String getCreditCardName() {
return creditCardName;
}
public void setCreditCardName(String creditCardName) {
this.creditCardName = creditCardName;
}
public int getCreditCardExpiryMonth() {
return creditCardExpiryMonth;
}
public void setCreditCardExpiryMonth(int creditCardExpiryMonth) {
this.creditCardExpiryMonth = creditCardExpiryMonth;
}
public int getCreditCardExpiryYear() {
return creditCardExpiryYear;
}
public void setCreditCardExpiryYear(int creditCardExpiryYear) {
this.creditCardExpiryYear = creditCardExpiryYear;
}
public boolean validate(MessageContext context) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -1);
boolean valid = true;
if (checkinDate.before(calendar.getTime())) {
context.addMessage(new MessageBuilder().error().source("checkinDate").defaultText(
"Check in date must be a future date").build());
valid = false;
} else if (!checkinDate.before(checkoutDate)) {
context.addMessage(new MessageBuilder().error().source("checkoutDate").defaultText(
"Check out date must be later than check in date").build());
valid = false;
}
return valid;
}
@Override
public String toString() {
return "Booking(" + user + "," + hotel + ")";
}
}

View File

@@ -1,59 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.List;
/**
* A service interface for retrieving hotels and bookings from a backing repository. Also supports the ability to cancel
* a booking.
*/
public interface BookingService {
/**
* Find bookings made by the given user
* @param username the user's name
* @return their bookings
*/
public List<Booking> findBookings(String username);
/**
* Find hotels available for booking by some criteria.
* @param criteria the search criteria
* @return a list of hotels meeting the criteria
*/
public List<Hotel> findHotels(SearchCriteria criteria);
/**
* Find hotels by their identifier.
* @param id the hotel id
* @return the hotel
*/
public Hotel findHotelById(Long id);
/**
* Find user by their username.
* @param username the user's username
* @return the user
*/
public User findUser(String username);
/**
* Create a new, transient hotel booking instance for the given user.
* @param hotelId the hotelId
* @param userName the user name
* @return the new transient booking instance
*/
public Booking createBooking(Long hotelId, String userName);
/**
* Persist the booking to the database
* @param booking the booking
*/
public void persistBooking(Booking booking);
/**
* Cancel an existing booking.
* @param id the booking id
*/
public void cancelBooking(Booking booking);
}

View File

@@ -1,110 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* A hotel where users may book stays.
*/
@Entity
public class Hotel implements Serializable {
private static final long serialVersionUID = 4011346719502656269L;
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
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Column(precision = 6, scale = 2)
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Booking createBooking(User user) {
return new Booking(this, user);
}
@Override
public String toString() {
return "Hotel(" + name + "," + address + "," + city + "," + zip + ")";
}
}

View File

@@ -1,93 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
/**
* A JPA-based implementation of the Booking Service. Delegates to a JPA entity manager to issue data access calls
* against the backing repository. The EntityManager reference is provided by the managing container (Spring)
* automatically.
*/
@Service("bookingService")
@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(String username) {
if (username != null) {
return em.createQuery("select b from Booking b where b.user.username = :username order by b.checkinDate")
.setParameter("username", username).getResultList();
} else {
return null;
}
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Hotel> findHotels(SearchCriteria criteria) {
String pattern = getSearchPattern(criteria);
return em
.createQuery(
"select h from Hotel h where lower(h.name) like :pattern or lower(h.city) like :pattern "
+ " or lower(h.zip) like :pattern or lower(h.address) like :pattern")
.setParameter("pattern", pattern).setMaxResults(criteria.getPageSize())
.setFirstResult(criteria.getPage() * criteria.getPageSize()).getResultList();
}
@Transactional(readOnly = true)
public Hotel findHotelById(Long id) {
return em.find(Hotel.class, id);
}
@Transactional(readOnly = true)
public User findUser(String username) {
return (User) em.createQuery("select u from User u where u.username = :username")
.setParameter("username", username).getSingleResult();
}
@Transactional(readOnly = true)
public Booking createBooking(Long hotelId, String username) {
Hotel hotel = em.find(Hotel.class, hotelId);
User user = findUser(username);
return new Booking(hotel, user);
}
@Transactional
public void persistBooking(Booking booking) {
em.persist(booking);
}
@Transactional
public void cancelBooking(Booking booking) {
booking = em.find(Booking.class, booking.getId());
if (booking != null) {
em.remove(booking);
}
}
// helpers
private String getSearchPattern(SearchCriteria criteria) {
if (StringUtils.hasText(criteria.getSearchString())) {
return "%" + criteria.getSearchString().toLowerCase().replace('*', '%') + "%";
} else {
return "%";
}
}
}

View File

@@ -1,83 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.ArrayList;
import java.util.List;
import javax.faces.model.SelectItem;
import org.springframework.stereotype.Service;
@Service
public class ReferenceData {
private List<SelectItem> bedOptions;
private List<SelectItem> smokingOptions;
private List<SelectItem> creditCardExpMonths;
private List<SelectItem> creditCardExpYears;
private List<SelectItem> pageSizeOptions;
public List<SelectItem> getBedOptions() {
if (bedOptions == null) {
bedOptions = new ArrayList<SelectItem>();
bedOptions.add(new SelectItem(new Integer(1), "One king-size bed"));
bedOptions.add(new SelectItem(new Integer(2), "Two double beds"));
bedOptions.add(new SelectItem(new Integer(3), "Three beds"));
}
return bedOptions;
}
public List<SelectItem> getSmokingOptions() {
if (smokingOptions == null) {
smokingOptions = new ArrayList<SelectItem>();
smokingOptions.add(new SelectItem(Boolean.TRUE, "Smoking"));
smokingOptions.add(new SelectItem(Boolean.FALSE, "Non-Smoking"));
}
return smokingOptions;
}
public List<SelectItem> getCreditCardExpMonths() {
if (creditCardExpMonths == null) {
creditCardExpMonths = new ArrayList<SelectItem>();
creditCardExpMonths.add(new SelectItem(new Integer(1), "Jan"));
creditCardExpMonths.add(new SelectItem(new Integer(2), "Feb"));
creditCardExpMonths.add(new SelectItem(new Integer(3), "Mar"));
creditCardExpMonths.add(new SelectItem(new Integer(4), "Apr"));
creditCardExpMonths.add(new SelectItem(new Integer(5), "May"));
creditCardExpMonths.add(new SelectItem(new Integer(6), "Jun"));
creditCardExpMonths.add(new SelectItem(new Integer(7), "Jul"));
creditCardExpMonths.add(new SelectItem(new Integer(8), "Aug"));
creditCardExpMonths.add(new SelectItem(new Integer(9), "Sep"));
creditCardExpMonths.add(new SelectItem(new Integer(10), "Oct"));
creditCardExpMonths.add(new SelectItem(new Integer(11), "Nov"));
creditCardExpMonths.add(new SelectItem(new Integer(12), "Dec"));
}
return creditCardExpMonths;
}
public List<SelectItem> getCreditCardExpYears() {
if (creditCardExpYears == null) {
creditCardExpYears = new ArrayList<SelectItem>();
creditCardExpYears.add(new SelectItem(new Integer(2008), "2008"));
creditCardExpYears.add(new SelectItem(new Integer(2009), "2009"));
creditCardExpYears.add(new SelectItem(new Integer(2010), "2010"));
creditCardExpYears.add(new SelectItem(new Integer(2010), "2011"));
creditCardExpYears.add(new SelectItem(new Integer(2010), "2012"));
}
return creditCardExpYears;
}
public List<SelectItem> getPageSizeOptions() {
if (pageSizeOptions == null) {
pageSizeOptions = new ArrayList<SelectItem>();
pageSizeOptions.add(new SelectItem(new Integer(5), "5"));
pageSizeOptions.add(new SelectItem(new Integer(10), "10"));
pageSizeOptions.add(new SelectItem(new Integer(20), "20"));
}
return pageSizeOptions;
}
}

View File

@@ -1,66 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
/**
* A backing bean for the main hotel search form. Encapsulates the criteria needed to perform a hotel search.
*/
public class SearchCriteria implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The user-provided search criteria for finding Hotels.
*/
private String searchString = "";
/**
* The maximum page size of the Hotel result list
*/
private int pageSize = 5;
/**
* The current page of the Hotel result list.
*/
private int page;
public String getSearchString() {
return searchString;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public void nextPage() {
page++;
}
public void previousPage() {
page--;
}
public void resetPage() {
page = 0;
}
public String toString() {
return "[Search Criteria searchString = '" + searchString + "'";
}
}

View File

@@ -1,62 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* A user who can book hotels.
*/
@Entity
@Table(name = "Customer")
public class User implements Serializable {
private static final long serialVersionUID = -3652559447682574722L;
private String username;
private String password;
private String name;
public User() {
}
public User(String username, String password, String name) {
this.username = username;
this.password = password;
this.name = name;
}
@Id
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User(" + username + ")";
}
}

View File

@@ -1,11 +0,0 @@
package org.springframework.webflow.samples.booking;
import org.springframework.webflow.mvc.portlet.AbstractFlowHandler;
public class ViewFlowHandler extends AbstractFlowHandler {
public String getFlowId() {
return "view";
}
}

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="bookingDatabase">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.springframework.webflow.samples.booking.User</class>
<class>org.springframework.webflow.samples.booking.Booking</class>
<class>org.springframework.webflow.samples.booking.Hotel</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
</properties>
</persistence-unit>
</persistence>

View File

@@ -1,28 +0,0 @@
insert into Customer (username, name) values ('keith', 'Keith')
insert into Customer (username, name) values ('erwin', 'Erwin')
insert into Customer (username, name) values ('jeremy', 'Jeremy')
insert into Customer (username, name) values ('scott', 'Scott')
insert into Customer (username, name) values ('pluto', 'Pluto')
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, 60, 'Jameson Inn', '890 Palm Bay Rd NE', 'Palm Bay', 'FL', '32905', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (3, 199, 'Chilworth Manor', 'The Cottage, Southampton Business Park', 'Southampton', 'Hants', 'SO16 7JF', 'UK')
insert into Hotel (id, price, name, address, city, state, zip, country) values (4, 120, 'Marriott Courtyard', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (5, 180, 'Doubletree', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (6, 450, 'W Hotel', 'Union Square, Manhattan', 'NY', 'NY', '10011', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (7, 450, 'W Hotel', 'Lexington Ave, Manhattan', 'NY', 'NY', '10011', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (8, 250, 'Hotel Rouge', '1315 16th Street NW', 'Washington', 'DC', '20036', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (9, 300, '70 Park Avenue Hotel', '70 Park Avenue', 'NY', 'NY', '10011', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (10, 300, 'Conrad Miami', '1395 Brickell Ave', 'Miami', 'FL', '33131', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (11, 80, 'Sea Horse Inn', '2106 N Clairemont Ave', 'Eau Claire', 'WI', '54703', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (12, 90, 'Super 8 Eau Claire Campus Area', '1151 W Macarthur Ave', 'Eau Claire', 'WI', '54701', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (13, 160, 'Marriot Downtown', '55 Fourth Street', 'San Francisco', 'CA', '94103', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (14, 200, 'Hilton Diagonal Mar', 'Passeig del Taulat 262-264', 'Barcelona', 'Catalunya', '08019', 'Spain')
insert into Hotel (id, price, name, address, city, state, zip, country) values (15, 210, 'Hilton Tel Aviv', 'Independence Park', 'Tel Aviv', '', '63405', 'Israel')
insert into Hotel (id, price, name, address, city, state, zip, country) values (16, 240, 'InterContinental Tokyo Bay', 'Takeshiba Pier', 'Tokyo', '', '105', 'Japan')
insert into Hotel (id, price, name, address, city, state, zip, country) values (17, 130, 'Hotel Beaulac', ' Esplanade L<>opold-Robert 2', 'Neuchatel', '', '2000', 'Switzerland')
insert into Hotel (id, price, name, address, city, state, zip, country) values (18, 140, 'Conrad Treasury Place', 'William & George Streets', 'Brisbane', 'QLD', '4001', 'Australia')
insert into Hotel (id, price, name, address, city, state, zip, country) values (19, 230, 'Ritz Carlton', '1228 Sherbrooke St', 'West Montreal', 'Quebec', 'H3G1H6', 'Canada')
insert into Hotel (id, price, name, address, city, state, zip, country) values (20, 460, 'Ritz Carlton', 'Peachtree Rd, Buckhead', 'Atlanta', 'GA', '30326', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (21, 220, 'Swissotel', '68 Market Street', 'Sydney', 'NSW', '2000', 'Australia')
insert into Hotel (id, price, name, address, city, state, zip, country) values (22, 250, 'Meli<EFBFBD> White House', 'Albany Street', 'Regents Park London', '', 'NW13UP', 'Great Britain')
insert into Hotel (id, price, name, address, city, state, zip, country) values (23, 210, 'Hotel Allegro', '171 West Randolph Street', 'Chicago', 'IL', '60601', 'USA')

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<logger name="org.springframework.samples" level="debug">
<appender-ref ref="STDOUT" />
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -1,11 +0,0 @@
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
# Enable web flow logging
log4j.category.org.springframework.webflow=DEBUG
log4j.category.org.springframework.faces=DEBUG
log4j.category.org.springframework.binding=DEBUG
log4j.category.org.springframework.transaction=DEBUG

View File

@@ -1,44 +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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- Activates annotation-based bean configuration -->
<context:annotation-config />
<!-- Scans for application @Components to deploy -->
<context:component-scan base-package="org.springframework.webflow.samples.booking" />
<!-- Instructs Spring to perfrom declarative transaction managemenet on annotated classes -->
<tx:annotation-driven />
<!-- Drives transactions using local JPA APIs -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Creates a EntityManagerFactory for use with the Hibernate JPA provider and a simple in-memory data source populated with test data -->
<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>
<!-- Deploys a in-memory "booking" datasource populated -->
<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>
</beans>

View File

@@ -1,59 +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:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd
http://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces-2.4.xsd">
<!-- Maps portlet modes to handlers -->
<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="portletModeMap">
<map>
<entry key="view">
<bean class="org.springframework.webflow.samples.booking.ViewFlowHandler" />
</entry>
</map>
</property>
</bean>
<!-- Serve JSF resources via the MVC portlet -->
<faces:resources/>
<!-- Maps logical view names selected by the url filename controller to .jsp view templates within the /WEB-INF directory -->
<bean id="internalJspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Enables FlowHandlers -->
<bean class="org.springframework.webflow.mvc.portlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextLifecycleListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices">
<webflow:flow-location path="/WEB-INF/flows/view/view.xml" />
<webflow:flow-location path="/WEB-INF/flows/main/main.xml" />
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>
<!-- Configures the Spring Web Flow JSF integration -->
<faces:flow-builder-services id="facesFlowBuilderServices" development="true" />
<!-- Installs a listener that creates and releases the FacesContext for each request. -->
<bean id="facesContextLifecycleListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>
</beans>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<view-handler>org.springframework.faces.webflow.context.portlet.PortletViewHandler</view-handler>
</application>
</faces-config>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<input name="hotelId" value="flowScope.hotelId"/>
<on-start>
<evaluate expression="bookingService.createBooking(hotelId, currentUser.name)" result="flowScope.booking" />
</on-start>
<view-state id="enterBookingDetails">
<transition on="proceed" to="reviewBooking">
<evaluate expression="booking.validate(messageContext)" />
</transition>
<transition on="cancel" to="bookingCancelled" />
</view-state>
<view-state id="reviewBooking">
<transition on="confirm" to="bookingConfirmed">
<evaluate expression="bookingService.persistBooking(booking)" />
</transition>
<transition on="revise" to="enterBookingDetails" />
<transition on="cancel" to="bookingCancelled" />
</view-state>
<end-state id="bookingConfirmed" />
<end-state id="bookingCancelled" />
</flow>

View File

@@ -1,122 +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">
<f:view contentType="text/html">
<h2>Book Hotel</h2>
<h:form id="booking">
<h:messages errorClass="errors" />
<fieldset>
<table>
<tr class="field">
<td class="label">Name:</td>
<td class="output">#{booking.hotel.name}</td>
</tr>
<tr class="field">
<td class="label">Address:</td>
<td class="output">#{booking.hotel.address}</td>
</tr>
<tr class="field">
<td class="label">City, State:</td>
<td class="output">#{booking.hotel.city}, #{booking.hotel.state}</td>
</tr>
<tr class="field">
<td class="label">Zip:</td>
<td class="output">#{booking.hotel.zip}</td>
</tr>
<tr class="field">
<td class="label">Country:</td>
<td class="output">#{booking.hotel.country}</td>
</tr>
<tr class="field">
<td class="label">Nightly rate:</td>
<td class="output">
<h:outputText value="#{booking.hotel.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="checkinDate">Check In Date:</h:outputLabel>
</td>
<td class="input">
<h:inputText id="checkinDate" value="#{booking.checkinDate}" required="true">
<f:convertDateTime pattern="yyyy-MM-dd" timeZone="EST"/>
</h:inputText>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="checkoutDate">Check Out Date:</h:outputLabel>
</td>
<td class="input">
<h:inputText id="checkoutDate" value="#{booking.checkoutDate}" required="true">
<f:convertDateTime pattern="yyyy-MM-dd" timeZone="EST"/>
</h:inputText>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="beds">Room Preference:</h:outputLabel>
</td>
<td class="input">
<h:selectOneMenu id="beds" value="#{booking.beds}">
<f:selectItems value="#{referenceData.bedOptions}"/>
</h:selectOneMenu>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="smoking">Smoking Preference:</h:outputLabel>
</td>
<td id="radio" class="input">
<h:selectOneRadio id="smoking" value="#{booking.smoking}" layout="pageDirection">
<f:selectItems value="#{referenceData.smokingOptions}"/>
</h:selectOneRadio>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="creditCard">Credit Card #:</h:outputLabel>
</td>
<td class="input">
<h:inputText id="creditCard" value="#{booking.creditCard}" required="true"/>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="creditCardName">Credit Card Name:</h:outputLabel>
</td>
<td class="input">
<h:inputText id="creditCardName" value="#{booking.creditCardName}" required="true"/>
</td>
</tr>
<tr class="field">
<td class="label">
<h:outputLabel for="creditCardExpiryMonth">Expiration Date:</h:outputLabel>
</td>
<td class="input">
<h:selectOneMenu id="creditCardExpiryMonth" value="#{booking.creditCardExpiryMonth}">
<f:selectItems value="#{referenceData.creditCardExpMonths}" />
</h:selectOneMenu>
<h:selectOneMenu id="creditCardExpiryYear" value="#{booking.creditCardExpiryYear}">
<f:selectItems value="#{referenceData.creditCardExpYears}"/>
</h:selectOneMenu>
</td>
</tr>
<tr>
<td colspan="2" class="buttonGroup">
<h:commandButton id="proceed" action="proceed" value="Proceed"/>&#160;
<h:commandButton id="cancel" immediate="true" value="Cancel" action="cancel"/>
</td>
</tr>
</table>
</fieldset>
</h:form>
</f:view>
</ui:composition>

View File

@@ -1,74 +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:sf="http://www.springframework.org/tags/faces">
<f:view contentType="text/html">
<h2>Confirm Hotel Booking</h2>
<h:form id="confirm">
<fieldset>
<table>
<tr class="field">
<td class="label">Name:</td>
<td class="output">#{booking.hotel.name}</td>
</tr>
<tr class="field">
<td class="label">Address:</td>
<td class="output">#{booking.hotel.address}</td>
</tr>
<tr class="field">
<td class="label">City, State:</td>
<td class="output">#{booking.hotel.city}, #{booking.hotel.state}</td>
</tr>
<tr class="field">
<td class="label">Zip:</td>
<td class="output">#{booking.hotel.zip}</td>
</tr>
<tr class="field">
<td class="label">Country:</td>
<td class="output">#{booking.hotel.country}</td>
</tr>
<tr class="field">
<td class="label">Total payment:</td>
<td class="output">
<h:outputText value="#{booking.total}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</td>
</tr>
<tr class="field">
<td class="label">Check In Date:</td>
<td class="output">
<h:outputText value="#{booking.checkinDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</td>
</tr>
<tr class="field">
<td class="label">Check Out Date:</td>
<td class="output">
<h:outputText value="#{booking.checkoutDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</td>
</tr>
<tr class="field">
<td class="label">Credit Card #:</td>
<td class="output">#{booking.creditCard}</td>
</tr>
<tr>
<td colspan="2" class="buttonGroup">
<h:commandButton id="confirm" value="Confirm" action="confirm"/>&#160;
<h:commandButton id="revise" value="Revise" action="revise"/>&#160;
<h:commandButton id="cancel" value="Cancel" action="cancel"/>
</td>
</tr>
</table>
</fieldset>
</h:form>
</f:view>
</ui:composition>

View File

@@ -1,77 +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">
<f:view contentType="text/html">
<div id="hotelSearch">
<h2>Search Hotels</h2>
<span class="errors">
<h:messages globalOnly="true" />
</span>
<h:form id="mainForm">
<fieldset>
<div class="searchGroup">
<div class="searchField">
<h:outputLabel for="searchString">Search String:</h:outputLabel>
<h:inputText id="searchString" value="#{searchCriteria.searchString}" style="width: 165px; height: 15px;" />
</div>
<div class="searchSize">
<h:outputLabel for="pageSize">Maximum results:</h:outputLabel>
<h:selectOneMenu id="pageSize" value="#{searchCriteria.pageSize}">
<f:selectItems value="#{referenceData.pageSizeOptions}" />
</h:selectOneMenu>
</div>
<div class="searchButton">
<h:commandButton value="Find Hotels" action="search" />
</div>
</div>
</fieldset>
</h:form>
</div>
<div id="bookingsSection">
<h:form id="bookingsForm">
<h2>Current Hotel Bookings</h2>
<h:outputText value="No Bookings Found" rendered="#{bookings.rowCount == 0}"/>
<h:dataTable id="bookings" styleClass="summary" value="#{bookings}" var="booking" rendered="#{bookings.rowCount > 0}">
<h:column>
<f:facet name="header">Name</f:facet>
#{booking.hotel.name}
</h:column>
<h:column>
<f:facet name="header">Address</f:facet>
#{booking.hotel.address}
</h:column>
<h:column>
<f:facet name="header">City, State</f:facet>
#{booking.hotel.city}, #{booking.hotel.state}
</h:column>
<h:column>
<f:facet name="header">Check in date</f:facet>
<h:outputText value="#{booking.checkinDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Check out date</f:facet>
<h:outputText value="#{booking.checkoutDate}">
<f:convertDateTime dateStyle="short"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">Confirmation number</f:facet>
#{booking.id}
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<h:commandLink value="Cancel" action="cancelBooking" />
</h:column>
</h:dataTable>
</h:form>
</div>
</f:view>
</ui:composition>

View File

@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="searchCriteria" class="org.springframework.webflow.samples.booking.SearchCriteria" />
<view-state id="enterSearchCriteria">
<on-render>
<evaluate expression="bookingService.findBookings(currentUser.name)" result="flowScope.bookings" result-type="dataModel" />
</on-render>
<transition on="search" to="reviewHotels" />
<transition on="cancelBooking">
<evaluate expression="bookingService.cancelBooking(bookings.selectedRow)" />
</transition>
</view-state>
<view-state id="reviewHotels">
<on-render>
<evaluate expression="bookingService.findHotels(searchCriteria)" result="flowScope.hotels" result-type="dataModel" />
</on-render>
<transition on="previous">
<evaluate expression="searchCriteria.previousPage()" />
</transition>
<transition on="next">
<evaluate expression="searchCriteria.nextPage()" />
</transition>
<transition on="select" to="reviewHotel" />
<transition on="changeSearch" to="enterSearchCriteria" />
</view-state>
<view-state id="reviewHotel">
<on-render>
<set name="requestScope.hotel" value="hotels.selectedRow" />
</on-render>
<transition on="book" to="bookHotel" />
<transition on="cancel" to="enterSearchCriteria" />
</view-state>
<subflow-state id="bookHotel" subflow="booking">
<input name="hotelId" value="hotels.selectedRow.id" />
<transition on="bookingConfirmed" to="finish" />
<transition on="bookingCancelled" to="enterSearchCriteria" />
</subflow-state>
<end-state id="finish" />
</flow>

View File

@@ -1,52 +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">
<f:view contentType="text/html">
<h2>View Hotel</h2>
<table>
<tr class="field">
<td class="label">Name:</td>
<td class="output">#{hotel.name}</td>
</tr>
<tr class="field">
<td class="label">Address:</td>
<td class="output">#{hotel.address}</td>
</tr>
<tr class="field">
<td class="label">City:</td>
<td class="output">#{hotel.city}</td>
</tr>
<tr class="field">
<td class="label">State:</td>
<td class="output">#{hotel.state}</td>
</tr>
<tr class="field">
<td class="label">Zip:</td>
<td class="output">#{hotel.zip}</td>
</tr>
<tr class="field">
<td class="label">Country:</td>
<td class="output">#{hotel.country}</td>
</tr>
<tr class="field">
<td class="label">Nightly rate:</td>
<td class="output">
<h:outputText value="#{hotel.price}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</td>
</tr>
</table>
<h:form id="hotel">
<input name="execution" type="hidden" value="${flowExecutionContext.key}"/>
<h:commandButton id="book" action="book" value="Book Hotel"/>&#160;
<h:commandButton id="cancel" action="cancel" value="Back to Search"/>
</h:form>
</f:view>
</ui:composition>

View File

@@ -1,48 +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">
<f:view contentType="text/html">
<h:form id="hotels">
<h2>Hotel Results</h2>
<p>
<h:commandLink value="Change Search" action="changeSearch"/>
</p>
<div id="searchResults">
<h:outputText id="noHotelsText" value="No Hotels Found" rendered="#{hotels.rowCount == 0}"/>
<h:dataTable id="hotelsTable" styleClass="summary" value="#{hotels}" var="hotel" rendered="#{hotels.rowCount > 0}">
<h:column>
<f:facet name="header">Name</f:facet>
#{hotel.name}
</h:column>
<h:column>
<f:facet name="header">Address</f:facet>
#{hotel.address}
</h:column>
<h:column>
<f:facet name="header">City, State</f:facet>
#{hotel.city}, #{hotel.state}, #{hotel.country}
</h:column>
<h:column>
<f:facet name="header">Zip</f:facet>
#{hotel.zip}
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<h:commandLink value="View Hotel" action="select"/>
</h:column>
</h:dataTable>
<div class="next">
<h:commandLink id="nextPageLink" value="More Results" action="next" rendered="#{not empty hotels and hotels.rowCount == searchCriteria.pageSize}"/>
</div>
<div class="previous">
<h:commandLink id="previousPageLink" value="Previous results" action="previous" rendered="#{searchCriteria.page > 0}"/>
</div>
</div>
</h:form>
</f:view>
</ui:composition>

View File

@@ -1,35 +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:sf="http://www.springframework.org/tags/faces">
<f:view contentType="text/html">
<h2>Welcome to Spring Travel</h2>
<p>
This reference application illustrates <a href="http://www.springframework.org/faces">Spring Faces</a>,
a software library that integrates Spring and JavaServerFaces technology in a portlet environment.
</p>
<p>
The key features illustrated in this sample include:
</p>
<ul>
<li>A declarative navigation model enabling full browser button support and dynamic navigation rules</li>
<li>A fine-grained state management model, including support for ConversationScope and ViewScope</li>
<li>Modularization of web application functionality by domain use case, illustrating project structure best-practices</li>
<li>Managed persistence contexts with the Java Persistence API (JPA)</li>
<li>Unified Expression Language (EL) integration</li>
<li>Declarative page authoring with Facelets, including applying reusable page layouts</li>
<li>Exception handling support across all layers of the application</li>
<li>Spring IDE tooling integration, with support for graphical flow modeling and visualization</li>
</ul>
<p align="right">
<h:form>
<h:commandLink action="main">Start your Spring Travel experience</h:commandLink>
</h:form>
</p>
</f:view>
</ui:composition>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<view-state id="intro">
<transition on="main" to="main" />
</view-state>
<subflow-state id="main" subflow="main">
<transition to="finish" />
</subflow-state>
<end-state id="finish"/>
</flow>

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
<portlet>
<portlet-name>swf-booking-faces</portlet-name>
<display-name>Spring Webflow Booking Faces</display-name>
<portlet-class>
org.springframework.web.portlet.DispatcherPortlet
</portlet-class>
<init-param>
<name>contextConfigLocation</name>
<value>
/WEB-INF/config/hotelbooking-portlet-config.xml
</value>
</init-param>
<init-param>
<name>viewRendererUrl</name>
<value>/WEB-INF/servlet/view</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>Spring Webflow Booking Faces</title>
</portlet-info>
</portlet>
</portlet-app>

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/application-config.xml
</param-value>
</context-param>
<!-- Use JSF view templates saved as *.xhtml, for use with Facelets -->
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<!-- Enables special Facelets debug output during development -->
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
<!-- Causes Facelets to refresh templates during development -->
<context-param>
<param-name>facelets.REFRESH_PERIOD</param-name>
<param-value>1</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Generated Portlet Wrapper Servlet for Apache Pluto deployment -->
<servlet>
<servlet-name>swf-booking-faces</servlet-name>
<servlet-class>org.apache.pluto.container.driver.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-name</param-name>
<param-value>swf-booking-faces</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>swf-booking-faces</servlet-name>
<url-pattern>/PlutoInvoker/swf-booking-faces</url-pattern>
</servlet-mapping>
<!-- Just here so the JSF implementation can initialize, *not* used at runtime -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Just here so the JSF implementation can initialize -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
</web-app>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="swf-booking-portlet-mvc">
<property name="source.version" value="1.5"/>
<property name="ivy.cache.dir" value="${basedir}/../../ivy-cache"/>
<property name="integration.repo.dir" value="${basedir}/../../integration-repo"/>
<property name="ivy.settings.file" value="${basedir}/../../build-spring-webflow/ivysettings.xml"/>
<property file="${basedir}/../../build.properties"/>
<import file="${basedir}/../../spring-build/war/default.xml"/>
</project>

View File

@@ -1,136 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.webflow.samples</groupId>
<artifactId>booking-portlet-mvc</artifactId>
<packaging>war</packaging>
<name>Hotel Booking : Spring Portlet MVC + Web Flow</name>
<version>1.0.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow-samples</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>${webflow.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-js</artifactId>
<version>${webflow.version}</version>
</dependency>
<!-- Servlet, Portlet API, JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Database, JPA -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- JSR 303 with Hibernate Validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- JAXB2 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<!-- Joda Time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time-jsptags</artifactId>
<version>1.1.1</version>
<scope>runtime</scope>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
<build>
<finalName>booking-portlet-mvc</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,192 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
/**
* A Hotel Booking made by a User.
*/
@Entity
@BookingDateRange
public class Booking implements Serializable {
private Long id;
private User user;
private Hotel hotel;
@DateTimeFormat(pattern = "MM-dd-yyyy")
private Date checkinDate;
@DateTimeFormat(pattern = "MM-dd-yyyy")
private Date checkoutDate;
private String creditCard;
private String creditCardName;
private int creditCardExpiryMonth;
private int creditCardExpiryYear;
private boolean smoking;
private int beds;
public Booking() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, 1);
setCheckinDate(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 1);
setCheckoutDate(calendar.getTime());
}
public Booking(Hotel hotel, User user) {
this();
this.hotel = hotel;
this.user = user;
}
@Transient
public BigDecimal getTotal() {
return hotel.getPrice().multiply(new BigDecimal(getNights()));
}
@Transient
public int getNights() {
return (int) (checkoutDate.getTime() - checkinDate.getTime()) / 1000 / 60 / 60 / 24;
}
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
@Temporal(TemporalType.DATE)
@NotNull
@Future
public Date getCheckinDate() {
return checkinDate;
}
public void setCheckinDate(Date datetime) {
this.checkinDate = datetime;
}
@ManyToOne
public Hotel getHotel() {
return hotel;
}
public void setHotel(Hotel hotel) {
this.hotel = hotel;
}
@ManyToOne
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Basic
@Temporal(TemporalType.DATE)
@NotNull
@Future
public Date getCheckoutDate() {
return checkoutDate;
}
public void setCheckoutDate(Date checkoutDate) {
this.checkoutDate = checkoutDate;
}
@NotEmpty
public String getCreditCard() {
return creditCard;
}
public void setCreditCard(String creditCard) {
this.creditCard = creditCard;
}
@Transient
public String getDescription() {
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
return hotel == null ? null : hotel.getName() + ", " + df.format(getCheckinDate()) + " to "
+ df.format(getCheckoutDate());
}
public boolean isSmoking() {
return smoking;
}
public void setSmoking(boolean smoking) {
this.smoking = smoking;
}
public int getBeds() {
return beds;
}
public void setBeds(int beds) {
this.beds = beds;
}
@NotEmpty
public String getCreditCardName() {
return creditCardName;
}
public void setCreditCardName(String creditCardName) {
this.creditCardName = creditCardName;
}
public int getCreditCardExpiryMonth() {
return creditCardExpiryMonth;
}
public void setCreditCardExpiryMonth(int creditCardExpiryMonth) {
this.creditCardExpiryMonth = creditCardExpiryMonth;
}
public int getCreditCardExpiryYear() {
return creditCardExpiryYear;
}
public void setCreditCardExpiryYear(int creditCardExpiryYear) {
this.creditCardExpiryYear = creditCardExpiryYear;
}
@Override
public String toString() {
return "Booking(" + user + "," + hotel + ")";
}
}

View File

@@ -1,22 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Constraint(validatedBy = BookingDateRangeValidator.class)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface BookingDateRange {
String message() default "Invalid check-in and check-out date range";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@@ -1,19 +0,0 @@
package org.springframework.webflow.samples.booking;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class BookingDateRangeValidator implements ConstraintValidator<BookingDateRange, Booking> {
public void initialize(BookingDateRange bookingDateRange) {
}
public boolean isValid(Booking booking, ConstraintValidatorContext context) {
if ((booking.getCheckinDate() != null) && (booking.getCheckoutDate() != null)
&& booking.getCheckoutDate().before(booking.getCheckinDate())) {
return false;
}
return true;
}
}

View File

@@ -1,59 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.List;
/**
* A service interface for retrieving hotels and bookings from a backing repository. Also supports the ability to cancel
* a booking.
*/
public interface BookingService {
/**
* Find user by their username.
* @param username the user's username
* @return the user
*/
public User findUser(String username);
/**
* Find bookings made by the given user
* @param username the user's name
* @return their bookings
*/
public List<Booking> findBookings(String username);
/**
* Find hotels available for booking by some criteria.
* @param criteria the search criteria
* @return a list of hotels meeting the criteria
*/
public List<Hotel> findHotels(SearchCriteria criteria);
/**
* Find hotels by their identifier.
* @param id the hotel id
* @return the hotel
*/
public Hotel findHotelById(Long id);
/**
* Create a new, transient hotel booking instance for the given user.
* @param hotelId the hotelId
* @param userName the user name
* @return the new transient booking instance
*/
public Booking createBooking(Long hotelId, String userName);
/**
* Persist the booking to the database
* @param booking the booking
*/
public void persistBooking(Booking booking);
/**
* Cancel an existing booking.
* @param id the booking id
*/
public void cancelBooking(Long id);
}

View File

@@ -1,31 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.Calendar;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class BookingValidator implements Validator {
public boolean supports(Class clazz) {
return Booking.class.equals(clazz);
}
public void validate(Object obj, Errors errors) {
Booking booking = (Booking) obj;
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -1);
if (booking.getCreditCard() == null || "".equals(booking.getCreditCard())) {
errors.rejectValue("creditCard", null, "Credit card number must be provided");
}
if (booking.getCreditCardName() == null || "".equals(booking.getCreditCardName())) {
errors.rejectValue("creditCardName", null, "Credit card name must be provided");
}
if (booking.getCheckinDate() == null || booking.getCheckinDate().before(calendar.getTime())) {
errors.rejectValue("checkinDate", null, "Check in date must be a future date");
} else if (booking.getCheckoutDate() == null || !booking.getCheckinDate().before(booking.getCheckoutDate())) {
errors.rejectValue("checkoutDate", null, "Check out date must be later than check in date");
}
}
}

View File

@@ -1,107 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* A hotel where users may book stays.
*/
@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
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Column(precision = 6, scale = 2)
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Booking createBooking(User user) {
return new Booking(this, user);
}
@Override
public String toString() {
return "Hotel(" + name + "," + address + "," + city + "," + zip + ")";
}
}

View File

@@ -1,93 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
/**
* A JPA-based implementation of the Booking Service. Delegates to a JPA entity manager to issue data access calls
* against the backing repository. The EntityManager reference is provided by the managing container (Spring)
* automatically.
*/
@Service("bookingService")
@Repository
public class JpaBookingService implements BookingService {
private EntityManager em;
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
@Transactional(readOnly = true)
public User findUser(String username) {
return (User) em.createQuery("select u from User u where u.username = :username")
.setParameter("username", username).getSingleResult();
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Booking> findBookings(String username) {
if (username != null) {
return em.createQuery("select b from Booking b where b.user.username = :username order by b.checkinDate")
.setParameter("username", username).getResultList();
} else {
return null;
}
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Hotel> findHotels(SearchCriteria criteria) {
String pattern = getSearchPattern(criteria);
return em
.createQuery(
"select h from Hotel h where lower(h.name) like :pattern or lower(h.city) like :pattern "
+ " or lower(h.zip) like :pattern or lower(h.address) like :pattern")
.setParameter("pattern", pattern).setMaxResults(criteria.getPageSize())
.setFirstResult(criteria.getPage() * criteria.getPageSize()).getResultList();
}
@Transactional(readOnly = true)
public Hotel findHotelById(Long id) {
return em.find(Hotel.class, id);
}
@Transactional(readOnly = true)
public Booking createBooking(Long hotelId, String username) {
Hotel hotel = em.find(Hotel.class, hotelId);
User user = findUser(username);
return new Booking(hotel, user);
}
@Transactional
public void persistBooking(Booking booking) {
em.persist(booking);
}
@Transactional
public void cancelBooking(Long id) {
Booking booking = em.find(Booking.class, id);
if (booking != null) {
em.remove(booking);
}
}
// helpers
private String getSearchPattern(SearchCriteria criteria) {
if (StringUtils.hasText(criteria.getSearchString())) {
return "%" + criteria.getSearchString().toLowerCase().replace('*', '%') + "%";
} else {
return "%";
}
}
}

View File

@@ -1,68 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
/**
* A backing bean for the main hotel search form. Encapsulates the criteria needed to perform a hotel search.
*
* It is expected a future milestone of Spring Web Flow 2.0 will allow flow-scoped beans like this one to hold
* references to transient services that are restored automatically when the flow is resumed on subsequent requests.
* This would allow this SearchCriteria object to delegate to the {@link BookingService} directly, for example,
* eliminating the need for the actions in {@link MainActions}.
*/
public class SearchCriteria implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The user-provided search criteria for finding Hotels.
*/
private String searchString;
/**
* The maximum page size of the Hotel result list
*/
private int pageSize;
/**
* The current page of the Hotel result list.
*/
private int page;
public String getSearchString() {
return searchString;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public void nextPage() {
page++;
}
public void previousPage() {
page--;
}
public void resetPage() {
page = 0;
}
}

View File

@@ -1,59 +0,0 @@
package org.springframework.webflow.samples.booking;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* A user who can book hotels.
*/
@Entity
@Table(name = "Customer")
public class User implements Serializable {
private String username;
private String password;
private String name;
public User() {
}
public User(String username, String password, String name) {
this.username = username;
this.password = password;
this.name = name;
}
@Id
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User(" + username + ")";
}
}

View File

@@ -1,11 +0,0 @@
package org.springframework.webflow.samples.booking;
import org.springframework.webflow.mvc.portlet.AbstractFlowHandler;
public class ViewFlowHandler extends AbstractFlowHandler {
public String getFlowId() {
return "view";
}
}

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="bookingDatabase">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.springframework.webflow.samples.booking.User</class>
<class>org.springframework.webflow.samples.booking.Booking</class>
<class>org.springframework.webflow.samples.booking.Hotel</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
</properties>
</persistence-unit>
</persistence>

View File

@@ -1,28 +0,0 @@
insert into Customer (username, name) values ('keith', 'Keith')
insert into Customer (username, name) values ('erwin', 'Erwin')
insert into Customer (username, name) values ('jeremy', 'Jeremy')
insert into Customer (username, name) values ('scott', 'Scott')
insert into Customer (username, name) values ('pluto', 'Pluto')
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, 60, 'Jameson Inn', '890 Palm Bay Rd NE', 'Palm Bay', 'FL', '32905', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (3, 199, 'Chilworth Manor', 'The Cottage, Southampton Business Park', 'Southampton', 'Hants', 'SO16 7JF', 'UK')
insert into Hotel (id, price, name, address, city, state, zip, country) values (4, 120, 'Marriott Courtyard', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (5, 180, 'Doubletree', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (6, 450, 'W Hotel', 'Union Square, Manhattan', 'NY', 'NY', '10011', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (7, 450, 'W Hotel', 'Lexington Ave, Manhattan', 'NY', 'NY', '10011', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (8, 250, 'Hotel Rouge', '1315 16th Street NW', 'Washington', 'DC', '20036', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (9, 300, '70 Park Avenue Hotel', '70 Park Avenue', 'NY', 'NY', '10011', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (10, 300, 'Conrad Miami', '1395 Brickell Ave', 'Miami', 'FL', '33131', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (11, 80, 'Sea Horse Inn', '2106 N Clairemont Ave', 'Eau Claire', 'WI', '54703', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (12, 90, 'Super 8 Eau Claire Campus Area', '1151 W Macarthur Ave', 'Eau Claire', 'WI', '54701', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (13, 160, 'Marriot Downtown', '55 Fourth Street', 'San Francisco', 'CA', '94103', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (14, 200, 'Hilton Diagonal Mar', 'Passeig del Taulat 262-264', 'Barcelona', 'Catalunya', '08019', 'Spain')
insert into Hotel (id, price, name, address, city, state, zip, country) values (15, 210, 'Hilton Tel Aviv', 'Independence Park', 'Tel Aviv', '', '63405', 'Israel')
insert into Hotel (id, price, name, address, city, state, zip, country) values (16, 240, 'InterContinental Tokyo Bay', 'Takeshiba Pier', 'Tokyo', '', '105', 'Japan')
insert into Hotel (id, price, name, address, city, state, zip, country) values (17, 130, 'Hotel Beaulac', ' Esplanade L<>opold-Robert 2', 'Neuchatel', '', '2000', 'Switzerland')
insert into Hotel (id, price, name, address, city, state, zip, country) values (18, 140, 'Conrad Treasury Place', 'William & George Streets', 'Brisbane', 'QLD', '4001', 'Australia')
insert into Hotel (id, price, name, address, city, state, zip, country) values (19, 230, 'Ritz Carlton', '1228 Sherbrooke St', 'West Montreal', 'Quebec', 'H3G1H6', 'Canada')
insert into Hotel (id, price, name, address, city, state, zip, country) values (20, 460, 'Ritz Carlton', 'Peachtree Rd, Buckhead', 'Atlanta', 'GA', '30326', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (21, 220, 'Swissotel', '68 Market Street', 'Sydney', 'NSW', '2000', 'Australia')
insert into Hotel (id, price, name, address, city, state, zip, country) values (22, 250, 'Meli<EFBFBD> White House', 'Albany Street', 'Regents Park London', '', 'NW13UP', 'Great Britain')
insert into Hotel (id, price, name, address, city, state, zip, country) values (23, 210, 'Hotel Allegro', '171 West Randolph Street', 'Chicago', 'IL', '60601', 'USA')

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<logger name="org.springframework.samples" level="debug">
<appender-ref ref="STDOUT" />
</logger>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -1,2 +0,0 @@
Manifest-Version: 1.0

View File

@@ -1,11 +0,0 @@
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
# Enable web flow logging
log4j.category.org.springframework.webflow=DEBUG
log4j.category.org.springframework.js=DEBUG
log4j.category.org.springframework.binding=DEBUG
log4j.category.org.springframework.transaction=DEBUG

View File

@@ -1,44 +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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Activates annotation-based bean configuration -->
<context:annotation-config />
<!-- Scans for application @Components to deploy -->
<context:component-scan base-package="org.springframework.webflow.samples.booking" />
<!-- Instructs Spring to perfrom declarative transaction managemenet on annotated classes -->
<tx:annotation-driven />
<!-- Drives transactions using local JPA APIs -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Creates a EntityManagerFactory for use with the Hibernate JPA provider and a simple in-memory data source populated with test data -->
<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>
<!-- Deploys a in-memory "booking" datasource populated -->
<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>
</beans>

View File

@@ -1,49 +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:webflow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd">
<!-- Maps portlet modes to handlers -->
<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="portletModeMap">
<map>
<entry key="view">
<bean class="org.springframework.webflow.samples.booking.ViewFlowHandler" />
</entry>
</map>
</property>
</bean>
<!-- Maps logical view names selected by the url filename controller to .jsp view templates within the /WEB-INF directory -->
<bean id="internalJspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Enables FlowHandlers -->
<bean class="org.springframework.webflow.mvc.portlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor" />
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<webflow:flow-location path="/WEB-INF/flows/view/view.xml" />
<webflow:flow-location path="/WEB-INF/flows/main/main.xml" />
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>
<!-- Plugs in Spring's JSR-303 validator adapter -->
<webflow:flow-builder-services id="flowBuilderServices" development="true" validator="validator" />
<!-- Bootstraps JSR-303 validation and exposes it through Spring's Validator interface -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
</beans>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<secured attributes="ROLE_USER" />
<input name="hotelId" />
<on-start>
<evaluate expression="bookingService.createBooking(hotelId, currentUser.name)" result="flowScope.booking" />
</on-start>
<view-state id="enterBookingDetails" model="booking">
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
<view-state id="reviewBooking" model="booking">
<transition on="confirm" to="bookingConfirmed">
<evaluate expression="bookingService.persistBooking(booking)" />
</transition>
<transition on="revise" to="enterBookingDetails" />
<transition on="cancel" to="cancel" />
</view-state>
<end-state id="bookingConfirmed" commit="true" />
<end-state id="cancel"/>
</flow>

View File

@@ -1,142 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<h2>Book Hotel</h2>
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
</portlet:actionURL>
<form:form id="booking" modelAttribute="booking" action="${actionUrl}">
<spring:hasBindErrors name="booking">
<div class="error">
<spring:bind path="booking.*">
<c:forEach items="${status.errorMessages}" var="error">
<span><c:out value="${error}"/></span><br>
</c:forEach>
</spring:bind>
</div>
</spring:hasBindErrors>
<fieldset>
<table>
<tr class="field">
<td class="label">Name:</td>
<td class="output">${booking.hotel.name}</td>
</tr>
<tr class="field">
<td class="label">Address:</td>
<td class="output">${booking.hotel.address}</td>
</tr>
<tr class="field">
<td class="label">City, State:</td>
<td class="output">${booking.hotel.city}, ${booking.hotel.state}</td>
</tr>
<tr class="field">
<td class="label">Zip:</td>
<td class="output">${booking.hotel.zip}</td>
</tr>
<tr class="field">
<td class="label">Country:</td>
<td class="output">${booking.hotel.country}</td>
</tr>
<tr class="field">
<td class="label">Nightly rate:</td>
<td class="output">
<spring:bind path="booking.hotel.price">${status.value}</spring:bind>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="checkinDate">Check In Date:</label>
</td>
<td class="input">
<form:errors path="checkinDate" cssClass="errors"/>
<form:input path="checkinDate"/>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="checkoutDate">Check Out Date:</label>
</td>
<td class="input">
<form:errors path="checkoutDate" cssClass="errors"/>
<form:input path="checkoutDate"/>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="beds">Room Preference:</label>
</td>
<td class="input">
<form:select id="beds" path="beds">
<form:option label="One king-size bed" value="1"/>
<form:option label="Two double beds" value="2"/>
<form:option label="Three beds" value="3"/>
</form:select>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="smoking">Smoking Preference:</label>
</td>
<td class="input">
<form:radiobutton id="smoking" path="smoking" label="Smoking" value="true"/>
<form:radiobutton path="smoking" label="Non Smoking" value="false"/>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="creditCard">Credit Card #:</label>
</td>
<td class="input">
<form:errors path="creditCard" cssClass="errors"/>
<form:input id="creditCard" path="creditCard"/>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="creditCardName">Credit Card Name:</label>
</td>
<td class="input">
<form:errors path="creditCardName" cssClass="errors"/>
<form:input id="creditCardName" path="creditCardName"/>
</td>
</tr>
<tr class="field">
<td class="label">
<label for="creditCardExpiryMonth">Expiration Date:</label>
</td>
<td class="input">
<form:select id="creditCardExpiryMonth" path="creditCardExpiryMonth">
<form:option label="Jan" value="1"/>
<form:option label="Feb" value="2"/>
<form:option label="Mar" value="3"/>
<form:option label="Apr" value="4"/>
<form:option label="May" value="5"/>
<form:option label="Jun" value="6"/>
<form:option label="Jul" value="7"/>
<form:option label="Aug" value="8"/>
<form:option label="Sep" value="9"/>
<form:option label="Oct" value="10"/>
<form:option label="Nov" value="11"/>
<form:option label="Dec" value="12"/>
</form:select>
<form:select path="creditCardExpiryYear">
<form:option label="2008" value="1"/>
<form:option label="2009" value="2"/>
<form:option label="2010" value="3"/>
<form:option label="2011" value="4"/>
<form:option label="2012" value="5"/>
</form:select>
</td>
</tr>
<tr class="field">
<td colspan="2" class="buttonGroup">
<input type="submit" name="_eventId_proceed" value="Proceed"/>&#160;
<input type="submit" name="_eventId_cancel" value="Cancel"/>&#160;
</td>
</tr>
</table>
</fieldset>
</form:form>

View File

@@ -1,16 +0,0 @@
booking.checkinDate.NotNull=The check in date is required
booking.checkinDate.Future=The check in date must be in the future
booking.checkinDate.beforeToday=The check in date must be a future date
booking.checkinDate.typeMismatch=The check in date must be in the format mm-dd-yyyy
booking.checkoutDate.Future=The check out date must be in the future
booking.checkoutDate.NotNull=The check out date is required
booking.checkoutDate.typeMismatch=The check out date must be in the format mm-dd-yyyy
booking.BookingDateRange=The check out date must be later than the check in date
booking.creditCard.NotEmpty=The credit card must be a valid 16 digit number
booking.creditCardName.NotEmpty=The name on the credit card is required
NotEmpty=The {0} field is required
NotNull=The {0} field is required
Future=The {0} date must be in the future

View File

@@ -1,65 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<h2>Confirm Hotel Booking</h2>
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
</portlet:actionURL>
<form:form id="confirm" modelAttribute="booking" action="${actionUrl}">
<fieldset>
<table>
<tr class="field">
<td class="label">Name:</td>
<td class="output">${booking.hotel.name}</td>
</tr>
<tr class="field">
<td class="label">Address:</td>
<td class="output">${booking.hotel.address}</td>
</tr>
<tr>
<td class="label">City, State:</td>
<td class="output">${booking.hotel.city}, ${booking.hotel.state}</td>
</tr>
<tr class="field">
<td class="label">Zip:</td>
<td class="output">${booking.hotel.zip}</td>
</tr>
<tr class="field">
<td class="label">Country:</td>
<td class="output">${booking.hotel.country}</td>
</tr>
<tr class="field">
<td class="label">Total payment:</td>
<td class="output">
<spring:bind path="total">${status.value}</spring:bind>
</td>
</tr>
<tr class="field">
<td class="label">Check In Date:</td>
<td class="output">
<spring:bind path="checkinDate">${status.value}</spring:bind>
</td>
</tr>
<tr class="field">
<td class="label">Check Out Date:</td>
<td class="output">
<spring:bind path="checkoutDate">${status.value}</spring:bind>
</td>
</tr>
<tr class="field">
<td class="label">Credit Card #:</td>
<td class="output">${booking.creditCard}</td>
</tr>
<tr>
<td colspan="2" class="buttonGroup">
<input type="submit" name="_eventId_confirm" value="Confim"/>&#160;
<input type="submit" name="_eventId_revise" value="Revise"/>&#160;
<input type="submit" name="_eventId_cancel" value="Cancel"/>&#160;
</td>
</tr>
</table>
</fieldset>
</form:form>

View File

@@ -1,64 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
</portlet:actionURL>
<form:form modelAttribute="searchCriteria" action="${actionUrl}">
<h2>Search Hotels</h2>
<span class="errors">
<form:errors path="*"/>
</span>
<fieldset>
<label for="searchString">Search For:</label>
<form:input path="searchString"/>
<label for="pageSize">Maximum results:</label>
<form:select path="pageSize">
<form:option label="5" value="5"/>
<form:option label="10" value="10"/>
<form:option label="20" value="20"/>
</form:select>
<input type="submit" class="button" name="_eventId_search" value="Find Hotels" />
</fieldset>
</form:form>
<h2>Current Hotel Bookings</h2>
<table class="summary">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>City, State</th>
<th>Check in Date</th>
<th>Check out Date</th>
<th>Confirmation Number</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<c:forEach var="booking" items="${bookings}">
<tr>
<td>${booking.hotel.name}</td>
<td>${booking.hotel.address}</td>
<td>${booking.hotel.city}, ${booking.hotel.state}</td>
<td>${booking.checkinDate}</td>
<td>${booking.checkoutDate}</td>
<td>${booking.id}</td>
<td>
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
<portlet:param name="_eventId" value="cancelBooking" />
<portlet:param name="bookingId" value="${booking.id}" />
</portlet:actionURL>
<a href="${actionUrl}">Cancel</a>
</td>
</tr>
</c:forEach>
<c:if test="${empty bookings}">
<tr>
<td colspan="7">No booking history</td>
</tr>
</c:if>
</tbody>
</table>

View File

@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="searchCriteria" class="org.springframework.webflow.samples.booking.SearchCriteria" />
<view-state id="enterSearchCriteria" model="searchCriteria">
<on-render>
<evaluate expression="bookingService.findBookings(currentUser.name)" result="requestScope.bookings" />
</on-render>
<transition on="search" to="reviewHotels" >
<evaluate expression="searchCriteria.resetPage()" />
</transition>
<transition on="cancelBooking" to="cancelBooking" bind="false" />
</view-state>
<view-state id="reviewHotels">
<on-render>
<evaluate expression="bookingService.findHotels(searchCriteria)" result="requestScope.hotels" />
</on-render>
<transition on="previous">
<evaluate expression="searchCriteria.previousPage()" />
</transition>
<transition on="next">
<evaluate expression="searchCriteria.nextPage()" />
</transition>
<transition on="select" to="reviewHotel">
<set name="flowScope.hotelId" value="requestParameters.hotelId" type="long"/>
</transition>
<transition on="changeSearch" to="enterSearchCriteria" />
</view-state>
<view-state id="reviewHotel">
<on-render>
<evaluate expression="bookingService.findHotelById(hotelId)" result="requestScope.hotel" />
</on-render>
<transition on="book" to="bookHotel" />
<transition on="cancel" to="enterSearchCriteria" />
</view-state>
<subflow-state id="bookHotel" subflow="booking">
<input name="hotelId" />
<transition on="bookingConfirmed" to="finish" />
<transition on="cancel" to="enterSearchCriteria" />
</subflow-state>
<action-state id="cancelBooking">
<evaluate expression="bookingService.cancelBooking(requestParameters.bookingId)" />
<transition on="success" to="enterSearchCriteria" />
</action-state>
<end-state id="finish"/>
</flow>

View File

@@ -1,53 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<h2>View Hotel</h2>
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
</portlet:actionURL>
<form:form id="hotel" modelAttribute="hotel" action="${actionUrl}">
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<fieldset>
<table>
<tr class="field">
<td class="label">Name:</td>
<td class="output">${hotel.name}</td>
</tr>
<tr class="field">
<td class="label">Address:</td>
<td class="output">${hotel.address}</td>
</tr>
<tr class="field">
<td class="label">City:</td>
<td class="output">${hotel.city}</td>
</tr>
<tr class="field">
<td class="label">State:</td>
<td class="output">${hotel.state}</td>
</tr>
<tr class="field">
<td class="label">Zip:</td>
<td class="output">${hotel.zip}</td>
</tr>
<tr class="field">
<td class="label">Country:</td>
<td class="output">${hotel.country}</td>
</tr>
<tr class="field">
<td class="label">Nightly rate:</td>
<td class="output">
<spring:bind path="price">${status.value}</spring:bind>
</td>
</tr>
<tr class="field">
<td colspan="2" class="buttonGroup">
<input type="submit" name="_eventId_book" value="Book Hotel"/>&#160;
<input type="submit" name="_eventId_cancel" value="Back to Search"/>&#160;
</td>
</tr>
</table>
</fieldset>
</form:form>

View File

@@ -1,63 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<h2>Hotel Results</h2>
<portlet:actionURL var="changeSearchUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
<portlet:param name="_eventId" value="changeSearch" />
</portlet:actionURL>
<a href="${changeSearchUrl}">Change Search</a>
<table class="summary">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>City, State</th>
<th>Zip</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<c:forEach var="hotel" items="${hotels}">
<tr>
<td>${hotel.name}</td>
<td>${hotel.address}</td>
<td>${hotel.city}, ${hotel.state}, ${hotel.country}</td>
<td>${hotel.zip}</td>
<td>
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
<portlet:param name="_eventId" value="select" />
<portlet:param name="hotelId" value="${hotel.id}" />
</portlet:actionURL>
<a href="${actionUrl}">View Hotel</a>
</td>
</tr>
</c:forEach>
<c:if test="${empty hotels}">
<tr>
<td colspan="5">No hotels found</td>
</tr>
</c:if>
</tbody>
</table>
<c:if test="${searchCriteria.page > 0}">
<portlet:actionURL var="prevResultsUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
<portlet:param name="_eventId" value="previous" />
</portlet:actionURL>
<a href="${prevResultsUrl}">Previous Results</a>
</c:if>
<c:if test="${not empty hotels && fn:length(hotels) == searchCriteria.pageSize}">
<portlet:actionURL var="moreResultsUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
<portlet:param name="_eventId" value="next" />
</portlet:actionURL>
<a href="${moreResultsUrl}">More Results</a>
</c:if>

View File

@@ -1,28 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<h2>Welcome to Spring Travel</h2>
<p>
This reference application shows how to use Spring MVC and Web Flow together with JavaServerPages (JSP) in a portlet.
</p>
<p>
The key features illustrated in this sample include:
</p>
<ul>
<li>A declarative navigation model enabling full browser button support and dynamic navigation rules</li>
<li>A fine-grained state management model, including support for ConversationScope and ViewScope</li>
<li>Managed persistence contexts with the Java Persistence API (JPA)</li>
<li>Unified Expression Language (EL) integration</li>
<li>Declarative page authoring with JSP, JSTL, and Spring MVC's form tag library
<li>Exception handling support across all layers of the application</li>
<li>Spring IDE tooling integration, with support for graphical flow modeling and visualization</li>
</ul>
<p align="right">
<portlet:actionURL var="actionUrl">
<portlet:param name="execution" value="${flowExecutionKey}" />
<portlet:param name="_eventId" value="main" />
</portlet:actionURL>
<a href="${actionUrl}">
Start your Spring Travel experience
</a>
</p>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<view-state id="intro">
<transition on="main" to="main" />
</view-state>
<subflow-state id="main" subflow="main">
<transition to="finish" />
</subflow-state>
<end-state id="finish"/>
</flow>

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<portlet-name>swf-booking-mvc</portlet-name>
<display-name>Spring Webflow Booking MVC</display-name>
<portlet-class>
org.springframework.web.portlet.DispatcherPortlet
</portlet-class>
<init-param>
<name>contextConfigLocation</name>
<value>
/WEB-INF/config/hotelbooking-portlet-config.xml
</value>
</init-param>
<init-param>
<name>viewRendererUrl</name>
<value>/WEB-INF/servlet/view</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>Spring Webflow Booking MVC</title>
</portlet-info>
</portlet>
</portlet-app>

View File

@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
version="2.5">
<!--
- Location of the XML file that defines the root application context
- Applied by ContextLoaderListener.
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/application-config.xml
</param-value>
</context-param>
<!--
- Loads the root application context of this web app at startup.
- The application context is then available via
- WebApplicationContextUtils.getWebApplicationContext(servletContext).
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Supports view rendering -->
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
<!-- Generated Portlet Wrapper Servlet for Apache Pluto deployment -->
<servlet>
<servlet-name>swf-booking-mvc</servlet-name>
<servlet-class>org.apache.pluto.container.driver.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-name</param-name>
<param-value>swf-booking-mvc</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>swf-booking-mvc</servlet-name>
<url-pattern>/PlutoInvoker/swf-booking-mvc</url-pattern>
</servlet-mapping>
</web-app>

View File

@@ -1,9 +0,0 @@
log4j.rootCategory=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
# Enable web flow logging
log4j.category.org.springframework.webflow=DEBUG
log4j.category.org.springframework.binding=DEBUG

View File

@@ -11,8 +11,6 @@
<modules>
<module>booking-mvc</module>
<module>booking-faces</module>
<module>booking-portlet-mvc</module>
<module>booking-portlet-faces</module>
<module>primefaces-showcase</module>
<module>webflow-showcase</module>
</modules>