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.support; 018 019import java.beans.PropertyEditor; 020import java.io.File; 021import java.io.InputStream; 022import java.io.Reader; 023import java.net.URI; 024import java.net.URL; 025 026import org.xml.sax.InputSource; 027 028import org.springframework.beans.PropertyEditorRegistrar; 029import org.springframework.beans.PropertyEditorRegistry; 030import org.springframework.beans.PropertyEditorRegistrySupport; 031import org.springframework.beans.propertyeditors.ClassArrayEditor; 032import org.springframework.beans.propertyeditors.ClassEditor; 033import org.springframework.beans.propertyeditors.FileEditor; 034import org.springframework.beans.propertyeditors.InputSourceEditor; 035import org.springframework.beans.propertyeditors.InputStreamEditor; 036import org.springframework.beans.propertyeditors.PathEditor; 037import org.springframework.beans.propertyeditors.ReaderEditor; 038import org.springframework.beans.propertyeditors.URIEditor; 039import org.springframework.beans.propertyeditors.URLEditor; 040import org.springframework.core.env.PropertyResolver; 041import org.springframework.core.io.ContextResource; 042import org.springframework.core.io.Resource; 043import org.springframework.core.io.ResourceEditor; 044import org.springframework.core.io.ResourceLoader; 045import org.springframework.core.io.support.ResourceArrayPropertyEditor; 046import org.springframework.core.io.support.ResourcePatternResolver; 047import org.springframework.util.ClassUtils; 048 049/** 050 * PropertyEditorRegistrar implementation that populates a given 051 * {@link org.springframework.beans.PropertyEditorRegistry} 052 * (typically a {@link org.springframework.beans.BeanWrapper} used for bean 053 * creation within an {@link org.springframework.context.ApplicationContext}) 054 * with resource editors. Used by 055 * {@link org.springframework.context.support.AbstractApplicationContext}. 056 * 057 * @author Juergen Hoeller 058 * @author Chris Beams 059 * @since 2.0 060 */ 061public class ResourceEditorRegistrar implements PropertyEditorRegistrar { 062 063 private static Class<?> pathClass; 064 065 static { 066 try { 067 pathClass = ClassUtils.forName("java.nio.file.Path", ResourceEditorRegistrar.class.getClassLoader()); 068 } 069 catch (ClassNotFoundException ex) { 070 // Java 7 Path class not available 071 pathClass = null; 072 } 073 } 074 075 076 private final PropertyResolver propertyResolver; 077 078 private final ResourceLoader resourceLoader; 079 080 081 /** 082 * Create a new ResourceEditorRegistrar for the given {@link ResourceLoader} 083 * and {@link PropertyResolver}. 084 * @param resourceLoader the ResourceLoader (or ResourcePatternResolver) 085 * to create editors for (usually an ApplicationContext) 086 * @param propertyResolver the PropertyResolver (usually an Environment) 087 * @see org.springframework.core.env.Environment 088 * @see org.springframework.core.io.support.ResourcePatternResolver 089 * @see org.springframework.context.ApplicationContext 090 */ 091 public ResourceEditorRegistrar(ResourceLoader resourceLoader, PropertyResolver propertyResolver) { 092 this.resourceLoader = resourceLoader; 093 this.propertyResolver = propertyResolver; 094 } 095 096 097 /** 098 * Populate the given {@code registry} with the following resource editors: 099 * ResourceEditor, InputStreamEditor, InputSourceEditor, FileEditor, URLEditor, 100 * URIEditor, ClassEditor, ClassArrayEditor. 101 * <p>If this registrar has been configured with a {@link ResourcePatternResolver}, 102 * a ResourceArrayPropertyEditor will be registered as well. 103 * @see org.springframework.core.io.ResourceEditor 104 * @see org.springframework.beans.propertyeditors.InputStreamEditor 105 * @see org.springframework.beans.propertyeditors.InputSourceEditor 106 * @see org.springframework.beans.propertyeditors.FileEditor 107 * @see org.springframework.beans.propertyeditors.URLEditor 108 * @see org.springframework.beans.propertyeditors.URIEditor 109 * @see org.springframework.beans.propertyeditors.ClassEditor 110 * @see org.springframework.beans.propertyeditors.ClassArrayEditor 111 * @see org.springframework.core.io.support.ResourceArrayPropertyEditor 112 */ 113 @Override 114 public void registerCustomEditors(PropertyEditorRegistry registry) { 115 ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver); 116 doRegisterEditor(registry, Resource.class, baseEditor); 117 doRegisterEditor(registry, ContextResource.class, baseEditor); 118 doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor)); 119 doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor)); 120 doRegisterEditor(registry, File.class, new FileEditor(baseEditor)); 121 if (pathClass != null) { 122 doRegisterEditor(registry, pathClass, new PathEditor(baseEditor)); 123 } 124 doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor)); 125 doRegisterEditor(registry, URL.class, new URLEditor(baseEditor)); 126 127 ClassLoader classLoader = this.resourceLoader.getClassLoader(); 128 doRegisterEditor(registry, URI.class, new URIEditor(classLoader)); 129 doRegisterEditor(registry, Class.class, new ClassEditor(classLoader)); 130 doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader)); 131 132 if (this.resourceLoader instanceof ResourcePatternResolver) { 133 doRegisterEditor(registry, Resource[].class, 134 new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver)); 135 } 136 } 137 138 /** 139 * Override default editor, if possible (since that's what we really mean to do here); 140 * otherwise register as a custom editor. 141 */ 142 private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) { 143 if (registry instanceof PropertyEditorRegistrySupport) { 144 ((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor); 145 } 146 else { 147 registry.registerCustomEditor(requiredType, editor); 148 } 149 } 150 151}