Browse Source

PathEditor tries file system path in case of non-existing resource

Issue: SPR-14549
pull/1132/head
Juergen Hoeller 8 years ago
parent
commit
d69afaada8
  1. 9
      spring-beans/src/main/java/org/springframework/beans/propertyeditors/FileEditor.java
  2. 25
      spring-beans/src/main/java/org/springframework/beans/propertyeditors/PathEditor.java
  3. 11
      spring-beans/src/test/java/org/springframework/beans/propertyeditors/FileEditorTests.java
  4. 28
      spring-beans/src/test/java/org/springframework/beans/propertyeditors/PathEditorTests.java

9
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. // Check whether we got an absolute file path without "file:" prefix.
// For backwards compatibility, we'll consider those as straight file path. // For backwards compatibility, we'll consider those as straight file path.
File file = null;
if (!ResourceUtils.isUrl(text)) { if (!ResourceUtils.isUrl(text)) {
File file = new File(text); file = new File(text);
if (file.isAbsolute()) { if (file.isAbsolute()) {
setValue(file); setValue(file);
return; return;
@ -97,7 +98,7 @@ public class FileEditor extends PropertyEditorSupport {
Resource resource = (Resource) this.resourceEditor.getValue(); Resource resource = (Resource) this.resourceEditor.getValue();
// If it's a URL or a path pointing to an existing resource, use it as-is. // 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 { try {
setValue(resource.getFile()); setValue(resource.getFile());
} }
@ -107,8 +108,8 @@ public class FileEditor extends PropertyEditorSupport {
} }
} }
else { else {
// Create a relative File reference and hope for the best. // Set a relative File reference and hope for the best.
setValue(new File(text)); setValue(file);
} }
} }

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

@ -36,13 +36,10 @@ import org.springframework.util.Assert;
* <p>Based on {@link Paths#get(URI)}'s resolution algorithm, checking * <p>Based on {@link Paths#get(URI)}'s resolution algorithm, checking
* registered NIO file system providers, including the default file system * registered NIO file system providers, including the default file system
* for "file:..." paths. Also supports Spring-style URL notation: any fully * for "file:..." paths. Also supports Spring-style URL notation: any fully
* qualified standard URL and Spring's special "classpath:" pseudo-URL, * qualified standard URL and Spring's special "classpath:" pseudo-URL, as
* as well as Spring's context-specific relative file paths. * 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)}
* <p>Note that, in contrast to {@link FileEditor}, relative paths are only * if no existing context-relative resource could be found.
* 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.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 4.3.2 * @since 4.3.2
@ -77,10 +74,12 @@ public class PathEditor extends PropertyEditorSupport {
@Override @Override
public void setAsText(String text) throws IllegalArgumentException { 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 { try {
URI uri = new URI(text); URI uri = new URI(text);
if (uri.getScheme() != null) { if (uri.getScheme() != null) {
nioPathCandidate = false;
// Let's try NIO file system providers via Paths.get(URI) // Let's try NIO file system providers via Paths.get(URI)
setValue(Paths.get(uri).normalize()); setValue(Paths.get(uri).normalize());
return; return;
@ -97,13 +96,21 @@ public class PathEditor extends PropertyEditorSupport {
this.resourceEditor.setAsText(text); this.resourceEditor.setAsText(text);
Resource resource = (Resource) this.resourceEditor.getValue(); Resource resource = (Resource) this.resourceEditor.getValue();
if (resource == null) {
setValue(null);
}
else if (!resource.exists() && nioPathCandidate) {
setValue(Paths.get(text).normalize());
}
else {
try { try {
setValue(resource != null ? resource.getFile().toPath() : null); setValue(resource.getFile().toPath());
} }
catch (IOException ex) { catch (IOException ex) {
throw new IllegalArgumentException("Failed to retrieve file for " + resource, ex); throw new IllegalArgumentException("Failed to retrieve file for " + resource, ex);
} }
} }
}
@Override @Override
public String getAsText() { public String getAsText() {

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

@ -28,6 +28,7 @@ import static org.junit.Assert.*;
/** /**
* @author Thomas Risberg * @author Thomas Risberg
* @author Chris Beams * @author Chris Beams
* @author Juergen Hoeller
*/ */
public class FileEditorTests { public class FileEditorTests {
@ -78,10 +79,7 @@ public class FileEditorTests {
assertTrue(value instanceof File); assertTrue(value instanceof File);
File file = (File) value; File file = (File) value;
assertTrue(file.exists()); assertTrue(file.exists());
String absolutePath = file.getAbsolutePath(); String absolutePath = file.getAbsolutePath().replace('\\', '/');
if (File.separatorChar == '\\') {
absolutePath = absolutePath.replace('\\', '/');
}
assertTrue(absolutePath.endsWith(fileName)); assertTrue(absolutePath.endsWith(fileName));
} }
@ -95,10 +93,7 @@ public class FileEditorTests {
assertTrue(value instanceof File); assertTrue(value instanceof File);
File file = (File) value; File file = (File) value;
assertFalse(file.exists()); assertFalse(file.exists());
String absolutePath = file.getAbsolutePath(); String absolutePath = file.getAbsolutePath().replace('\\', '/');
if (File.separatorChar == '\\') {
absolutePath = absolutePath.replace('\\', '/');
}
assertTrue(absolutePath.endsWith(fileName)); assertTrue(absolutePath.endsWith(fileName));
} }

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

@ -59,6 +59,16 @@ public class PathEditorTests {
assertTrue(!path.toFile().exists()); 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 @Test
public void testUnqualifiedPathNameFound() throws Exception { public void testUnqualifiedPathNameFound() throws Exception {
PropertyEditor pathEditor = new PathEditor(); PropertyEditor pathEditor = new PathEditor();
@ -77,4 +87,22 @@ public class PathEditorTests {
assertTrue(absolutePath.endsWith(fileName)); 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));
}
} }

Loading…
Cancel
Save