]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add Bindinding.setRequired
authorPekka Hyvönen <pekka@vaadin.com>
Tue, 1 Nov 2016 09:53:44 +0000 (11:53 +0200)
committerPekka Hyvönen <pekka@vaadin.com>
Wed, 2 Nov 2016 07:51:19 +0000 (09:51 +0200)
Shorthand for making field show required indicator and validating against empty.
Removes obsolete NotNullValidator and NotEmptyValidator. Latter is still used
in some tests, that why it is still in test packages.

Fixes vaadin/framework8-issues#29

Change-Id: Ib116739a20a0bbd1b1460423ee36ed2752c5496a

server/src/main/java/com/vaadin/data/Binder.java
server/src/main/java/com/vaadin/data/validator/NotEmptyValidator.java [deleted file]
server/src/main/java/com/vaadin/data/validator/NotNullValidator.java [deleted file]
server/src/test/java/com/vaadin/data/BinderTest.java
server/src/test/java/com/vaadin/data/validator/BeanValidatorTest.java
server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java [new file with mode: 0644]
server/src/test/java/com/vaadin/data/validator/NotNullValidatorTest.java [deleted file]

index f8ddace8a636b2e7dbada9e817294d9d2255f77a..7912a55d7208c7ed1d3fe56f5791adcca0ec2bb9 100644 (file)
@@ -422,6 +422,47 @@ public class Binder<BEAN> implements Serializable {
          */
         public ValidationStatus<TARGET> validate();
 
+        /**
+         * Sets the field to be required. This means two things:
+         * <ol>
+         * <li>the required indicator is visible</li>
+         * <li>the field value is validated for not being empty*</li>
+         * </ol>
+         * For localizing the error message, use
+         * {@link #setRequired(SerializableFunction)}.
+         * <p>
+         * *Value not being the equal to what {@link HasValue#getEmptyValue()}
+         * returns.
+         *
+         * @see #setRequired(SerializableFunction)
+         * @see HasValue#setRequiredIndicatorVisible(boolean)
+         * @see HasValue#isEmpty()
+         * @param errorMessage
+         *            the error message to show for the invalid value
+         * @return this binding, for chaining
+         */
+        public default Binding<BEAN, FIELDVALUE, TARGET> setRequired(
+                String errorMessage) {
+            return setRequired(context -> errorMessage);
+        }
+
+        /**
+         * Sets the field to be required. This means two things:
+         * <ol>
+         * <li>the required indicator is visible</li>
+         * <li>the field value is validated for not being empty*</li>
+         * </ol>
+         * *Value not being the equal to what {@link HasValue#getEmptyValue()}
+         * returns.
+         *
+         * @see HasValue#setRequiredIndicatorVisible(boolean)
+         * @see HasValue#isEmpty()
+         * @param errorMessageProvider
+         *            the provider for localized validation error message
+         * @return this binding, for chaining
+         */
+        public Binding<BEAN, FIELDVALUE, TARGET> setRequired(
+                ErrorMessageProvider errorMessageProvider);
     }
 
     /**
@@ -521,6 +562,17 @@ public class Binder<BEAN> implements Serializable {
             return this;
         }
 
+        @Override
+        public Binding<BEAN, FIELDVALUE, TARGET> setRequired(
+                ErrorMessageProvider errorMessageProvider) {
+            checkUnbound();
+
+            getField().setRequiredIndicatorVisible(true);
+            return withValidator(
+                    value -> !Objects.equals(value, getField().getEmptyValue()),
+                    errorMessageProvider);
+        }
+
         @Override
         public HasValue<FIELDVALUE> getField() {
             return field;
diff --git a/server/src/main/java/com/vaadin/data/validator/NotEmptyValidator.java b/server/src/main/java/com/vaadin/data/validator/NotEmptyValidator.java
deleted file mode 100644 (file)
index 2223c33..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2000-2016 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.validator;
-
-import java.util.Objects;
-
-import com.vaadin.data.HasValue;
-import com.vaadin.data.ValidationResult;
-import com.vaadin.data.Validator;
-import com.vaadin.data.util.converter.ValueContext;
-
-/**
- * Simple validator to check against {@code null} value and empty {@link String}
- * value.
- * <p>
- * This validator works similar to {@link NotNullValidator} but in addition it
- * also check whether the value is not an empty String.
- * <p>
- * The main purpose of this validator is its usage with {@link HasRequired}
- * field instances.
- * <p>
- * If the field is required, it is visually indicated in the user interface.
- * Furthermore, required fields requires "non-empty" validator. So in addition
- * to call {@link HasRequired#setRequiredIndicatorVisible(boolean)} method one
- * should add an instance of this validator explicitly so the code looks like
- * this:
- *
- * <pre>
- * <code>
- * Binder<Bean,String, String> binder = new Binder<>();
- * TextField name = new TextField();
- * name.setRequiredIndicatorVisible(true);
- * binder.forField(name).withValidator(
- *      new NonEmptyValidator("Name cannot be empty"))
- *              .bind(Bean::getName, Bean::setName);
- * </code>
- * </pre>
- *
- * @see HasValue#setRequiredIndicatorVisible(boolean)
- * @author Vaadin Ltd
- * @since 8.0
- *
- */
-public class NotEmptyValidator<T> implements Validator<T> {
-
-    private final String message;
-
-    /**
-     * @param message
-     *            error validation message
-     */
-    public NotEmptyValidator(String message) {
-        this.message = message;
-    }
-
-    @Override
-    public ValidationResult apply(T value, ValueContext context) {
-        if (Objects.isNull(value) || Objects.equals(value, "")) {
-            return ValidationResult.error(message);
-        } else {
-            return ValidationResult.ok();
-        }
-    }
-
-}
diff --git a/server/src/main/java/com/vaadin/data/validator/NotNullValidator.java b/server/src/main/java/com/vaadin/data/validator/NotNullValidator.java
deleted file mode 100644 (file)
index c92aefa..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2000-2016 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.validator;
-
-import java.util.Objects;
-
-import com.vaadin.data.ValidationResult;
-import com.vaadin.data.util.converter.ValueContext;
-
-/**
- * This validator is used for validating properties that do not allow null
- * values.
- *
- * @author Vaadin Ltd.
- * @since 8.0
- */
-@SuppressWarnings("serial")
-public class NotNullValidator extends AbstractValidator<String> {
-
-    /**
-     * Creates a new NullValidator.
-     *
-     * @param errorMessage
-     *            the error message to display on invalidation.
-     */
-    public NotNullValidator(String errorMessage) {
-        super(errorMessage);
-    }
-
-    @Override
-    public ValidationResult apply(String value, ValueContext context) {
-        return Objects.isNull(value) ? ValidationResult.error(getMessage(value))
-                : ValidationResult.ok();
-    }
-
-}
index 6d33ab437b01a87e837ed52c907b2702081cf341..22af7d22724ccdf02d50d7ade9bbfdf7dc4e8c83 100644 (file)
@@ -5,14 +5,18 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Locale;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import com.vaadin.data.Binder.Binding;
 import com.vaadin.data.util.converter.StringToIntegerConverter;
