From 01cd193225c1c32da0a8b57e857206fa7a38423a Mon Sep 17 00:00:00 2001 From: YeongJae Min Date: Sat, 23 May 2026 19:48:54 +0900 Subject: [PATCH] Add DataSize converters Signed-off-by: YeongJae Min --- .../support/DefaultConversionService.java | 3 ++ .../support/NumberToDataSizeConverter.java | 36 ++++++++++++++++ .../support/StringToDataSizeConverter.java | 41 +++++++++++++++++++ .../DefaultConversionServiceTests.java | 32 +++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java create mode 100644 spring-core/src/main/java/org/springframework/core/convert/support/StringToDataSizeConverter.java diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java index 05017f5a2275..2cd79caaf6bb 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java @@ -142,6 +142,9 @@ private static void addScalarConverters(ConverterRegistry converterRegistry) { converterRegistry.addConverterFactory(new StringToNumberConverterFactory()); converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter()); + converterRegistry.addConverter(new StringToDataSizeConverter()); + converterRegistry.addConverter(new NumberToDataSizeConverter()); + converterRegistry.addConverter(new StringToCharacterConverter()); converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter()); diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java new file mode 100644 index 000000000000..dbca7e95ca93 --- /dev/null +++ b/spring-core/src/main/java/org/springframework/core/convert/support/NumberToDataSizeConverter.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-present the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.core.convert.support; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.util.unit.DataSize; + +/** + * Converts from a {@link Number} to a {@link DataSize}. + * + * @author YeongJae Min + * @since 7.1 + * @see DataSize#parse(CharSequence) + */ +final class NumberToDataSizeConverter implements Converter { + + @Override + public DataSize convert(Number source) { + return DataSize.parse(source.toString()); + } + +} diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/StringToDataSizeConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/StringToDataSizeConverter.java new file mode 100644 index 000000000000..465d6d2dca28 --- /dev/null +++ b/spring-core/src/main/java/org/springframework/core/convert/support/StringToDataSizeConverter.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-present the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.core.convert.support; + +import org.jspecify.annotations.Nullable; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.util.unit.DataSize; + +/** + * Converts from a {@link String} to a {@link DataSize}. + * + * @author YeongJae Min + * @since 7.1 + * @see DataSize#parse(CharSequence) + */ +final class StringToDataSizeConverter implements Converter { + + @Override + public @Nullable DataSize convert(String source) { + if (source.isEmpty()) { + return null; + } + return DataSize.parse(source); + } + +} diff --git a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java index 03205ad34ec5..553339e0fc8a 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java @@ -58,6 +58,7 @@ import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.util.ClassUtils; +import org.springframework.util.unit.DataSize; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -231,6 +232,37 @@ void stringToNumberEmptyString() { assertThat(conversionService.convert("", Number.class)).isNull(); } + @Test + void stringToDataSize() { + assertThat(conversionService.convert("10B", DataSize.class)).isEqualTo(DataSize.ofBytes(10)); + assertThat(conversionService.convert("+10KB", DataSize.class)).isEqualTo(DataSize.ofKilobytes(10)); + assertThat(conversionService.convert("-10MB", DataSize.class)).isEqualTo(DataSize.ofMegabytes(-10)); + assertThat(conversionService.convert("10", DataSize.class)).isEqualTo(DataSize.ofBytes(10)); + } + + @Test + void stringToDataSizeEmptyString() { + assertThat(conversionService.convert("", DataSize.class)).isNull(); + } + + @Test + void stringToDataSizeInvalidString() { + assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() -> + conversionService.convert("10WB", DataSize.class)); + } + + @Test + void numberToDataSize() { + assertThat(conversionService.convert(10, DataSize.class)).isEqualTo(DataSize.ofBytes(10)); + assertThat(conversionService.convert(-10L, DataSize.class)).isEqualTo(DataSize.ofBytes(-10)); + } + + @Test + void numberToDataSizeWithDecimalNumber() { + assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() -> + conversionService.convert(10.5, DataSize.class)); + } + @Test void stringToEnum() { assertThat(conversionService.convert("BAR", Foo.class)).isEqualTo(Foo.BAR);