/**
* Checks if the given converter can handle conversion between the given
- * presentation and model type
+ * presentation and model type. Does strict type checking and only returns
+ * true if the converter claims it can handle exactly the given types.
+ *
+ * @see #canConverterPossiblyHandle(Converter, Class, Class)
*
* @param converter
- * The converter to check
+ * The converter to check. If this is null the result is always
+ * false.
* @param presentationType
* The presentation type
* @param modelType
return false;
}
- if (!modelType.isAssignableFrom(converter.getModelType())) {
+ if (modelType != converter.getModelType()) {
+ return false;
+ }
+ if (presentationType != converter.getPresentationType()) {
return false;
}
- if (!presentationType.isAssignableFrom(converter.getPresentationType())) {
+
+ return true;
+ }
+
+ /**
+ * Checks if it possible that the given converter can handle conversion
+ * between the given presentation and model type somehow.
+ *
+ * @param converter
+ * The converter to check. If this is null the result is always
+ * false.
+ * @param presentationType
+ * The presentation type
+ * @param modelType
+ * The model type
+ * @return true if the converter possibly support conversion between the
+ * given presentation and model type, false otherwise
+ */
+ public static boolean canConverterPossiblyHandle(Converter<?, ?> converter,
+ Class<?> presentationType, Class<?> modelType) {
+ if (converter == null) {
+ return false;
+ }
+ Class<?> converterModelType = converter.getModelType();
+
+ if (!modelType.isAssignableFrom(converterModelType)
+ && !converterModelType.isAssignableFrom(modelType)) {
+ // model types are not compatible in any way
+ return false;
+ }
+
+ Class<?> converterPresentationType = converter.getPresentationType();
+ if (!presentationType.isAssignableFrom(converterPresentationType)
+ && !converterPresentationType
+ .isAssignableFrom(presentationType)) {
+ // presentation types are not compatible in any way
return false;
}
// Check if the current converter is compatible.
if (newDataSource != null
- && !ConverterUtil.canConverterHandle(getConverter(), getType(),
- newDataSource.getType())) {
- // Changing from e.g. Number -> Double should set a new converter,
- // changing from Double -> Number can keep the old one (Property
- // accepts Number)
-
- // Set a new converter if there is a new data source and
- // there is no old converter or the old is incompatible.
+ && !ConverterUtil.canConverterPossiblyHandle(getConverter(),
+ getType(), newDataSource.getType())) {
+ // There is no converter set or there is no way the current
+ // converter can be compatible.
setConverter(newDataSource.getType());
}
- // Gets the value from source
+ // Gets the value from source. This requires that a valid converter has
+ // been set.
try {
if (dataSource != null) {
T fieldValue = convertFromModel(getDataSourceValue());
((Property.ValueChangeNotifier) dataSource).removeListener(this);
}
+ // Check if the current converter is compatible.
if (newDataSource != null
- && !ConverterUtil.canConverterHandle(getConverter(),
- String.class, newDataSource.getType())) {
- // Try to find a converter
+ && !ConverterUtil.canConverterPossiblyHandle(getConverter(),
+ getType(), newDataSource.getType())) {
+ // There is no converter set or there is no way the current
+ // converter can be compatible.
Converter<String, ?> c = ConverterUtil.getConverter(String.class,
newDataSource.getType(), getSession());
setConverter(c);
}
+
dataSource = newDataSource;
if (dataSource != null) {
// Update the value from the data source. If data source was set to
--- /dev/null
+package com.vaadin.tests.data.converter;
+
+public enum AnotherTestEnum {
+ ONE("ONE"), TWO("TWO");
+
+ private String id;
+
+ private AnotherTestEnum(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.data.converter;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.ui.TextField;
+
+public class TestAnyEnumToStringConverter {
+
+ public class AnyEnumToStringConverter implements Converter<Enum, String> {
+
+ private Class<? extends Enum>[] enumClass;
+
+ public AnyEnumToStringConverter(Class<? extends Enum>... enumClass) {
+ this.enumClass = enumClass;
+ }
+
+ @Override
+ public String convertToModel(Enum value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public Enum convertToPresentation(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+ for (Class<? extends Enum> candidate : enumClass) {
+ for (Enum e : candidate.getEnumConstants()) {
+ if (e.toString().equals(value)) {
+ return e;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<Enum> getPresentationType() {
+ return Enum.class;
+ }
+
+ }
+
+ private AnyEnumToStringConverter converter;
+
+ @Before
+ public void setup() {
+ converter = new AnyEnumToStringConverter(TestEnum.class,
+ AnotherTestEnum.class);
+ }
+
+ @Test
+ public void nullConversion() {
+ Assert.assertEquals(null, converter.convertToModel(null, null));
+ }
+
+ @Test
+ public void enumToStringConversion() {
+ Assert.assertEquals(TestEnum.TWO.toString(),
+ converter.convertToModel(TestEnum.TWO, null));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(),
+ converter.convertToModel(AnotherTestEnum.TWO, null));
+ }
+
+ @Test
+ public void stringToEnumConversion() {
+ Assert.assertEquals(TestEnum.TWO,
+ converter.convertToPresentation(TestEnum.TWO.toString(), null));
+ Assert.assertEquals(AnotherTestEnum.TWO, converter
+ .convertToPresentation(AnotherTestEnum.TWO.toString(), null));
+ }
+
+ @Test
+ public void stringToEnumWithField() {
+ TextField tf = new TextField();
+ tf.setConverter(new ReverseConverter(converter));
+ tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(AnotherTestEnum.ONE.toString());
+ Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getPropertyDataSource()
+ .getValue());
+
+ tf.setPropertyDataSource(new ObjectProperty(TestEnum.TWO));
+ Assert.assertEquals(TestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(TestEnum.ONE.toString());
+ Assert.assertEquals(TestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(TestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(TestEnum.ONE, tf.getPropertyDataSource().getValue());
+
+ }
+}
--- /dev/null
+package com.vaadin.tests.data.converter;
+
+public enum TestEnum {
+ ONE("1"), TWO("2");
+
+ private String id;
+
+ private TestEnum(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.data.converter;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.ui.TextField;
+
+public class TestSpecificEnumToStringConverter {
+
+ public class SpecificEnumToStringConverter implements
+ Converter<Enum, String> {
+
+ private Class<? extends Enum> enumClass;
+
+ public SpecificEnumToStringConverter(Class<? extends Enum> enumClass) {
+ this.enumClass = enumClass;
+ }
+
+ @Override
+ public String convertToModel(Enum value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return value.toString();
+ }
+
+ @Override
+ public Enum convertToPresentation(String value, Locale locale)
+ throws com.vaadin.data.util.converter.Converter.ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ for (Enum e : enumClass.getEnumConstants()) {
+ if (e.toString().equals(value)) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<String> getModelType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<Enum> getPresentationType() {
+ return (Class<Enum>) enumClass;
+ }
+
+ }
+
+ SpecificEnumToStringConverter testEnumConverter;
+ SpecificEnumToStringConverter anotherTestEnumConverter;
+
+ @Before
+ public void setup() {
+ testEnumConverter = new SpecificEnumToStringConverter(TestEnum.class);
+ anotherTestEnumConverter = new SpecificEnumToStringConverter(
+ AnotherTestEnum.class);
+ }
+
+ @Test
+ public void nullConversion() {
+ Assert.assertEquals(null, testEnumConverter.convertToModel(null, null));
+ }
+
+ @Test
+ public void enumToStringConversion() {
+ Assert.assertEquals(TestEnum.TWO.toString(),
+ testEnumConverter.convertToModel(TestEnum.TWO, null));
+ }
+
+ @Test
+ public void stringToEnumConversion() {
+ Assert.assertEquals(TestEnum.TWO, testEnumConverter
+ .convertToPresentation(TestEnum.TWO.toString(), null));
+ }
+
+ @Test
+ public void stringToEnumWithField() {
+ TextField tf = new TextField();
+ tf.setConverter(new ReverseConverter(anotherTestEnumConverter));
+ tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO));
+ Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue());
+ tf.setValue(AnotherTestEnum.ONE.toString());
+ Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue());
+ Assert.assertEquals(AnotherTestEnum.ONE, tf.getPropertyDataSource()
+ .getValue());
+
+ }
+}