You are viewing a plain text version of this content. The canonical link for it is here.
Posted to taglibs-dev@jakarta.apache.org by lu...@apache.org on 2002/01/31 00:26:34 UTC

cvs commit: jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt ExceptionTag.java FormatNumberTag.java ParseNumberTag.java

luehe       02/01/30 15:26:33

  Modified:    standard/conf fmt-rt.tld fmt.tld
               standard/examples/web/format FormatNumber.jsp
               standard/src/org/apache/taglibs/standard/tag/common/fmt
                        BundleSupport.java ExceptionSupport.java
                        FormatNumberSupport.java LocaleSupport.java
                        ParseNumberSupport.java
               standard/src/org/apache/taglibs/standard/tag/el/fmt
                        ExceptionTag.java FormatNumberTag.java
                        ParseNumberTag.java
               standard/src/org/apache/taglibs/standard/tag/rt/fmt
                        ExceptionTag.java FormatNumberTag.java
                        ParseNumberTag.java
  Log:
  - <fmt:exception>:
    - Removed "stackTrace" attribute, since stack trace is never
    localized. Removal of this attribute is conditional on whether the EL
    will make it easy to access the exception info, in which case the
    stack trace could be added using <c:expr> instead.
  
    - Use the servlet specs name of the request attribute storing the
    exception of an error page if looking up the JSP specs attribute name
    has failed (this is necessary since the JSP and servlet specs do not
    agree on the request attribute name):
  
      JSP spec: javax.servlet.jsp.jspException
      Servlet spec: javax.servlet.error.exception
  
  - <fmt:formatNumber>: Added "currencyCode", "currencySymbol",
    "groupingUsed", "maxIntegerDigits", "minIntegerDigits",
    "maxFractionDigits", "minFractionDigits" attributes.
  
  - <fmt:parseNumber>: Added "integerOnly" attribute.
  
  - Aligned locale determination algorithm for I18N and formatting
    locales. The algorithm now gives preference to a "language match" over
    an "exact match" that might have occurred later on in the list of
    available locales. The only difference between the I18N and formatting
    logic is that in the I18N case, the container's default locale is always
    ignored, whereas in the formatting case, it is used only as a last resort.
  
  Revision  Changes    Path
  1.9       +40 -5     jakarta-taglibs/standard/conf/fmt-rt.tld
  
  Index: fmt-rt.tld
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/conf/fmt-rt.tld,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- fmt-rt.tld	18 Dec 2001 02:43:28 -0000	1.8
  +++ fmt-rt.tld	30 Jan 2002 23:26:33 -0000	1.9
  @@ -50,11 +50,6 @@
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
  -    <attribute>
  -        <name>stackTrace</name>
  -        <required>false</required>
  -        <rtexprvalue>true</rtexprvalue>
  -    </attribute>
     </tag>
   
     <tag>
  @@ -242,6 +237,41 @@
           <rtexprvalue>true</rtexprvalue>
       </attribute>
       <attribute>
  +        <name>currencyCode</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>currencySymbol</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>groupingUsed</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>maxIntegerDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>minIntegerDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>maxFractionDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>minFractionDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
           <name>var</name>
           <required>false</required>
           <rtexprvalue>false</rtexprvalue>
  @@ -278,6 +308,11 @@
       </attribute>
       <attribute>
           <name>parseLocale</name>
  +        <required>false</required>
  +        <rtexprvalue>true</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>integerOnly</name>
           <required>false</required>
           <rtexprvalue>true</rtexprvalue>
       </attribute>
  
  
  
  1.10      +48 -6     jakarta-taglibs/standard/conf/fmt.tld
  
  Index: fmt.tld
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/conf/fmt.tld,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- fmt.tld	18 Dec 2001 02:43:28 -0000	1.9
  +++ fmt.tld	30 Jan 2002 23:26:33 -0000	1.10
  @@ -20,7 +20,6 @@
               requestEncoding:value 
   	    exception:value
   	    exception:bundle
  -	    exception:stackTrace
   	    locale:value
   	    locale:variant
   	    timeZone:value
  @@ -35,9 +34,17 @@
   	    formatNumber:value
   	    formatNumber:pattern
   	    formatNumber:parseLocale
  +            formatNumber:currencyCode
  +            formatNumber:currencySymbol
  +            formatNumber:groupingUsed
  +            formatNumber:maxIntegerDigits
  +            formatNumber:minIntegerDigits
  +            formatNumber:maxFractionDigits
  +            formatNumber:minFractionDigits
   	    parseNumber:value
   	    parseNumber:pattern
   	    parseNumber:parseLocale
  +            parseNumber:integerOnly
   	    formatDate:value
   	    formatDate:pattern
   	    formatDate:timeZone
  @@ -97,11 +104,6 @@
           <required>false</required>
           <rtexprvalue>false</rtexprvalue>
       </attribute>
  -    <attribute>
  -        <name>stackTrace</name>
  -        <required>false</required>
  -        <rtexprvalue>false</rtexprvalue>
  -    </attribute>
     </tag>
   
     <tag>
  @@ -289,6 +291,41 @@
           <rtexprvalue>false</rtexprvalue>
       </attribute>
       <attribute>
  +        <name>currencyCode</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>currencySymbol</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>groupingUsed</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>maxIntegerDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>minIntegerDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>maxFractionDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>minFractionDigits</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
           <name>var</name>
           <required>false</required>
           <rtexprvalue>false</rtexprvalue>
  @@ -325,6 +362,11 @@
       </attribute>
       <attribute>
           <name>parseLocale</name>
  +        <required>false</required>
  +        <rtexprvalue>false</rtexprvalue>
  +    </attribute>
  +    <attribute>
  +        <name>integerOnly</name>
           <required>false</required>
           <rtexprvalue>false</rtexprvalue>
       </attribute>
  
  
  
  1.6       +29 -9     jakarta-taglibs/standard/examples/web/format/FormatNumber.jsp
  
  Index: FormatNumber.jsp
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/examples/web/format/FormatNumber.jsp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FormatNumber.jsp	15 Jan 2002 02:19:27 -0000	1.5
  +++ FormatNumber.jsp	30 Jan 2002 23:26:33 -0000	1.6
  @@ -8,31 +8,51 @@
   <h3>Formatting Numbers, Currencies, and Percentages</h3>
   
   <ul>
  - <li> Format as number: 
  + <li> Format &quot;123456789&quot; as number:<br>
     <fmt:formatNumber value="123456789"/>
   
  - <li> Format as currency: 
  + <li> Format &quot;123456789&quot; as currency (using browser locale):<br>
     <fmt:formatNumber value="123456789" type="currency"/>
   
  - <li> Format as percentage: 
  + <li> Format &quot;123456789&quot; as currency with &quot;EUR&quot; currency
  +      code:<br>
  +  <fmt:formatNumber value="123456789" type="currency" currencyCode="EUR"/>
  +
  + <li> Format &quot;123456789&quot; as currency (using browser locale), with
  +      grouping turned off, the maximum number of digits in the integer portion
  +      limited to 4, and no fraction portion:<br>
  +  <fmt:formatNumber value="123456789" type="currency" groupingUsed="false" maxIntegerDigits="4" maxFractionDigits="0"/>
  +
  + <li> Format &quot;123456789&quot; as percentage:<br>
     <fmt:formatNumber type="percent">
      123456789
     </fmt:formatNumber>
   
  - <li> Format as currency, parse, and print parsed result: 
  + <li> Format &quot;123456789&quot; as currency (using browser locale):<br>
  +  <fmt:formatNumber value="123456789" type="currency"/><br>
  +      then parse it back in and print the parsed result:<br> 
     <fmt:formatNumber value="123456789" type="currency" var="cur"/>
     <fmt:parseNumber value="$cur" type="currency"/>
   
  - <li> Parse numeric string (using default &quot;en&quot; locale) and format as currency:
  -  <fmt:locale value="de-de"/>
  + <li> Format &quot;12345.67&quot; as US Dollar:<br>
  +  <fmt:locale value="en-US"/>
  +  <fmt:formatNumber value="12345.67" type="currency"/><br>
  +      then parse its integer portion only and output the result:<br>
  +  <fmt:formatNumber value="12345.67" type="currency" var="cur"/>
  +  <fmt:parseNumber value="$cur" type="currency" integerOnly="true"/>
  +
  + <li> Format &quot;12345.67&quot; as German currency (given string is
  +      parsed using default &quot;en&quot; locale before it is formatted):<br>
  +  <fmt:locale value="de-DE"/>
     <fmt:formatNumber value="12345.67" type="currency"/>
   
  - <li> Parse numeric string (using 'parseLocale' locale) and format as currency:
  -  <fmt:locale value="de-de"/>
  + <li> Format &quot;12345.67&quot; as German currency (given string is parsed
  +      using &quot;de&quot; locale before it is formatted):<br>
  +  <fmt:locale value="de-DE"/>
     <fmt:formatNumber parseLocale="de" type="currency">
      12345.67
     </fmt:formatNumber>
  -</ul>
  + </ul>
   
   </body>
   </html>
  
  
  
  1.9       +66 -72    jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java
  
  Index: BundleSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BundleSupport.java	4 Jan 2002 00:29:21 -0000	1.8
  +++ BundleSupport.java	30 Jan 2002 23:26:33 -0000	1.9
  @@ -87,13 +87,6 @@
   
   
       //*********************************************************************
  -    // Private constants
  -
  -    private static final String FALLBACK_LOCALE =
  -	"javax.servlet.jsp.jstl.i18n.fallbackLocale";
  -
  -
  -    //*********************************************************************
       // Protected state
   
       protected String basename;                          // 'basename' attribute
  @@ -211,10 +204,8 @@
        * use the best matching locale.
        *
        * <li> If no match is found, use the fallback locale given by the
  -     * <tt>javax.servlet.jsp.jstl.i18n.fallbackLocale</tt> scoped attribute,
  -     * if it exists.
  -     *
  -     * <li> Otherwise, use the runtime's default locale.
  +     * <tt>javax.servlet.jsp.jstl.i18n.fallbackLocale</tt> scoped attribute
  +     * or config parameter (if present).
        * </ul>
        *
        * @param pageContext the page in which the resource bundle with the
  @@ -226,34 +217,22 @@
        */
       public static ResourceBundle getBundle(PageContext pageContext,
   					   String basename) {
  -	Locale loc = null;
   	ResourceBundle ret = null;
   	    
  -	loc = LocaleSupport.getLocale(pageContext, LocaleSupport.LOCALE);
  -	if (loc != null) {
  -	    /*
  -	     * Use resource bundle with specified locale. If specified locale
  -	     * is not available, fall back on container's default locale.
  -	     */
  -	    ret = getBundle(basename, loc);
  +	Locale pref = LocaleSupport.getLocale(pageContext,
  +					      LocaleSupport.LOCALE);
  +	if (pref != null) {
  +	    // Use resource bundle with specified locale.
  +	    ret = getBundle(basename, pref);
   	} else {
   	    // use resource bundle with best matching locale
  -	    ret = getBestMatch(pageContext, basename);
  +	    ret = getBestLocaleMatch(pageContext, basename);
   	    if (ret == null) {
   		// no match available, use fallback locale (if present)
  -		loc = LocaleSupport.getLocale(pageContext, FALLBACK_LOCALE);
  -		if (loc != null) {
  -		    ret = getBundle(basename, loc);
  -		} else {
  -		    /*
  -		     * No fallback locale specified. Use container's default
  -		     * locale, which was already considered by
  -		     * ResourceBundle.getBundle() in getBestMatch(), but was
  -		     * not returned by the latter, since it did not match
  -		     * the language/country of any of the client's preferred
  -		     * locales
  -		     */
  -		    ret = getBundle(basename, Locale.getDefault());
  +		pref = LocaleSupport.getLocale(pageContext,
  +					       LocaleSupport.FALLBACK_LOCALE);
  +		if (pref != null) {
  +		    ret = getBundle(basename, pref);
   		}
   	    }
   	}
  @@ -281,8 +260,7 @@
        * does not exist, or the requested resource bundle does not exist
        */
       public static ResourceBundle getDefaultBundle(PageContext pageContext,
  -						  String name) {
  -	
  +						  String name) {	
   	ResourceBundle ret = null;
   
   	String defaultBasename = (String) pageContext.findAttribute(name);
  @@ -300,19 +278,18 @@
       // Private utility methods
       
       /*
  -     * Compares the client's preferred locales (in order of preference) against
  -     * the available locales for the resource bundle with the given base name,
  -     * and returns the resource bundle for the best matching locale.
  -     *
  -     * <p> The best matching locale is a client's preferred locale that matches
  -     * both the language and country components of an available locale for the
  -     * given base name. This is considered an exact match. An exact match may
  -     * exist only if the client's preferred locale specifies a country.
  +     * Returns the resource bundle with the best matching locale.
  +     *
  +     * Each of the client's preferred locales (in order of preference) is
  +     * compared against the available locales (using the
  +     * java.util.ResourceBundle method getBundle()), and the best matching
  +     * locale is determined as the first available locale which either:
        *
  -     * <p> If no exact match exists, the first client locale that matches 
  -     * (just) the language component of an available locale is used.
  +     * - exactly matches a preferred locale
  +     *   (using java.util.Locale.equals()), or
        *
  -     * <p> If still no match is found, <tt>null</tt> is returned.
  +     * - does not have a country component and matches (just) the language 
  +     *   component of a preferred locale.
        *
        * @param pageContext the page in which the resource bundle with the
        * given base name is requested
  @@ -321,8 +298,8 @@
        * @return the resource bundle with the given base name and best matching
        * locale, or <tt>null</tt> if no match was found
        */
  -    private static ResourceBundle getBestMatch(PageContext pageContext,
  -					       String basename) {
  +    private static ResourceBundle getBestLocaleMatch(PageContext pageContext,
  +						     String basename) {
   	ResourceBundle ret = null;
   	
   	// Determine locale from client's browser settings.
  @@ -334,43 +311,60 @@
   	     * locale, so it always contains at least one element.
   	     */
   	    Locale pref = (Locale) enum.nextElement();
  -	    ResourceBundle bundle = getBundle(basename, pref);
  -	    if (bundle == null)
  -		continue;
  -	    Locale avail = bundle.getLocale();
  -	    if (pref.getLanguage().equals(avail.getLanguage())) {
  -		if (pref.getCountry().length() > 0
  -		    && pref.getCountry().equals(avail.getCountry())) {
  -		    // exact match
  -		    ret = bundle;
  -		    break;
  -		} else {
  -		    if (ret == null) {
  -			ret = bundle;
  -		    }
  -		}
  +	    ret = getBundle(basename, pref);
  +	    if (ret != null) {
  +		break;
   	    }
   	}
  -
  +	
   	return ret;
       }
   
       /*
  -     * Gets the resource bundle with the given base name and locale.
  +     * Gets the resource bundle with the given base name and preferred locale.
        * 
  -     * <p> This method simply calls
  -     * <tt>java.util.ResourceBundle.getBundle()</tt> and catches the
  -     * potential <tt>java.util.MissingResourceException</tt>.
  +     * This method calls java.util.ResourceBundle.getBundle(), but ignores
  +     * its return value unless its locale represents an exact or language match
  +     * with the given preferred locale.
        *
        * @param basename the resource bundle base name
  -     * @param loc the requested locale
  +     * @param pref the preferred locale
        *
  -     * @return the requested resource bundle, or <tt>null</tt> if not found
  +     * @return the requested resource bundle, or <tt>null</tt> if no resource
  +     * bundle with the given base name exists or if there is no exact- or
  +     * language-match between the preferred locale and the locale of
  +     * the bundle returned by java.util.ResourceBundle.getBundle().
        */
  -    private static ResourceBundle getBundle(String basename, Locale loc) {
  +    private static ResourceBundle getBundle(String basename, Locale pref) {
   	ResourceBundle ret = null;
  +
   	try {
  -	    ret = ResourceBundle.getBundle(basename, loc);
  +	    ResourceBundle bundle = ResourceBundle.getBundle(basename, pref);
  +	    Locale avail = bundle.getLocale();
  +	    if (pref.equals(avail)) {
  +		// Exact match
  +		ret = bundle;
  +	    } else {
  +		if (pref.getLanguage().equals(avail.getLanguage())
  +		    && (avail.getCountry() == null)) {
  +		    /*
  +		     * Language match.
  +		     * By making sure the available locale does not have a 
  +		     * country and matches the preferred locale's language, we
  +		     * rule out "matches" based on the container's default
  +		     * locale. For example, if the preferred locale is 
  +		     * "en-US", the container's default locale is "en-UK", and
  +		     * there is a resource bundle (with the requested base
  +		     * name) available for "en-UK", ResourceBundle.getBundle()
  +		     * will return it, but even though its language matches
  +		     * that of the preferred locale, we must ignore it,
  +		     * because matches based on the container's default locale
  +		     * are not portable across different containers with
  +		     * different default locales.
  +		     */
  +		    ret = bundle;
  +		}
  +	    }
   	} catch (MissingResourceException mre) {
   	}
   
  
  
  
  1.3       +24 -11    jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/ExceptionSupport.java
  
  Index: ExceptionSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/ExceptionSupport.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ExceptionSupport.java	21 Nov 2001 20:26:36 -0000	1.2
  +++ ExceptionSupport.java	30 Jan 2002 23:26:33 -0000	1.3
  @@ -74,11 +74,16 @@
   public abstract class ExceptionSupport extends TagSupport {
   
       //*********************************************************************
  +    // Private constants
  +    private static final String SERVLET_EXCEPTION =
  +	"javax.servlet.error.exception";
  +
  +    
  +    //*********************************************************************
       // Protected state
   
       protected Exception value;                       // 'value' attribute
       protected ResourceBundle bundle;                 // 'bundle' attribute
  -    protected boolean stackTrace;		     // 'stackTrace' attribute
   
   
       //*********************************************************************
  @@ -92,7 +97,6 @@
       private void init() {
   	value = null;
   	bundle = null;
  -	stackTrace = false;
       }
   
   
  @@ -103,10 +107,24 @@
   	Object[] messageArgs = null;
   
   	if (value == null) {
  +	    /*
  +	     * Check javax.servlet.jsp.jspException request attribute
  +	     * defined in JSP 1.2
  +	     */
   	    value = pageContext.getException();
  -	    if (value == null)
  -		throw new JspTagException(
  -		    Resources.getMessage("EXCEPTION_NOT_IN_ERROR_PAGE"));
  +	    if (value == null) {
  +		/*
  +		 * Check javax.servlet.error.exception request attribute
  +		 * defined in Servlet 2.3
  +		 */
  +		value = (Exception)
  +		    pageContext.getAttribute(SERVLET_EXCEPTION,
  +					     PageContext.REQUEST_SCOPE);
  +		if (value == null) {
  +		    throw new JspTagException(
  +		        Resources.getMessage("EXCEPTION_NOT_IN_ERROR_PAGE"));
  +		}
  +	    }
   	}
   
   	if (bundle == null) {
  @@ -144,12 +162,7 @@
   	}
   
   	try {
  -	    JspWriter writer = pageContext.getOut();
  -	    writer.print(message);
  -	    if (stackTrace) {
  -		writer.newLine();
  -		value.printStackTrace(new PrintWriter(writer));
  -	    }
  +	    pageContext.getOut().print(message);
   	} catch (IOException ioe) {
   	    throw new JspTagException(ioe.getMessage());
   	}
  
  
  
  1.7       +150 -8    jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/FormatNumberSupport.java
  
  Index: FormatNumberSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/FormatNumberSupport.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- FormatNumberSupport.java	11 Jan 2002 22:38:17 -0000	1.6
  +++ FormatNumberSupport.java	30 Jan 2002 23:26:33 -0000	1.7
  @@ -58,6 +58,7 @@
   import java.util.*;
   import java.text.*;
   import java.io.IOException;
  +import java.lang.reflect.*;
   import javax.servlet.jsp.*;
   import javax.servlet.jsp.tagext.*;
   import org.apache.taglibs.standard.tag.common.core.Util;
  @@ -89,35 +90,66 @@
   
   
       //*********************************************************************
  +    // Private constants
  +
  +    private static final Class[] GET_INSTANCE_PARAM_TYPES =
  +	new Class[] { String.class };
  +
  +
  +    //*********************************************************************
       // Protected state
   
  -    protected Object value;                      // 'value' attribute
  -    protected String pattern;                    // 'pattern' attribute
  -    protected Locale parseLocale;                // 'parseLocale' attribute
  +    protected Object value;                    // 'value' attribute
  +    protected String pattern;                  // 'pattern' attribute
  +    protected Locale parseLocale;              // 'parseLocale' attribute
  +    protected String currencyCode;             // 'currencyCode' attribute
  +    protected String currencySymbol;           // 'currencySymbol' attribute
  +    protected boolean isGroupingUsed;          // 'groupingUsed' attribute
  +    protected boolean groupingUsedSpecified;
  +    protected int maxIntegerDigits;            // 'maxIntegerDigits' attribute
  +    protected boolean maxIntegerDigitsSpecified;
  +    protected int minIntegerDigits;            // 'minIntegerDigits' attribute
  +    protected boolean minIntegerDigitsSpecified;
  +    protected int maxFractionDigits;           // 'maxFractionDigits' attribute
  +    protected boolean maxFractionDigitsSpecified;
  +    protected int minFractionDigits;           // 'minFractionDigits' attribute
  +    protected boolean minFractionDigitsSpecified;
   
   
       //*********************************************************************
       // Private state
   
  -    private int type;                            // 'type' attribute
  -    private String var;                          // 'var' attribute
  -    private int scope;                           // 'scope' attribute
  +    private int type;                          // 'type' attribute
  +    private String var;                        // 'var' attribute
  +    private int scope;                         // 'scope' attribute
  +    private static Class currencyClass;
   
   
       //*********************************************************************
       // Constructor and initialization
   
  +    static {
  +	try {
  +	    currencyClass = Class.forName("java.util.Currency");
  +	    // container's runtime is J2SE 1.4 or greater
  +	} catch (Exception cnfe) {
  +	}
  +    }
  +
       public FormatNumberSupport() {
   	super();
   	init();
       }
   
       private void init() {
  -	pattern = var = null;
   	value = null;
  +	pattern = var = currencyCode = currencySymbol = null;
  +	groupingUsedSpecified = false;
  +	maxIntegerDigitsSpecified = minIntegerDigitsSpecified = false;
  +	maxFractionDigitsSpecified = minFractionDigitsSpecified = false;
  +	parseLocale = null;
   	type = NUMBER_TYPE;
   	scope = PageContext.PAGE_SCOPE;
  -	parseLocale = null;
       }
   
   
  @@ -191,18 +223,33 @@
   	case NUMBER_TYPE:
   	    formatter = NumberFormat.getNumberInstance(locale);
   	    if (pattern != null) {
  +		/*
  +		 * Let potential ClassCastException propagate up (will almost
  +		 * never happen)
  +		 */
   		DecimalFormat df = (DecimalFormat) formatter;
   		df.applyPattern(pattern);
   	    }
   	    break;
   	case CURRENCY_TYPE:
   	    formatter = NumberFormat.getCurrencyInstance(locale);
  +	    if ((currencyCode != null) || (currencySymbol != null)) {
  +		try {
  +		    setCurrency(formatter);
  +		} catch (Exception e) {
  +		    throw new JspTagException(e.getMessage());
  +		}
  +	    }
   	    break;
   	case PERCENT_TYPE:
   	    formatter = NumberFormat.getPercentInstance(locale);
   	    break;
   	} // switch
   
  +	// Configure the formatter
  +	configureFormatter(formatter);
  +
  +	// Format given numeric value
   	String formatted = formatter.format(value);
   	if (var != null) {
   	    pageContext.setAttribute(var, formatted, scope);	
  @@ -220,5 +267,100 @@
       // Releases any resources we may have (or inherit)
       public void release() {
   	init();
  +    }
  +
  +
  +    //*********************************************************************
  +    // Private utility methods
  +
  +    private void configureFormatter(NumberFormat formatter) {
  +	if (groupingUsedSpecified)
  +	    formatter.setGroupingUsed(isGroupingUsed);
  +	if (maxIntegerDigitsSpecified)
  +	    formatter.setMaximumIntegerDigits(maxIntegerDigits);
  +	if (minIntegerDigitsSpecified)
  +	    formatter.setMinimumIntegerDigits(minIntegerDigits);
  +	if (maxFractionDigitsSpecified)
  +	    formatter.setMaximumFractionDigits(maxFractionDigits);
  +	if (minFractionDigitsSpecified)
  +	    formatter.setMinimumFractionDigits(minFractionDigits);
  +    }
  +
  +    /*
  +     * Override the formatting locale's default currency symbol with the
  +     * specified currency code (specified via the "currencyCode" attribute) or
  +     * currency symbol (specified via the "currencySymbol" attribute).
  +     *
  +     * If both "currencyCode" and "currencySymbol" are present,
  +     * "currencyCode" takes precedence over "currencySymbol" if the
  +     * java.util.Currency class is defined in the container's runtime (that
  +     * is, if the container's runtime is J2SE 1.4 or greater), and
  +     * "currencySymbol" takes precendence over "currencyCode" otherwise.
  +     *
  +     * If only "currencyCode" is given, it is used as a currency symbol if
  +     * java.util.Currency is not defined.
  +     *
  +     * Example:
  +     *
  +     * JDK    "currencyCode" "currencySymbol" Currency symbol being displayed
  +     * -----------------------------------------------------------------------
  +     * all         ---            ---         Locale's default currency symbol
  +     *
  +     * <1.4        EUR            ---         EUR
  +     * >=1.4       EUR            ---         Locale's currency symbol for Euro
  +     *
  +     * all         ---           \u20AC       \u20AC
  +     * 
  +     * <1.4        EUR           \u20AC       \u20AC
  +     * >=1.4       EUR           \u20AC       Locale's currency symbol for Euro
  +     */
  +    private void setCurrency(NumberFormat currencyFormat) throws Exception {
  +	String code = null;
  +	String symbol = null;
  +
  +	if ((currencyCode != null) && (currencySymbol != null)) {
  +	    if (currencyClass != null)
  +		code = currencyCode;
  +	    else
  +		symbol = currencySymbol;
  +	} else if (currencyCode == null) {
  +	    symbol = currencySymbol;
  +	} else {
  +	    if (currencyClass != null)
  +		code = currencyCode;
  +	    else
  +		symbol = currencyCode;
  +	}
  +
  +	if (code != null) {
  +	    Object[] methodArgs = new Object[1];
  +
  +	    /*
  +	     * java.util.Currency.getInstance()
  +	     */
  +	    Method m = currencyClass.getMethod("getInstance",
  +					       GET_INSTANCE_PARAM_TYPES);
  +	    methodArgs[0] = code;
  +	    Object currency = m.invoke(null, methodArgs);
  +
  +	    /*
  +	     * java.text.NumberFormat.setCurrency()
  +	     */
  +	    Class[] paramTypes = new Class[1];
  +	    paramTypes[0] = currencyClass;
  +	    Class numberFormatClass = Class.forName("java.text.NumberFormat");
  +	    m = numberFormatClass.getMethod("setCurrency", paramTypes);
  +	    methodArgs[0] = currency;
  +	    m.invoke(currencyFormat, methodArgs);
  +	} else {
  +	    /*
  +	     * Let potential ClassCastException propagate up (will almost
  +	     * never happen)
  +	     */
  +	    DecimalFormat df = (DecimalFormat) currencyFormat;
  +	    DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
  +	    dfs.setCurrencySymbol(symbol);
  +	    df.setDecimalFormatSymbols(dfs);
  +	}
       }
   }
  
  
  
  1.9       +86 -38    jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/LocaleSupport.java
  
  Index: LocaleSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/LocaleSupport.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- LocaleSupport.java	10 Jan 2002 02:24:53 -0000	1.8
  +++ LocaleSupport.java	30 Jan 2002 23:26:33 -0000	1.9
  @@ -75,6 +75,8 @@
       // Package-scoped constants
   
       static final String LOCALE = "javax.servlet.jsp.jstl.i18n.locale";
  +    static final String FALLBACK_LOCALE =
  +	"javax.servlet.jsp.jstl.i18n.fallbackLocale";
   
       
       //*********************************************************************
  @@ -236,6 +238,10 @@
        * against the available formatting locales given in the
        * <tt>avail</tt> parameter, and use the best matching locale.
        *
  +     * <li> If no match is found, use the fallback locale given by the
  +     * <tt>javax.servlet.jsp.jstl.i18n.fallbackLocale</tt> scoped attribute
  +     * or config parameter (if present).
  +     *
        * <li> If no match is found, use the runtime's default locale.
        * </ul>
        *
  @@ -243,6 +249,9 @@
        * @param fromTag the formatting action
        * @param format <tt>true</tt> if the formatting action is of type
        * <formatXXX> (as opposed to <parseXXX>), and <tt>false</tt> otherwise
  +     * (if set to <tt>true</tt>, the formatting locale that is returned by
  +     * this method is used to set the response locale).
  +     *
        * @param avail the array of available locales
        *
        * @return the formatting locale to use
  @@ -251,6 +260,8 @@
   				      Tag fromTag,
   				      boolean format,
   				      Locale[] avail) {
  +	Locale[] pref = null;
  +
   	Locale ret = getLocale(pageContext, LOCALE);
   	if (ret == null) {
   	    Tag t = findAncestorWithClass(fromTag, BundleSupport.class);
  @@ -266,21 +277,35 @@
   		    ret = bundle.getLocale();
   		} else {
   		    // get best matching formatting locale
  -		    ret = getBestMatch(pageContext, avail);
  +		    pref = getRequestLocales(pageContext);
  +		    ret = getBestMatch(pref, avail);
   		    if (ret == null) {
  -			// no match available, use runtime's default locale
  -			ret = Locale.getDefault();
  +			/*
  +			 * No match available. Use fallback locale (if defined
  +			 * and available).
  +			 */
  +			ret = getLocale(pageContext, FALLBACK_LOCALE);
  +			if (ret != null) {
  +			    pref = new Locale[1];
  +			    pref[0] = ret;
  +			}
  +			if ((ret == null)
  +			    || ((ret = getBestMatch(pref, avail)) == null)) {
  +			    /*
  +			     * No fallback locale defined, or specified
  +			     * fallback locale not among the available locales.
  +			     * Use runtime's default locale.
  +			     */
  +			    ret = Locale.getDefault();
  +			}
   		    }
   		}
   	    }
   	}
   	
  -	/*
  -	 * If this is a <formatXXX> (as opposed to a <parseXXX>) action,
  -	 * set the response locale
  -	 */
  -	if (format)
  +	if (format) {
   	    LocaleSupport.setResponseLocale(pageContext, ret);
  +	}
   
   	return ret;
       }
  @@ -321,51 +346,74 @@
       // Private utility methods
       
       /*
  -     * Compares the client's preferred locales (in order of preference) against
  -     * the available formatting locales, and returns the best matching locale.
  +     * Returns the best matching formatting locale.
        *
  -     * <p> The best matching locale is a client's preferred locale that matches
  -     * both the language and country components of an available formatting
  -     * locale. This is considered an exact match. An exact match may exist only
  -     * if the client's preferred locale specifies a country.
  +     * Each of the client's preferred locales (in order of preference) is
  +     * compared against the available formatting locales, and the best matching
  +     * locale is determined as the first available locale which either:
        *
  -     * <p> If no exact match exists, the first client locale that matches 
  -     * (just) the language component of an available locale is chosen.
  +     * - exactly matches a preferred locale
  +     *   (using java.util.Locale.equals()), or
        *
  -     * <p> If still no match is found, <tt>null</tt> is returned.
  +     * - does not have a country component and matches (just) the language 
  +     *   component of a preferred locale.
        *
  -     * @param pageContext the page in which the best matching formatting
  -     * locale needs to be determined
  +     * @param pref the preferred locales
        * @param avail the available formatting locales
        *
        * @return the best matching formatting locale, or <tt>null</tt> if no
        * match was found
        */
  -    private static Locale getBestMatch(PageContext pageContext,
  -				       Locale[] avail) {
  +    private static Locale getBestMatch(Locale[] pref, Locale[] avail) {
   	Locale ret = null;
   
  -	boolean foundExactMatch = false;
  -	for (Enumeration enum = pageContext.getRequest().getLocales();
  -	     enum.hasMoreElements() && !foundExactMatch; ) {
  -	    Locale pref = (Locale) enum.nextElement();
  -	    for (int i=0; i<avail.length; i++) {
  -		if (pref.getLanguage().equals(avail[i].getLanguage())) {
  -		    if (pref.getCountry().length() > 0
  -			&& pref.getCountry().equals(avail[i].getCountry())) {
  -			// exact match
  -			ret = avail[i];
  -			foundExactMatch = true;	
  +	boolean matchFound = false;
  +	for (int i=0; (i<pref.length) && !matchFound; i++) {
  +	    for (int j=0; j<avail.length; j++) {
  +		if (pref[i].equals(avail[j])) {
  +		    // Exact match
  +		    ret = avail[j];
  +		    matchFound = true;
  +		    break;
  +		} else {
  +		    if (pref[i].getLanguage().equals(avail[j].getLanguage())
  +			&& (avail[j].getCountry() == null)) {
  +			// Language match
  +			ret = avail[j];
  +			matchFound = true;
   			break;
  -		    } else {
  -			if (ret == null) {
  -			    ret = avail[i];
  -			}
   		    }
   		}
  -	    } // for
  -	} // for
  +	    }
  +	}
   
  +	return ret;
  +    }
  +
  +    /*
  +     * Returns the preferred locales from the request as an array.
  +     *
  +     * @param pageContext the page in which the preferred request locales need
  +     * to be determined
  +     *
  +     * @return array of preferred request locales
  +     */
  +    private static Locale[] getRequestLocales(PageContext pageContext) {
  +	Vector vec = new Vector();
  +	for (Enumeration enum = pageContext.getRequest().getLocales();
  +	     enum.hasMoreElements(); ) {
  +	    vec.addElement((Locale) enum.nextElement());
  +	}
  +	
  +	/*
  +	 * The Enumeration returned by ServletRequest.getLocales() always
  +	 * contains at least one element: the default locale for the server.
  +	 */
  +	Locale[] ret = new Locale[vec.size()];
  +	for (int i=0; i<ret.length; i++) {
  +	    ret[i] = (Locale) vec.elementAt(i);
  +	}
  +	    
   	return ret;
       }
   }
  
  
  
  1.5       +14 -7     jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/ParseNumberSupport.java
  
  Index: ParseNumberSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/common/fmt/ParseNumberSupport.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ParseNumberSupport.java	18 Dec 2001 01:53:15 -0000	1.4
  +++ ParseNumberSupport.java	30 Jan 2002 23:26:33 -0000	1.5
  @@ -78,6 +78,8 @@
       protected String value;                      // 'value' attribute
       protected String pattern;                    // 'pattern' attribute
       protected Locale parseLocale;                // 'parseLocale' attribute
  +    protected boolean isIntegerOnly;             // 'integerOnly' attribute
  +    protected boolean integerOnlySpecified;
   
   
       //*********************************************************************
  @@ -98,9 +100,10 @@
   
       private void init() {
   	value = pattern = var = null;
  +	parseLocale = null;
  +	integerOnlySpecified = false;
   	type = FormatNumberSupport.NUMBER_TYPE;
   	scope = PageContext.PAGE_SCOPE;
  -	parseLocale = null;
       }
   
   
  @@ -147,27 +150,31 @@
   	        NumberFormat.getAvailableLocales());
   
   	// Get appropriate formatter instance
  -	NumberFormat formatter = null;
  +	NumberFormat parser = null;
   	switch (type) {
   	case FormatNumberSupport.NUMBER_TYPE:
  -	    formatter = NumberFormat.getNumberInstance(locale);
  +	    parser = NumberFormat.getNumberInstance(locale);
   	    if (pattern != null) {
  -		DecimalFormat df = (DecimalFormat) formatter;
  +		DecimalFormat df = (DecimalFormat) parser;
   		df.applyPattern(pattern);
   	    }
   	    break;
   	case FormatNumberSupport.CURRENCY_TYPE:
  -	    formatter = NumberFormat.getCurrencyInstance(locale);
  +	    parser = NumberFormat.getCurrencyInstance(locale);
   	    break;
   	case FormatNumberSupport.PERCENT_TYPE:
  -	    formatter = NumberFormat.getPercentInstance(locale);
  +	    parser = NumberFormat.getPercentInstance(locale);
   	    break;
   	} // switch
   
  +	// Configure parser
  +	if (integerOnlySpecified)
  +	    parser.setParseIntegerOnly(isIntegerOnly);
  +
   	// Parse number
   	Number parsed = null;
   	try {
  -	    parsed = formatter.parse(value);
  +	    parsed = parser.parse(value);
   	} catch (ParseException pe) {
   	    throw new JspTagException(pe.getMessage());
   	}
  
  
  
  1.3       +1 -18     jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/el/fmt/ExceptionTag.java
  
  Index: ExceptionTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/el/fmt/ExceptionTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ExceptionTag.java	9 Jan 2002 16:56:10 -0000	1.2
  +++ ExceptionTag.java	30 Jan 2002 23:26:33 -0000	1.3
  @@ -76,7 +76,6 @@
   
       private String value_;                       // stores EL-based property
       private String bundle_;		         // stores EL-based property
  -    private String stackTrace_;		         // stores EL-based property
   
   
       //*********************************************************************
  @@ -126,11 +125,6 @@
           this.bundle_ = bundle_;
       }
   
  -    // for EL-based attribute
  -    public void setStackTrace(String stackTrace_) {
  -        this.stackTrace_ = stackTrace_;
  -    }
  -
   
       //*********************************************************************
       // Private (utility) methods
  @@ -138,7 +132,7 @@
       // (re)initializes state (during release() or construction)
       private void init() {
           // null implies "no expression"
  -	value_ = bundle_ = stackTrace_ = null;
  +	value_ = bundle_  = null;
       }
   
       // Evaluates expressions as necessary
  @@ -156,16 +150,5 @@
   	bundle = (ResourceBundle) ExpressionUtil.evalNotNull(
   	    "exception", "bundle", bundle_, ResourceBundle.class, this,
   	    pageContext);
  -
  -	if (stackTrace_ != null) {
  -	    if (stackTrace_.equalsIgnoreCase("false"))
  -	        stackTrace = false;
  -	    else if (stackTrace_.equalsIgnoreCase("true"))
  -		stackTrace = true;
  -	    else
  -		throw new JspTagException(
  -		    Resources.getMessage("EXCEPTION_STACKTRACE_BOOLEAN",
  -					 stackTrace_));
  -	}
       }
   }
  
  
  
  1.3       +101 -3    jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/el/fmt/FormatNumberTag.java
  
  Index: FormatNumberTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/el/fmt/FormatNumberTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FormatNumberTag.java	3 Dec 2001 22:43:50 -0000	1.2
  +++ FormatNumberTag.java	30 Jan 2002 23:26:33 -0000	1.3
  @@ -76,6 +76,13 @@
       private String value_;                       // stores EL-based property
       private String pattern_;		         // stores EL-based property
       private String parseLocale_;	         // stores EL-based property
  +    private String currencyCode_;   	         // stores EL-based property
  +    private String currencySymbol_;   	         // stores EL-based property
  +    private String groupingUsed_;   	         // stores EL-based property
  +    private String maxIntegerDigits_;   	 // stores EL-based property
  +    private String minIntegerDigits_;   	 // stores EL-based property
  +    private String maxFractionDigits_;   	 // stores EL-based property
  +    private String minFractionDigits_;   	 // stores EL-based property
   
   
       //*********************************************************************
  @@ -130,6 +137,46 @@
           this.parseLocale_ = parseLocale_;
       }
   
  +    // for EL-based attribute
  +    public void setCurrencyCode(String currencyCode_) {
  +        this.currencyCode_ = currencyCode_;
  +    }
  +
  +    // for EL-based attribute
  +    public void setCurrencySymbol(String currencySymbol_) {
  +        this.currencySymbol_ = currencySymbol_;
  +    }
  +
  +    // for EL-based attribute
  +    public void setGroupingUsed(String groupingUsed_) {
  +        this.groupingUsed_ = groupingUsed_;
  +	this.groupingUsedSpecified = true;
  +    }
  +
  +    // for EL-based attribute
  +    public void setMaxIntegerDigits(String maxIntegerDigits_) {
  +        this.maxIntegerDigits_ = maxIntegerDigits_;
  +	this.maxIntegerDigitsSpecified = true;
  +    }
  +
  +    // for EL-based attribute
  +    public void setMinIntegerUsed(String minIntegerDigits_) {
  +        this.minIntegerDigits_ = minIntegerDigits_;
  +	this.minIntegerDigitsSpecified = true;
  +    }
  +
  +    // for EL-based attribute
  +    public void setMaxFractionDigits(String maxFractionDigits_) {
  +        this.maxFractionDigits_ = maxFractionDigits_;
  +	this.maxFractionDigitsSpecified = true;
  +    }
  +
  +    // for EL-based attribute
  +    public void minFractionDigits(String minFractionDigits_) {
  +        this.minFractionDigits_ = minFractionDigits_;
  +	this.minFractionDigitsSpecified = true;
  +    }
  +
   
       //*********************************************************************
       // Private (utility) methods
  @@ -138,10 +185,16 @@
       private void init() {
           // null implies "no expression"
   	value_ = pattern_ = parseLocale_ = null;
  +	currencyCode_ = currencySymbol_ = null;
  +	groupingUsed_ = null;
  +	maxIntegerDigits_ = minIntegerDigits_ = null;
  +	maxFractionDigits_ = minFractionDigits_ = null;
       }
   
       // Evaluates expressions as necessary
       private void evaluateExpressions() throws JspException {
  +	Object r = null;
  +
           /* 
            * Note: we don't check for type mismatches here; we assume
            * the expression evaluator will return the expected type
  @@ -152,15 +205,60 @@
   
   	value = ExpressionUtil.evalNotNull(
   	    "formatNumber", "value", value_, Object.class, this, pageContext);
  +
   	pattern = (String) ExpressionUtil.evalNotNull(
   	    "formatNumber", "pattern", pattern_, String.class, this,
   	    pageContext);
   
  -	String pl = (String) ExpressionUtil.evalNotNull(
  +	// parseLocale
  +	r = ExpressionUtil.evalNotNull(
   	    "formatNumber", "parseLocale", parseLocale_, String.class, this,
   	    pageContext);
  -	if (pl != null)
  -	    parseLocale = LocaleSupport.parseLocale(pl, null);
  +	if (r != null)
  +	    parseLocale = LocaleSupport.parseLocale((String) r, null);
  +
  +	currencyCode = (String) ExpressionUtil.evalNotNull(
  +	    "formatNumber", "currencyCode", currencyCode_, String.class, this,
  +	    pageContext);
  +
  +	currencySymbol = (String) ExpressionUtil.evalNotNull(
  +	    "formatNumber", "currencySymbol", currencySymbol_, String.class,
  +	    this, pageContext);
  +
  +	// groupingUsed
  +	r = ExpressionUtil.evalNotNull(
  +	    "formatNumber", "groupingUsed", groupingUsed_, Boolean.class, this,
  +	    pageContext);
  +	if (r != null)
  +	    isGroupingUsed = ((Boolean) r).booleanValue();
  +	
  +	// maxIntegerDigits
  +	r = ExpressionUtil.evalNotNull(
  +	    "formatNumber", "maxIntegerDigits", maxIntegerDigits_,
  +	    Integer.class, this, pageContext);
  +	if (r != null)
  +	    maxIntegerDigits = ((Integer) r).intValue();
  +
  +	// minIntegerDigits	
  +	r = ExpressionUtil.evalNotNull(
  +	    "formatNumber", "minIntegerDigits", minIntegerDigits_,
  +	    Integer.class, this, pageContext);
  +	if (r != null)
  +	    minIntegerDigits = ((Integer) r).intValue();
  +	
  +	// maxFractionDigits
  +	r = ExpressionUtil.evalNotNull(
  +	    "formatNumber", "maxFractionDigits", maxFractionDigits_,
  +	    Integer.class, this, pageContext);
  +	if (r != null)
  +	    maxFractionDigits = ((Integer) r).intValue();
  +	
  +	// minFractionDigits
  +	r = ExpressionUtil.evalNotNull(
  +	    "formatNumber", "minFractionDigits", minFractionDigits_,
  +	    Integer.class, this, pageContext);
  +	if (r != null)
  +	    minFractionDigits = ((Integer) r).intValue();
       }
   }
   
  
  
  
  1.3       +20 -4     jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/el/fmt/ParseNumberTag.java
  
  Index: ParseNumberTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/el/fmt/ParseNumberTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ParseNumberTag.java	3 Dec 2001 22:43:50 -0000	1.2
  +++ ParseNumberTag.java	30 Jan 2002 23:26:33 -0000	1.3
  @@ -76,6 +76,7 @@
       private String value_;                       // stores EL-based property
       private String pattern_;		         // stores EL-based property
       private String parseLocale_;	         // stores EL-based property
  +    private String integerOnly_;	         // stores EL-based property
   
   
       //*********************************************************************
  @@ -130,6 +131,12 @@
           this.parseLocale_ = parseLocale_;
       }
   
  +    // for EL-based attribute
  +    public void setIntegerOnly(String integerOnly_) {
  +        this.integerOnly_ = integerOnly_;
  +	this.integerOnlySpecified = true;
  +    }
  +
   
       //*********************************************************************
       // Private (utility) methods
  @@ -137,11 +144,13 @@
       // (re)initializes state (during release() or construction)
       private void init() {
           // null implies "no expression"
  -	value_ = pattern_ = parseLocale_ = null;
  +	value_ = pattern_ = parseLocale_ = integerOnly_ = null;
       }
   
       // Evaluates expressions as necessary
       private void evaluateExpressions() throws JspException {
  +	Object r = null;
  +
           /* 
            * Note: we don't check for type mismatches here; we assume
            * the expression evaluator will return the expected type
  @@ -152,15 +161,22 @@
   
   	value = (String) ExpressionUtil.evalNotNull(
   	    "parseNumber", "value", value_, String.class, this, pageContext);
  +
   	pattern = (String) ExpressionUtil.evalNotNull(
   	    "parseNumber", "pattern", pattern_, String.class, this,
   	    pageContext);
   
  -	String pl = (String) ExpressionUtil.evalNotNull(
  +	r = ExpressionUtil.evalNotNull(
   	    "parseNumber", "parseLocale", parseLocale_, String.class, this,
   	    pageContext);
  -	if (pl != null)
  -	    parseLocale = LocaleSupport.parseLocale(pl, null);
  +	if (r != null)
  +	    parseLocale = LocaleSupport.parseLocale((String) r, null);
  +
  +	r = ExpressionUtil.evalNotNull(
  +	    "parseNumber", "integerOnly", integerOnly_, Boolean.class, this,
  +	    pageContext);
  +	if (r != null)
  +	    isIntegerOnly = ((Boolean) r).booleanValue();
       }
   }
   
  
  
  
  1.2       +0 -5      jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt/ExceptionTag.java
  
  Index: ExceptionTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt/ExceptionTag.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExceptionTag.java	21 Nov 2001 07:38:51 -0000	1.1
  +++ ExceptionTag.java	30 Jan 2002 23:26:33 -0000	1.2
  @@ -81,9 +81,4 @@
       public void setBundle(ResourceBundle bundle) throws JspTagException {
           this.bundle = bundle;
       }
  -
  -    // for tag attribute
  -    public void setStackTrace(boolean stackTrace) throws JspTagException {
  -        this.stackTrace = stackTrace;
  -    }
   }
  
  
  
  1.3       +42 -0     jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt/FormatNumberTag.java
  
  Index: FormatNumberTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt/FormatNumberTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FormatNumberTag.java	3 Dec 2001 22:43:50 -0000	1.2
  +++ FormatNumberTag.java	30 Jan 2002 23:26:33 -0000	1.3
  @@ -86,4 +86,46 @@
       public void setParseLocale(String parseLocale) throws JspTagException {
           this.parseLocale = LocaleSupport.parseLocale(parseLocale, null);
       }
  +
  +    // for tag attribute
  +    public void setCurrencyCode(String currencyCode) throws JspTagException {
  +        this.currencyCode = currencyCode;
  +    }
  +
  +    // for tag attribute
  +    public void setCurrencySymbol(String currencySymbol)
  +	throws JspTagException {
  +        this.currencySymbol = currencySymbol;
  +    }
  +
  +    // for tag attribute
  +    public void setGroupingUsed(boolean isGroupingUsed)
  +	throws JspTagException {
  +        this.isGroupingUsed = isGroupingUsed;
  +	this.groupingUsedSpecified = true;
  +    }
  +
  +    // for tag attribute
  +    public void setMaxIntegerDigits(int maxDigits) throws JspTagException {
  +        this.maxIntegerDigits = maxDigits;
  +	this.maxIntegerDigitsSpecified = true;
  +    }
  +
  +    // for tag attribute
  +    public void setMinIntegerDigits(int minDigits) throws JspTagException {
  +        this.minIntegerDigits = minDigits;
  +	this.minIntegerDigitsSpecified = true;
  +    }
  +
  +    // for tag attribute
  +    public void setMaxFractionDigits(int maxDigits) throws JspTagException {
  +        this.maxFractionDigits = maxDigits;
  +	this.maxFractionDigitsSpecified = true;
  +    }
  +
  +    // for tag attribute
  +    public void setMinFractionDigits(int minDigits) throws JspTagException {
  +        this.minFractionDigits = minDigits;
  +	this.minFractionDigitsSpecified = true;
  +    }
   }
  
  
  
  1.3       +6 -0      jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt/ParseNumberTag.java
  
  Index: ParseNumberTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/tag/rt/fmt/ParseNumberTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ParseNumberTag.java	3 Dec 2001 22:43:50 -0000	1.2
  +++ ParseNumberTag.java	30 Jan 2002 23:26:33 -0000	1.3
  @@ -86,4 +86,10 @@
       public void setParseLocale(String parseLocale) throws JspTagException {
           this.parseLocale = LocaleSupport.parseLocale(parseLocale, null);
       }
  +
  +    // for tag attribute
  +    public void setIntegerOnly(boolean isIntegerOnly) throws JspTagException {
  +        this.isIntegerOnly = isIntegerOnly;
  +	this.integerOnlySpecified = true;
  +    }
   }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>