Contents | Prev | Next



An Iteration Tag

Constructing page content dependent on dynamically generated data often requires the use of flow control scripting statements. By moving the flow control logic to tag handlers, flow control tags reduce the amount of scripting needed in JSP pages.

The iteration tag retrieves objects from a collection stored in a JavaBeans component and assigns them to a scripting variable. The body of the tag retrieves information from the scripting variable. While elements remain in the collection, the iteration tag causes the body to be reevaluated.


JSP Page

The iteration example application contains two JSP pages that uses the iterator tag; one of the pages, index.jsp, is shown below. The page initializes the iteration tag with a collection maintained by a JavaBeans component that represents an organization. The iteration tag populates a table with the names of departments in the organization. The other jsp page, list.jsp, uses the iterator tag to display the members of a selected department.

<%@ taglib uri="/tlt" prefix="tlt" %>
<html>
   <head>
   <title>Organization</title>
   </head>
   <body bgcolor="white">
   <jsp:useBean id="org" class="Organization"/>   
   <table border=2 cellspacing=3 cellpadding=3>
   <tlt:iteration name="departmentName" type="String" 
      group="<%= org.getDepartmentNames()%>">
      <tr>
         <td><b>Departments</b></td>
      </tr>   
      <tr>
         <td><a href="list.jsp?deptName=
            <%= departmentName %>">
            <%= departmentName %></a></td>
      </tr>
      </tlt:iteration>
   </table>
   </body>
</html>
The following figure shows the result of executing list.jsp:


Tag Handler

The iteration tag uses an iterator initialized from the collection provided via the group tag attribute. If the iterator contains more elements, doStartTag sets the value of the scripting variable to the next element and then indicates that the body should be evaluated.

After the body has been evaluated, the doAfterBody method retrieves the body content and writes it to the out stream. The body content is cleared in preparation for another body evaluation. If the iterator contains more elements, doAfterBody again sets the value of the scripting variable to the next element and indicates that the body should be evaluated again, which causes the reexecution of doAfterBody. When there are no remaining elements, doAfterBody terminates the process by returning SKIP_BODY.

private Iterator iterator;
public void setGroup(Collection members) {
   if(members.size() > 0)
      iterator = members.iterator();
}

public int doStartTag() {
   if(iterator == null) {
      return SKIP_BODY;
   }
   if(iterator.hasNext()) {
      pageContext.setAttribute(name, iterator.next());
      return EVAL_BODY_TAG;
   } else {
      return SKIP_BODY;
   }
}

public int doAfterBody() throws JspTagException {
   BodyContent body = getBodyContent();
   try {
      body.writeOut(getPreviousOut());
   } catch (IOException e) {
      throw new JspTagException("IterationTag: " +
         e.getMessage());
   }

   // clear up so the next time the body content is empty
   body.clearBody();
   if (iterator.hasNext()) {
      pageContext.setAttribute(name, iterator.next());
      return EVAL_BODY_TAG;
   } else {
      return SKIP_BODY;
   }
}

Tag Extra Info Class

The scripting variable is defined in the following tag extra info class. Since the name (member) and class (Member) of the scripting variable were passed in as tag attributes, they are retrieved with the data.getAttributeString method and used to fill in the VariableInfo constructor.

public class IterationTEI extends TagExtraInfo {
   ...
   public VariableInfo[] getVariableInfo(TagData data) {
      VariableInfo info1
         = new VariableInfo(
            data.getAttributeString("name"),
            data.getAttributeString("type"),
            true,
            VariableInfo.NESTED);
      VariableInfo [] info = { info1 };
      return info;
   }
}


Contents | Prev | Next
Copyright © 2000 Sun Microsystems, Inc. All rights reserved.