The Library

   

In this section, we turn the book viewer into a library, shown in Figure 8-7.

Figure 8-7. Library Implemented with JSF and Tiles

graphics/08fig07.jpg


The library application shown in Figure 8-7 contains a menu at the top of the page that lets you select a book, either Alice in Wonderland or Peter Pan. The rest of the application works like the book viewer we've discussed throughout this chapter.

The library employs two Tiles techniques that are of interest to us: nesting tiles and using tile controllers.

Nested Tiles

The library shown in Figure 8-7 contains a book viewer. So does the library tile:

 

 <definition name="book">     ... </definition> <definition name="library" path="/libraryLayout.jsp"       controller>    <put name="header"  value="/bookSelector.jsp"/>    <put name="book" value="book"/> </definition> 

Notice the value for the book attribute it's a tile, not a JSP page. Using a tile name instead of a JSP page lets you nest tiles, as we did by nesting the book tile in the library.

Tile Controllers

In our book viewer application, we had one managed bean named book see "The Book Viewer" on page 318 for more information about the book bean. The library, on the other hand, must be aware of more than one book.

In this section with a sleight of hand we show you how to support multiple books without having to change the book viewer. The book viewer will continue to manipulate a book bean, but that bean will no longer be a managed bean. Instead, it will be the book that was last selected in the library's pull-down menu at the top of the page.

We accomplish that sleight of hand with a Tiles controller. Tiles lets you attach a Java object, known as a tile controller, to a tile. That object's class must implement the org.apache.struts.tiles.Controller interface, which defines a single perform method. Tiles invokes that method just before it loads the controller's associated tile. Tile controllers have access to their tile's context, which lets the controller access the tile's attributes or create new attributes.

We attach a controller to the library tile. The controller looks for a library attribute in session scope. If the library's not there, the controller creates a library and stores it in session scope. The controller then consults the library's selectedBook property to see if a book has been selected. If so, the controller sets the value of the book session attribute to the selected book. If there is no selected book, the controller sets the book attribute to Alice in Wonderland. Subsequently, when the library tile is loaded, the book viewer accesses the selected book. The controller is listed in Listing 8-19 on page 345.

Figure 8-8 shows the directory structure for the library application. For brevity, we left out the book HTML files.

Figure 8-8. Library Directory Structure

graphics/08fig08.jpg


The files shown in Figure 8-8 are listed in Listing 8-14 through Listing 8-27, with the exception of the HTML files. As you look through those listings, note the effort required to add a new book. All you have to do is modify the constructor in Library.java see Listing 8-18 on page 343 to create your book and add it to the book map. You could even implement the Library class so that it reads XML book definitions. That way, you could add books without any programming. Digesting XML is an easy task with Tiles's distant cousin, the Apache Commons Digester. See http://jakarta.apache.org/commons/digester/ for more information about the Digester.

Listing 8-14. library/library.jsp
  1. <html>  2.    <%@ taglib uri="http://java.sun.com/jsf/core"  prefix="f" %>  3.    <%@ taglib uri="http://java.sun.com/jsf/html"  prefix="h" %>  4.    <%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>  5.  6.    <f:view>  7.       <head>  8.          <link href="styles.css" rel="stylesheet" type="text/css"/>  9.          <f:loadBundle basename="com.corejsf.messages" var="msgs"/> 10.          <title><h:outputText value="#{msgs.libraryWindowTitle}"/></title> 11.       </head> 12.       <body> 13.          <f:subview > 14.             <h:form> 15.                <tiles:insert definition="library" flush="false"/> 16.             </h:form> 17.          </f:subview> 18.       </body> 19.    </f:view> 20. </html> 

