Skip to content

Commit d69afaa

Browse files
committed
PathEditor tries file system path in case of non-existing resource
Issue: SPR-14549
1 parent d128830 commit d69afaa

File tree

4 files changed

+55
-24
lines changed

4 files changed

+55
-24
lines changed

spring-beans/src/main/java/org/springframework/beans/propertyeditors/FileEditor.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ public void setAsText(String text) throws IllegalArgumentException {
8484

8585
// Check whether we got an absolute file path without "file:" prefix.
8686
// For backwards compatibility, we'll consider those as straight file path.
87+
File file = null;
8788
if (!ResourceUtils.isUrl(text)) {
88-
File file = new File(text);
89+
file = new File(text);
8990
if (file.isAbsolute()) {
9091
setValue(file);
9192
return;
@@ -97,7 +98,7 @@ public void setAsText(String text) throws IllegalArgumentException {
9798
Resource resource = (Resource) this.resourceEditor.getValue();
9899

99100
// If it's a URL or a path pointing to an existing resource, use it as-is.
100-
if (ResourceUtils.isUrl(text) || resource.exists()) {
101+
if (file == null || resource.exists()) {
101102
try {
102103
setValue(resource.getFile());
103104
}
@@ -107,8 +108,8 @@ public void setAsText(String text) throws IllegalArgumentException {
107108
}
108109
}
109110
else {
110-
// Create a relative File reference and hope for the best.
111-
setValue(new File(text));
111+
// Set a relative File reference and hope for the best.
112+
setValue(file);
112113
}
113114
}
114115

spring-beans/src/main/java/org/springframework/beans/propertyeditors/PathEditor.java

+19-12
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,10 @@
3636
* <p>Based on {@link Paths#get(URI)}'s resolution algorithm, checking
3737
* registered NIO file system providers, including the default file system
3838
* for "file:..." paths. Also supports Spring-style URL notation: any fully
39-
* qualified standard URL and Spring's special "classpath:" pseudo-URL,
40-
* as well as Spring's context-specific relative file paths.
41-
*
42-
* <p>Note that, in contrast to {@link FileEditor}, relative paths are only
43-
* supported by Spring's resource abstraction here. Direct {@code Paths.get}
44-
* resolution in a file system always has to go through the corresponding
45-
* file system provider's scheme, i.e. "file" for the default file system.
39+
* qualified standard URL and Spring's special "classpath:" pseudo-URL, as
40+
* well as Spring's context-specific relative file paths. As a fallback, a
41+
* path will be resolved in the file system via {@code Paths#get(String)}
42+
* if no existing context-relative resource could be found.
4643
*
4744
* @author Juergen Hoeller
4845
* @since 4.3.2
@@ -77,10 +74,12 @@ public PathEditor(ResourceEditor resourceEditor) {
7774

7875
@Override
7976
public void setAsText(String text) throws IllegalArgumentException {
80-
if (!text.startsWith("/") && !text.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX)) {
77+
boolean nioPathCandidate = !text.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX);
78+
if (nioPathCandidate && !text.startsWith("/")) {
8179
try {
8280
URI uri = new URI(text);
8381
if (uri.getScheme() != null) {
82+
nioPathCandidate = false;
8483
// Let's try NIO file system providers via Paths.get(URI)
8584
setValue(Paths.get(uri).normalize());
8685
return;
@@ -97,11 +96,19 @@ public void setAsText(String text) throws IllegalArgumentException {
9796

9897
this.resourceEditor.setAsText(text);
9998
Resource resource = (Resource) this.resourceEditor.getValue();
100-
try {
101-
setValue(resource != null ? resource.getFile().toPath() : null);
99+
if (resource == null) {
100+
setValue(null);
101+
}
102+
else if (!resource.exists() && nioPathCandidate) {
103+
setValue(Paths.get(text).normalize());
102104
}
103-
catch (IOException ex) {
104-
throw new IllegalArgumentException("Failed to retrieve file for " + resource, ex);
105+
else {
106+
try {
107+
setValue(resource.getFile().toPath());
108+
}
109+
catch (IOException ex) {
110+
throw new IllegalArgumentException("Failed to retrieve file for " + resource, ex);
111+
}
105112
}
106113
}
107114

spring-beans/src/test/java/org/springframework/beans/propertyeditors/FileEditorTests.java

+3-8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
/**
2929
* @author Thomas Risberg
3030
* @author Chris Beams
31+
* @author Juergen Hoeller
3132
*/
3233
public class FileEditorTests {
3334

@@ -78,10 +79,7 @@ public void testUnqualifiedFileNameFound() throws Exception {
7879
assertTrue(value instanceof File);
7980
File file = (File) value;
8081
assertTrue(file.exists());
81-
String absolutePath = file.getAbsolutePath();
82-
if (File.separatorChar == '\\') {
83-
absolutePath = absolutePath.replace('\\', '/');
84-
}
82+
String absolutePath = file.getAbsolutePath().replace('\\', '/');
8583
assertTrue(absolutePath.endsWith(fileName));
8684
}
8785

@@ -95,10 +93,7 @@ public void testUnqualifiedFileNameNotFound() throws Exception {
9593
assertTrue(value instanceof File);
9694
File file = (File) value;
9795
assertFalse(file.exists());
98-
String absolutePath = file.getAbsolutePath();
99-
if (File.separatorChar == '\\') {
100-
absolutePath = absolutePath.replace('\\', '/');
101-
}
96+
String absolutePath = file.getAbsolutePath().replace('\\', '/');
10297
assertTrue(absolutePath.endsWith(fileName));
10398
}
10499

spring-beans/src/test/java/org/springframework/beans/propertyeditors/PathEditorTests.java

+28
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ public void testWithNonExistentPath() throws Exception {
5959
assertTrue(!path.toFile().exists());
6060
}
6161

62+
@Test
63+
public void testAbsolutePath() throws Exception {
64+
PropertyEditor pathEditor = new PathEditor();
65+
pathEditor.setAsText("/no_way_this_file_is_found.doc");
66+
Object value = pathEditor.getValue();
67+
assertTrue(value instanceof Path);
68+
Path path = (Path) value;
69+
assertTrue(!path.toFile().exists());
70+
}
71+
6272
@Test
6373
public void testUnqualifiedPathNameFound() throws Exception {
6474
PropertyEditor pathEditor = new PathEditor();
@@ -77,4 +87,22 @@ public void testUnqualifiedPathNameFound() throws Exception {
7787
assertTrue(absolutePath.endsWith(fileName));
7888
}
7989

90+
@Test
91+
public void testUnqualifiedPathNameNotFound() throws Exception {
92+
PropertyEditor pathEditor = new PathEditor();
93+
String fileName = ClassUtils.classPackageAsResourcePath(getClass()) + "/" +
94+
ClassUtils.getShortName(getClass()) + ".clazz";
95+
pathEditor.setAsText(fileName);
96+
Object value = pathEditor.getValue();
97+
assertTrue(value instanceof Path);
98+
Path path = (Path) value;
99+
File file = path.toFile();
100+
assertFalse(file.exists());
101+
String absolutePath = file.getAbsolutePath();
102+
if (File.separatorChar == '\\') {
103+
absolutePath = absolutePath.replace('\\', '/');
104+
}
105+
assertTrue(absolutePath.endsWith(fileName));
106+
}
107+
80108
}

0 commit comments

Comments
 (0)