InvoiceIterator.java

/*
  Copyright 2001, Pajato Systems Group
  Copyright 2001, Allaire Corporation
*/

package allaire.samples.invoice.taglib;

import allaire.samples.invoice.InvoiceDataModel;
import allaire.samples.invoice.ParameterUtil;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * An <inv:foreach> tag encapsulates an iterator, specified by a
 * <i>collectionName</i> attribute.  The <i>parameterName</i>
 * attribute specifies the Java variable accessed by the <inv:getItem>
 * tag on each iteration.
 */

public class InvoiceIterator extends BodyTagSupport {

    // Specify application scope for all saved attributes.
    public static final int SCOPE = PageContext.APPLICATION_SCOPE;

    // The invoice data model.
    private InvoiceDataModel dataModel;

    // The iteration item.
    private String item;

    // The collection iterator.
    private Iterator iterator;

    // The currently selected value.
    private String selectedValue;

    // Collection name property.
    private String collectionName;

    /**
     * Collection name accessor.
     */
    public String getCollectionName() {
	return collectionName;
    }

    /**
     * Collection name mutator.
     */
    public void setCollectionName( String name ) {
	collectionName = name;
    }

    // Parameter name property.
    private String parameterName;

    /**
     * Parameter name accessor.
     */
    public String getParameterName() {
	return parameterName;
    }

    /**
     * Parameter name mutator.
     */
    public void setParameterName( String name ) {
	parameterName = name;
    }

    /**
     * Return the iteration item.
     */
    public String getItem() {
	return item;
    }

    /**
     * Return an indication that the current item is the selected item.
     */
    public boolean isSelectedItem() {

	// If the item being processed matches the value of the
	// request parameter indicated by the parameter name, then
	// this item is the selected item.
	return selectedValue != null && selectedValue.equals( item );
    }
	
    /**
     * Initialize the <b><inv:foreach></b> tag.
     */
    public int doStartTag() throws JspException {

	try {
	    // The name is valid.  Initialize and save the data model.
	    // after making sure that it has been loaded.
	    dataModel = (InvoiceDataModel)
		pageContext.getAttribute( "invoiceDataModel", SCOPE );
	    if ( dataModel == null ) {
		// Create a data model.
		dataModel = new InvoiceDataModel( pageContext );
		pageContext.setAttribute( "invoiceDataModel", dataModel, SCOPE );
	    }

	    // Save the currently selected value.
	    ServletRequest request = pageContext.getRequest();
	    ServletResponse response = pageContext.getResponse(); 
	    selectedValue = ParameterUtil.getParameterWithEncoding( request, response, parameterName );

	    // Initialize and save the iterator.
	    iterator = dataModel.getIterator( collectionName );

	    // Set up the weeks collection for a client company if one
	    // has been selected.
	    HttpSession session = pageContext.getSession();
	    String clientCompany = ParameterUtil.getParameterWithEncoding( request, response, "clientCompany" );
	    if ( clientCompany == null || iterator == null ) {
		// Disable the weeks selection box from being displayed.
		session.setAttribute( "displayWeeks", new Boolean( false ) );
	    } else {
		// Set up the week ending selections and enable their
		// display.
		dataModel.setClientCompany( clientCompany );
		session.setAttribute( "displayWeeks", new Boolean( true ) );
	    }
	    
	} catch (Exception exc) {
	    exc.printStackTrace();
	    throw new JspException( exc.getMessage() );
	}

	return getNext();
    }


    /**
     * Output any accumulating content.
     */
    public int doAfterBody () throws JspException {

	// Predispose the result to skip evaluation of the tag body.
	int result = SKIP_BODY;

	// Output the body content.
	BodyContent body = getBodyContent();
	try {
	    body.writeOut( getPreviousOut() );
	} catch (IOException exc) {
	    throw new JspTagException( "unexpected IO error" );
	}
	body.clearBody();

	// Setup for the next iteration.
	return getNext();
    }


    // Generate and save the next item.  Return an indication on
    // whether or not to process the body one more time.
    private int getNext() {

	// Predispose the result to be finished.
	int result = SKIP_BODY;

	// Determine if the tag body needs to get executed, i.e. if
	// the iterator has more items.
	if ( iterator != null && iterator.hasNext() ) {
	    result = EVAL_BODY_TAG;
	    item = (String) iterator.next();
	}

	return result;
    }
}