Listing 8-15. library/WEB-INF/tiles.xml
  1. <!DOCTYPE tiles-definitions PUBLIC  2.  "-//Apache Software Foundation//DTD Tiles Configuration//EN"  3.  "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">  4.  5. <tiles-definitions>  6.    <definition name="menu-header-content" path="/headerMenuContentLayout.jsp">  7.       <put name="gridClass"           value="headerMenuContent"/>  8.       <put name="headerClass"         value="header"/>  9.       <put name="menuColumnClass"     value="menuColumn"/> 10.       <put name="contentColumnClass"  value="contentColumn"/> 11.    </definition> 12. 13.    <definition name="book" extends="menu-header-content"> 14.       <put name="header"  value="/bookHeader.jsp"/> 15.       <put name="menu"    value="/bookMenu.jsp"/> 16.       <put name="content" value="/bookContent.jsp"/> 17.    </definition> 18. 19.    <definition name="library" path="/libraryLayout.jsp" 20.                    controller> 21.       <put name="header"  value="/bookSelector.jsp"/> 22.       <put name="book" value="book"/> 23.    </definition> 24. </tiles-definitions> 

Listing 8-16. library/libraryLayout.jsp
  1. <%@ taglib uri="http://java.sun.com/jsf/core"  prefix="f" %>  2. <%@ taglib uri="http://java.sun.com/jsf/html"  prefix="h" %>  3. <%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>  4.  5. <h:panelGrid columns="1" style header>  6.    <f:facet name="header">  7.       <f:subview >  8.          <tiles:insert attribute="header" flush="false"/>  9.       </f:subview> 10.    </f:facet> 11. 12.    <f:subview > 13.       <tiles:insert attribute="book" flush="false"/> 14.    </f:subview> 15. </h:panelGrid> 

Listing 8-17. library/bookSelector.jsp
  1. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>  2. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>  3.  4. <h:outputText value="#{msgs.selectABookPrompt}"/>  5.  6. <f:verbatim>&nbsp;&nbsp;</f:verbatim>  7.  8. <h:selectOneMenu onchange="submit()" value="#{library.book}"  9.       valueChangeListener="#{library.bookSelected}"> 10.    <f:selectItems value="#{library.bookItems}"/> 11. </h:selectOneMenu> 

Listing 8-18. library/WEB-INF/classes/com/corejsf/Library.java
  1. package com.corejsf;  2.  3. import java.util.*;  4. import javax.faces.model.SelectItem;  5. import javax.faces.event.ValueChangeEvent;  6.  7. public class Library {  8.    private Map bookMap = new HashMap();  9.    private Book initialBook = null; 10.    private List bookItems = null; 11.    private String book = null; 12.    private String selectedBook = null; 13. 14.    public Library() { 15.       Book peterpan = new Book(); 16.       Book aliceInWonderland = new Book(); 17. 18.       initialBook = peterpan; 19. 20.       aliceInWonderland.setDirectory("books/aliceInWonderland"); 21.       aliceInWonderland.setTitleKey("aliceInWonderland"); 22.       aliceInWonderland.setImage("books/aliceInWonderland/cheshire.jpg"); 23.       aliceInWonderland.setNumChapters(12); 24. 25.       peterpan.setDirectory("books/peterpan"); 26.       peterpan.setTitleKey("peterpan"); 27.       peterpan.setImage("books/peterpan/peterpan.jpg"); 28.       peterpan.setNumChapters(15); 29. 30.       bookMap.put("aliceInWonderland", aliceInWonderland); 31.       bookMap.put("peterpan", peterpan); 32.    } 33.    public void setBook(String book) { this.book = book; } 34.    public String getBook() { return book; } 35. 36.    public Map getBooks() { 37.       return bookMap; 38.    } 39.    public void bookSelected(ValueChangeEvent e) { 40.       selectedBook = (String) e.getNewValue(); 41.    } 42.    public Book getSelectedBook() { 43.       return selectedBook != null ? (Book) bookMap.get(selectedBook) : 44.                                             initialBook; 45.    } 46.    public List getBookItems() { 47.       if(bookItems == null) { 48.           bookItems = new LinkedList(); 49.           Iterator it = bookMap.values().iterator(); 50.           while(it.hasNext()) { 51.              Book book = (Book)it.next(); 52.              bookItems.add(new SelectItem(book.getTitleKey(), 53.                                           getBookTitle(book.getTitleKey()))); 54.           } 55.       } 56.       return bookItems; 57.    } 58.    private String getBookTitle(String key) { 59.       return com.corejsf.util.Messages. 60.                        getString("com.corejsf.messages", key, null); 61.    } 62. } 

