diff --git a/spring-beans/src/main/java/org/springframework/beans/propertyeditors/FileEditor.java b/spring-beans/src/main/java/org/springframework/beans/propertyeditors/FileEditor.java index 676fd0c643..fed7d430b3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/propertyeditors/FileEditor.java +++ b/spring-beans/src/main/java/org/springframework/beans/propertyeditors/FileEditor.java @@ -84,8 +84,9 @@ public class FileEditor extends PropertyEditorSupport { // Check whether we got an absolute file path without "file:" prefix. // For backwards compatibility, we'll consider those as straight file path. + File file = null; if (!ResourceUtils.isUrl(text)) { - File file = new File(text); + file = new File(text); if (file.isAbsolute()) { setValue(file); return; @@ -97,7 +98,7 @@ public class FileEditor extends PropertyEditorSupport { Resource resource = (Resource) this.resourceEditor.getValue(); // If it's a URL or a path pointing to an existing resource, use it as-is. - if (ResourceUtils.isUrl(text) || resource.exists()) { + if (file == null || resource.exists()) { try { setValue(resource.getFile()); } @@ -107,8 +108,8 @@ public class FileEditor extends PropertyEditorSupport { } } else { - // Create a relative File reference and hope for the best. - setValue(new File(text)); + // Set a relative File reference and hope for the best. + setValue(file); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/propertyeditors/PathEditor.java b/spring-beans/src/main/java/org/springframework/beans/propertyeditors/PathEditor.java index df59203699..0d9cd7fba8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/propertyeditors/PathEditor.java +++ b/spring-beans/src/main/java/org/springframework/beans/propertyeditors/PathEditor.java @@ -36,13 +36,10 @@ import org.springframework.util.Assert; *

Based on {@link Paths#get(URI)}'s resolution algorithm, checking * registered NIO file system providers, including the default file system * for "file:..." paths. Also supports Spring-style URL notation: any fully - * qualified standard URL and Spring's special "classpath:" pseudo-URL, - * as well as Spring's context-specific relative file paths. - * - *

Note that, in contrast to {@link FileEditor}, relative paths are only - * supported by Spring's resource abstraction here. Direct {@code Paths.get} - * resolution in a file system always has to go through the corresponding - * file system provider's scheme, i.e. "file" for the default file system. + * qualified standard URL and Spring's special "classpath:" pseudo-URL, as + * well as Spring's context-specific relative file paths. As a fallback, a + * path will be resolved in the file system via {@code Paths#get(String)} + * if no existing context-relative resource could be found. * * @author Juergen Hoeller * @since 4.3.2 @@ -77,10 +74,12 @@ public class PathEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { - if (!text.startsWith("/") && !text.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX)) { + boolean nioPathCandidate = !text.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX); + if (nioPathCandidate && !text.startsWith("/")) { try { URI uri = new URI(text); if (uri.getScheme() != null) { + nioPathCandidate = false; // Let's try NIO file system providers via Paths.get(URI) setValue(Paths.get(uri).normalize()); return; @@ -97,11 +96,19 @@ public class PathEditor extends PropertyEditorSupport { this.resourceEditor.setAsText(text); Resource resource = (Resource) this.resourceEditor.getValue(); - try { - setValue(resource != null ? resource.getFile().toPath() : null); + if (resource == null) { + setValue(null); + } + else if (!resource.exists() && nioPathCandidate) { + setValue(Paths.get(text).normalize()); } - catch (IOException ex) { - throw new IllegalArgumentException("Failed to retrieve file for " + resource, ex); + else { + try { + setValue(resource.getFile().toPath()); + } + catch (IOException ex) { + throw new IllegalArgumentException("Failed to retrieve file for " + resource, ex); + } } } diff --git a/spring-beans/src/test/java/org/springframework/beans/propertyeditors/FileEditorTests.java b/spring-beans/src/test/java/org/springframework/beans/propertyeditors/FileEditorTests.java index ae6a5c6838..ab76a6498f 100644 --- a/spring-beans/src/test/java/org/springframework/beans/propertyeditors/FileEditorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/propertyeditors/FileEditorTests.java @@ -28,6 +28,7 @@ import static org.junit.Assert.*; /** * @author Thomas Risberg * @author Chris Beams + * @author Juergen Hoeller */ public class FileEditorTests { @@ -78,10 +79,7 @@ public class FileEditorTests { assertTrue(value instanceof File); File file = (File) value; assertTrue(file.exists()); - String absolutePath = file.getAbsolutePath(); - if (File.separatorChar == '\\') { - absolutePath = absolutePath.replace('\\', '/'); - } + String absolutePath = file.getAbsolutePath().replace('\\', '/'); assertTrue(absolutePath.endsWith(fileName)); } @@ -95,10 +93,7 @@ public class FileEditorTests { assertTrue(value instanceof File); File file = (File) value; assertFalse(file.exists()); - String absolutePath = file.getAbsolutePath(); - if (File.separatorChar == '\\') { - absolutePath = absolutePath.replace('\\', '/'); - } + String absolutePath = file.getAbsolutePath().replace('\\', '/'); assertTrue(absolutePath.endsWith(fileName)); } diff --git a/spring-beans/src/test/java/org/springframework/beans/propertyeditors/PathEditorTests.java b/spring-beans/src/test/java/org/springframework/beans/propertyeditors/PathEditorTests.java index 440a3e38c7..e96bd94a84 100644 --- a/spring-beans/src/test/java/org/springframework/beans/propertyeditors/PathEditorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/propertyeditors/PathEditorTests.java @@ -59,6 +59,16 @@ public class PathEditorTests { assertTrue(!path.toFile().exists()); } + @Test + public void testAbsolutePath() throws Exception { + PropertyEditor pathEditor = new PathEditor(); + pathEditor.setAsText("/no_way_this_file_is_found.doc"); + Object value = pathEditor.getValue(); + assertTrue(value instanceof Path); + Path path = (Path) value; + assertTrue(!path.toFile().exists()); + } + @Test public void testUnqualifiedPathNameFound() throws Exception { PropertyEditor pathEditor = new PathEditor(); @@ -77,4 +87,22 @@ public class PathEditorTests { assertTrue(absolutePath.endsWith(fileName)); } + @Test + public void testUnqualifiedPathNameNotFound() throws Exception { + PropertyEditor pathEditor = new PathEditor(); + String fileName = ClassUtils.classPackageAsResourcePath(getClass()) + "/" + + ClassUtils.getShortName(getClass()) + ".clazz"; + pathEditor.setAsText(fileName); + Object value = pathEditor.getValue(); + assertTrue(value instanceof Path); + Path path = (Path) value; + File file = path.toFile(); + assertFalse(file.exists()); + String absolutePath = file.getAbsolutePath(); + if (File.separatorChar == '\\') { + absolutePath = absolutePath.replace('\\', '/'); + } + assertTrue(absolutePath.endsWith(fileName)); + } + }