Hi Glenn (et. al.)

Started to use the Jakarta datetime lib and wanted to suggest a few
improvements (nothing earth-shattering here, just some small suggestions):

1.  Addition of a "date" and "defaultText" attribute:
    date = used for formatting (overrides tag body)
    defaultText = if NumberFormatException when parsing body or date ==
null this is the text used for defaults

The above allows you to significantly cut down on the amount of code for
formatting (i.e. you can do something like this:
        <td width="50%">Last Unsuccessful Login:</td>
        <td width="50%">
        <dt:format pattern="M-d-yyyy 'at' hh:mm:ss zzz"
                   defaultText="&nbsp;"
                   date="<%= bean.getLastBadLoginDate() %>" />
        </td>

rather than checking to see if lastBadLoginDate == null explicitly and
also having a default format -- especially useful for table and formatting
based on data obtained via data sources.

2.  Adjustments to tld:  (ADD)

        <attribute>
            <name>date</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>defaultText</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>


excellent work BTW on the taglib!  I'll have more suggestions maybe
later...

/*
 * $Header: 
/opt/cvsroot/Beantree-General/src/main/com/beantree/util/jsp/tags/datetime/FormatTag.java,v
 1.1 2001/03/28 00:34:13 mark Exp $
 * $Revision: 1.1 $
 * $Date: 2001/03/28 00:34:13 $
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package com.beantree.util.jsp.tags.datetime;

import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

/**
 * JSP Tag <b>format</b>, used to format a Date for display.
 * <p>
 * The Date as a long in milliseconds is obtained from the body of the tag.
 * <p>
 * Uses the optional attribute <b>pattern</b> as the time pattern
 * string to use when formatting the Date.
 * <p>
 * The optional attribute <b>timezone</b> can be set to the id of
 * a timezone script varaible so that the Date if adjusted for 
 * that timezone.
 * <p>
 * If the optional attribute <b>locale</b> is true, the Date
 * is formatted for the clients locale if known.
 * <p>
 * JSP Tag Lib Descriptor
 * <p><pre>
 * &lt;name&gt;format&lt;/name&gt;
 * &lt;tagclass&gt;org.apache.taglibs.datetime.FormatTag&lt;/tagclass&gt;
 * &lt;bodycontent&gt;JSP&lt;/bodycontent&gt;
 * &lt;info&gt;Formats a date for output.&lt;/info&gt;
 *   &lt;attribute&gt;
 *     &lt;name&gt;pattern&lt;/name&gt;
 *     &lt;sessuired&gt;false&lt;/sessuired&gt;
 *     &lt;rtexprvalue&gt;false&lt;/rtexprvalue&gt;
 *   &lt;/attribute&gt;
 *   &lt;attribute&gt;
 *     &lt;name&gt;timezone&lt;/name&gt;
 *     &lt;sessuired&gt;false&lt;/sessuired&gt;
 *     &lt;rtexprvalue&gt;false&lt;/rtexprvalue&gt;
 *   &lt;/attribute&gt;
 *   &lt;attribute&gt;
 *     &lt;name&gt;locale&lt;/name&gt;
 *     &lt;sessuired&gt;false&lt;/sessuired&gt;
 *     &lt;rtexprvalue&gt;false&lt;/rtexprvalue&gt;
 *   &lt;/attribute&gt;
 * </pre>
 *
 * MODIFIED:
 * Included the defaultText attribute and the ability to set the "date"
 *
 * @author Glenn Nielsen
 * @author Mark Femal
 */

public class FormatTag extends BodyTagSupport
{
    // Optional attribute, use users locale if known when formatting date
    private Locale locale = null;
    // Optional attribute, time pattern string to use when formatting date
    private String pattern = null;
    // Optional attribute, timezone script variable id to use when formatting date
    private TimeZone timezone = null;
    // The date after being formatted for output
    private String date_formatted = null;
    // The raw date given from the tag
    private Date date = null;
    // The default text if the tag body or date given is invalid/null
    private String defaultText = null;

    /**
     * Method called at start of tag, always returns EVAL_BODY_TAG
     *
     * @return EVAL_BODY_TAG
     */
    public final int doStartTag() throws JspException
    {
        return EVAL_BODY_TAG;
    }

    /**
     * Method called at end of format tag body.
     *
     * @return SKIP_BODY
     */
    public final int doAfterBody() throws JspException
    {
        // Use the body of the tag as input for the date
        BodyContent body = getBodyContent();
        String s = body.getString();  
        // Clear the body since we will output only the formatted date
        body.clearBody();
        if (s != null || date != null) {
            long time = 0;
            if (date != null) {
                time = date.getTime();
            } else {
                try {
                    time = Long.valueOf(getOnlyDigits(s)).longValue();
                } catch (NumberFormatException nfe) {
                    date_formatted = defaultText;
                    return SKIP_BODY;
                }
            }
                
            Date d = new Date(time);
            SimpleDateFormat sdf;
            // Get the default pattern if none defined
            if( pattern == null ) {
                sdf = new SimpleDateFormat();
                pattern = sdf.toPattern();
            }
            // Get a SimpleDateFormat using locale if necessary
            if( locale == null )
                sdf = new SimpleDateFormat(pattern);
            else
                sdf = new SimpleDateFormat(pattern,locale);

            // See if there is a timezone
            if( timezone != null )
                sdf.setTimeZone(timezone);

            // Format the date for display
            date_formatted = sdf.format(d);
        } else {
            date_formatted = defaultText;
        }

        return SKIP_BODY;
    }

    /**
     * Method called at end of Tag
     *
     * @return EVAL_PAGE
     */
    public final int doEndTag() throws JspException
    {
        try {
            pageContext.getOut().write(date_formatted);
        } catch(Exception e) {
            throw new JspException("IO Error: " + e.getMessage());
        }

        return EVAL_PAGE;
    }

    /**
     * Retrieve only the digits from the tag body input
     *
     * @param String for the tag body input
     * @return Only the digits from the input
     */
    public static final String getOnlyDigits(String s)
    {
        StringBuffer buf = new StringBuffer();
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                buf.append(c);
            }
        }

        return buf.toString();
    }

    /**
     * Locale flag, if set to true, format date
     * for client's preferred locale if known.
     *
     * @param String use users locale, true or false
     */
    public final void setLocale(String str)
    {
        if( str.equals("true") )
            locale = pageContext.getRequest().getLocale();
    }

    /**
     * Set the date to use (overrides tag body) for formatting
     *
     * @param Date to use for formatting (could be null)
     */
    public final void setDate(Date date)
    {
        this.date = date;
    }

    /**
     * Se the default text if an invalid date or no tag body is given
     */
    public final void setDefaultText(String defaultText)
    {
        this.defaultText = defaultText;
    }

    /**
     * Set the time zone to use when formatting date.
     *
     * Value must be the name of a <b>timezone</b> tag script
     * variable ID.
     *
     * @param String name of timezone to use
     */
    public final void setTimezone(String tz)
    {
        timezone = 
            (TimeZone)pageContext.getAttribute(tz,PageContext.SESSION_SCOPE);
    }

    /**
     * Set the pattern to use when formatting Date.
     *
     * @param String SimpleDateFormat style time pattern format string
     */
    public final void setPattern(String str)
    {
        pattern = str;
    }
}

Reply via email to