Listing 8-19. library/WEB-INF/classes/com/corejsf/LibraryTileController.java
  1. package com.corejsf;  2.  3.  4. import java.io.IOException;  5. import javax.servlet.ServletContext;  6. import javax.servlet.ServletException;  7. import javax.servlet.http.HttpServletRequest;  8. import javax.servlet.http.HttpServletResponse;  9. import javax.servlet.http.HttpSession; 10. import org.apache.struts.tiles.ComponentContext; 11. import org.apache.struts.tiles.Controller; 12. 13. public class LibraryTileController implements Controller { 14.    public void perform(ComponentContext tilesContext, 15.                        HttpServletRequest request, HttpServletResponse response, 16.                        ServletContext context) 17.                                         throws IOException, ServletException { 18.       HttpSession session = request.getSession(); 19. 20.       String chapter = (String) request.getParameter("chapter"); 21.       session.setAttribute("chapter", chapter == null || "".equals(chapter) ? 22.                            "chapter1" : chapter); 23. 24.       Library library = (Library) session.getAttribute("library"); 25. 26.       if(library == null) { 27.          library = new Library(); 28.          session.setAttribute("library", library); 29.       } 30. 31.       Book selectedBook = library.getSelectedBook(); 32.       if(selectedBook != null) { 33.          session.setAttribute("book", selectedBook); 34.       } 35.    } 36. } 

