sourceClass) throws Exception;
diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/converter/TwoWayConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/TwoWayConverter.java
new file mode 100644
index 0000000000..f31ba5e1d2
--- /dev/null
+++ b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/TwoWayConverter.java
@@ -0,0 +1,25 @@
+package org.springframework.core.convert.converter;
+
+import org.springframework.core.convert.ConversionService;
+import org.springframework.core.convert.ConvertException;
+
+/**
+ * A converter that can also convert a target object of type T to a source of class S.
+ *
+ * Implementations of this interface are thread-safe and can be shared. Converters are typically registered with and
+ * accessed through a {@link ConversionService}.
+ *
+ * @author Keith Donald
+ */
+public interface TwoWayConverter extends Converter {
+
+ /**
+ * Convert the target of type T back to source type S.
+ * @param target the target object to convert, which must be an instance of T
+ * @return the converted object, which must be an instance of S
+ * @throws Exception an exception occurred performing the conversion; may be any checked exception, the conversion
+ * system will handle wrapping the failure in a {@link ConvertException} that provides a consistent type
+ * conversion error context
+ */
+ public S convertBack(T target) throws Exception;
+}
diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java
index 4adf86d348..d9f35da6d3 100644
--- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java
+++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java
@@ -33,6 +33,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterInfo;
import org.springframework.core.convert.converter.SuperConverter;
import org.springframework.core.convert.converter.SuperTwoWayConverter;
+import org.springframework.core.convert.converter.TwoWayConverter;
import org.springframework.util.Assert;
/**
@@ -89,9 +90,11 @@ public class GenericConversionService implements ConversionService {
// index forward
Map sourceMap = getSourceMap(sourceType);
sourceMap.put(targetType, converter);
- // index reverse
- sourceMap = getSourceMap(targetType);
- sourceMap.put(sourceType, new ReverseConverter(converter));
+ if (converter instanceof TwoWayConverter) {
+ // index reverse
+ sourceMap = getSourceMap(targetType);
+ sourceMap.put(sourceType, new ReverseConverter((TwoWayConverter) converter));
+ }
}
/**
@@ -228,7 +231,7 @@ public class GenericConversionService implements ConversionService {
for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof ParameterizedType) {
ParameterizedType pInterface = (ParameterizedType) genericInterface;
- if (Converter.class.equals(pInterface.getRawType())
+ if (Converter.class.isAssignableFrom((Class) pInterface.getRawType())
|| SuperConverter.class.isAssignableFrom((Class) pInterface.getRawType())) {
Class s = getParameterClass(pInterface.getActualTypeArguments()[0], converter.getClass());
Class t = getParameterClass(pInterface.getActualTypeArguments()[1], converter.getClass());
diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ReverseConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ReverseConverter.java
index eb85ac1aed..d35559cd91 100644
--- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ReverseConverter.java
+++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ReverseConverter.java
@@ -16,6 +16,7 @@
package org.springframework.core.convert.service;
import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.TwoWayConverter;
/**
* A converter that reverses another converter.
@@ -24,17 +25,14 @@ import org.springframework.core.convert.converter.Converter;
@SuppressWarnings("unchecked")
class ReverseConverter implements Converter {
- private Converter converter;
+ private TwoWayConverter converter;
- public ReverseConverter(Converter converter) {
+ public ReverseConverter(TwoWayConverter converter) {
this.converter = converter;
}
public Object convert(Object source) throws Exception {
return converter.convertBack(source);
}
-
- public Object convertBack(Object target) throws Exception {
- throw new IllegalStateException("Should not be called");
- }
+
}
diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
index 0c9f36dfa9..50cf3c432a 100644
--- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
+++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
@@ -16,7 +16,7 @@
package org.springframework.expression.spel.support;
-import org.springframework.core.convert.ConversionException;
+import org.springframework.core.convert.ConvertException;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
@@ -55,7 +55,7 @@ public class StandardTypeConverter implements TypeConverter {
return conversionService.convert(value, typeDescriptor);
} catch (ConverterNotFoundException cenfe) {
throw new SpelException(cenfe, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
- } catch (ConversionException ce) {
+ } catch (ConvertException ce) {
throw new SpelException(ce, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
}
}