From cb7de2a9636005103436ee3343afda1fed853cc4 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 4 Sep 2018 11:04:22 +0200 Subject: [PATCH] Allow binding number to DataSize Closes gh-14294 --- .../convert/ApplicationConversionService.java | 1 + .../convert/NumberToDataSizeConverter.java | 49 +++++++++++ .../NumberToDataSizeConverterTests.java | 88 +++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/NumberToDataSizeConverter.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToDataSizeConverterTests.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/ApplicationConversionService.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/ApplicationConversionService.java index 89b18c956a3..83ad9a07ded 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/ApplicationConversionService.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/ApplicationConversionService.java @@ -100,6 +100,7 @@ public class ApplicationConversionService extends FormattingConversionService { registry.addConverter(new NumberToDurationConverter()); registry.addConverter(new DurationToNumberConverter()); registry.addConverter(new StringToDataSizeConverter()); + registry.addConverter(new NumberToDataSizeConverter()); registry.addConverterFactory(new StringToEnumIgnoringCaseConverterFactory()); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/NumberToDataSizeConverter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/NumberToDataSizeConverter.java new file mode 100644 index 00000000000..4ff0f31614a --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/NumberToDataSizeConverter.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2018 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 + * + * 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.springframework.boot.convert; + +import java.util.Collections; +import java.util.Set; + +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.util.unit.DataSize; + +/** + * {@link Converter} to convert from a {@link Number} to a {@link DataSize}. + * + * @author Stephane Nicoll + * @see DataSizeUnit + */ +final class NumberToDataSizeConverter implements GenericConverter { + + private final StringToDataSizeConverter delegate = new StringToDataSizeConverter(); + + @Override + public Set getConvertibleTypes() { + return Collections.singleton(new ConvertiblePair(Number.class, DataSize.class)); + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, + TypeDescriptor targetType) { + return this.delegate.convert((source != null) ? source.toString() : null, + TypeDescriptor.valueOf(String.class), targetType); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToDataSizeConverterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToDataSizeConverterTests.java new file mode 100644 index 00000000000..925a083eeb6 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToDataSizeConverterTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-2018 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 + * + * 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.springframework.boot.convert; + +import java.util.Collections; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.util.unit.DataSize; +import org.springframework.util.unit.DataUnit; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link NumberToDataSizeConverter}. + * + * @author Stephane Nicoll + */ +@RunWith(Parameterized.class) +public class NumberToDataSizeConverterTests { + + private final ConversionService conversionService; + + public NumberToDataSizeConverterTests(String name, + ConversionService conversionService) { + this.conversionService = conversionService; + } + + @Test + public void convertWhenSimpleWithoutSuffixShouldReturnDataSize() { + assertThat(convert(10)).isEqualTo(DataSize.ofBytes(10)); + assertThat(convert(+10)).isEqualTo(DataSize.ofBytes(10)); + assertThat(convert(-10)).isEqualTo(DataSize.ofBytes(-10)); + } + + @Test + public void convertWhenSimpleWithoutSuffixButWithAnnotationShouldReturnDataSize() { + assertThat(convert(10, DataUnit.KILOBYTES)).isEqualTo(DataSize.ofKiloBytes(10)); + assertThat(convert(+10, DataUnit.KILOBYTES)).isEqualTo(DataSize.ofKiloBytes(10)); + assertThat(convert(-10, DataUnit.KILOBYTES)).isEqualTo(DataSize.ofKiloBytes(-10)); + } + + private DataSize convert(Integer source) { + return this.conversionService.convert(source, DataSize.class); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private DataSize convert(Integer source, DataUnit defaultUnit) { + TypeDescriptor targetType = mock(TypeDescriptor.class); + if (defaultUnit != null) { + DataSizeUnit unitAnnotation = AnnotationUtils.synthesizeAnnotation( + Collections.singletonMap("value", defaultUnit), DataSizeUnit.class, + null); + given(targetType.getAnnotation(DataSizeUnit.class)) + .willReturn(unitAnnotation); + } + given(targetType.getType()).willReturn((Class) DataSize.class); + return (DataSize) this.conversionService.convert(source, + TypeDescriptor.forObject(source), targetType); + } + + @Parameterized.Parameters(name = "{0}") + public static Iterable conversionServices() { + return new ConversionServiceParameters(new NumberToDataSizeConverter()); + } + +}