Generalized iterating tags Listing 10.4 Source code for

Generalized iterating tags Listing 10.4 Source code for the generic iteration interface package book.iteration; import javax.servlet.jsp.JspException; public interface IterationSupport { public boolean hasNext() throws JspException; public Object getNext() throws JspException; } Why do we need another iteration/enumeration interface, as Java already offers plenty. You may also wonder, why a JspException is thrown from the methods hasNext() and getNext(). Shouldn t a generic interface remove JSP related ties? We do this because we want to provide better JSP integration. Let s explore our motivation for this integration. NOTE We could consider the option of defining a new exception type (such as IterationException) that the iteration support methods could throw; but why should we? This code is written for the JSP tags, and we are not going to reuse it. In 99 percent of all cases, you are going to throw a JspException as a result of the error. Based on this argument, we ve rejected the new exception type idea, and continue to use JspException as our error-reporting vehicle. 10.2.2 IterationTagSupport Let s look at the basic iteration tag class, IterationTagSupport, and how it uses IterationSupport. Before taking a look into the implementation of Iteration- TagSupport as presented in listing 10.5, let s consider how we would like it to work. What should IterationTagSupport do? Most emphatically, the generic iteration tag class should automatically take care of iteration-related issues such as flow control, as well as exporting default iterator variables. In addition, it must be able to: Create an IterationSupport object out of the elements provided as a tag attribute. This can be accomplished by defining a method that our specialized iteration tags can override and that IterationTagSupport will call during its doStartTag(). By specialized tag we mean the special version of the tag that

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services

Iterating with tags 101 to export the values

CHAPTER 10 Iterating with tags elements=”1,2,3,4″> The selected item is < %= item %>
Now when we execute our JSP, SimpleForeachTag will repeat its body four times (one for each string in elements ); first with 1 as the value of the item (our iterator), and lastly with 4 as its value. 10.2 Generalized iterating tags In perusing the implementation of SimpleForeachTag it appears that most of the work done by the tag is not unique to it. In fact, other than the creation of the Iterator object in parseElements() all the other code was generic. True, some tags will not want to expose an iterator, and others may want to expose more than a single iterator as a scripting variable (for some other tag-specific purpose), but these tags are not representative of the majority. In most cases, tags will differ only in the objects they iterate (some will iterate over an Enumeration, others on Array, etc.) but the general structure will stay the same; a single iterator scripting variable will be exposed and updated for each element. Based on this general iterating structure, we ll build: A generic iteration interface that lets the tag developer specify how to iterate over some set of objects. A basic iterator tag that takes a generic iteration object (Enumeration, Array, etc.) and iterates on it. Creating these two, generic components will then streamline the creation of various iteration tags. These specialized iteration tags will be custom-built, based on the type of Java object to be contained in the iterator, and the iterator type in which these objects are to be contained. For example, our SimpleForeachTag had an iterator type of java.util.Iterator, and contained in that iterator was a list of Strings. We are now going to build these two components (the class and interface) and modify SimpleForeachTag to use this new, more generic infrastructure. 10.2.1 A generic iteration interface Before looking into the new ForeachTag, let s study the generic iteration infrastructure on which it is constructed, starting with the generic iteration interface as seen in listing 10.4.

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services

Iterating with tags 101 to export the values

Iterating with tags 101 to export the values of the iterator, we ll create a TagExtraInfo class for it that will inform the runtime of this. We ll call this class ForeachTagExtraInfo. Its implementation is in listing 10.2 wherein you see that it merely notifies the JSP runtime that a new scripting variable of type String is exported. Listing 10.2 Source code for the ForeachTagExtraInfo class package book.iteration; import javax.servlet.jsp.tagext.TagData; import javax.servlet.jsp.tagext.TagExtraInfo; import javax.servlet.jsp.tagext.VariableInfo; public class ForeachTagExtraInfo extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData data) { VariableInfo[] rc = new VariableInfo[1]; rc[0] = new VariableInfo(data.getId(), java.lang.String, true, VariableInfo.NESTED); return rc; } } NOTE Note that the scope defined for the scripting variable is NESTED, meaning the variable exists and is accessible only within the body of the tag that exported it. This is important since the variable we export is our iterator, and so should exist only within the body of the loop. SimpleForeachTag in action Having written SimpleForeachTag and its TagExtraInfo we can now write JSP code to work with it. Since this is only the beginning of our iteration tags discussion, we will take that same JSP fragment and make it the content of our JSP as seen in listing 10.3. Listing 10.3 JSP driver for SimpleForeachTag < %@ page errorPage="error.jsp" %> < %@ taglib uri="http://www.manning.com/jsptagsbook/iteration-taglib" prefix="iter" %> JSP Web Hosting services

Iterating with tags 101 } protected void parseElements()

