This commit is contained in:
Keith Donald
2007-08-21 06:54:15 +00:00
parent 1cb556c215
commit 1e9baf44b5
9 changed files with 116 additions and 1 deletions

View File

@@ -16,6 +16,9 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
/**
* A Hotel Booking made by a User.
*/
@Entity
public class Booking implements Serializable {
private Long id;

View File

@@ -2,13 +2,38 @@ package org.springframework.webflow.samples.booking.app;
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 searchString the search query string to filter hotels by name
* @param pageSize the page size
* @param page the current page
* @return a list of hotels not exceeding the page size
*/
public List<Hotel> findHotels(String searchString, int pageSize, int page);
/**
* Find hotels by their identifier.
* @param id the hotel id
* @return the hotel
*/
public Hotel findHotelById(Long id);
/**
* Cancel an existing booking.
* @param id the booking id
*/
public void cancelBooking(Long id);
}

View File

@@ -8,6 +8,9 @@ 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;

View File

@@ -9,6 +9,11 @@ import org.springframework.stereotype.Repository;
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.
*/
@Repository
public class JpaBookingService implements BookingService {
@@ -42,6 +47,7 @@ public class JpaBookingService implements BookingService {
return em.find(Hotel.class, id);
}
// this one is a read/write transaction
@Transactional
public void cancelBooking(Long id) {
Booking booking = em.find(Booking.class, id);

View File

@@ -6,6 +6,9 @@ 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 {

View File

@@ -13,8 +13,24 @@ import org.springframework.webflow.samples.booking.app.Booking;
import org.springframework.webflow.samples.booking.app.Hotel;
import org.springframework.webflow.samples.booking.app.User;
/**
* Actions invoked by the booking flow. These actions are extensions of the flow definition, called by the flow
* definition at the appropriate points. Actions allow an externalized flow definition to delegate out to Java code to
* perform processing.
*/
public class BookingActions extends MultiAction {
/**
* Create a new booking object and register it with the flow-managed entity manager. The booking is not actually
* flushed to the database at this time; that only occurs when the booking flow reaches its "bookingAuthorized"
* end-state, which is a "commit" state.
*
* It is expected a future milestone of Spring Web Flow 2.0 will support Flows being defined fully in Java and
* Groovy, allowing logic like this to be defined with the flow definition and without the attribute lookup code you
* see here.
* @param context the current flow execution request context
* @return success if the booking was created successfully.
*/
public Event createBooking(RequestContext context) {
Hotel hotel = (Hotel) context.getFlowScope().get("hotel");
User user = (User) context.getConversationScope().get("user");
@@ -25,7 +41,15 @@ public class BookingActions extends MultiAction {
return success();
}
public Event validateBooking(RequestContext context) throws Exception {
/**
* Perform some custom server-side validation on the flow-scoped Booking object updated by the booking form.
*
* It is expected a future milestone of Spring Web Flow 2.0 will add a Messages abstraction that decouples SWF
* artifacts from environment-specific constructs like the FacesContext.
* @param context the current flow execution request context
* @return success if validation was successful, error if not
*/
public Event validateBooking(RequestContext context) {
Booking booking = (Booking) context.getFlowScope().get("booking");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -1);

View File

@@ -11,20 +11,40 @@ import org.springframework.webflow.samples.booking.app.Hotel;
import org.springframework.webflow.samples.booking.app.User;
import org.springframework.webflow.samples.booking.web.util.SerializableListDataModel;
/**
* Actions invoked by the main flow. These actions are extensions of the flow definition, called by the flow definition
* at the appropriate points. Actions allow an externalized flow definition to delegate out to Java code to perform
* processing.
*/
public class MainActions extends MultiAction {
private BookingService bookingService;
/**
* Constructs a new multi-action for the main flow that will delegate to the provided booking service
* @param bookingService the booking service
*/
public MainActions(BookingService bookingService) {
this.bookingService = bookingService;
}
/**
* Simply put a dummy user in conversation scope to simulate a user login. In the future this sample may add user
* authentication support.
* @param context the current flow execution request context
* @return success
*/
public Event initCurrentUser(RequestContext context) {
User user = new User("springer", "springrocks", "Springer");
context.getConversationScope().put("user", user);
return success();
}
/**
* Find all active bookings made by the current user.
* @param context the current flow execution request context
* @return success
*/
public Event findCurrentUserBookings(RequestContext context) {
User user = (User) context.getConversationScope().get("user");
List<Booking> bookings = bookingService.findBookings(user.getUsername());
@@ -32,6 +52,11 @@ public class MainActions extends MultiAction {
return success();
}
/**
* Find all hotels that meet the current search criteria in flow scope.
* @param context the current flow execution request context
* @return success
*/
public Event findHotels(RequestContext context) {
SearchCriteria search = (SearchCriteria) context.getFlowScope().get("searchCriteria");
List<Hotel> hotels = bookingService

View File

@@ -4,6 +4,16 @@ import java.io.Serializable;
import javax.faces.event.ActionEvent;
import org.springframework.webflow.samples.booking.app.BookingService;
/**
* 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;
@@ -23,14 +33,23 @@ public class SearchCriteria implements Serializable {
*/
private int page;
/**
* Increase the current page
*/
public void nextPageListener(ActionEvent event) {
page++;
}
/**
* Decrease the current page
*/
public void prevPageListener(ActionEvent event) {
page--;
}
/**
* Signal that a find is about to occur and reset the page size to 0.
*/
public void findHotelsListener(ActionEvent event) {
page = 0;
}

View File

@@ -7,6 +7,9 @@ import javax.faces.model.DataModel;
import javax.faces.model.DataModelEvent;
import javax.faces.model.DataModelListener;
/**
* A simple List-to-JSF-DataModel adapter that is also serializable.
*/
public class SerializableListDataModel extends DataModel implements Serializable {
private static final long serialVersionUID = 1L;
@@ -19,6 +22,10 @@ public class SerializableListDataModel extends DataModel implements Serializable
super();
}
/**
* Adapt the list to a data model;
* @param list the list
*/
public SerializableListDataModel(List list) {
if (list == null)
throw new NullPointerException("list");