You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gc...@apache.org on 2008/12/20 01:31:53 UTC

svn commit: r728194 - in /myfaces/trinidad/trunk_1.2.x: trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/ trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/

Author: gcrawford
Date: Fri Dec 19 16:31:53 2008
New Revision: 728194

URL: http://svn.apache.org/viewvc?rev=728194&view=rev
Log:
TRINIDAD-1338 Users shouldn't be forced to enter % or currency symbols

Modified:
    myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/NumberConverter.java
    myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberConverter.js
    myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberFormat.js

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/NumberConverter.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/NumberConverter.java?rev=728194&r1=728193&r2=728194&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/NumberConverter.java (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/convert/NumberConverter.java Fri Dec 19 16:31:53 2008
@@ -181,8 +181,7 @@
     UIComponent component,
     String value)
   {
-
-    if ( null == context || null == component )
+    if (null == context || null == component)
     {
       throw new NullPointerException(_LOG.getMessage(
         "NULL_FACESCONTEXT_OR_UICOMPONENT"));
@@ -210,30 +209,63 @@
     NumberFormat fmt = _getNumberFormat(pattern, type, locale, reqCtx);
     
     DecimalFormat df = (DecimalFormat)fmt;
-    df.setParseBigDecimal(true);
+    df.setParseBigDecimal(true); // TODO What does this do?
     DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
-
+    
     // We change the grouping_separator b/c TRINIDAD-849
-    // we parse a second-time, once the first run fails
     // source is this JDK bug: 4510618.
     boolean changed = false;
-    if(dfs.getGroupingSeparator() == '\u00a0')
+    if (dfs.getGroupingSeparator() == '\u00a0')
     {
+      // In some locales, such as fr_FR, the grouping separator is '\u00a0', a 
+      // non-breaking space. However, users will normally enter a regular space 
+      // character into an input field, so in order for the input to be parsed 
+      // correctly, we set the grouping separator to a regular space character. 
       dfs.setGroupingSeparator(' ');
       df.setDecimalFormatSymbols(dfs);
+      
+      // In the (rare) case that the user actually enters a non-breaking space, 
+      // we replace it with a regular space. This should be fine, since the 
+      // percent format for fr_FR is " %" (regular space followed by percent).
+      value = value.replace('\u00a0', ' ');
+      
       changed = true;
     }
-    ParsePosition pp = new ParsePosition(0);
-    Number num = (Number) fmt.parseObject(value,pp);
-    if(changed)
-    {
-      dfs.setGroupingSeparator('\u00a0');
-      df.setDecimalFormatSymbols(dfs);
+    
+    ParsePosition pp = new ParsePosition(0);  
+    Number num = (Number)fmt.parseObject(value, pp);   
+    
+    // The following determines whether the percent/currency symbol was left off.
+    int typeIdx = _getType(pattern, type);
+    if (num == null && (typeIdx == _CURRENCY_TYPE || typeIdx == _PERCENT_TYPE))
+    {
+      // For parsing 'value' as a Number when the percent/currency symbol is left off.
+      NumberFormat nfmt = NumberFormat.getNumberInstance(locale);
+      DecimalFormat ndf = (DecimalFormat)nfmt;
+      ndf.setParseBigDecimal(true); // TODO What does this do?
+      DecimalFormatSymbols ndfs = null;
+      
+      if (changed)
+      {
+        ndfs = ndf.getDecimalFormatSymbols();
+        ndfs.setGroupingSeparator(' ');
+        ndf.setDecimalFormatSymbols(ndfs);
+      }
+      
+      // Assume the percent/currency symbol was left off, in which case we should 
+      // be able to parse 'value' as a Number.
+      // An error occured, so the index of pp should still be 0.
+      num = (Number)nfmt.parseObject(value, pp);      
+      if("percent".equals(type) && num != null)
+        num = num.doubleValue() / 100.0;
     }
     
-    if(num == null)
+    // Change it back, since we could have been handed a cached reference. This 
+    // may not be thread-safe, but it probably doesn't have to be.
+    if (changed)
     {
-      num = (Number) fmt.parseObject(value, pp);
+      dfs.setGroupingSeparator('\u00a0');
+      df.setDecimalFormatSymbols(dfs);
     }
 
     if (pp.getIndex() != value.length())
@@ -257,6 +289,7 @@
       throw new ConverterException(
         getConvertMessage(context, component, value, params));
     }
+
     // if we set setParseIntegerOnly(isIntegerOnly()) - This may result in
     // the formatter stopping to parse after the first decimal point.
     // that is number of value 222.22 which is legitimate, hence our test would
@@ -269,8 +302,8 @@
       return Long.valueOf(num.longValue());
 
     return num;
-
   }
+
   /**
    *
    * @param context {@link FacesContext} for the request being processed
@@ -1307,4 +1340,4 @@
     _EXAMPLE_PERCENT = 0.3423d;
     _EXAMPLE_CURRENCY = 10250;
   }
-}
\ No newline at end of file
+}

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberConverter.js
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberConverter.js?rev=728194&r1=728193&r2=728194&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberConverter.js (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberConverter.js Fri Dec 19 16:31:53 2008
@@ -234,50 +234,55 @@
     var parsedValue;
     if(this._type=="percent" || this._type=="currency")
     {
+      // TODO matzew - see TRINIDAD-682
+      // Remove the thousands separator - which Javascript doesn't want to see
+      var groupingSeparator = getLocaleSymbols().getGroupingSeparator();
+      var grouping = new RegExp("\\" + groupingSeparator, "g");
+      numberString = numberString.replace(grouping, "");
+
+      // Then change the decimal separator into a period, the only
+      // decimal separator allowed by JS
+      var decimalSeparator = getLocaleSymbols().getDecimalSeparator();
+      var decimal = new RegExp("\\" + decimalSeparator, "g");
+      numberString = numberString.replace(decimal, ".");
+      
       try
       {
-        //TODO matzew - see TRINIDAD-682
-        // Remove the thousands separator - which Javascript doesn't want to see
-        var groupingSeparator = getLocaleSymbols().getGroupingSeparator();
-        var grouping = new RegExp("\\" + groupingSeparator,  "g");
-        numberString = numberString.replace(grouping, "");
-
-        // Then change the decimal separator into a period, the only
-        // decimal separator allowed by JS
-        var decimalSeparator = getLocaleSymbols().getDecimalSeparator();
-        var decimal = new RegExp("\\" + decimalSeparator,  "g");
-        numberString = numberString.replace(decimal, ".");
-
-        //parse the numberString
-        numberString = this._numberFormat.parse(numberString)+"";
-
-        //to be able to pass the _decimalParse, we replace the decimal separator...
-        var jsSeparator = new RegExp("\\" + ".",  "g");
-        numberString = numberString.replace(jsSeparator, decimalSeparator);
+        // parse the numberString
+        numberString = this._numberFormat.parse(numberString)+"";     
       }
       catch(e)
       {
-        var facesMessage;
-        var example = this._numberFormat.format(this._example);
-        var key = "org.apache.myfaces.trinidad.convert.NumberConverter.CONVERT_" + this._type.toUpperCase();
-        if(this._messages && this._messages[this._type])
+        // The user could have just left off the percent/currency symbol, so try 
+        // parsing 'numberString' as a Number instead; if it still fails, then 
+        // throw a converter exception.
+        try
         {
-          facesMessage = _createCustomFacesMessage(TrMessageFactory.getSummaryString(key),
-                                                  this._messages[this._type],
-                                                  label,
-                                                  numberString,
-                                                  example);
+          numberString = TrNumberFormat.getNumberInstance().parse(numberString)+"";
         }
-        else
+        catch (e)
         {
-          facesMessage = _createFacesMessage(key,
-                                            label,
-                                            numberString,
-                                            example);
-        }
+          var facesMessage;
+          var example = this._numberFormat.format(this._example);
+          var key = "org.apache.myfaces.trinidad.convert.NumberConverter.CONVERT_" + this._type.toUpperCase();
+          if (this._messages && this._messages[this._type])
+          {
+            facesMessage = _createCustomFacesMessage(TrMessageFactory.getSummaryString(key), this._messages[this._type], label, numberString, example);
+          }
+          else 
+          {
+            facesMessage = _createFacesMessage(key, label, numberString, example);
+          }
+
           throw new TrConverterException(facesMessage);
+        }
       }
+      
+      // to be able to pass the _decimalParse, we replace the decimal separator...
+      var jsSeparator = new RegExp("\\" + ".",  "g");
+      numberString = numberString.replace(jsSeparator, decimalSeparator);
     }
+    
     parsedValue = _decimalParse(numberString, 
                          this._messages,
                          "org.apache.myfaces.trinidad.convert.NumberConverter",

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberFormat.js
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberFormat.js?rev=728194&r1=728193&r2=728194&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberFormat.js (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/NumberFormat.js Fri Dec 19 16:31:53 2008
@@ -238,6 +238,22 @@
     return this.stringToPercentage(string);
   else if (this._type=="currency")
     return this.stringToCurrency(string);
+    
+  // ELSE: assume this._type=="number"
+  return this.stringToNumber(string);
+}
+
+/**
+ * Formats a number string into a number.
+ */
+TrNumberFormat.prototype.stringToNumber = function(numberString)
+{
+  numberString = parseFloat(numberString);
+  if(isNaN(numberString))
+  {
+    throw new TrParseException("not able to parse number");
+  }
+  return numberString;
 }
 
 /**