1 /*
2  * Copyright 2002-2009 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.beans.propertyeditors;
18 
19 import java.beans.PropertyEditorSupport;
20 import java.io.File;
21 import java.io.IOException;
22 
23 import org.springframework.core.io.Resource;
24 import org.springframework.core.io.ResourceEditor;
25 import org.springframework.util.Assert;
26 import org.springframework.util.ResourceUtils;
27 import org.springframework.util.StringUtils;
28 
29 /**
30  * Editor for <code>java.io.File</code>, to directly populate a File property
31  * from a Spring resource location.
32  *
33  * <p>Supports Spring-style URL notation: any fully qualified standard URL
34  * ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL.
35  *
36  * <p><b>NOTE:</b> The behavior of this editor has changed in Spring 2.0.
37  * Previously, it created a File instance directly from a filename.
38  * As of Spring 2.0, it takes a standard Spring resource location as input;
39  * this is consistent with URLEditor and InputStreamEditor now.
40  *
41  * <p><b>NOTE:</b> In Spring 2.5 the following modification was made.
42  * If a file name is specified without a URL prefix or without an absolute path
43  * then we try to locate the file using standard ResourceLoader semantics.
44  * If the file was not found, then a File instance is created assuming the file
45  * name refers to a relative file location.
46  *
47  * @author Juergen Hoeller
48  * @author Thomas Risberg
49  * @since 09.12.2003
50  * @see java.io.File
51  * @see org.springframework.core.io.ResourceEditor
52  * @see org.springframework.core.io.ResourceLoader
53  * @see URLEditor
54  * @see InputStreamEditor
55  */
56 public class FileEditor extends PropertyEditorSupport {
57 
58 	private final ResourceEditor resourceEditor;
59 
60 
61 	/**
62 	 * Create a new FileEditor,
63 	 * using the default ResourceEditor underneath.
64 	 */
FileEditor()65 	public FileEditor() {
66 		this.resourceEditor = new ResourceEditor();
67 	}
68 
69 	/**
70 	 * Create a new FileEditor,
71 	 * using the given ResourceEditor underneath.
72 	 * @param resourceEditor the ResourceEditor to use
73 	 */
FileEditor(ResourceEditor resourceEditor)74 	public FileEditor(ResourceEditor resourceEditor) {
75 		Assert.notNull(resourceEditor, "ResourceEditor must not be null");
76 		this.resourceEditor = resourceEditor;
77 	}
78 
79 
80 	@Override
setAsText(String text)81 	public void setAsText(String text) throws IllegalArgumentException {
82 		if (!StringUtils.hasText(text)) {
83 			setValue(null);
84 			return;
85 		}
86 
87 		// Check whether we got an absolute file path without "file:" prefix.
88 		// For backwards compatibility, we'll consider those as straight file path.
89 		if (!ResourceUtils.isUrl(text)) {
90 			File file = new File(text);
91 			if (file.isAbsolute()) {
92 				setValue(file);
93 				return;
94 			}
95 		}
96 
97 		// Proceed with standard resource location parsing.
98 		this.resourceEditor.setAsText(text);
99 		Resource resource = (Resource) this.resourceEditor.getValue();
100 
101 		// If it's a URL or a path pointing to an existing resource, use it as-is.
102 		if (ResourceUtils.isUrl(text) || resource.exists()) {
103 			try {
104 				setValue(resource.getFile());
105 			}
106 			catch (IOException ex) {
107 				throw new IllegalArgumentException(
108 						"Could not retrieve File for " + resource + ": " + ex.getMessage());
109 			}
110 		}
111 		else {
112 			// Create a relative File reference and hope for the best.
113 			setValue(new File(text));
114 		}
115 	}
116 
117 	@Override
getAsText()118 	public String getAsText() {
119 		File value = (File) getValue();
120 		return (value != null ? value.getPath() : "");
121 	}
122 
123 }
124