Skip to content

Commit

Permalink
Fix binding of classpath*: to resource arrays and collections
Browse files Browse the repository at this point in the history
Fixes gh-15835
  • Loading branch information
wilkinsona committed Oct 16, 2023
1 parent 339f75d commit 0e3a196
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
Expand Down Expand Up @@ -42,6 +42,7 @@
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.io.Resource;
import org.springframework.util.CollectionUtils;

/**
Expand Down Expand Up @@ -154,8 +155,8 @@ private static class ResolvableTypeDescriptor extends TypeDescriptor {
private static class TypeConverterConversionService extends GenericConversionService {

TypeConverterConversionService(Consumer<PropertyEditorRegistry> initializer) {
addConverter(new TypeConverterConverter(initializer));
ApplicationConversionService.addDelimitedStringConverters(this);
addConverter(new TypeConverterConverter(initializer));
}

@Override
Expand Down Expand Up @@ -196,16 +197,23 @@ private static class TypeConverterConverter implements ConditionalGenericConvert

@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, Object.class));
return Set.of(new ConvertiblePair(String.class, Object.class),
new ConvertiblePair(String.class, Object[].class),
new ConvertiblePair(String.class, Collection.class));
}

@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
Class<?> type = targetType.getType();
if (type == null || type == Object.class || Collection.class.isAssignableFrom(type)
|| Map.class.isAssignableFrom(type)) {
if (type == null || type == Object.class || Map.class.isAssignableFrom(type)) {
return false;
}
if (Collection.class.isAssignableFrom(type)) {
TypeDescriptor elementType = targetType.getElementTypeDescriptor();
if (elementType == null || (!Resource.class.isAssignableFrom(elementType.getType()))) {
return false;
}
}
PropertyEditor editor = this.matchesOnlyTypeConverter.getDefaultEditor(type);
if (editor == null) {
editor = this.matchesOnlyTypeConverter.findCustomEditor(type, null);
Expand All @@ -218,7 +226,7 @@ public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {

@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return createTypeConverter().convertIfNecessary(source, targetType.getType());
return createTypeConverter().convertIfNecessary(source, targetType.getType(), targetType);
}

private SimpleTypeConverter createTypeConverter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -1173,6 +1174,22 @@ void loadWhenPotentiallyConstructorBoundPropertiesAreImportedUsesJavaBeanBinding
assertThat(properties.getProp()).isEqualTo("alpha");
}

@Test
void loadWhenBindingClasspathPatternToResourceArrayShouldBindMultipleValues() {
load(ResourceArrayPropertiesConfiguration.class,
"test.resources=classpath*:org/springframework/boot/context/properties/*.class");
ResourceArrayProperties properties = this.context.getBean(ResourceArrayProperties.class);
assertThat(properties.getResources()).hasSizeGreaterThan(1);
}

@Test
void loadWhenBindingClasspathPatternToResourceCollectionShouldBindMultipleValues() {
load(ResourceCollectionPropertiesConfiguration.class,
"test.resources=classpath*:org/springframework/boot/context/properties/*.class");
ResourceCollectionProperties properties = this.context.getBean(ResourceCollectionProperties.class);
assertThat(properties.getResources()).hasSizeGreaterThan(1);
}

private AnnotationConfigApplicationContext load(Class<?> configuration, String... inlinedProperties) {
return load(new Class<?>[] { configuration }, inlinedProperties);
}
Expand Down Expand Up @@ -3058,4 +3075,44 @@ void setProp(String prop) {

}

@EnableConfigurationProperties(ResourceArrayProperties.class)
static class ResourceArrayPropertiesConfiguration {

}

@ConfigurationProperties("test")
static class ResourceArrayProperties {

private Resource[] resources;

Resource[] getResources() {
return this.resources;
}

void setResources(Resource[] resources) {
this.resources = resources;
}

}

@EnableConfigurationProperties(ResourceCollectionProperties.class)
static class ResourceCollectionPropertiesConfiguration {

}

@ConfigurationProperties("test")
static class ResourceCollectionProperties {

private Collection<Resource> resources;

Collection<Resource> getResources() {
return this.resources;
}

void setResources(Collection<Resource> resources) {
this.resources = resources;
}

}

}

0 comments on commit 0e3a196

Please sign in to comment.