From 9704b809b117705ee365613df14d1493e7ac6660 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Tue, 28 Nov 2023 10:15:47 +0800 Subject: [PATCH 1/2] Add support for location patterns in ResourceArrayPropertyEditor This commit adds support for comma delimited location patterns in ResourceArrayPropertyEditor. See gh-31700 --- .../support/ResourceArrayPropertyEditor.java | 34 +++++++++++++++---- .../ResourceArrayPropertyEditorTests.java | 14 +++++++- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java b/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java index 0bc2a6612352..19e1321378de 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-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. @@ -18,10 +18,12 @@ import java.beans.PropertyEditorSupport; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; @@ -33,6 +35,7 @@ import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Editor for {@link org.springframework.core.io.Resource} arrays, to @@ -50,6 +53,7 @@ * * @author Juergen Hoeller * @author Chris Beams + * @author Yanming Zhou * @since 1.1.2 * @see org.springframework.core.io.Resource * @see ResourcePatternResolver @@ -108,17 +112,33 @@ public ResourceArrayPropertyEditor(ResourcePatternResolver resourcePatternResolv /** - * Treat the given text as a location pattern and convert it to a Resource array. + * Treat the given text as a location pattern or comma delimited location patterns and convert it to a Resource array. */ @Override public void setAsText(String text) { String pattern = resolvePath(text).trim(); - try { - setValue(this.resourcePatternResolver.getResources(pattern)); + if (pattern.indexOf(',') > 0) { + List resources = new ArrayList<>(); + for (String locationPattern : StringUtils.commaDelimitedListToStringArray(pattern)) { + try { + for (Resource resource : this.resourcePatternResolver.getResources(locationPattern)) { + resources.add(resource); + } + } + catch (IOException ex) { + throw new IllegalArgumentException( + "Could not resolve resource location pattern [" + locationPattern + "]: " + ex.getMessage()); + } + } + setValue(resources.toArray()); } - catch (IOException ex) { - throw new IllegalArgumentException( - "Could not resolve resource location pattern [" + pattern + "]: " + ex.getMessage()); + else { + try { + setValue(this.resourcePatternResolver.getResources(pattern)); + } catch (IOException ex) { + throw new IllegalArgumentException( + "Could not resolve resource location pattern [" + pattern + "]: " + ex.getMessage()); + } } } diff --git a/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java b/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java index 4bb19cdc33de..2f2a02263861 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2013 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. @@ -21,6 +21,8 @@ import org.junit.jupiter.api.Test; import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileUrlResource; import org.springframework.core.io.Resource; import static org.assertj.core.api.Assertions.assertThat; @@ -29,6 +31,7 @@ /** * @author Dave Syer * @author Juergen Hoeller + * @author Yanming Zhou */ class ResourceArrayPropertyEditorTests { @@ -83,4 +86,13 @@ void strictSystemPropertyReplacementWithUnresolvablePlaceholder() { } } + @Test + void commaDelimitedResources() { + PropertyEditor editor = new ResourceArrayPropertyEditor(); + editor.setAsText("classpath:org/springframework/core/io/support/ResourceArrayPropertyEditor.class,file:/foo/bar.txt"); + Resource[] resources = (Resource[]) editor.getValue(); + assertThat(resources).isNotNull(); + assertThat(resources[0]).isInstanceOf(ClassPathResource.class); + assertThat(resources[1]).isInstanceOf(FileUrlResource.class); + } } From 25537938d68e5cae88f98deb287417f3b3992a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Wed, 6 Dec 2023 14:49:41 +0100 Subject: [PATCH 2/2] Polish contribution See gh-31700 --- .../support/ResourceArrayPropertyEditor.java | 42 +++++++++---------- .../ResourceArrayPropertyEditorTests.java | 31 +++++++++++--- .../io/support/test-resources/resource1.txt | 0 .../io/support/test-resources/resource2.txt | 0 .../io/support/test-resources/resource3.text | 0 5 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource1.txt create mode 100644 spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource2.txt create mode 100644 spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource3.text diff --git a/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java b/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java index 19e1321378de..f54fc1f5261c 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.java @@ -18,12 +18,10 @@ import java.beans.PropertyEditorSupport; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; @@ -54,6 +52,7 @@ * @author Juergen Hoeller * @author Chris Beams * @author Yanming Zhou + * @author Stephane Nicoll * @since 1.1.2 * @see org.springframework.core.io.Resource * @see ResourcePatternResolver @@ -112,33 +111,30 @@ public ResourceArrayPropertyEditor(ResourcePatternResolver resourcePatternResolv /** - * Treat the given text as a location pattern or comma delimited location patterns and convert it to a Resource array. + * Treat the given text as a location pattern or comma delimited location patterns + * and convert it to a Resource array. */ @Override public void setAsText(String text) { String pattern = resolvePath(text).trim(); - if (pattern.indexOf(',') > 0) { - List resources = new ArrayList<>(); - for (String locationPattern : StringUtils.commaDelimitedListToStringArray(pattern)) { - try { - for (Resource resource : this.resourcePatternResolver.getResources(locationPattern)) { - resources.add(resource); - } - } - catch (IOException ex) { - throw new IllegalArgumentException( - "Could not resolve resource location pattern [" + locationPattern + "]: " + ex.getMessage()); - } - } - setValue(resources.toArray()); + String[] locationPatterns = StringUtils.commaDelimitedListToStringArray(pattern); + if (locationPatterns.length == 1) { + setValue(getResources(locationPatterns[0])); } else { - try { - setValue(this.resourcePatternResolver.getResources(pattern)); - } catch (IOException ex) { - throw new IllegalArgumentException( - "Could not resolve resource location pattern [" + pattern + "]: " + ex.getMessage()); - } + Resource[] resources = Arrays.stream(locationPatterns).map(String::trim) + .map(this::getResources).flatMap(Arrays::stream).toArray(Resource[]::new); + setValue(resources); + } + } + + private Resource[] getResources(String locationPattern) { + try { + return this.resourcePatternResolver.getResources(locationPattern); + } + catch (IOException ex) { + throw new IllegalArgumentException( + "Could not resolve resource location pattern [" + locationPattern + "]: " + ex.getMessage()); } } diff --git a/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java b/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java index 2f2a02263861..b17f1a4637ff 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/ResourceArrayPropertyEditorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -29,9 +29,12 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; /** + * Tests for {@link ResourceArrayPropertyEditor}. + * * @author Dave Syer * @author Juergen Hoeller * @author Yanming Zhou + * @author Stephane Nicoll */ class ResourceArrayPropertyEditorTests { @@ -87,12 +90,30 @@ void strictSystemPropertyReplacementWithUnresolvablePlaceholder() { } @Test - void commaDelimitedResources() { + void commaDelimitedResourcesWithSingleResource() { + PropertyEditor editor = new ResourceArrayPropertyEditor(); + editor.setAsText("classpath:org/springframework/core/io/support/ResourceArrayPropertyEditor.class,file:/test.txt"); + Resource[] resources = (Resource[]) editor.getValue(); + assertThat(resources).isNotNull(); + assertThat(resources[0]).isInstanceOfSatisfying(ClassPathResource.class, + resource -> assertThat(resource.exists()).isTrue()); + assertThat(resources[1]).isInstanceOfSatisfying(FileUrlResource.class, + resource -> assertThat(resource.getFilename()).isEqualTo("test.txt")); + } + + @Test + void commaDelimitedResourcesWithMultipleResources() { PropertyEditor editor = new ResourceArrayPropertyEditor(); - editor.setAsText("classpath:org/springframework/core/io/support/ResourceArrayPropertyEditor.class,file:/foo/bar.txt"); + editor.setAsText("file:/test.txt, classpath:org/springframework/core/io/support/test-resources/*.txt"); Resource[] resources = (Resource[]) editor.getValue(); assertThat(resources).isNotNull(); - assertThat(resources[0]).isInstanceOf(ClassPathResource.class); - assertThat(resources[1]).isInstanceOf(FileUrlResource.class); + assertThat(resources[0]).isInstanceOfSatisfying(FileUrlResource.class, + resource -> assertThat(resource.getFilename()).isEqualTo("test.txt")); + assertThat(resources).anySatisfy(candidate -> + assertThat(candidate.getFilename()).isEqualTo("resource1.txt")); + assertThat(resources).anySatisfy(candidate -> + assertThat(candidate.getFilename()).isEqualTo("resource2.txt")); + assertThat(resources).hasSize(3); } + } diff --git a/spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource1.txt b/spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource1.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource2.txt b/spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource2.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource3.text b/spring-core/src/test/resources/org/springframework/core/io/support/test-resources/resource3.text new file mode 100644 index 000000000000..e69de29bb2d1