001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.propertyeditors; 018 019import java.beans.PropertyEditorSupport; 020import java.io.File; 021import java.io.IOException; 022 023import org.springframework.core.io.Resource; 024import org.springframework.core.io.ResourceEditor; 025import org.springframework.util.Assert; 026import org.springframework.util.ResourceUtils; 027import org.springframework.util.StringUtils; 028 029/** 030 * Editor for {@code java.io.File}, to directly populate a File property 031 * from a Spring resource location. 032 * 033 * <p>Supports Spring-style URL notation: any fully qualified standard URL 034 * ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL. 035 * 036 * <p><b>NOTE:</b> The behavior of this editor has changed in Spring 2.0. 037 * Previously, it created a File instance directly from a filename. 038 * As of Spring 2.0, it takes a standard Spring resource location as input; 039 * this is consistent with URLEditor and InputStreamEditor now. 040 * 041 * <p><b>NOTE:</b> In Spring 2.5 the following modification was made. 042 * If a file name is specified without a URL prefix or without an absolute path 043 * then we try to locate the file using standard ResourceLoader semantics. 044 * If the file was not found, then a File instance is created assuming the file 045 * name refers to a relative file location. 046 * 047 * @author Juergen Hoeller 048 * @author Thomas Risberg 049 * @since 09.12.2003 050 * @see java.io.File 051 * @see org.springframework.core.io.ResourceEditor 052 * @see org.springframework.core.io.ResourceLoader 053 * @see URLEditor 054 * @see InputStreamEditor 055 */ 056public class FileEditor extends PropertyEditorSupport { 057 058 private final ResourceEditor resourceEditor; 059 060 061 /** 062 * Create a new FileEditor, using a default ResourceEditor underneath. 063 */ 064 public FileEditor() { 065 this.resourceEditor = new ResourceEditor(); 066 } 067 068 /** 069 * Create a new FileEditor, using the given ResourceEditor underneath. 070 * @param resourceEditor the ResourceEditor to use 071 */ 072 public FileEditor(ResourceEditor resourceEditor) { 073 Assert.notNull(resourceEditor, "ResourceEditor must not be null"); 074 this.resourceEditor = resourceEditor; 075 } 076 077 078 @Override 079 public void setAsText(String text) throws IllegalArgumentException { 080 if (!StringUtils.hasText(text)) { 081 setValue(null); 082 return; 083 } 084 085 // Check whether we got an absolute file path without "file:" prefix. 086 // For backwards compatibility, we'll consider those as straight file path. 087 File file = null; 088 if (!ResourceUtils.isUrl(text)) { 089 file = new File(text); 090 if (file.isAbsolute()) { 091 setValue(file); 092 return; 093 } 094 } 095 096 // Proceed with standard resource location parsing. 097 this.resourceEditor.setAsText(text); 098 Resource resource = (Resource) this.resourceEditor.getValue(); 099 100 // If it's a URL or a path pointing to an existing resource, use it as-is. 101 if (file == null || resource.exists()) { 102 try { 103 setValue(resource.getFile()); 104 } 105 catch (IOException ex) { 106 throw new IllegalArgumentException( 107 "Could not retrieve file for " + resource + ": " + ex.getMessage()); 108 } 109 } 110 else { 111 // Set a relative File reference and hope for the best. 112 setValue(file); 113 } 114 } 115 116 @Override 117 public String getAsText() { 118 File value = (File) getValue(); 119 return (value != null ? value.getPath() : ""); 120 } 121 122}