CHAPTER 10 Iterating with tags E Breaks the string list into a Java list. F Writes the results of this iteration back to the user and clears the body buffer. G If we have more elements in the list, exports a new iterator value and repeats evaluat ing the body. The work in SimpleForeachTag takes place in three designated locations: The service phase initialization in doStartTag(). The tag initializes the set of objects on which we plan to iterate, and determines if we need to process the body. This is not necessary if the list of objects is empty. The loop initialization in doInitBody(). The tag exports the needed iterator object by calling pageContext.setAttribute() with the name of the object and the object itself. In doing so, we publish the iterator as a scripting variable, so that it ends up in the scope in the JSP (a practice we first came across with JavaBean tags in chapter 8). By exporting the iterator object, other tags and scriptlets can take advantage of it. The loop termination/repeating in doAfterBody(). The tag writes the results of the last loop into the previous writer (usually the writer that goes to the user) and then clears the body content to prepare it for the next iteration. In the final step, if there are additional items to iterate, the tag exposes a new iterator value and signals the JSP environment to repeat the execution by returning EVAL_BODY_TAG. NOTE When implementing iterations using tags, you do not have to write the results of each loop separately. You may instead wait for the body execution to finish (no more elements on which to iterate) and then write the complete result. Doing so usually results in improved performance, but it may also cause a delay in the user s receipt of the results. For example, consider reading a substantial amount of data from a database and presenting it to the user with some iteration on the result set. Since we are working with a database, completing the iteration may take a while and writing the response only on completion may cause the user to leave the page. Writing the result of each loop incrementally would (depending on buffer size) cause the results to return to the user incrementally, instead of in a large chunk. SimpleForeachTag s TagExtraInfo Following the development of SimpleForeachTag we must now create its TagExtraInfo counterpart. You may recall from our discussions of the TagExtraInfo class in chapters 6 and 8, we need to create a subclass of TagExtraInfo whenever we have a tag that exports a scripting variable. Since SimpleForeachTag will need

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

Iterating with tags 101 } protected void parseElements()

