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;
025import java.nio.file.Path;
026
027import org.xml.sax.InputSource;
028
029import org.springframework.beans.PropertyEditorRegistrar;
030import org.springframework.beans.PropertyEditorRegistry;
031import org.springframework.beans.PropertyEditorRegistrySupport;
032import org.springframework.beans.propertyeditors.ClassArrayEditor;
033import org.springframework.beans.propertyeditors.ClassEditor;
034import org.springframework.beans.propertyeditors.FileEditor;
035import org.springframework.beans.propertyeditors.InputSourceEditor;
036import org.springframework.beans.propertyeditors.InputStreamEditor;
037import org.springframework.beans.propertyeditors.PathEditor;
038import org.springframework.beans.propertyeditors.ReaderEditor;
039import org.springframework.beans.propertyeditors.URIEditor;
040import org.springframework.beans.propertyeditors.URLEditor;
041import org.springframework.core.env.PropertyResolver;
042import org.springframework.core.io.ContextResource;
043import org.springframework.core.io.Resource;
044import org.springframework.core.io.ResourceEditor;
045import org.springframework.core.io.ResourceLoader;
046import org.springframework.core.io.support.ResourceArrayPropertyEditor;
047import org.springframework.core.io.support.ResourcePatternResolver;
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 final PropertyResolver propertyResolver;
064
065        private final ResourceLoader resourceLoader;
066
067
068        /**
069         * Create a new ResourceEditorRegistrar for the given {@link ResourceLoader}
070         * and {@link PropertyResolver}.
071         * @param resourceLoader the ResourceLoader (or ResourcePatternResolver)
072         * to create editors for (usually an ApplicationContext)
073         * @param propertyResolver the PropertyResolver (usually an Environment)
074         * @see org.springframework.core.env.Environment
075         * @see org.springframework.core.io.support.ResourcePatternResolver
076         * @see org.springframework.context.ApplicationContext
077         */
078        public ResourceEditorRegistrar(ResourceLoader resourceLoader, PropertyResolver propertyResolver) {
079                this.resourceLoader = resourceLoader;
080                this.propertyResolver = propertyResolver;
081        }
082
083
084        /**
085         * Populate the given {@code registry} with the following resource editors:
086         * ResourceEditor, InputStreamEditor, InputSourceEditor, FileEditor, URLEditor,
087         * URIEditor, ClassEditor, ClassArrayEditor.
088         * <p>If this registrar has been configured with a {@link ResourcePatternResolver},
089         * a ResourceArrayPropertyEditor will be registered as well.
090         * @see org.springframework.core.io.ResourceEditor
091         * @see org.springframework.beans.propertyeditors.InputStreamEditor
092         * @see org.springframework.beans.propertyeditors.InputSourceEditor
093         * @see org.springframework.beans.propertyeditors.FileEditor
094         * @see org.springframework.beans.propertyeditors.URLEditor
095         * @see org.springframework.beans.propertyeditors.URIEditor
096         * @see org.springframework.beans.propertyeditors.ClassEditor
097         * @see org.springframework.beans.propertyeditors.ClassArrayEditor
098         * @see org.springframework.core.io.support.ResourceArrayPropertyEditor
099         */
100        @Override
101        public void registerCustomEditors(PropertyEditorRegistry registry) {
102                ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
103                doRegisterEditor(registry, Resource.class, baseEditor);
104                doRegisterEditor(registry, ContextResource.class, baseEditor);
105                doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
106                doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
107                doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
108                doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
109                doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
110                doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
111
112                ClassLoader classLoader = this.resourceLoader.getClassLoader();
113                doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
114                doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
115                doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
116
117                if (this.resourceLoader instanceof ResourcePatternResolver) {
118                        doRegisterEditor(registry, Resource[].class,
119                                        new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
120                }
121        }
122
123        /**
124         * Override default editor, if possible (since that's what we really mean to do here);
125         * otherwise register as a custom editor.
126         */
127        private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {
128                if (registry instanceof PropertyEditorRegistrySupport) {
129                        ((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
130                }
131                else {
132                        registry.registerCustomEditor(requiredType, editor);
133                }
134        }
135
136}