-import com.vaadin.data.validator.NotNullValidator;
+import com.vaadin.data.validator.NotEmptyValidator;
+import com.vaadin.server.ErrorMessage;
 import com.vaadin.tests.data.bean.Person;
 import com.vaadin.tests.data.bean.Sex;
 import com.vaadin.ui.TextField;
@@ -310,7 +314,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
     public void withValidator_doesNotDisablesDefaulNullRepresentation() {
         String nullRepresentation = "foo";
         binder.forField(nameField).withNullRepresentation(nullRepresentation)
-                .withValidator(new NotNullValidator(""))
+                .withValidator(new NotEmptyValidator<>(""))
                 .bind(Person::getFirstName, Person::setFirstName);
         item.setFirstName(null);
         binder.setBean(item);
@@ -321,4 +325,64 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
         nameField.setValue(newValue);
         Assert.assertEquals(newValue, item.getFirstName());
     }
+
+    @Test
+    public void setRequired_withErrorMessage_fieldGetsRequiredIndicatorAndValidator() {
+        TextField textField = new TextField();
+        Assert.assertFalse(textField.isRequiredIndicatorVisible());
+
+        Binding<Person, String, String> binding = binder.forField(textField);
+        Assert.assertFalse(textField.isRequiredIndicatorVisible());
+
+        binding.setRequired("foobar");
+        Assert.assertTrue(textField.isRequiredIndicatorVisible());
+
+        binding.bind(Person::getFirstName, Person::setFirstName);
+        binder.setBean(item);
+        Assert.assertNull(textField.getErrorMessage());
+
+        textField.setValue(textField.getEmptyValue());
+        ErrorMessage errorMessage = textField.getErrorMessage();
+        Assert.assertNotNull(errorMessage);
+        Assert.assertEquals("foobar", errorMessage.getFormattedHtmlMessage());
+
+        textField.setValue("value");
+        Assert.assertNull(textField.getErrorMessage());
+        Assert.assertTrue(textField.isRequiredIndicatorVisible());
+    }
+
+    @Test
+    public void setRequired_withErrorMessageProvider_fieldGetsRequiredIndicatorAndValidator() {
+        TextField textField = new TextField();
+        textField.setLocale(Locale.CANADA);
+        Assert.assertFalse(textField.isRequiredIndicatorVisible());
+
+        Binding<Person, String, String> binding = binder.forField(textField);
+        Assert.assertFalse(textField.isRequiredIndicatorVisible());
+        AtomicInteger invokes = new AtomicInteger();
+
+        binding.setRequired(context -> {
+            invokes.incrementAndGet();
+            Assert.assertSame(Locale.CANADA, context.getLocale().get());
+            return "foobar";
+        });
+        Assert.assertTrue(textField.isRequiredIndicatorVisible());
+
+        binding.bind(Person::getFirstName, Person::setFirstName);
+        binder.setBean(item);
+        Assert.assertNull(textField.getErrorMessage());
+        Assert.assertEquals(0, invokes.get());
+
+        textField.setValue(textField.getEmptyValue());
+        ErrorMessage errorMessage = textField.getErrorMessage();
+        Assert.assertNotNull(errorMessage);
+        Assert.assertEquals("foobar", errorMessage.getFormattedHtmlMessage());
+        // validation is run twice, once for the field, then for all the fields
+        // for cross field validation...
+        Assert.assertEquals(2, invokes.get());
+
+        textField.setValue("value");
+        Assert.assertNull(textField.getErrorMessage());
+        Assert.assertTrue(textField.isRequiredIndicatorVisible());
+    }
 }