Iterating with tags 101 } protected void parseElements() throws JspException { List l = new LinkedList(); StringTokenizer st = new StringTokenizer(elements, “,”); e while(st.hasMoreTokens()) { l.add(st.nextToken()); } elementsList = l.iterator(); } public int doAfterBody() throws JspException { try { getBodyContent().writeOut(getPreviousOut()); getBodyContent().clear(); } catch(java.io.IOException ioe) { // User probably disconnected … log(ls.getStr(Constants.IO_ERROR), ioe); throw new JspTagException(ls.getStr(Constants.IO_ERROR)); } f if(elementsList.hasNext()) { g pageContext.setAttribute(id, elementsList.next()); return EVAL_BODY_TAG; } return SKIP_BODY; } protected void clearProperties() { id = null; elements = null; super.clearProperties(); } protected void clearServiceState() { elementsList = null; } } B Parses the list of strings into a Java list and creates an enumerator. C If we have an element in the list, continues the body evaluation; otherwise skips the body (empty iteration). D Sets the iterator variable with the first element in the list.

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

Iterating with tags 101 To further illustrate how

CHAPTER 10 Iterating with tags The selected item is < %= item %>
Executing the above JSP fragment generates the following content: The selected item is 1
The selected item is 2
The selected item is 3
The selected item is 4
Let s look at the code for the SimpleForeachTag s handler (listing 10.1). Listing 10.1 Source code for the SimpleForeachTag handler class package book.iteration; import java.util.StringTokenizer; import java.util.LinkedList; import java.util.List; import java.util.Iterator; import book.util.LocalStrings; import book.util.ExBodyTagSupport; import javax.servlet.jsp.JspException; public class SimpleForeachTag extends ExBodyTagSupport { static LocalStrings ls = LocalStrings.getLocalStrings(SimpleForeachTag.class); Iterator elementsList = null; protected String elements = null; public void setElements(String elements) { this.elements = elements; } public int doStartTag() throws JspException { parseElements(); b if(elementsList.hasNext()) { c return EVAL_BODY_TAG; } return SKIP_BODY; } public void doInitBody() throws JspException { pageContext.setAttribute(id, elementsList.next()); d

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

Iterating with tags 101 To further illustrate how

Iterating with tags 101 To further illustrate how iteration is accomplished with tags, we ve translated the flow chart in figure 10.1 into (roughly) its Java equivalent. t.doInitBody(); do { // The JSP runtime execute // the tag s body … } while(t.doAfterBody() == BodyTag.EVAL_BODY_TAG); As figure 10.1 and the code fragment show, two methods (table 10.1) take part in implementing the iteration: Table 10.1 Iteration methods JSP method Description doBodyInit() Used to initialize preiteration JSP scripting variables and the tags internal values. For example, if your tag exposes some iterator object as a JSP scripting variable, it will probably use doBodyInit() to export its initial value. doAfterBody() Controls the iteration with its return codes: To continue the iteration, doAfterBody() returns a value of BodyTag.EVAL_BODY_TAG (or IterationTag.EVAL_BODY_AGAIN in JSP1.2).To break the iteration , it returns a value BodyTag.SKIP_BODY. This method is also where we re-export the iterator value (the current value of the property on which we are iterating), and where we write the result of the current iteration into the response. NOTE You can skip the implementation of doBodyInit() and perform its work in doStartTag(). This will not have any effect on performance and may even simplify your tags. Better yet, since doStartTag() is not available in IterationTag, code that does not use it will be easier to port to this new tag. In any case, it is a good idea to separate the iteration handling from doStartTag() so that doStartTag() will only deal with service initialization (e.g., obtaining the object set that we are going to iterate) and doBodyInit() will deal with the initialization of the loop. 10.1.1 Iteration example: SimpleForeachTag Now that you know how to implement iteration in your tags, we will take a look at a sample iterative tag and the code that performs iteration. Our first iteration tag, SimpleForeachTag, will take a tag attribute that specifies a list of strings, walk over the string list, and, one by one, export an iterator object that contains the current string value for that iteration round. The following JSP fragment shows a sample usage of this tag:

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

Iterating With Tags This is obviously quite an

CHAPTER 10 Iterating with tags 10.1 Iterating with tags 101 Developing custom JSP tags that iterate over some set of values requires us to work, once again, with the familiar BodyTag interface. The BodyTag interface provides a method call protocol to control the execution of the tag s body which we ll need in order to repeat the tag s body for every value in the JavaBean s indexed property. NOTE In JSP1.2 a new IterationTag interface was defined and we can also create tags using this interface. You can find information regarding the IterationTag later in this chapter. Figure 10.1 shows how a tag can implement iteration using the BodyTag method call protocol. Iteration Initalization t.doInitBody() Reiterating or Termination t.doAfterBody() doAfterBody() returns EVAL_BODY_TAG doAfterBody() returns SKIP_BODY Iteration is done Body Processing The JSP environment Process the body Figure 10.1 Implementing iteration using the BodyTag interface

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

Iterating With Tags This is obviously quite an

Iterating With Tags ” property=”header” index=”< %= name %>“/>

This is obviously quite an improvement. Why should we bother creating special iteration tags when a two-line scriptlet hardly seems demanding for a Java developer? Again, we can t forget that the goal of building custom tag libraries is to make it possible for non-Java developers (presentation/HTML developers) to build complex sites. Though iteration using scriptlets may not be complex for the Java programmer, it does require the JSP developer to: Know how to iterate on different Java types Enumerations, Iterators, arrays, and so forth. To further complicate the situation, iteration methods usually return an Object that the JSP developer will have to cast. Position the curly brackets in the correct location. If the JSP developer forgets a curly bracket, the JSP compilation will fail, usually with a relatively obscure error message. Maintain and debug yet another portion of Java code. As a result, iteration tags are necessary to enhance the effectiveness of our JavaBean tags and to keep our JSPs scriptlet-free. This chapter explores iteration with tags and shows how to build JSP custom tags that perform iteration for us. We ll start with a brief introduction to iterating with custom JSP tags and discuss their design principles; later, we will develop iteration tags to handle cases in which we wish to iterate over Java s common object containers. NOTE In this chapter, you will see the word iterator used in two distinct ways. When we use the generic term, we mean any multivalued object (be it an Array, an implementation of the java.util.Enumeration interface or an implementation of the java.util.Iterator interface). When we mention Iterator we are speaking strictly about the Java interface.

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

10 Iterating with tags In this chapter

CHAPTER 10 Iterating with tags At the end of chapter 8, we used our newly created JavaBean tags to export an Enumeration which was then iterated over with a scriptlet. Let s take another look at this JSP fragment.

” property=”header” index=”< %= name %>“/>

< % } %>

Header Value

As you can see (note the highlighted code), although our JavaBean tags greatly reduce the need for scriptlets, we are still unable to avoid them when working with indexed JavaBean properties that have more than one value. In cases of multivalued properties (Enumerations, arrays, etc.) we typically want to loop through (iterate) and perform a function with each value in the property. Without a tag to handle this iteration, we re left using a scriptlet like the one here. This is unfortunate since we want to be able to provide our JSP authors with the ability to perform common functions on JavaBeans without prior knowledge of Java. Ideally, we d like to offer them a very user-friendly JSP custom tag that would work for iteration. Iteration, especially enumerating some value, can be very declarative, and, as we ve seen, declarative tasks are easily performed with tags. For example, by using iteration tags we can modify the previous JSP fragment:

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

Header Value