Repository: commons-lang Updated Branches: refs/heads/master 05a6beba7 -> dad86bc0a
LANG-1252: better naming and java 6 specifics around handling a leading + Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/c503d742 Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/c503d742 Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/c503d742 Branch: refs/heads/master Commit: c503d742f094dc2048b72c3f78f5e2e6070a44e1 Parents: 1a1fc65 Author: Rob Tompkins <[email protected]> Authored: Sat Sep 10 21:01:08 2016 -0400 Committer: Rob Tompkins <[email protected]> Committed: Sat Sep 10 21:01:08 2016 -0400 ---------------------------------------------------------------------- .../apache/commons/lang3/math/NumberUtils.java | 42 +++++- .../apache/commons/lang3/math/package-info.java | 2 +- .../commons/lang3/math/NumberUtilsTest.java | 144 ++++++++++--------- 3 files changed, 119 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/c503d742/src/main/java/org/apache/commons/lang3/math/NumberUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java index 3d59057..3205a6e 100644 --- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java +++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java @@ -1349,6 +1349,34 @@ public class NumberUtils { * <p>Checks whether the String a valid Java number.</p> * * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or + * <code>0X</code> qualifier, octal numbers, scientific notation and numbers + * marked with a type qualifier (e.g. 123L).</p> + * + * <p>Non-hexadecimal strings beginning with a leading zero are + * treated as octal values. Thus the string <code>09</code> will return + * <code>false</code>, since <code>9</code> is not a valid octal value. + * However, numbers beginning with {@code 0.} are treated as decimal.</p> + * + * <p><code>null</code> and empty/blank {@code String} will return + * <code>false</code>.</p> + * + * <p>Note, {@link #createNumber(String)} should return a number for every + * input resuling in <code>true</code>.</p> + * + * @param str the <code>String</code> to check + * @return <code>true</code> if the string is a correctly formatted number + * @since 3.3 the code supports hex {@code 0Xhhh} and octal {@code 0ddd} validation + * @deprecated This feature will be removed in Lang 4.0, use {@link NumberUtils#isCreatable(String)} instead + */ + @Deprecated + public static boolean isNumber(final String str) { + return isCreatable(str); + } + + /** + * <p>Checks whether the String a valid Java number.</p> + * + * <p>Valid numbers include hexadecimal marked with the <code>0x</code> or * <code>0X</code> qualifier, octal numbers, scientific notation and numbers * marked with a type qualifier (e.g. 123L).</p> * @@ -1360,11 +1388,14 @@ public class NumberUtils { * <p><code>null</code> and empty/blank {@code String} will return * <code>false</code>.</p> * + * <p>Note, {@link #createNumber(String)} should return a number for every + * input resuling in <code>true</code>.</p> + * * @param str the <code>String</code> to check * @return <code>true</code> if the string is a correctly formatted number * @since 3.3 the code supports hex {@code 0Xhhh} and octal {@code 0ddd} validation */ - public static boolean isNumber(final String str) { + public static boolean isCreatable(final String str) { if (StringUtils.isEmpty(str)) { return false; } @@ -1374,8 +1405,10 @@ public class NumberUtils { boolean hasDecPoint = false; boolean allowSigns = false; boolean foundDigit = false; + boolean isJava6 = StringUtils.startsWith(System.getProperty("java.version"), "1.6"); // deal with any possible sign up front - final int start = (chars[0] == '-') ? 1 : 0; + final int start = (chars[0] == '-' || chars[0] == '+') ? 1 : 0; + final boolean hasLeadingPlusSign = (start == 1 && chars[0] == '+'); if (sz > start + 1 && chars[start] == '0') { // leading 0 if ( (chars[start + 1] == 'x') || @@ -1445,6 +1478,9 @@ public class NumberUtils { } if (i < chars.length) { if (chars[i] >= '0' && chars[i] <= '9') { + if (isJava6 && hasLeadingPlusSign && !hasDecPoint) { + return false; + } // no type qualifier, OK return true; } @@ -1489,7 +1525,7 @@ public class NumberUtils { * when calling one of those methods.</p> * * <p>Hexadecimal and scientific notations are <strong>not</strong> considered parsable. - * See {@link #isNumber(String)} on those cases.</p> + * See {@link #isCreatable(String)} on those cases.</p> * * <p>{@code Null} and empty String will return <code>false</code>.</p> * http://git-wip-us.apache.org/repos/asf/commons-lang/blob/c503d742/src/main/java/org/apache/commons/lang3/math/package-info.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/lang3/math/package-info.java b/src/main/java/org/apache/commons/lang3/math/package-info.java index fd6f862..2ae6306 100644 --- a/src/main/java/org/apache/commons/lang3/math/package-info.java +++ b/src/main/java/org/apache/commons/lang3/math/package-info.java @@ -26,7 +26,7 @@ * <p>There are two aspects of this package that should be highlighted. * The first is {@link org.apache.commons.lang3.math.NumberUtils#createNumber(String)}, a method which does its best to convert a String into a {@link java.lang.Number} object. * You have no idea what type of Number it will return, so you should call the relevant <code>xxxValue</code> method when you reach the point of needing a number. - * NumberUtils also has a related {@link org.apache.commons.lang3.math.NumberUtils#isNumber(String) isNumber(String)} method.</p> + * NumberUtils also has a related {@link org.apache.commons.lang3.math.NumberUtils#isCreatable(String) isCreatable(String)} method.</p> * * @since 2.0 */ http://git-wip-us.apache.org/repos/asf/commons-lang/blob/c503d742/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java index 9b785f0..5a5814c 100644 --- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java @@ -27,6 +27,7 @@ import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; +import org.apache.commons.lang3.StringUtils; import org.junit.Test; /** @@ -1216,91 +1217,104 @@ public class NumberUtilsTest { } /** - * Tests isNumber(String) and tests that createNumber(String) returns - * a valid number iff isNumber(String) returns false. + * Tests isCreatable(String) and tests that createNumber(String) returns + * a valid number iff isCreatable(String) returns false. */ @Test - public void testIsNumber() { - compareIsNumberWithCreateNumber("12345", true); - compareIsNumberWithCreateNumber("1234.5", true); - compareIsNumberWithCreateNumber(".12345", true); - compareIsNumberWithCreateNumber("1234E5", true); - compareIsNumberWithCreateNumber("1234E+5", true); - compareIsNumberWithCreateNumber("1234E-5", true); - compareIsNumberWithCreateNumber("123.4E5", true); - compareIsNumberWithCreateNumber("-1234", true); - compareIsNumberWithCreateNumber("-1234.5", true); - compareIsNumberWithCreateNumber("-.12345", true); - compareIsNumberWithCreateNumber("-1234E5", true); - compareIsNumberWithCreateNumber("0", true); - compareIsNumberWithCreateNumber("-0", true); - compareIsNumberWithCreateNumber("01234", true); - compareIsNumberWithCreateNumber("-01234", true); - compareIsNumberWithCreateNumber("-0xABC123", true); - compareIsNumberWithCreateNumber("-0x0", true); - compareIsNumberWithCreateNumber("123.4E21D", true); - compareIsNumberWithCreateNumber("-221.23F", true); - compareIsNumberWithCreateNumber("22338L", true); - - compareIsNumberWithCreateNumber(null, false); - compareIsNumberWithCreateNumber("", false); - compareIsNumberWithCreateNumber(" ", false); - compareIsNumberWithCreateNumber("\r\n\t", false); - compareIsNumberWithCreateNumber("--2.3", false); - compareIsNumberWithCreateNumber(".12.3", false); - compareIsNumberWithCreateNumber("-123E", false); - compareIsNumberWithCreateNumber("-123E+-212", false); - compareIsNumberWithCreateNumber("-123E2.12", false); - compareIsNumberWithCreateNumber("0xGF", false); - compareIsNumberWithCreateNumber("0xFAE-1", false); - compareIsNumberWithCreateNumber(".", false); - compareIsNumberWithCreateNumber("-0ABC123", false); - compareIsNumberWithCreateNumber("123.4E-D", false); - compareIsNumberWithCreateNumber("123.4ED", false); - compareIsNumberWithCreateNumber("1234E5l", false); - compareIsNumberWithCreateNumber("11a", false); - compareIsNumberWithCreateNumber("1a", false); - compareIsNumberWithCreateNumber("a", false); - compareIsNumberWithCreateNumber("11g", false); - compareIsNumberWithCreateNumber("11z", false); - compareIsNumberWithCreateNumber("11def", false); - compareIsNumberWithCreateNumber("11d11", false); - compareIsNumberWithCreateNumber("11 11", false); - compareIsNumberWithCreateNumber(" 1111", false); - compareIsNumberWithCreateNumber("1111 ", false); - - compareIsNumberWithCreateNumber("2.", true); // LANG-521 - compareIsNumberWithCreateNumber("1.1L", false); // LANG-664 + public void testIsCreatable() { + compareIsCreatableWithCreateNumber("12345", true); + compareIsCreatableWithCreateNumber("1234.5", true); + compareIsCreatableWithCreateNumber(".12345", true); + compareIsCreatableWithCreateNumber("1234E5", true); + compareIsCreatableWithCreateNumber("1234E+5", true); + compareIsCreatableWithCreateNumber("1234E-5", true); + compareIsCreatableWithCreateNumber("123.4E5", true); + compareIsCreatableWithCreateNumber("-1234", true); + compareIsCreatableWithCreateNumber("-1234.5", true); + compareIsCreatableWithCreateNumber("-.12345", true); + compareIsCreatableWithCreateNumber("-1234E5", true); + compareIsCreatableWithCreateNumber("0", true); + compareIsCreatableWithCreateNumber("-0", true); + compareIsCreatableWithCreateNumber("01234", true); + compareIsCreatableWithCreateNumber("-01234", true); + compareIsCreatableWithCreateNumber("-0xABC123", true); + compareIsCreatableWithCreateNumber("-0x0", true); + compareIsCreatableWithCreateNumber("123.4E21D", true); + compareIsCreatableWithCreateNumber("-221.23F", true); + compareIsCreatableWithCreateNumber("22338L", true); + + compareIsCreatableWithCreateNumber(null, false); + compareIsCreatableWithCreateNumber("", false); + compareIsCreatableWithCreateNumber(" ", false); + compareIsCreatableWithCreateNumber("\r\n\t", false); + compareIsCreatableWithCreateNumber("--2.3", false); + compareIsCreatableWithCreateNumber(".12.3", false); + compareIsCreatableWithCreateNumber("-123E", false); + compareIsCreatableWithCreateNumber("-123E+-212", false); + compareIsCreatableWithCreateNumber("-123E2.12", false); + compareIsCreatableWithCreateNumber("0xGF", false); + compareIsCreatableWithCreateNumber("0xFAE-1", false); + compareIsCreatableWithCreateNumber(".", false); + compareIsCreatableWithCreateNumber("-0ABC123", false); + compareIsCreatableWithCreateNumber("123.4E-D", false); + compareIsCreatableWithCreateNumber("123.4ED", false); + compareIsCreatableWithCreateNumber("1234E5l", false); + compareIsCreatableWithCreateNumber("11a", false); + compareIsCreatableWithCreateNumber("1a", false); + compareIsCreatableWithCreateNumber("a", false); + compareIsCreatableWithCreateNumber("11g", false); + compareIsCreatableWithCreateNumber("11z", false); + compareIsCreatableWithCreateNumber("11def", false); + compareIsCreatableWithCreateNumber("11d11", false); + compareIsCreatableWithCreateNumber("11 11", false); + compareIsCreatableWithCreateNumber(" 1111", false); + compareIsCreatableWithCreateNumber("1111 ", false); + + compareIsCreatableWithCreateNumber("2.", true); // LANG-521 + compareIsCreatableWithCreateNumber("1.1L", false); // LANG-664 } @Test public void testLANG971() { - compareIsNumberWithCreateNumber("0085", false); - compareIsNumberWithCreateNumber("085", false); - compareIsNumberWithCreateNumber("08", false); - compareIsNumberWithCreateNumber("07", true); - compareIsNumberWithCreateNumber("00", true); + compareIsCreatableWithCreateNumber("0085", false); + compareIsCreatableWithCreateNumber("085", false); + compareIsCreatableWithCreateNumber("08", false); + compareIsCreatableWithCreateNumber("07", true); + compareIsCreatableWithCreateNumber("00", true); } @Test public void testLANG992() { - compareIsNumberWithCreateNumber("0.0", true); - compareIsNumberWithCreateNumber("0.4790", true); + compareIsCreatableWithCreateNumber("0.0", true); + compareIsCreatableWithCreateNumber("0.4790", true); } @Test public void testLANG972() { - compareIsNumberWithCreateNumber("0xABCD", true); - compareIsNumberWithCreateNumber("0XABCD", true); + compareIsCreatableWithCreateNumber("0xABCD", true); + compareIsCreatableWithCreateNumber("0XABCD", true); } - private void compareIsNumberWithCreateNumber(final String val, final boolean expected) { - final boolean isValid = NumberUtils.isNumber(val); + @Test + public void testLANG1252() { + //Check idiosyncries between java 1.6 and 1.7,1.8 redarding leading + signs + if (StringUtils.startsWith(System.getProperty("java.version"), "1.6")) { + compareIsCreatableWithCreateNumber("+2", false); + } else { + compareIsCreatableWithCreateNumber("+2", true); + } + + //The Following should work regardless of 1.6, 1.7, or 1.8 + compareIsCreatableWithCreateNumber("+2.0", true); + } + + private void compareIsCreatableWithCreateNumber(final String val, final boolean expected) { + final boolean isValid = NumberUtils.isCreatable(val); final boolean canCreate = checkCreateNumber(val); if (isValid == expected && canCreate == expected) { return; } - fail("Expecting "+ expected + " for isNumber/createNumber using \"" + val + "\" but got " + isValid + " and " + canCreate); + fail("Expecting "+ expected + " for isCreatable/createNumber using \"" + val + "\" but got " + isValid + " and " + canCreate); } @Test
