[jboss-cvs] jboss-seam/examples/booking/view/exp ...

Michael Yuan michael.yuan at jboss.com
Tue Jul 25 13:38:20 EDT 2006


  User: myuan   
  Date: 06/07/25 13:38:20

  Modified:    examples/booking/view/exp      bookingExp.html
                        confirmExp.html introExp.html loginExp.html
                        mainExp.html
  Log:
  Update the explanation docs
  
  Revision  Changes    Path
  1.3       +107 -93   jboss-seam/examples/booking/view/exp/bookingExp.html
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: bookingExp.html
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/booking/view/exp/bookingExp.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- bookingExp.html	15 Apr 2006 23:27:11 -0000	1.2
  +++ bookingExp.html	25 Jul 2006 17:38:20 -0000	1.3
  @@ -28,7 +28,9 @@
   
       <p>
          The hotel booking "wizard" is implemented by a conversation-scoped
  -       stateful session bean. The <code>HotelBookingAction</code> maintains
  +       stateful session bean. All Seam components are in the 
  +       conversation scope by default. 
  +       The <code>HotelBookingAction</code> maintains
          state associated with the booking process in the Seam conversation
          scope. This ensures that if the user is working in multiple brower
          tabs or multiple brower windows, the various conversations are
  @@ -38,12 +40,13 @@
          To see this working in practice, right click on the "View Hotel" button 
          in the search screen and select "open in new tab" or "open in new window",
          and try working on multiple hotel bookings simultaneously.
  +       In the <a href="workspaceExp.html"/>next step</a>, we will discuss
  +       Seam's built-in components to manage multiple concurrent conversations.
       </p>
       
   <code class="block">
   @Stateful
   @Name("hotelBooking")
  - at Conversational(ifNotBegunOutcome="main")
   @LoggedIn
   public class HotelBookingAction implements HotelBooking
   {
  @@ -56,34 +59,29 @@
      
      @In(required=false) 
      @Out(required=false)
  -   @Valid
      private Booking booking;
      
      @In
      private User user;
      
      @In(create=true)
  -   private transient FacesMessages facesMessages;
  +   private FacesMessages facesMessages;
         
  -   @In(required=false)
  -   private BookingList bookingList;
  +   @In(create=true)
  +   private Events events;
  +      
  +   @In 
  +   private HotelSearching hotelSearch;
      
  -   @RequestParameter
  -   private Long hotelId; 
  +   @Logger 
  +   private Log log;
      
      @Begin
      public String selectHotel()
      {
  -      if (hotelId!=null)
  -      {
  -         hotel = em.find(Hotel.class, hotelId);
  +      hotel = em.merge( hotelSearch.getSelectedHotel() );
            return "hotel";
         }
  -      else
  -      {
  -         return null;
  -      }
  -   }
      
      public String bookHotel()
      {      
  @@ -96,7 +94,6 @@
         return "book";
      }
   
  -   @IfInvalid(outcome=REDISPLAY)
      public String setBookingDetails()
      {
         if (booking==null || hotel==null) return "main";
  @@ -116,9 +113,9 @@
      {
         if (booking==null || hotel==null) return "main";
         em.persist(booking);
  -      if (bookingList!=null) bookingList.refresh();
         facesMessages.add("Thank you, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}");
  -      //hotels=null;
  +      log.info("New booking: #{booking.id} for #{user.username}");
  +      events.raiseEvent("bookingConfirmed");
         return "confirmed";
      }
      
  @@ -134,11 +131,28 @@
   }</code>
   
       <p>
  -       The conversation begins when <code>selectHotel()</code> is called, and ends when 
  -       <code>confirm()</code> or <code>cancel()</code> is called.
  +       The conversation begins when the <code>@Begin</code> annotated
  +       <code>selectHotel()</code> is called, and ends when 
  +       the <code>@End</code> annotated 
  +       <code>confirm()</code> or <code>cancel()</code> is called. Between the
  +       <code>@Begin</code> and <code>@End</code> methods, the user can do
  +       any number of things with the application (i.e., invoke any 
  +       event handler method or use the BACK button etc.) and the 
  +       <code>hotelBooking</code> maintains its state throughout the process.
  +       When the <code>@End</code> method is called, Seam destroys this
  +       component and avoids any memory leak.
       </p>
   
       <p>
  +      However, none of the <code>HotelBookingAction</code> bean methods 
  +      may be called outside of a long-running conversation. 
  +      So if we try to use the 
  +      back button after the end of the conversation, Seam will redirect to the main page, with an 
  +      error message.
  +   </p>
  +
  +
  +    <p>
          <center>
          <form>
             <INPUT type="button" value="Close Window" onClick="window.close()">
  
  
  
  1.2       +28 -8     jboss-seam/examples/booking/view/exp/confirmExp.html
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: confirmExp.html
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/booking/view/exp/confirmExp.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- confirmExp.html	31 Mar 2006 11:49:54 -0000	1.1
  +++ confirmExp.html	25 Jul 2006 17:38:20 -0000	1.2
  @@ -53,8 +53,9 @@
      {
         if (booking==null || hotel==null) return "main";
         em.persist(booking);
  -      if (bookingList!=null) bookingList.refresh();
         facesMessages.add("Thank you, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}");
  +      log.info("New booking: #{booking.id} for #{user.username}");
  +      events.raiseEvent("bookingConfirmed");
         return "confirmed";
      }
      
  @@ -75,12 +76,31 @@
      </p>
      
      <p>
  -      The <code>HotelBookingAction</code> bean is marked <code>@Conversational</code>. This means that
  -      none of its methods may be called outside of a long-running conversation. So if we try to use the 
  -      back button after the end of the conversation, Seam will redirect to the main page, with an 
  -      error message.
  +      Notice that the <code>HotelBookingAction.confirm()</code> method
  +      raises a <code>bookingConfirmed</code> event before it finishes. The
  +      event mechanism allows Seam components to communicate with each other
  +      without direct coupling. In this case, the <code>BookingListAction</code>
  +      component captures the <code>bookingConfirmed</code> event and refreshes
  +      the existing booking list for the current user.
      </p>
   
  +<code class="block">
  +public class BookingListAction implements BookingList, Serializable
  +{
  +
  +   ... ...
  +   
  +   @Factory
  +   @Observer("bookingConfirmed")
  +   public void getBookings()
  +   {
  +      bookings = em.createQuery("from Booking b where b.user.username = :username order by b.checkinDate")
  +            .setParameter("username", user.getUsername())
  +            .getResultList();
  +   }
  +}
  +</code>
  +   
      <p>
         <center>
         <form>
  
  
  
  1.2       +4 -2      jboss-seam/examples/booking/view/exp/introExp.html
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: introExp.html
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/booking/view/exp/introExp.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- introExp.html	31 Mar 2006 11:49:54 -0000	1.1
  +++ introExp.html	25 Jul 2006 17:38:20 -0000	1.2
  @@ -52,11 +52,13 @@
          Like all JBoss software, this entire software stack is free. The full source code of this 
          sample application is available in the <code>examples/booking</code> directory of the 
          <a href="http://www.jboss.com/products/list/downloads#seam">Seam distribution</a>. 
  +       <!--
          There is even a  
          <a target="_blank" href="http://docs.jboss.com/TrailBlazer/seam-booking/Seam.htm">
             10-minute flash demo 
          </a>
          showing how to build a Seam web application from ground up.
  +       -->
       </p>
   
       <p>
  
  
  
  1.3       +5 -1      jboss-seam/examples/booking/view/exp/loginExp.html
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: loginExp.html
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/booking/view/exp/loginExp.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- loginExp.html	15 Apr 2006 23:27:11 -0000	1.2
  +++ loginExp.html	25 Jul 2006 17:38:20 -0000	1.3
  @@ -58,7 +58,11 @@
          The <code>User</code> enity bean is mapped to the Seam  
          context variable named <code>user</code> bean via the 
          <code>@Name</code> annotation. <code>User</code> is
  -       a session scoped bean.
  +       a session scoped bean, meaning that the <code>user</code>
  +       component value is retained for the entire session for
  +       each user. You might also notice there are validation annotation
  +       on the data properties. We will discuss those annotations in the
  +       <a href="registerExp.html">next step</a>.
       </p>
   
   <code class="block">
  
  
  
  1.4       +37 -18    jboss-seam/examples/booking/view/exp/mainExp.html
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: mainExp.html
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/booking/view/exp/mainExp.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -b -r1.3 -r1.4
  --- mainExp.html	15 Apr 2006 23:27:11 -0000	1.3
  +++ mainExp.html	25 Jul 2006 17:38:20 -0000	1.4
  @@ -70,6 +70,8 @@
      
      @DataModel
      private List&lt;Hotel&gt; hotels;
  +   @DataModelSelection
  +   private Hotel selectedHotel;
      
      public String find()
      {
  @@ -82,6 +84,11 @@
         return "main";
      }
      
  +   public Hotel getSelectedHotel()
  +   {
  +      return selectedHotel;
  +   }
  +   
      public int getPageSize() {
         return pageSize;
      }
  @@ -112,6 +119,13 @@
          returns, Seam outjects an instance of <code>ListDataModel</code> to a context
          variable named <code>hotels</code>. So, when the search page is re-rendered, the
          result list is available to the JSF <code>dataTable</code>.
  +       Each row of the data table has an associated command button or link 
  +       (see below). When the user
  +       clicks on the button / link, the <code>Hotel</code> represented by that
  +       row is injected into the <code>hotel</code> field annotated by the
  +       <code>@DataModelSelection</code> annotation. Other application components
  +       can then access the selected hotel via the
  +       <code>HotelSearching.selectedHotel</code> property.
       </p>
   
   <code class="block">
  @@ -141,36 +155,41 @@
   </code>
   
       <p>
  -       The "View Hotel" link is implemented using a Seam <code>&lt;s:actionLink></code>.
  +       The "View Hotel" link is the above mentioned command link associated
  +       with each row of the data table. It is implemented 
  +       using a Seam <code>&lt;s:Link></code>, which is part of Seam's 
  +       extension of JSF controls.
          This JSF control let's us call an action, and pass a request parameter, without 
  -       submitting any JSF form. The advantage of <code>&lt;s:actionLink></code> is that, 
  +       submitting any JSF form. The advantage of <code>&lt;s:link></code> is that, 
          unlike a standard JSF <code>&lt;h:commandLink></code>, there is no JavaScript 
          used, so "open link in new tab" works seamlessly.
       </p>
       <p>
          When this link is clicked, the <code>selectHotel()</code> method of the
  -       <code>HotelBookingAction</code> bean is called and, after injecting the
  -       value of the request parameter, the hotel is fetched from the database, 
  -       and a Seam conversation begins!
  +       <code>HotelBookingAction</code> bean is called. It gets the selected
  +       hotel from the <code>HotelSearching.selectedHotel</code> property,
  +       merges it to the current persistence context (in case the same
  +       hotel has been accessed before in the same session),
  +       and starts a Seam conversation. We will discuss Seam conversations
  +       in the next step.
       </p>
   
   <code class="block">
  -   @RequestParameter
  -   private Long hotelId; 
  + at Stateful
  + at Name("hotelBooking")
  + at LoggedIn
  +public class HotelBookingAction implements HotelBooking
  +{
  +
  +   ... ...
      
      @Begin
      public String selectHotel()
      {
  -      if (hotelId!=null)
  -      {
  -         hotel = em.find(Hotel.class, hotelId);
  +      hotel = em.merge( hotelSearch.getSelectedHotel() );
            return "hotel";
         }
  -      else
  -      {
  -         return null;
  -      }
  -   }
  +}
   </code>
   
      <p>
  
  
  



More information about the jboss-cvs-commits mailing list