Skip to content

Commit b152ac3

Browse files
committed
CustomEditorConfigurer supports PropertyEditor instances again (with deprecation warning); for XFire compatibility (SPR-6157)
1 parent 0c47a01 commit b152ac3

File tree

3 files changed

+103
-13
lines changed

3 files changed

+103
-13
lines changed

org.springframework.beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,9 @@ public void registerCustomEditor(Class requiredType, String propertyPath, Proper
266266
* shared editor that might be used concurrently.
267267
* @param requiredType the type of the property
268268
* @param propertyEditor the shared editor to register
269+
* @deprecated as of Spring 3.0, in favor of PropertyEditorRegistrars or ConversionService usage
269270
*/
271+
@Deprecated
270272
public void registerSharedEditor(Class requiredType, PropertyEditor propertyEditor) {
271273
registerCustomEditor(requiredType, null, propertyEditor);
272274
if (this.sharedEditors == null) {

org.springframework.beans/src/main/java/org/springframework/beans/factory/config/CustomEditorConfigurer.java

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.springframework.beans.BeansException;
2626
import org.springframework.beans.FatalBeanException;
2727
import org.springframework.beans.PropertyEditorRegistrar;
28+
import org.springframework.beans.PropertyEditorRegistry;
29+
import org.springframework.beans.PropertyEditorRegistrySupport;
2830
import org.springframework.beans.factory.BeanClassLoaderAware;
2931
import org.springframework.core.Ordered;
3032
import org.springframework.util.Assert;
@@ -90,7 +92,7 @@ public class CustomEditorConfigurer implements BeanFactoryPostProcessor, BeanCla
9092

9193
private PropertyEditorRegistrar[] propertyEditorRegistrars;
9294

93-
private Map<String, String> customEditors;
95+
private Map<String, ?> customEditors;
9496

9597
private boolean ignoreUnresolvableEditors = false;
9698

@@ -123,10 +125,11 @@ public void setPropertyEditorRegistrars(PropertyEditorRegistrar[] propertyEditor
123125
* Specify the custom editors to register via a {@link Map}, using the
124126
* class name of the required type as the key and the class name of the
125127
* associated {@link PropertyEditor} as value.
126-
* @param customEditors said <code>Map</code> of editors (can be <code>null</code>)
128+
* <p>Also supports {@link PropertyEditor} instances as values; however,
129+
* this is deprecated since Spring 2.0.7!
127130
* @see ConfigurableListableBeanFactory#registerCustomEditor
128131
*/
129-
public void setCustomEditors(Map<String, String> customEditors) {
132+
public void setCustomEditors(Map<String, ?> customEditors) {
130133
this.customEditors = customEditors;
131134
}
132135

@@ -156,16 +159,35 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
156159
}
157160

158161
if (this.customEditors != null) {
159-
for (Map.Entry<String, String> entry : this.customEditors.entrySet()) {
162+
for (Map.Entry<String, ?> entry : this.customEditors.entrySet()) {
160163
String key = entry.getKey();
161-
String value = entry.getValue();
164+
Object value = entry.getValue();
162165
Class requiredType = null;
163166

164167
try {
165168
requiredType = ClassUtils.forName(key, this.beanClassLoader);
166-
Class editorClass = ClassUtils.forName(value, this.beanClassLoader);
167-
Assert.isAssignable(PropertyEditor.class, editorClass);
168-
beanFactory.registerCustomEditor(requiredType, (Class<? extends PropertyEditor>) editorClass);
169+
if (value instanceof PropertyEditor) {
170+
if (logger.isWarnEnabled()) {
171+
logger.warn("Passing PropertyEditor instances into CustomEditorConfigurer is deprecated: " +
172+
"use PropertyEditorRegistrars or PropertyEditor class names instead. " +
173+
"Offending key [" + key + "; offending editor instance: " + value);
174+
}
175+
beanFactory.addPropertyEditorRegistrar(
176+
new SharedPropertyEditorRegistrar(requiredType, (PropertyEditor) value));
177+
}
178+
else if (value instanceof Class) {
179+
beanFactory.registerCustomEditor(requiredType, (Class) value);
180+
}
181+
else if (value instanceof String) {
182+
Class editorClass = ClassUtils.forName((String) value, this.beanClassLoader);
183+
Assert.isAssignable(PropertyEditor.class, editorClass);
184+
beanFactory.registerCustomEditor(requiredType, (Class<? extends PropertyEditor>) editorClass);
185+
}
186+
else {
187+
throw new IllegalArgumentException("Mapped value [" + value + "] for custom editor key [" +
188+
key + "] is not of required type [" + PropertyEditor.class.getName() +
189+
"] or a corresponding Class or String value indicating a PropertyEditor implementation");
190+
}
169191
}
170192
catch (ClassNotFoundException ex) {
171193
if (this.ignoreUnresolvableEditors) {
@@ -181,4 +203,29 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
181203
}
182204
}
183205

206+
207+
/**
208+
* PropertyEditorRegistrar that registers a (deprecated) shared editor.
209+
*/
210+
private static class SharedPropertyEditorRegistrar implements PropertyEditorRegistrar {
211+
212+
private final Class requiredType;
213+
214+
private final PropertyEditor sharedEditor;
215+
216+
public SharedPropertyEditorRegistrar(Class requiredType, PropertyEditor sharedEditor) {
217+
this.requiredType = requiredType;
218+
this.sharedEditor = sharedEditor;
219+
}
220+
221+
public void registerCustomEditors(PropertyEditorRegistry registry) {
222+
if (!(registry instanceof PropertyEditorRegistrySupport)) {
223+
throw new IllegalArgumentException("Cannot registered shared editor " +
224+
"on non-PropertyEditorRegistrySupport registry: " + registry);
225+
}
226+
((PropertyEditorRegistrySupport) registry).registerSharedEditor(this.requiredType, this.sharedEditor);
227+
}
228+
}
229+
230+
184231
}

org.springframework.beans/src/test/java/org/springframework/beans/factory/config/CustomEditorConfigurerTests.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
1616

1717
package org.springframework.beans.factory.config;
1818

19-
import static org.junit.Assert.*;
20-
19+
import java.beans.PropertyEditor;
2120
import java.beans.PropertyEditorSupport;
2221
import java.text.DateFormat;
2322
import java.text.ParseException;
@@ -26,7 +25,10 @@
2625
import java.util.Locale;
2726
import java.util.Map;
2827

28+
import static org.junit.Assert.*;
2929
import org.junit.Test;
30+
import test.beans.TestBean;
31+
3032
import org.springframework.beans.FatalBeanException;
3133
import org.springframework.beans.MutablePropertyValues;
3234
import org.springframework.beans.PropertyEditorRegistrar;
@@ -35,8 +37,6 @@
3537
import org.springframework.beans.factory.support.RootBeanDefinition;
3638
import org.springframework.beans.propertyeditors.CustomDateEditor;
3739

38-
import test.beans.TestBean;
39-
4040
/**
4141
* Unit tests for {@link CustomEditorConfigurer}.
4242
*
@@ -72,6 +72,29 @@ public void registerCustomEditors(PropertyEditorRegistry registry) {
7272
assertEquals(df.parse("2.12.1975"), tb2.getSomeMap().get("myKey"));
7373
}
7474

75+
@Test
76+
public void testCustomEditorConfigurerWithEditorInstance() throws ParseException {
77+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
78+
CustomEditorConfigurer cec = new CustomEditorConfigurer();
79+
Map<String, PropertyEditor> editors = new HashMap<String, PropertyEditor>();
80+
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);
81+
editors.put(Date.class.getName(), new CustomDateEditor(df, true));
82+
cec.setCustomEditors(editors);
83+
cec.postProcessBeanFactory(bf);
84+
85+
MutablePropertyValues pvs = new MutablePropertyValues();
86+
pvs.addPropertyValue("date", "2.12.1975");
87+
bf.registerBeanDefinition("tb1", new RootBeanDefinition(TestBean.class, pvs));
88+
pvs = new MutablePropertyValues();
89+
pvs.addPropertyValue("someMap[myKey]", new TypedStringValue("2.12.1975", Date.class));
90+
bf.registerBeanDefinition("tb2", new RootBeanDefinition(TestBean.class, pvs));
91+
92+
TestBean tb1 = (TestBean) bf.getBean("tb1");
93+
assertEquals(df.parse("2.12.1975"), tb1.getDate());
94+
TestBean tb2 = (TestBean) bf.getBean("tb2");
95+
assertEquals(df.parse("2.12.1975"), tb2.getSomeMap().get("myKey"));
96+
}
97+
7598
@Test
7699
public void testCustomEditorConfigurerWithEditorClassName() throws ParseException {
77100
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -90,6 +113,24 @@ public void testCustomEditorConfigurerWithEditorClassName() throws ParseExceptio
90113
assertEquals(df.parse("2.12.1975"), tb.getDate());
91114
}
92115

116+
@Test
117+
public void testCustomEditorConfigurerWithEditorAsClass() throws ParseException {
118+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
119+
CustomEditorConfigurer cec = new CustomEditorConfigurer();
120+
Map<String, Class> editors = new HashMap<String, Class>();
121+
editors.put(Date.class.getName(), MyDateEditor.class);
122+
cec.setCustomEditors(editors);
123+
cec.postProcessBeanFactory(bf);
124+
125+
MutablePropertyValues pvs = new MutablePropertyValues();
126+
pvs.addPropertyValue("date", "2.12.1975");
127+
bf.registerBeanDefinition("tb", new RootBeanDefinition(TestBean.class, pvs));
128+
129+
TestBean tb = (TestBean) bf.getBean("tb");
130+
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);
131+
assertEquals(df.parse("2.12.1975"), tb.getDate());
132+
}
133+
93134
@Test
94135
public void testCustomEditorConfigurerWithRequiredTypeArray() throws ParseException {
95136
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();

0 commit comments

Comments
 (0)