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=" "
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>
* <name>format</name>
* <tagclass>org.apache.taglibs.datetime.FormatTag</tagclass>
* <bodycontent>JSP</bodycontent>
* <info>Formats a date for output.</info>
* <attribute>
* <name>pattern</name>
* <sessuired>false</sessuired>
* <rtexprvalue>false</rtexprvalue>
* </attribute>
* <attribute>
* <name>timezone</name>
* <sessuired>false</sessuired>
* <rtexprvalue>false</rtexprvalue>
* </attribute>
* <attribute>
* <name>locale</name>
* <sessuired>false</sessuired>
* <rtexprvalue>false</rtexprvalue>
* </attribute>
* </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;
}
}