\ No newline at end of file
index fb504eea6514f1dfa455c96c718f928a568a5f2d..97f767bbc77c8372b913665650e19539053c34ad 100644 (file)
@@ -3,6 +3,7 @@ package com.vaadin.data.validator;
 import java.util.Calendar;
 import java.util.Locale;
 
+import org.junit.After;
 import org.junit.Test;
 
 import com.vaadin.tests.data.bean.Address;
@@ -77,6 +78,11 @@ public class BeanValidatorTest extends ValidatorTestBase {
         assertPasses(null, validator("nickname"));
     }
 
+    @After
+    public void tearDown() {
+        UI.setCurrent(null);
+    }
+
     private BeanValidator validator(String propertyName) {
         return new BeanValidator(BeanToValidate.class, propertyName);
     }
diff --git a/server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java b/server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java
new file mode 100644 (file)
index 0000000..61cacf8
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2016 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.validator;
+
+import java.util.Objects;
+
+import com.vaadin.data.Binder.Binding;
+import com.vaadin.data.HasValue;
+import com.vaadin.data.ValidationResult;
+import com.vaadin.data.Validator;
+import com.vaadin.data.util.converter.ValueContext;
+
+/**
+ * Simple validator to check against {@code null} value and empty {@link String}
+ * value.
+ * <p>
+ * This validator works similar to {@link NotNullValidator} but in addition it
+ * also check whether the value is not an empty String.
+ * <p>
+ * This validator can be suitable for fields that have been marked as required
+ * with {@link HasValue#setRequiredIndicatorVisible(boolean)}.
+ * <p>
+ * Note that {@link Binding#setRequired(com.vaadin.data.ErrorMessageProvider)}
+ * does almost the same thing, but verifies against the value NOT being equal to
+ * what {@link HasValue#getEmptyValue()} returns and sets the required indicator
+ * visible with {@link HasValue#setRequiredIndicatorVisible(boolean)}.
+ *
+ * @see HasValue#setRequiredIndicatorVisible(boolean)
+ * @see Binding#setRequired(com.vaadin.data.ErrorMessageProvider)
+ * @author Vaadin Ltd
+ * @since 8.0
+ *
+ */
+public class NotEmptyValidator<T> implements Validator<T> {
+
+    private final String message;
+
+    /**
+     * @param message
+     *            error validation message
+     */
+    public NotEmptyValidator(String message) {
+        this.message = message;
+    }
+
+    @Override
+    public ValidationResult apply(T value, ValueContext context) {
+        if (Objects.isNull(value) || Objects.equals(value, "")) {
+            return ValidationResult.error(message);
+        } else {
+            return ValidationResult.ok();
+        }
+    }
+
+}
diff --git a/server/src/test/java/com/vaadin/data/validator/NotNullValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/NotNullValidatorTest.java
deleted file mode 100644 (file)
index 24b95bf..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2000-2016 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.validator;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.vaadin.data.ValidationResult;
-import com.vaadin.data.util.converter.ValueContext;
-
-public class NotNullValidatorTest {
-
-    @Test
-    public void nullValueIsDisallowed() {
-        NotNullValidator validator = new NotNullValidator("foo");
-        ValidationResult result = validator.apply(null, new ValueContext());
-        Assert.assertTrue(result.isError());
-        Assert.assertEquals("foo", result.getErrorMessage());
-    }
-
-    @Test
-    public void nonNullValueIsAllowed() {
-        NotNullValidator validator = new NotNullValidator("foo");
-        ValidationResult result = validator.apply("bar", new ValueContext());
-        Assert.assertFalse(result.isError());
-        Assert.assertFalse(result.isError());
-    }
-
-}