]> source.dussan.org Git - vaadin-framework.git/commitdiff
String <-> Enum converter which produces a human readable string (#14756)
authorArtur Signell <artur@vaadin.com>
Wed, 24 Sep 2014 16:20:43 +0000 (19:20 +0300)
committerVaadin Code Review <review@vaadin.com>
Tue, 30 Sep 2014 12:39:03 +0000 (12:39 +0000)
Change-Id: I3a825f52a43daea3172ced23bc510118376e76cb

server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
server/src/com/vaadin/data/util/converter/StringToEnumConverter.java [new file with mode: 0644]
server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java [new file with mode: 0644]

index fdf858a5285d57f277cb87f56bb532d6b176ab93..26613c5d027857bcffd544581d6d4388c53bba4a 100644 (file)
@@ -110,6 +110,8 @@ public class DefaultConverterFactory implements ConverterFactory {
             return new StringToBooleanConverter();
         } else if (Date.class.isAssignableFrom(sourceType)) {
             return new StringToDateConverter();
+        } else if (Enum.class.isAssignableFrom(sourceType)) {
+            return new StringToEnumConverter();
         } else {
             return null;
         }
diff --git a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
new file mode 100644 (file)
index 0000000..a1328d8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2000-2014 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.data.util.converter;
+
+import java.util.EnumSet;
+import java.util.Locale;
+
+/**
+ * A converter that converts from {@link String} to an {@link Enum} and back.
+ * <p>
+ * Designed to provide nice human readable strings for {@link Enum} classes
+ * where the constants are named SOME_UPPERCASE_WORDS. Will not necessarily work
+ * correctly for other cases.
+ * </p>
+ * 
+ * @author Vaadin Ltd
+ * @since
+ */
+public class StringToEnumConverter implements Converter<String, Enum> {
+
+    @Override
+    public Enum convertToModel(String value, Class<? extends Enum> targetType,
+            Locale locale) throws ConversionException {
+        if (value == null) {
+            return null;
+        }
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+
+        // Foo -> FOO
+        // Foo bar -> FOO_BAR
+        String result = value.replace(" ", "_").toUpperCase(locale);
+        try {
+            return Enum.valueOf(targetType, result);
+        } catch (IllegalArgumentException ee) {
+            // There was no match. Try to compare the available values to see if
+            // the constant is using something else than all upper case
+
+            EnumSet<?> set = EnumSet.allOf(targetType);
+            for (Enum e : set) {
+                if (e.name().toUpperCase(locale).equals(result)) {
+                    return e;
+                }
+            }
+
+            // Fallback did not work either, re-throw original exception so user
+            // knows what went wrong
+            throw new ConversionException(ee);
+        }
+    }
+
+    @Override
+    public String convertToPresentation(Enum value,
+            Class<? extends String> targetType, Locale locale)
+            throws ConversionException {
+        if (value == null) {
+            return null;
+        }
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+
+        String enumString = value.toString();
+        // FOO -> Foo
+        // FOO_BAR -> Foo bar
+        // _FOO -> _foo
+        String result = enumString.substring(0, 1).toUpperCase(locale);
+        result += enumString.substring(1).toLowerCase(locale).replace('_', ' ');
+
+        return result;
+    }
+
+    @Override
+    public Class<Enum> getModelType() {
+        return Enum.class;
+    }
+
+    @Override
+    public Class<String> getPresentationType() {
+        return String.class;
+    }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
new file mode 100644 (file)
index 0000000..2b19395
--- /dev/null
@@ -0,0 +1,59 @@
+package com.vaadin.tests.data.converter;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ReverseConverter;
+import com.vaadin.data.util.converter.StringToEnumConverter;
+
+public class TestStringToEnumConverter extends TestCase {
+
+    public static enum FooEnum {
+        VALUE1, SOME_VALUE, FOO_BAR_BAZ, Bar, nonStandardCase, _HUGH;
+    }
+
+    StringToEnumConverter converter = new StringToEnumConverter();
+    Converter<Enum, String> reverseConverter = new ReverseConverter<Enum, String>(
+            converter);
+
+    public void testNullConversion() {
+        assertEquals(null, converter.convertToModel(null, Enum.class, null));
+    }
+
+    public void testReverseNullConversion() {
+        assertEquals(null,
+                reverseConverter.convertToModel(null, String.class, null));
+    }
+
+    public void testValueConversion() {
+        assertEquals(FooEnum.VALUE1,
+                converter.convertToModel("Value1", FooEnum.class, null));
+        assertEquals(FooEnum.SOME_VALUE,
+                converter.convertToModel("Some value", FooEnum.class, null));
+        assertEquals(FooEnum.FOO_BAR_BAZ,
+                converter.convertToModel("Foo bar baz", FooEnum.class, null));
+        assertEquals(FooEnum.Bar,
+                converter.convertToModel("Bar", FooEnum.class, null));
+        assertEquals(FooEnum.nonStandardCase, converter.convertToModel(
+                "Nonstandardcase", FooEnum.class, null));
+        assertEquals(FooEnum._HUGH,
+                converter.convertToModel("_hugh", FooEnum.class, null));
+    }
+
+    public void testReverseValueConversion() {
+        assertEquals("Value1", reverseConverter.convertToModel(FooEnum.VALUE1,
+                String.class, null));
+        assertEquals("Some value", reverseConverter.convertToModel(
+                FooEnum.SOME_VALUE, String.class, null));
+        assertEquals("Foo bar baz", reverseConverter.convertToModel(
+                FooEnum.FOO_BAR_BAZ, String.class, null));
+        assertEquals("Bar", reverseConverter.convertToModel(FooEnum.Bar,
+                String.class, null));
+        assertEquals("Nonstandardcase", reverseConverter.convertToModel(
+                FooEnum.nonStandardCase, String.class, null));
+        assertEquals("_hugh", reverseConverter.convertToModel(FooEnum._HUGH,
+                String.class, null));
+
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java b/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java
new file mode 100644 (file)
index 0000000..67b3b84
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2014 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.components.textfield;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.TextField;
+
+public class EnumTextField extends AbstractTestUIWithLog {
+
+    public enum MyEnum {
+        FIRST_VALUE, VALUE, THE_LAST_VALUE;
+    }
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        final TextField tf = new TextField();
+        tf.addValueChangeListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+                if (tf.isValid()) {
+                    log(tf.getValue() + " (valid)");
+                } else {
+                    log(tf.getValue() + " (INVALID)");
+                }
+            }
+        });
+
+        tf.setPropertyDataSource(new ObjectProperty<Enum>(MyEnum.FIRST_VALUE));
+        addComponent(tf);
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java b/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java
new file mode 100644 (file)
index 0000000..113acee
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.components.textfield;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class EnumTextFieldTest extends SingleBrowserTest {
+    @Test
+    public void validValues() {
+        openTestURL();
+        $(TextFieldElement.class).first().clear();
+        $(TextFieldElement.class).first().sendKeys("Value");
+        $(TextFieldElement.class).first().sendKeys(Keys.TAB);
+        Assert.assertEquals("3. Value (valid)", getLogRow(0));
+
+        $(TextFieldElement.class).first().clear();
+        $(TextFieldElement.class).first().sendKeys("VaLuE");
+        $(TextFieldElement.class).first().sendKeys(Keys.TAB);
+        Assert.assertEquals("5. Value (valid)", getLogRow(0));
+
+        $(TextFieldElement.class).first().clear();
+        $(TextFieldElement.class).first().sendKeys("The last value");
+        $(TextFieldElement.class).first().sendKeys(Keys.TAB);
+        Assert.assertEquals("7. The last value (valid)", getLogRow(0));
+
+    }
+
+    @Test
+    public void invalidValue() {
+        openTestURL();
+        $(TextFieldElement.class).first().clear();
+        Assert.assertEquals("2. (INVALID)", getLogRow(0));
+
+        $(TextFieldElement.class).first().sendKeys("bar");
+        $(TextFieldElement.class).first().sendKeys(Keys.TAB);
+        Assert.assertEquals("3. bar (INVALID)", getLogRow(0));
+
+    }
+}