Listing 8-20. library/WEB-INF/classes/com/corejsf/Book.java
  1. package com.corejsf;  2.  3. import java.util.LinkedList;  4. import java.util.List;  5.  6. public class Book {  7.    private String titleKey;  8.    private String image;  9.   private String directory; 10.    private int numChapters; 11.    private List chapterKeys = null; 12. 13.    // PROPERTY: titleKey 14.    public void setTitleKey(String titleKey) { this.titleKey = titleKey; } 15.    public String getTitleKey() { return titleKey; } 16. 17.    // PROPERTY: image 18.    public void setImage(String image) { this.image = image; } 19.    public String getImage() { return image; } 20. 21.    // PROPERTY: directory 22.    public void setDirectory(String directory) { this.directory = directory; } 23.    public String getDirectory() { return directory; } 24. 25.    // PROPERTY: numChapters 26.    public void setNumChapters(int numChapters) { this.numChapters = numChapters; } 27.    public int getNumChapters() { return numChapters; } 28. 29.    // PROPERTY: chapterKeys 30.    public List getChapterKeys() { 31.       if(chapterKeys == null) { 32.          chapterKeys = new LinkedList(); 33.          for(int i=1; i <= numChapters; ++i) 34.             chapterKeys.add("chapter" + i); 35.       } 36.       return chapterKeys; 37.    } 38. } 

Listing 8-21. library/bookHeader.jsp
 1. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 2. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 3. 4. <h:panelGrid columns="1" style> 5.    <h:graphicImage value="#{book.image}"/> 6.    <h:outputText value="#{msgs[book.titleKey]}" style/> 7.    <f:verbatim><hr></f:verbatim> 8. </h:panelGrid> 

Listing 8-22. library/bookMenu.jsp
  1. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>  2. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>  3.  4. <h:dataTable value="#{book.chapterKeys}" var="chapterKey"  5.         style columnClasses="linksColumn">  6.    <h:column>  7.       <h:commandLink>  8.          <h:outputText value="#{msgs[chapterKey]}"/>  9.          <f:param name="chapter" value="#{chapterKey}"/> 10.       </h:commandLink> 11.    </h:column> 12. </h:dataTable> 

Listing 8-23. library/bookContent.jsp
 1. <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> 2. 3. <c:import url="${book.directory}/${chapter}.html"/> 

Listing 8-24. library/styles.css
  1. .library {  2.    vertical-align: top;  3.    width: 100%;  4.    height: 100%;  5. }  6. .libraryHeader {  7.    width: 100%;  8.    text-align: left;  9.    vertical-align: top; 10.    background-color: #ddd; 11.    font-weight: lighter; 12.    border: thin solid #777; 13. } 14. .bookHeader { 15.    width: 100%; 16.    text-align: center; 17.    background-color: #eee; 18.    border: thin solid CornflowerBlue; 19. } 20. .bookTitle { 21.    text-align: center; 22.    font-style: italic; 23.    font-size: 1.3em; 24.    font-family: Helvetica; 25. } 26. .menuColumn { 27.    vertical-align: top; 28.    background-color: #eee; 29.    border: thin solid #777; 30. } 31. .chapterColumn { 32.    vertical-align: top; 33.    text-align: left; 34.    width: *; 35.    padding: 3px; 36. } 37. .contentColumn { 38.    vertical-align: top; 39.    text-align: left; 40.    width: *; 41. } 42. .links { 43.    width: 85px; 44.    vertical-align: top; 45.    text-align: center; 46. } 47. .linksColumn { 48.    vertical-align: top; 49.    text-align: center; 50. } 

Listing 8-25. library/WEB-INF/faces-config.xml
 1. <?xml version="1.0"?> 2. 3. <!DOCTYPE faces-config PUBLIC 4.   "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" 5.   "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> 6. 7. <faces-config> 8. 9. </faces-config> 

Listing 8-26. library/WEB-INF/web.xml
  1. <?xml version="1.0"?>  2. <!DOCTYPE web-app PUBLIC  3.    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  4.    "http://java.sun.com/dtd/web-app_2_3.dtd">  5. <web-app>  6.    <servlet>  7.       <servlet-name>Tiles Servlet</servlet-name>  8.       <servlet-class>org.apache.struts.tiles.TilesServlet</servlet-class>  9.       <init-param> 10.          <param-name>definitions-config</param-name> 11.          <param-value>/WEB-INF/tiles.xml</param-value> 12.       </init-param> 13.       <load-on-startup>2</load-on-startup> 14.    </servlet> 15. 16.    <servlet> 17.       <servlet-name>Faces Servlet</servlet-name> 18.       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 19.       <load-on-startup>1</load-on-startup> 20.    </servlet> 21. 22.    <servlet-mapping> 23.       <servlet-name>Faces Servlet</servlet-name> 24.       <url-pattern>*.faces</url-pattern> 25.    </servlet-mapping> 26. 27.    <welcome-file-list> 28.       <welcome-file>index.html</welcome-file> 29.    </welcome-file-list> 30. </web-app> 

Listing 8-27. library/classes/com/corejsf/messages.properties
  1. libraryWindowTitle=Gutenberg Library  2. aliceInWonderland=Alice in Wonderland  3. peterpan=Peter Pan  4. selectABookPrompt=Select a book  5.  6. chapter1=Chapter 1  7. chapter2=Chapter 2  8. chapter3=Chapter 3  9. chapter4=Chapter 4 10. chapter5=Chapter 5 11. chapter6=Chapter 6 12. chapter7=Chapter 7 13. chapter8=Chapter 8 14. chapter9=Chapter 9 15. chapter10=Chapter 10 16. chapter11=Chapter 11 17. chapter12=Chapter 12 18. chapter13=Chapter 13 19. chapter14=Chapter 14 20. chapter15=Chapter 15 



core JavaServer Faces
Core JavaServer Faces
ISBN: 0131463055
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net