diff --git a/api/src/main/java/jakarta/faces/convert/NumberConverter.java b/api/src/main/java/jakarta/faces/convert/NumberConverter.java
index c1ed215037..b45a9fdcfa 100755
--- a/api/src/main/java/jakarta/faces/convert/NumberConverter.java
+++ b/api/src/main/java/jakarta/faces/convert/NumberConverter.java
@@ -27,6 +27,7 @@
import java.text.ParsePosition;
import java.util.Currency;
import java.util.Locale;
+import java.util.regex.Pattern;
import jakarta.el.ValueExpression;
import jakarta.faces.component.PartialStateHolder;
@@ -61,6 +62,11 @@ public class NumberConverter implements Converter, PartialStateHolder
public static final String PATTERN_ID = "jakarta.faces.converter.NumberConverter.PATTERN";
public static final String PERCENT_ID = "jakarta.faces.converter.NumberConverter.PERCENT";
+ private static final Pattern FIXED_WIDTH_WHITESPACE =
+ Pattern.compile("[\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000]");
+ private static final Pattern ZERO_WIDTH_WHITESPACE =
+ Pattern.compile("[\u200b-\u200d\u2060\ufeff]");
+
private String _currencyCode;
private String _currencySymbol;
private Locale _locale;
@@ -89,17 +95,11 @@ public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, St
Assert.notNull(facesContext, "facesContext");
Assert.notNull(uiComponent, "uiComponent");
- if (value == null)
- {
- return null;
- }
-
- value = value.trim();
- if (value.length() < 1)
+ if (value == null || value.isBlank())
{
return null;
}
-
+
NumberFormat format = getNumberFormat(facesContext);
format.setParseIntegerOnly(_integerOnly);
@@ -122,65 +122,89 @@ public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, St
}
}
- DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
- boolean changed = false;
- if(dfs.getGroupingSeparator() == '\u00a0')
- {
- dfs.setGroupingSeparator(' ');
- df.setDecimalFormatSymbols(dfs);
- value = value.replace('\u00a0', ' ');
- changed = true;
- }
-
formatCurrency(format);
try
{
+ DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
+ char origGroupingSep = symbols.getGroupingSeparator();
+ String origPrefix = df.getPositivePrefix();
+ String origSuffix = df.getPositiveSuffix();
+ String origNegPrefix = df.getNegativePrefix();
+ String origNegSuffix = df.getNegativeSuffix();
+
+ boolean hasFixedWidthWhitespace =
+ FIXED_WIDTH_WHITESPACE.matcher(String.valueOf(origGroupingSep)).matches()
+ || FIXED_WIDTH_WHITESPACE.matcher(origPrefix).find()
+ || FIXED_WIDTH_WHITESPACE.matcher(origSuffix).find()
+ || FIXED_WIDTH_WHITESPACE.matcher(origNegPrefix).find()
+ || FIXED_WIDTH_WHITESPACE.matcher(origNegSuffix).find();
+
+ if (hasFixedWidthWhitespace)
+ {
+ String normalizedValue = normalizeWhitespace(value);
+
+ if (FIXED_WIDTH_WHITESPACE.matcher(String.valueOf(origGroupingSep)).matches())
+ {
+ symbols.setGroupingSeparator(' ');
+ symbols.setMonetaryGroupingSeparator(' ');
+ }
+
+ df.setDecimalFormatSymbols(symbols);
+ df.setPositivePrefix(normalizeWhitespace(origPrefix));
+ df.setPositiveSuffix(normalizeWhitespace(origSuffix));
+ df.setNegativePrefix(normalizeWhitespace(origNegPrefix));
+ df.setNegativeSuffix(normalizeWhitespace(origNegSuffix));
+
+ try
+ {
+ return parse(normalizedValue, format, destType);
+ }
+ catch (ParseException pe)
+ {
+ symbols.setGroupingSeparator(origGroupingSep);
+ symbols.setMonetaryGroupingSeparator(origGroupingSep);
+ df.setDecimalFormatSymbols(symbols);
+ df.setPositivePrefix(origPrefix);
+ df.setPositiveSuffix(origSuffix);
+ df.setNegativePrefix(origNegPrefix);
+ df.setNegativeSuffix(origNegSuffix);
+ }
+ }
+
return parse(value, format, destType);
}
catch (ParseException e)
{
- if(changed)
+ if (getPattern() != null)
{
- dfs.setGroupingSeparator('\u00a0');
- df.setDecimalFormatSymbols(dfs);
+ throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
+ PATTERN_ID,
+ new Object[]{value, "$###,###", MessageUtils.getLabel(facesContext, uiComponent)}));
}
- try
+ else if (getType().equals("number"))
{
- return parse(value, format, destType);
+ throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
+ NUMBER_ID,
+ new Object[]{value, format.format(21),
+ MessageUtils.getLabel(facesContext, uiComponent)}));
}
- catch (ParseException pe)
+ else if (getType().equals("currency"))
{
- if (getPattern() != null)
- {
- throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
- PATTERN_ID,
- new Object[]{value, "$###,###", MessageUtils.getLabel(facesContext, uiComponent)}));
- }
- else if (getType().equals("number"))
- {
- throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
- NUMBER_ID,
- new Object[]{value, format.format(21),
- MessageUtils.getLabel(facesContext, uiComponent)}));
- }
- else if (getType().equals("currency"))
- {
- throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
- CURRENCY_ID,
- new Object[]{value, format.format(42.25),
- MessageUtils.getLabel(facesContext, uiComponent)}));
- }
- else if (getType().equals("percent"))
- {
- throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
- PERCENT_ID,
- new Object[]{value, format.format(.90),
- MessageUtils.getLabel(facesContext, uiComponent)}));
- }
+ throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
+ CURRENCY_ID,
+ new Object[]{value, format.format(42.25),
+ MessageUtils.getLabel(facesContext, uiComponent)}));
+ }
+ else if (getType().equals("percent"))
+ {
+ throw new ConverterException(MessageUtils.getErrorMessage(facesContext,
+ PERCENT_ID,
+ new Object[]{value, format.format(.90),
+ MessageUtils.getLabel(facesContext, uiComponent)}));
}
}
-
+
return null;
}
@@ -587,6 +611,12 @@ public void setType(String type)
clearInitialState();
}
+ private static String normalizeWhitespace(String text)
+ {
+ String normalized = FIXED_WIDTH_WHITESPACE.matcher(text).replaceAll(" ");
+ return ZERO_WIDTH_WHITESPACE.matcher(normalized).replaceAll("");
+ }
+
private DecimalFormatSymbols getDecimalFormatSymbols()
{
return new DecimalFormatSymbols(getLocale());
diff --git a/extensions/quarkus/pom.xml b/extensions/quarkus/pom.xml
index dc5e55437f..f62f0992e4 100644
--- a/extensions/quarkus/pom.xml
+++ b/extensions/quarkus/pom.xml
@@ -43,6 +43,9 @@
3.2.9.Final
3.0.0
+ 17
+ 17
+ 17
diff --git a/impl/pom.xml b/impl/pom.xml
index 945bcc51f8..1a3b631bbf 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -35,7 +35,7 @@
https://myfaces.apache.org/#/core40
- 2.0.19
+ 2.0.27
@@ -579,7 +579,7 @@
COMPAT
- -Djava.locale.providers=COMPAT
+ -Djava.locale.providers=COMPAT --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED
diff --git a/parent/pom.xml b/parent/pom.xml
index c20fb3d4cc..b3906be95c 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -195,13 +195,10 @@
1.9.1
-
org.apache.felix
maven-bundle-plugin
- 4.0.0
+ 5.1.9