This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-configuration.git
The following commit(s) were added to refs/heads/master by this push: new 4d6d4b95 PropertyConverter.to(Class, Object, DefaultConversionHandler) doesn't convert custom java.lang.Number subclasses 4d6d4b95 is described below commit 4d6d4b95b3678a34bd58d23a7f6a44d594f8e149 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Mon Jul 1 15:51:00 2024 -0400 PropertyConverter.to(Class, Object, DefaultConversionHandler) doesn't convert custom java.lang.Number subclasses - DefaultConversionHandler.convertValue(Object, Class, ConfigurationInterpolator) doesn't convert custom java.lang.Number subclasses.</action> - DefaultConversionHandler.to(Object, Class, ConfigurationInterpolator) doesn't convert custom java.lang.Number subclasses --- src/changes/changes.xml | 3 + .../configuration2/convert/PropertyConverter.java | 8 ++- .../commons/configuration2/convert/MyNumber.java | 84 ++++++++++++++++++++++ .../convert/TestDefaultConversionHandler.java | 14 ++++ .../convert/TestPropertyConverter.java | 7 ++ 5 files changed, 113 insertions(+), 3 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 6ffe5cca..6a0c31e3 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -25,6 +25,9 @@ <body> <release version="2.11.1" date="YYYY-MM-DD" description="This is a feature and maintenance release. Java 8 or later is required."> <!-- FIX --> + <action type="fix" dev="ggregory" due-to="Gary Gregory">PropertyConverter.to(Class, Object, DefaultConversionHandler) doesn't convert custom java.lang.Number subclasses.</action> + <action type="fix" dev="ggregory" due-to="Gary Gregory">DefaultConversionHandler.convertValue(Object, Class, ConfigurationInterpolator) doesn't convert custom java.lang.Number subclasses.</action> + <action type="fix" dev="ggregory" due-to="Gary Gregory">DefaultConversionHandler.to(Object, Class, ConfigurationInterpolator) doesn't convert custom java.lang.Number subclasses.</action> <!-- ADD --> <action type="add" dev="ggregory" due-to="Gary Gregory">Add PrefixedKeysIterator.toString() to package-private PrefixedKeysIterator.</action> <!-- UPDATE --> diff --git a/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java b/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java index 27f6c0f4..d7b1fba8 100644 --- a/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java +++ b/src/main/java/org/apache/commons/configuration2/convert/PropertyConverter.java @@ -38,6 +38,7 @@ import java.time.format.DateTimeParseException; import java.util.Calendar; import java.util.Date; import java.util.Locale; +import java.util.Objects; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -137,6 +138,7 @@ public final class PropertyConverter { if (BigDecimal.class.equals(cls)) { return toBigDecimal(value); } + return toNumber(value, cls); } else if (Date.class.equals(cls)) { return toDate(value, convHandler.getDateFormat()); } else if (Calendar.class.equals(cls)) { @@ -592,8 +594,8 @@ public final class PropertyConverter { if (value instanceof Number) { return (Number) value; } - final String str = value.toString(); - if (str.startsWith(HEX_PREFIX)) { + final String str = Objects.toString(value, null); + if (StringUtils.startsWithAny(str, HEX_PREFIX)) { try { return new BigInteger(str.substring(HEX_PREFIX.length()), HEX_RADIX); } catch (final NumberFormatException nex) { @@ -601,7 +603,7 @@ public final class PropertyConverter { } } - if (str.startsWith(BIN_PREFIX)) { + if (StringUtils.startsWithAny(str, BIN_PREFIX)) { try { return new BigInteger(str.substring(BIN_PREFIX.length()), BIN_RADIX); } catch (final NumberFormatException nex) { diff --git a/src/test/java/org/apache/commons/configuration2/convert/MyNumber.java b/src/test/java/org/apache/commons/configuration2/convert/MyNumber.java new file mode 100644 index 00000000..e4c4f9ff --- /dev/null +++ b/src/test/java/org/apache/commons/configuration2/convert/MyNumber.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.configuration2.convert; + +import java.util.Objects; + +/** + * A custom {@link Number}. + */ +public final class MyNumber extends Number { + + private static final long serialVersionUID = 1L; + + private final long value; + + public MyNumber() { + this("0"); + } + + public MyNumber(final long value) { + this.value = value; + } + + public MyNumber(final String string) { + value = string != null ? Long.parseLong(string) : 0; + } + + @Override + public double doubleValue() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof MyNumber)) { + return false; + } + MyNumber other = (MyNumber) obj; + return value == other.value; + } + + @Override + public float floatValue() { + return value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public int intValue() { + return (int) value; + } + + @Override + public long longValue() { + return value; + } + + @Override + public String toString() { + return Long.toString(value); + } +} diff --git a/src/test/java/org/apache/commons/configuration2/convert/TestDefaultConversionHandler.java b/src/test/java/org/apache/commons/configuration2/convert/TestDefaultConversionHandler.java index 84a65001..514b54fb 100644 --- a/src/test/java/org/apache/commons/configuration2/convert/TestDefaultConversionHandler.java +++ b/src/test/java/org/apache/commons/configuration2/convert/TestDefaultConversionHandler.java @@ -222,6 +222,20 @@ public class TestDefaultConversionHandler { assertEquals(Arrays.asList(Integer.valueOf(REPLACEMENT), Integer.valueOf(src[1].toString())), col); } + @Test + public void testToCustomNumber() { + // convertValue() + assertEquals(new MyNumber(1), DefaultConversionHandler.INSTANCE.convertValue(new MyNumber(1), MyNumber.class, null)); + assertEquals(new MyNumber(2), DefaultConversionHandler.INSTANCE.convertValue(new MyNumber(2), MyNumber.class, null)); + assertEquals(new MyNumber(3), DefaultConversionHandler.INSTANCE.convertValue("3", MyNumber.class, null)); + assertNull(DefaultConversionHandler.INSTANCE.convertValue(null, MyNumber.class, null)); + // to() + assertEquals(new MyNumber(1), DefaultConversionHandler.INSTANCE.to(new MyNumber(1), MyNumber.class, null)); + assertEquals(new MyNumber(2), DefaultConversionHandler.INSTANCE.to(new MyNumber(2), MyNumber.class, null)); + assertEquals(new MyNumber(3), DefaultConversionHandler.INSTANCE.to("3", MyNumber.class, null)); + assertNull(DefaultConversionHandler.INSTANCE.to(null, MyNumber.class, null)); + } + /** * Tests whether a conversion to a date object is possible if a specific date format is used. */ diff --git a/src/test/java/org/apache/commons/configuration2/convert/TestPropertyConverter.java b/src/test/java/org/apache/commons/configuration2/convert/TestPropertyConverter.java index e2839301..e60d522b 100644 --- a/src/test/java/org/apache/commons/configuration2/convert/TestPropertyConverter.java +++ b/src/test/java/org/apache/commons/configuration2/convert/TestPropertyConverter.java @@ -96,6 +96,13 @@ public class TestPropertyConverter { assertEquals(Character.valueOf('X'), PropertyConverter.to(Character.TYPE, value, new DefaultConversionHandler())); } + @Test + public void testToCustomNumber() { + assertEquals(new MyNumber(1), PropertyConverter.to(MyNumber.class, "1", null)); + assertEquals(new MyNumber(2), PropertyConverter.to(MyNumber.class, new MyNumber(2), null)); + assertEquals(new MyNumber(0), PropertyConverter.to(MyNumber.class, null, null)); + } + @Test public void testToEnumFromEnum() { assertEquals(ElementType.METHOD, PropertyConverter.toEnum(ElementType.METHOD, ENUM_CLASS));