Generalized iterating tags protected void clearProperties() { elements

Generalized iterating tags protected void clearProperties() { elements = null; c super.clearProperties(); } } class IteratorIterationSupport implements IterationSupport { d Iterator i = null; IteratorIterationSupport(Iterator i) { this.i = i; } public boolean hasNext() throws JspException { return i.hasNext(); } public Object getNext() throws JspException { return i.next(); } } b Parsing the list specification string and making an IterationSupport out of it. C Clearing the additional tag property. D Implementing an IterationSupport class that uses a Java Iterator object. The new ForeachTag has most of its code implementing its tag-specific functionality, that is, dealing with an Iterator of Strings. Also of note in our implementation is the additional IteratorIterationSupport class we created, which is simply an implementation of the generic IterationSupport that works on the java.util.Iterator interface. We can imagine a similar class that works on Arrays and even another for Enumerations (or perhaps one that handles all?). The IteratorIterationSupport class is not, of course, unique to ForeachTag and we will be able to reuse it many times in other specialized tags. We now have a way to easily create iteration tags that iterate on all sorts of objects. We ll flex the power of this infrastructure in the next section in creating a tag that is capable of iterating on just about anything.

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

Generalized iterating tags // User probably disconnected …

CHAPTER 10 Iterating with tags D Override if you have additional attributes in the specialized tag (you probably do). E Override if you have additional service state in the specialized tag. Listing 10.5 shows that the general structure of IterationTagSupport is very similar to the one presented in SimpleForeachTag. The tag is merely a generic iteration infrastructure with several methods to override as explaned in the annotations. Note also that IterationTagSupport extends our now familiar ExBodyTagSupport, and therefore inherits its functionality. An improved ForeachTag which uses IterationTagSupport We ve mentioned several times the concept of a specialized tag, by which we infer a tag that uses our generic interface and class for a specific iterator and object type. Let s now look at one such specialized tag, ForeachTag, which uses IterationTag- Support to support an Iterator containing a list of Strings (see listing 10.6). Listing 10.6 Source code for the ForeachTag handler class package book.iteration; import java.util.StringTokenizer; import java.util.LinkedList; import java.util.Iterator; import java.util.List; import book.util.LocalStrings; import book.util.ExBodyTagSupport; import javax.servlet.jsp.JspException; public class ForeachTag extends IterationTagSupport { static LocalStrings ls = LocalStrings.getLocalStrings(ForeachTag.class); protected String elements = null; public void setElements(String elements) { this.elements = elements; } protected void fetchIterationSupport() throws JspException { List l = new LinkedList(); b StringTokenizer st = new StringTokenizer(elements, “,”); while(st.hasMoreTokens()) { l.add(st.nextToken()); } elementsList = new IteratorIterationSupport(l.iterator()); }

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

Generalized iterating tags // User probably disconnected …

Generalized iterating tags // User probably disconnected … // Log and throw a JspTagException } if(elementsList.hasNext()) { exportVariables(); return EVAL_BODY_TAG; } return SKIP_BODY; } protected abstract void fetchIterationSupport() b throws JspException; protected void exportVariables() c throws JspException { pageContext.setAttribute(id, elementsList.getNext()); } protected void clearProperties() d { id = null; super.clearProperties(); } protected void clearServiceState() e { elementsList = null; } } B First override point. The specialized tag must implement this method to create and set an IterationSupport object The first method that tags can and must override is fetchIterationSupport(). This abstract method is the location wherein the overriding tag should implement the creating and setting of the IterationSupport object and any specialized iteration tag must provide such objects to make the generic infrastructure work. If problems rise within fetchIterationSupport(), it can throw a JspException that the generic implementation will pass to the JSP runtime. C Second override point. The specialized tag may want to export additional objects The second method that can be overridden is exportVariables(), which is where the generic iteration tag exports the iterator (based in the id attribute). An overriding tag may override this method to add more variables. For example, a certain tag iterates a hash table and wants to export both the key to the table and the value itself. In this case you would like to add the exportation of the value variable along with the default iterator.

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

Generalized iterating tags Listing 10.4 Source code for

CHAPTER 10 Iterating with tags is custom built to handle a particular iterator type and a particular type of object in that iterator. Export a different set of JSP variables. Whenever IterationTagSupport wants to export its iterator value, it should call yet another method that can be overridden by the specialized tag (but the default implementation of the variable exportation method should export only a single iterator). IterationTagSupport s implementation IterationTagSupport was created with a few methods that may be overridden by specialized iteration tags. Listing 10.5 Source code for the generic iteration tag handler package book.iteration; import book.util.LocalStrings; import book.util.ExBodyTagSupport; import javax.servlet.jsp.JspException; public abstract class IterationTagSupport extends ExBodyTagSupport { static LocalStrings ls = LocalStrings.getLocalStrings(IterationTagSupport.class); IterationSupport elementsList = null; public int doStartTag() throws JspException { fetchIterationSupport(); if(elementsList.hasNext()) { return EVAL_BODY_TAG; } return SKIP_BODY; } public void doInitBody() throws JspException { exportVariables(); } public int doAfterBody() throws JspException { try { getBodyContent().writeOut(getPreviousOut()); getBodyContent().clear(); } catch(java.io.IOException ioe) {

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

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