Understanding Tile Scope

 < Day Day Up > 



The Tiles framework defines an additional scope called Tile scope. Like page scope, Tile scope is more private than request scope. It allows the user of the Tile to pass arguments (called parameters) to the Tile. Like a display function, it makes the page callable.

Remember, jsp:include allows you to call a page and pass it request parameters (jsp:param); tiles:insert is similar but is more powerful. The tiles:insert directive allows you to call a page and pass it sub-pages (called Tiles) and attributes. Tile scope lets you pass variables that are available only to that Tile layout.

It becomes easier to understand Tile scope if you know how it is implemented. In my travels, I created a debug utility called listTileScope (Listing 13.3) that allows me to print out variables that are in Tile scope. This code should help you understand how Tile scope is implemented.

Listing 13.3: listTileScope.

start example
 import org.apache.struts.taglib.tiles.ComponentConstants; import org.apache.struts.tiles.ComponentContext; public static void listTileScope(PageContext context)                    throws JspException, IOException {     JspWriter out = context.getOut();     ComponentContext compContext =             (ComponentContext)context.getAttribute(                         ComponentConstants.COMPONENT_CONTEXT,                         PageContext.REQUEST_SCOPE);     out.println("--- TILE Attributes --- <br />");     if (compContext!=null){         Iterator iter = compContext.getAttributeNames();         while(iter.hasNext()){             String name = (String)iter.next();             Object value = compContext.getAttribute(name);             printNameValueType(name, value, out);         }     }else{         out.println("---TILE Attributes NOT FOUND---<br />");     }     out.println("----------------------------- <br />"); } private static void printNameValueType(                             String name,                             Object value,                             JspWriter out)                                     throws IOException{     if (value !=null){         out.println(         name + " = " + value +         " type (" +             value.getClass().getName()+ ") " +         "<br /><br />");     }else{         out.println(name + " = " + value +         "<br /><br />");     } } 
end example

Notice that the class ComponentContext implements Tile scope. The ComponentContext class is located in request scope under the key ComponentConstants.COMPONENT_CONTEXT. The Tiles system ensures that each Tile gets its own component context.

Nested Tiles do not share the same Tile scope as their parent (I learned this one the hard way). The Tile scope of the current Tile is saved before the nested Tile is displayed; after the nested Tile finishes, the parent's Tile scope is restored to the request. This magic is done in the InsertTag (org.apache.struts.taglib.tiles.InsertTag) class's nested class InsertHandler.

So far, you have passed attributes to the Tile layout that corresponds to sub-Tiles or simple strings. You can pass in any bean type as attributes to the Tile layout and then use those attributes inside the Tile layout.

Let's say you have an action in your application that puts a User object into session scope, perhaps after the user logs into the system:

   public ActionForward execute(ActionMapping mapping,     ActionForm form,     HttpServletRequest request,     HttpServletResponse response)     throws IOException, ServletException {     // Default target to success     String target = new String("success");     //if login successful.     UserDomainObject user = new UserDomainObject();     ...     request.getSession().setAttribute("user", user);     return (mapping.findForward(target));   } 

Now you want to pass that user to a Tile you are inserting. In this example, use the Tile you used inside your Tile layout (siteLayout2.jsp):

 <tiles:insert attribute="header" ignore="true">     <tiles:put name="title" beanName="title" beanScope="tile"/>     <tiles:put name="user" beanName="user"                                           beanScope="session"/> </tiles:insert> 

The Tile layout passes the user bean to the header Tile by specifying a scope of session and a bean name of user. You can pass any bean from any JSP scope into the Tile or Tile layout using this technique; thus, the Tile scope becomes just another scope. This is not much different than before.

To use this user bean in header.jsp, you have to copy it from Tile scope into a scope that other beans understand. You can do this by using the tiles:useAttribute tag. This tag is analogous to the jsp:useBean action, except that it works only with Tile scope:

 <tiles:useAttribute                      name="user"                     classname="ch13.UserDomainObject"                     /> 

This code defines a user in page scope of the header.jsp JSP. Once the bean is defined, you can start using it as you would any bean defined in page scope:

    <bean:write name="user" property="userName"/> 

Listing 13.4 contains the new header2.jsp file.

Listing 13.4: header2.jsp.

start example
 <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <center> <table> <tr> <tiles:useAttribute                      name="user"                     classname="ch13.UserDomainObject"                     />        <td width="33%" bgcolor="#36566E">          &nbsp;           <div align='left'>           <font size="1" color="orange">                  currently logged in as                  <bean:write name="user" property="userName"/>           </font>           </div>           &nbsp;        </td>        <td width="33%">            &nbsp;            <font color="#36566E">                <tiles:getAsString name="title" ignore="true"/>            </font>            &nbsp;        </td>        <td width="33%" bgcolor="#36566E">           &nbsp;           <div align='left'>           <font size="1" color="white">               <blockquote>                  <bean:write name="user" property="firstName"/>               <br />                  <bean:write name="user" property="lastName"/>               <br />                  </blockquote>           </font>           </div>           &nbsp;        </td> </tr> </table> </center> 
end example

As you can see, the header now displays information about the current user logged into the site. This is a powerful feature. You can create Tiles that specialize in displaying domain objects and then reuse those Tiles in many parts of your application—you can in effect create display components. Unlike custom tags (pre-JSP 2.0), these components are all created in JSP pages.



 < Day Day Up > 



Professional Jakarta Struts
Professional Jakarta Struts (Programmer to Programmer)
ISBN: 0764544373
EAN: 2147483647
Year: 2003
Pages: 183

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