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 e3db0c096ee6..bff195f3d104 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 @@ -20,6 +20,7 @@ import java.util.Set; import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.core.KotlinDetector; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterRegistry; @@ -120,6 +121,10 @@ public static void addApplicationConverters(ConverterRegistry registry) { registry.addConverter(new NumberToDataSizeConverter()); registry.addConverter(new StringToFileConverter()); registry.addConverter(new InputStreamSourceToByteArrayConverter()); + registry.addConverter(new StringToPatternConverter()); + if (KotlinDetector.isKotlinPresent()) { + registry.addConverter(StringToRegexConverter.INSTANCE); + } registry.addConverterFactory(new LenientStringToEnumConverterFactory()); registry.addConverterFactory(new LenientBooleanToEnumConverterFactory()); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/StringToPatternConverter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/StringToPatternConverter.java new file mode 100644 index 000000000000..c5de05abfc88 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/StringToPatternConverter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2020 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.boot.convert; + +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.util.ObjectUtils; + +import java.util.Collections; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * {@link Converter} to convert from a {@link String} to a {@link Pattern} + * + * @author Mikhael Sokolov + * @see Pattern + */ +final class StringToPatternConverter implements GenericConverter { + + @Override + public Set getConvertibleTypes() { + return Collections.singleton(new GenericConverter.ConvertiblePair(String.class, Pattern.class)); + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (ObjectUtils.isEmpty(source)) return null; + return Pattern.compile((String) source, Pattern.MULTILINE); + } +} diff --git a/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/convert/StringToRegexConverter.kt b/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/convert/StringToRegexConverter.kt new file mode 100644 index 000000000000..03d7751fe9aa --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/convert/StringToRegexConverter.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2020 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.boot.convert + +import org.springframework.core.convert.TypeDescriptor +import org.springframework.core.convert.converter.Converter +import org.springframework.core.convert.converter.GenericConverter + +/** + * [Converter] to convert from a [String] to a [Regex] + * + * @author Mikhael Sokolov + * @see Regex + */ +internal object StringToRegexConverter : GenericConverter { + override fun getConvertibleTypes(): Set = setOf(GenericConverter.ConvertiblePair(String::class.java, Regex::class.java)) + override fun convert(str: Any?, p1: TypeDescriptor, p2: TypeDescriptor): Any? = (str as? String)?.ifEmpty { return null }?.toRegex(RegexOption.MULTILINE) +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPatternConverterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPatternConverterTests.java new file mode 100644 index 000000000000..843c38a19a9b --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPatternConverterTests.java @@ -0,0 +1,54 @@ + +/* + * Copyright 2012-2020 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.boot.convert; + +import org.junit.jupiter.params.provider.Arguments; +import org.springframework.core.convert.ConversionService; + +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link StringToPatternConverter}. + * + * @author Mikhael Sokolov + */ +class StringToPatternConverterTests { + + @ConversionServiceTest + void convertWhenStringShouldReturnPattern(ConversionService conversionService) { + assertThat(convert(conversionService, "([A-Z])\\w+").pattern()).isEqualTo(Pattern.compile("([A-Z])\\w+", Pattern.MULTILINE).pattern()); + assertThat(convert(conversionService, "(\\\\W)*(\\\\S)*").pattern()).isEqualTo(Pattern.compile("(\\\\W)*(\\\\S)*", Pattern.MULTILINE).pattern()); + } + + @ConversionServiceTest + void convertWhenEmptyShouldReturnNull(ConversionService conversionService) { + assertThat(convert(conversionService, "")).isNull(); + } + + private Pattern convert(ConversionService conversionService, String source) { + return conversionService.convert(source, Pattern.class); + } + + @SuppressWarnings("unused") + static Stream conversionServices() { + return ConversionServiceArguments.with(new StringToPatternConverter()); + } +} diff --git a/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/convert/StringToRegexConverterTests.kt b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/convert/StringToRegexConverterTests.kt new file mode 100644 index 000000000000..34990e41f1ea --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/convert/StringToRegexConverterTests.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2020 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.boot.convert + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.provider.Arguments +import org.springframework.core.convert.ConversionService +import java.util.stream.Stream + +/** + * Tests for [StringToRegexConverter]. + * + * @author Mikhael Sokolov + */ +internal class StringToRegexConverterTests { + + @ConversionServiceTest + fun convertWhenStringShouldReturnPattern(conversionService: ConversionService) { + assertThat(conversionService.convert("([A-Z])\\w+")?.pattern).isEqualTo(Regex("([A-Z])\\w+", RegexOption.MULTILINE).pattern) + assertThat(conversionService.convert("(\\\\W)*(\\\\S)*")?.pattern).isEqualTo(Regex("(\\\\W)*(\\\\S)*", RegexOption.MULTILINE).pattern) + } + + @ConversionServiceTest + fun convertWhenEmptyShouldReturnNull(conversionService: ConversionService) { + assertThat(conversionService.convert("")).isNull() + } + + private fun ConversionService.convert(source: String): Regex? = convert(source, Regex::class.java) + + companion object { + @JvmStatic + fun conversionServices(): Stream = ConversionServiceArguments.with(StringToRegexConverter) + } +} \ No newline at end of file