[ https://jira.codehaus.org/browse/JBEHAVE-739?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=294175#comment-294175 ]
Daniel Schneller commented on JBEHAVE-739: ------------------------------------------ I suggest this implementation of {{canonicalize}}. I don't have access to GitHub currently, so I cannot create a patch yet. I will do so, including the tests I have locally for it, when no objections come up: {code:title="ParametersConverters.java"} /** * Canonicalized a number represented as a String to a format suitable * for the BigDecimal(String) constructor. Takes into account the * settings of the currently configures NumberFormat. * * @param value * a localized number string * @return the same number, but as a String suitable for consumption by * BigDecimal */ String canonicalize(String value) { char decimalPointSeparator = '.'; // default char minusSign = '-'; // default String rxNotDigits = "[^0-9]"; StringBuilder returnBuilder = new StringBuilder(value.length()); // override defaults according to numberFormat's settings if (numberFormat instanceof DecimalFormat) { DecimalFormatSymbols decimalFormatSymbols = ((DecimalFormat) numberFormat) .getDecimalFormatSymbols(); minusSign = decimalFormatSymbols.getMinusSign(); decimalPointSeparator = decimalFormatSymbols .getDecimalSeparator(); } value = value.trim(); int decimalPointPosition = value.lastIndexOf(decimalPointSeparator); boolean isNegative = value.charAt(0) == minusSign; if (isNegative) { returnBuilder.append('-'); // fixed "-" for BigDecimal // constructor } if (decimalPointPosition != -1) { String sf = value.substring(0, decimalPointPosition) .replaceAll(rxNotDigits, ""); String dp = value.substring(decimalPointPosition + 1) .replaceAll(rxNotDigits, ""); returnBuilder.append(sf); returnBuilder.append('.'); // fixed "." for BigDecimal // constructor returnBuilder.append(dp); } else { returnBuilder.append(value.replaceAll(rxNotDigits, "")); } return returnBuilder.toString(); } {code} > NumberFormatException when trying to convert parameters to BigDecimal with > Locale > --------------------------------------------------------------------------------- > > Key: JBEHAVE-739 > URL: https://jira.codehaus.org/browse/JBEHAVE-739 > Project: JBehave > Issue Type: Bug > Components: Core > Affects Versions: 3.6 > Reporter: Daniel Schneller > > When using a German localized number with group separators and decimals, a > conversion to BigDecimal fails with a {{NumberFormatException}}. For German, > group separators are dots, decimal separator is a comma (just the other way > round of the US version). > In the following test class, the first case is green, the second fails with > {noformat} > org.jbehave.core.steps.ParameterConverters$ParameterConvertionFailed: > 1.000.000,01 > at > org.jbehave.core.steps.ParameterConverters$NumberConverter.convertValue(ParameterConverters.java:256) > at > de.westlb.jets.xce.jbehave.tools.NumberFormatTest.jbehaveConverter(NumberFormatTest.java:39) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:597) > at > org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99) > ... > at > org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) > Caused by: java.lang.NumberFormatException > at java.math.BigDecimal.<init>(BigDecimal.java:453) > at java.math.BigDecimal.<init>(BigDecimal.java:728) > at > org.jbehave.core.steps.ParameterConverters$NumberConverter.convertValue(ParameterConverters.java:247) > ... 21 more > {noformat} > Putting a breakpoint in the BigDecimal constructor reveals it is fed a String > "1.000.000.000.00" which is obviously wrong. I suspect, the > "canonicalization" of the original String breaks it. > {code:title=Test.java} > public class NumberFormatTest { > private static final BigDecimal EXPECTED = new BigDecimal("1000000.01"); > private final String localizedString = "1.000.000,01"; > private DecimalFormat germanNumbers; > @Before > public void setup() { > germanNumbers = (DecimalFormat) DecimalFormat > .getNumberInstance(Locale.GERMAN); > germanNumbers.setParseBigDecimal(true); > } > @Test > public void plainConverter() throws Exception { > Number parse = germanNumbers.parse(localizedString); > assertEquals(EXPECTED, parse); > } > @Test > public void jbehaveConverter() throws Exception { > ParameterConverters.NumberConverter numberConverter = new > ParameterConverters.NumberConverter( > germanNumbers); > Object v = numberConverter.convertValue(localizedString, > BigDecimal.class); > assertEquals(EXPECTED, v); > } > {code} -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators: https://jira.codehaus.org/secure/ContactAdministrators!default.jspa For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email