diff options
author | Denis Anisimov <denis@vaadin.com> | 2016-08-09 16:47:56 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-08-11 12:04:10 +0000 |
commit | 81b849c1af199be481e00c86ca324cfaffe8a7a0 (patch) | |
tree | c6387ced1dc828134c7766e1bdbc859ed9ba0668 | |
parent | 5c515c1680d053d9087c2dc7783a6b8ec181f9b8 (diff) | |
download | vaadin-framework-81b849c1af199be481e00c86ca324cfaffe8a7a0.tar.gz vaadin-framework-81b849c1af199be481e00c86ca324cfaffe8a7a0.zip |
Convert old validators (#87).
Change-Id: I6e4a56855f78595975b645a08390fb56e0e52ef9
43 files changed, 2066 insertions, 118 deletions
diff --git a/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java b/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java new file mode 100644 index 0000000000..276a991b62 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java @@ -0,0 +1,85 @@ +/* + * 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.validator; + +import java.util.Objects; +import java.util.function.Function; + +import com.vaadin.data.Result; +import com.vaadin.data.Validator; + +/** + * An abstract base class for typed validators. + * + * @param <T> + * The value type + * @author Vaadin Ltd. + * @since 8.0 + */ +public abstract class AbstractValidator<T> implements Validator<T> { + + private Function<T, String> messageProvider; + + /** + * Constructs a validator with the given error message. The substring "{0}" + * is replaced by the value that failed validation. + * + * @param errorMessage + * the message to be included in a failed result, not null + */ + protected AbstractValidator(String errorMessage) { + Objects.requireNonNull(errorMessage, "error message cannot be null"); + this.messageProvider = value -> errorMessage.replace("{0}", + String.valueOf(value)); + } + + /** + * Returns the error message for the given value. + * + * @param value + * an invalid value + * @return the formatted error message + */ + protected String getMessage(T value) { + return messageProvider.apply(value); + } + + /** + * A helper method for creating a {@code Result} from a value and a validity + * flag. If the flag is true, returns {@code Result.ok}, otherwise yields + * {@code Result.error} bearing the error message returned by + * {@link #getMessage(T)}. + * <p> + * For instance, the following {@code apply} method only accepts even + * numbers: + * + * <pre> + * @Override + * public Result<T> apply(Integer value) { + * return toResult(value, value % 2 == 0); + * } + * </pre> + * + * @param value + * the validated value + * @param isValid + * whether the value is valid or not + * @return the validation result + */ + protected Result<T> toResult(T value, boolean isValid) { + return isValid ? Result.ok(value) : Result.error(getMessage(value)); + } +} diff --git a/server/src/main/java/com/vaadin/data/validator/BeanValidator.java b/server/src/main/java/com/vaadin/data/validator/BeanValidator.java new file mode 100644 index 0000000000..0c09c89371 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/BeanValidator.java @@ -0,0 +1,195 @@ +/* + * 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.validator; + +import java.util.Locale; +import java.util.Objects; +import java.util.Set; +import java.util.function.BinaryOperator; + +import javax.validation.ConstraintViolation; +import javax.validation.MessageInterpolator.Context; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.metadata.ConstraintDescriptor; + +import com.vaadin.data.Result; +import com.vaadin.data.Validator; + +/** + * A {@code Validator} using the JSR-303 (javax.validation) annotation-based + * bean validation mechanism. Values passed to this validator are compared + * against the constraints, if any, specified by annotations on the + * corresponding bean property. + * <p> + * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean + * Validation - formerly agimatec validation) must be present on the project + * classpath when using bean validation. + * + * @author Petri Hakala + * @author Vaadin Ltd. + * + * @since 8.0 + */ +public class BeanValidator implements Validator<Object> { + + private static final long serialVersionUID = 1L; + private static ValidatorFactory factory; + + private String propertyName; + private Class<?> beanType; + private Locale locale; + + /** + * Creates a new JSR-303 {@code BeanValidator} that validates values of the + * specified property. Localizes validation messages using the + * {@linkplain Locale#getDefault() default locale}. + * + * @param beanType + * the bean type declaring the property, not null + * @param propertyName + * the property to validate, not null + */ + public BeanValidator(Class<?> beanType, String propertyName) { + this(beanType, propertyName, Locale.getDefault()); + } + + /** + * Creates a new JSR-303 {@code BeanValidator} that validates values of the + * specified property. Localizes validation messages using the given locale. + * + * @param beanType + * the bean class declaring the property, not null + * @param propertyName + * the property to validate, not null + * @param locale + * the locale to use, not null + */ + public BeanValidator(Class<?> beanType, String propertyName, + Locale locale) { + Objects.requireNonNull(beanType, "bean class cannot be null"); + Objects.requireNonNull(propertyName, "property name cannot be null"); + this.beanType = beanType; + this.propertyName = propertyName; + setLocale(locale); + } + + /** + * Validates the given value as if it were the value of the bean property + * configured for this validator. Returns {@code Result.ok} if there are no + * JSR-303 constraint violations, a {@code Result.error} of chained + * constraint violation messages otherwise. + * <p> + * Null values are accepted unless the property has an {@code @NotNull} + * annotation or equivalent. + */ + @Override + public Result<Object> apply(final Object value) { + Set<? extends ConstraintViolation<?>> violations = getJavaxBeanValidator() + .validateValue(beanType, propertyName, value); + + BinaryOperator<Result<Object>> accumulator = (result1, + result2) -> result1.flatMap(val -> result2); + + return violations.stream().map(v -> Result.error(getMessage(v))) + .reduce(Result.ok(value), accumulator); + } + + /** + * Returns the locale used for validation error messages. + * + * @return the locale used for error messages + */ + public Locale getLocale() { + return locale; + } + + @Override + public String toString() { + return String.format("%s[%s.%s]", getClass().getSimpleName(), + beanType.getSimpleName(), propertyName); + } + + /** + * Returns the underlying JSR-303 bean validator factory used. A factory is + * created using {@link Validation} if necessary. + * + * @return the validator factory to use + */ + protected static ValidatorFactory getJavaxBeanValidatorFactory() { + if (factory == null) { + factory = Validation.buildDefaultValidatorFactory(); + } + return factory; + } + + /** + * Returns a shared JSR-303 validator instance to use. + * + * @return the validator to use + */ + protected javax.validation.Validator getJavaxBeanValidator() { + return getJavaxBeanValidatorFactory().getValidator(); + } + + /** + * Returns the interpolated error message for the given constraint violation + * using the locale specified for this validator. + * + * @param v + * the constraint violation + * @return the localized error message + */ + protected String getMessage(ConstraintViolation<?> v) { + return getJavaxBeanValidatorFactory().getMessageInterpolator() + .interpolate(v.getMessageTemplate(), createContext(v), locale); + } + + /** + * Creates a simple message interpolation context based on the given + * constraint violation. + * + * @param v + * the constraint violation + * @return the message interpolation context + */ + protected Context createContext(ConstraintViolation<?> v) { + return new Context() { + @Override + public ConstraintDescriptor<?> getConstraintDescriptor() { + return v.getConstraintDescriptor(); + } + + @Override + public Object getValidatedValue() { + return v.getInvalidValue(); + } + }; + } + + /** + * Sets the locale used for validation error messages. Revalidation is not + * automatically triggered by setting the locale. + * + * @param locale + * the locale to use for error messages, not null + */ + private void setLocale(Locale locale) { + Objects.requireNonNull(locale, "locale cannot be null"); + this.locale = locale; + } +} diff --git a/server/src/main/java/com/vaadin/data/validator/BigDecimalRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/BigDecimalRangeValidator.java new file mode 100644 index 0000000000..0bdbd70356 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/BigDecimalRangeValidator.java @@ -0,0 +1,51 @@ +/* + * 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.validator; + +import java.math.BigDecimal; +import java.util.Comparator; + +/** + * Validator for validating that an {@link BigDecimal} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class BigDecimalRangeValidator extends RangeValidator<BigDecimal> { + + /** + * Creates a validator for checking that an BigDecimal is within a given + * range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public BigDecimalRangeValidator(String errorMessage, BigDecimal minValue, + BigDecimal maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/BigIntegerRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/BigIntegerRangeValidator.java new file mode 100644 index 0000000000..87ab5605a7 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/BigIntegerRangeValidator.java @@ -0,0 +1,51 @@ +/* + * 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.validator; + +import java.math.BigInteger; +import java.util.Comparator; + +/** + * Validator for validating that an {@link BigInteger} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class BigIntegerRangeValidator extends RangeValidator<BigInteger> { + + /** + * Creates a validator for checking that an BigInteger is within a given + * range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public BigIntegerRangeValidator(String errorMessage, BigInteger minValue, + BigInteger maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/ByteRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/ByteRangeValidator.java new file mode 100644 index 0000000000..fd11fc6aa4 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/ByteRangeValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Comparator; + +/** + * Validator for validating that an {@link Byte} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class ByteRangeValidator extends RangeValidator<Byte> { + + /** + * Creates a validator for checking that an Byte is within a given range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public ByteRangeValidator(String errorMessage, Byte minValue, + Byte maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/DateRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/DateRangeValidator.java new file mode 100644 index 0000000000..43164d0fe2 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/DateRangeValidator.java @@ -0,0 +1,62 @@ +/* + * 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.validator; + +import java.util.Comparator; +import java.util.Date; + +import com.vaadin.shared.ui.datefield.Resolution; + +/** + * Validator for validating that a Date is inside a given range. + * + * <p> + * Note that the comparison is done directly on the Date object so take care + * that the hours/minutes/seconds/milliseconds of the min/max values are + * properly set. + * </p> + * + * @author Vaadin Ltd. + * @since 8.0 + */ +public class DateRangeValidator extends RangeValidator<Date> { + + /** + * Creates a validator for checking that an Date is within a given range. + * <p> + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * </p> + * <p> + * Note that the comparison is done directly on the Date object so take care + * that the hours/minutes/seconds/milliseconds of the min/max values are + * properly set. + * </p> + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public DateRangeValidator(String errorMessage, Date minValue, Date maxValue, + Resolution resolution) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/DoubleRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/DoubleRangeValidator.java new file mode 100644 index 0000000000..aa02ba9fe4 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/DoubleRangeValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Comparator; + +/** + * Validator for validating that a {@link Double} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class DoubleRangeValidator extends RangeValidator<Double> { + + /** + * Creates a validator for checking that an Double is within a given range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public DoubleRangeValidator(String errorMessage, Double minValue, + Double maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/EmailValidator.java b/server/src/main/java/com/vaadin/data/validator/EmailValidator.java new file mode 100644 index 0000000000..44243b0712 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/EmailValidator.java @@ -0,0 +1,44 @@ +/* + * 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.validator; + +/** + * A string validator for e-mail addresses. The e-mail address syntax is not + * complete according to RFC 822 but handles the vast majority of valid e-mail + * addresses correctly. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class EmailValidator extends RegexpValidator { + + private static final String PATTERN = "^" + "([a-zA-Z0-9_\\.\\-+])+" // local + + "@" + "[a-zA-Z0-9-.]+" // domain + + "\\." + "[a-zA-Z0-9-]{2,}" // tld + + "$"; + + /** + * Creates a validator for checking that a string is a syntactically valid + * e-mail address. + * + * @param errorMessage + * the message to display in case the value does not validate. + */ + public EmailValidator(String errorMessage) { + super(errorMessage, PATTERN, true); + } +} diff --git a/server/src/main/java/com/vaadin/data/validator/FloatRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/FloatRangeValidator.java new file mode 100644 index 0000000000..ef57900f2f --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/FloatRangeValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Comparator; + +/** + * Validator for validating that a {@link Float} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class FloatRangeValidator extends RangeValidator<Float> { + + /** + * Creates a validator for checking that an Float is within a given range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public FloatRangeValidator(String errorMessage, Float minValue, + Float maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/IntegerRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/IntegerRangeValidator.java new file mode 100644 index 0000000000..c7dc7cbee9 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/IntegerRangeValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Comparator; + +/** + * Validator for validating that an {@link Integer} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class IntegerRangeValidator extends RangeValidator<Integer> { + + /** + * Creates a validator for checking that an Integer is within a given range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public IntegerRangeValidator(String errorMessage, Integer minValue, + Integer maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/LongRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/LongRangeValidator.java new file mode 100644 index 0000000000..85cdb907ac --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/LongRangeValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Comparator; + +/** + * Validator for validating that an {@link Long} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class LongRangeValidator extends RangeValidator<Long> { + + /** + * Creates a validator for checking that an Long is within a given range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public LongRangeValidator(String errorMessage, Long minValue, + Long maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/NotNullValidator.java b/server/src/main/java/com/vaadin/data/validator/NotNullValidator.java new file mode 100644 index 0000000000..e44e086c0f --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/NotNullValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Objects; + +import com.vaadin.data.Result; + +/** + * 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 Result<String> apply(String value) { + return Objects.isNull(value) ? Result.error(getMessage(value)) + : Result.ok(value); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/RangeValidator.java b/server/src/main/java/com/vaadin/data/validator/RangeValidator.java new file mode 100644 index 0000000000..eed79d0b8b --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/RangeValidator.java @@ -0,0 +1,224 @@ +/* + * 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.validator; + +import java.util.Comparator; +import java.util.Objects; + +import com.vaadin.data.Result; + +/** + * Verifies that a value is within the given range. + * + * @param <T> + * the type to validate + * @author Vaadin Ltd. + * @since 8.0 + */ +public class RangeValidator<T> extends AbstractValidator<T> { + + private T minValue = null; + private T maxValue = null; + private boolean minValueIncluded = true; + private boolean maxValueIncluded = true; + private Comparator<? super T> comparator; + + /** + * Creates a new range validator of the given type. Passing null to either + * {@code minValue} or {@code maxValue} means there is no limit in that + * direction. Both limits may be null; this can be useful if the limits are + * resolved programmatically. The result of passing null to {@code apply} + * depends on the given comparator. + * + * @param errorMessage + * the error message to return if validation fails, not null + * @param comparator + * the comparator to compare with, not null + * @param minValue + * the least value of the accepted range or null for no limit + * @param maxValue + * the greatest value of the accepted range or null for no limit + */ + public RangeValidator(String errorMessage, Comparator<? super T> comparator, + T minValue, T maxValue) { + super(errorMessage); + Objects.requireNonNull(comparator, "comparator cannot be null"); + + this.minValue = minValue; + this.maxValue = maxValue; + this.minValueIncluded = minValue != null; + this.maxValueIncluded = maxValue != null; + this.comparator = comparator; + } + + /** + * Returns a {@code RangeValidator} comparing values of a {@code Comparable} + * type using their <i>natural order</i>. Passing null to either + * {@code minValue} or {@code maxValue} means there is no limit in that + * direction. Both limits may be null; this can be useful if the limits are + * resolved programmatically. + * <p> + * Null is considered to be less than any non-null value. This means null + * never passes validation if a minimum value is specified. + * + * @param <C> + * the {@code Comparable} value type + * @param errorMessage + * the error message to return if validation fails, not null + * @param minValue + * the least value of the accepted range or null for no limit + * @param maxValue + * the greatest value of the accepted range or null for no limit + * @return the new validator + */ + public static <C extends Comparable<? super C>> RangeValidator<C> of( + String errorMessage, C minValue, C maxValue) { + return new RangeValidator<>(errorMessage, + Comparator.nullsFirst(Comparator.naturalOrder()), minValue, + maxValue); + } + + /** + * Returns {@code Result.ok} if the value is within the specified bounds, + * {@code Result.error} otherwise. If null is passed to {@code apply}, the + * behavior depends on the used comparator. + */ + @Override + public Result<T> apply(T value) { + return toResult(value, isValid(value)); + } + + /** + * Returns whether the minimum value is part of the accepted range. + * + * @return true if the minimum value is part of the range, false otherwise + */ + public boolean isMinValueIncluded() { + return minValueIncluded; + } + + /** + * Sets whether the minimum value is part of the accepted range. + * + * @param minValueIncluded + * true if the minimum value should be part of the range, false + * otherwise + */ + public void setMinValueIncluded(boolean minValueIncluded) { + this.minValueIncluded = minValueIncluded; + } + + /** + * Returns whether the maximum value is part of the accepted range. + * + * @return true if the maximum value is part of the range, false otherwise + */ + public boolean isMaxValueIncluded() { + return maxValueIncluded; + } + + /** + * Sets whether the maximum value is part of the accepted range. + * + * @param maxValueIncluded + * true if the maximum value should be part of the range, false + * otherwise + */ + public void setMaxValueIncluded(boolean maxValueIncluded) { + this.maxValueIncluded = maxValueIncluded; + } + + /** + * Returns the minimum value of the range. + * + * @return the minimum value + */ + public T getMinValue() { + return minValue; + } + + /** + * Sets the minimum value of the range. Use + * {@link #setMinValueIncluded(boolean)} to control whether this value is + * part of the range or not. + * + * @param minValue + * the minimum value + */ + public void setMinValue(T minValue) { + this.minValue = minValue; + } + + /** + * Gets the maximum value of the range. + * + * @return the maximum value + */ + public T getMaxValue() { + return maxValue; + } + + /** + * Sets the maximum value of the range. Use + * {@link #setMaxValueIncluded(boolean)} to control whether this value is + * part of the range or not. + * + * @param maxValue + * the maximum value + */ + public void setMaxValue(T maxValue) { + this.maxValue = maxValue; + } + + @Override + public String toString() { + T min = getMinValue(); + T max = getMaxValue(); + return String.format("%s %c%s, %s%c", getClass().getSimpleName(), + isMinValueIncluded() ? '[' : '(', min != null ? min : "-∞", + max != null ? max : "∞", isMaxValueIncluded() ? ']' : ')'); + } + + /** + * Returns whether the given value lies in the valid range. + * + * @param value + * the value to validate + * @return true if the value is valid, false otherwise + */ + protected boolean isValid(T value) { + if (value == null) { + return true; + } + if (getMinValue() != null) { + int result = comparator.compare(value, getMinValue()); + if (result < 0) { + return false; + } else if (result == 0 && !isMinValueIncluded()) { + return false; + } + } + if (getMaxValue() != null) { + int result = comparator.compare(value, getMaxValue()); + if (result > 0) { + return false; + } else if (result == 0 && !isMaxValueIncluded()) { + return false; + } + } + return true; + } +} diff --git a/server/src/main/java/com/vaadin/data/validator/RegexpValidator.java b/server/src/main/java/com/vaadin/data/validator/RegexpValidator.java new file mode 100644 index 0000000000..ce72d79e74 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/RegexpValidator.java @@ -0,0 +1,115 @@ +/* + * 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.validator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.vaadin.data.Result; + +/** + * A string validator comparing the string against a Java regular expression. + * Both complete matches and substring matches are supported. + * <p> + * For the Java regular expression syntax, see {@link java.util.regex.Pattern}. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class RegexpValidator extends AbstractValidator<String> { + + private Pattern pattern; + private boolean complete; + private transient Matcher matcher = null; + + /** + * Creates a validator for checking that the regular expression matches the + * complete string to validate. + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param regexp + * a Java regular expression + */ + public RegexpValidator(String errorMessage, String regexp) { + this(errorMessage, regexp, true); + } + + /** + * Creates a validator for checking that the regular expression matches the + * string to validate. + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param regexp + * a Java regular expression + * @param complete + * true to use check for a complete match, false to look for a + * matching substring + * + */ + public RegexpValidator(String errorMessage, String regexp, + boolean complete) { + super(errorMessage); + pattern = Pattern.compile(regexp); + this.complete = complete; + } + + @Override + public Result<String> apply(String value) { + return toResult(value, isValid(value)); + } + + @Override + public String toString() { + return "RegexpValidator[" + pattern + "]"; + } + + /** + * Returns whether the given string matches the regular expression. + * + * @param value + * the string to match + * @return true if the string matched, false otherwise + */ + protected boolean isValid(String value) { + if (value == null) { + return true; + } + if (complete) { + return getMatcher(value).matches(); + } else { + return getMatcher(value).find(); + } + } + + /** + * Returns a new or reused matcher for the pattern. + * + * @param value + * the string to find matches in + * @return a matcher for the string + */ + private Matcher getMatcher(String value) { + if (matcher == null) { + matcher = pattern.matcher(value); + } else { + matcher.reset(value); + } + return matcher; + } +} diff --git a/server/src/main/java/com/vaadin/data/validator/ShortRangeValidator.java b/server/src/main/java/com/vaadin/data/validator/ShortRangeValidator.java new file mode 100644 index 0000000000..4fee15bca0 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/ShortRangeValidator.java @@ -0,0 +1,49 @@ +/* + * 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.validator; + +import java.util.Comparator; + +/** + * Validator for validating that an {@link Short} is inside a given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class ShortRangeValidator extends RangeValidator<Short> { + + /** + * Creates a validator for checking that an Short is within a given range. + * + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public ShortRangeValidator(String errorMessage, Short minValue, + Short maxValue) { + super(errorMessage, Comparator.naturalOrder(), minValue, maxValue); + } + +} diff --git a/server/src/main/java/com/vaadin/data/validator/StringLengthValidator.java b/server/src/main/java/com/vaadin/data/validator/StringLengthValidator.java new file mode 100644 index 0000000000..2e796cfdb2 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/validator/StringLengthValidator.java @@ -0,0 +1,104 @@ +/* + * 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.validator; + +import com.vaadin.data.Result; + +/** + * Verifies that the length of a string is within the given range. + * + * @author Vaadin Ltd. + * @since 8.0 + */ +@SuppressWarnings("serial") +public class StringLengthValidator extends AbstractValidator<String> { + + private RangeValidator<Integer> validator; + + /** + * Creates a new StringLengthValidator with a given error message and + * minimum and maximum length limits. + * + * @param errorMessage + * the error message to return if validation fails + * @param minLength + * the minimum permissible length of the string or null for no + * limit. + * @param maxLength + * the maximum permissible length of the string or null for no + * limit. + */ + public StringLengthValidator(String errorMessage, Integer minLength, + Integer maxLength) { + super(errorMessage); + validator = RangeValidator.of(errorMessage, minLength, maxLength); + } + + @Override + public Result<String> apply(String value) { + if (value == null) { + return toResult(value, true); + } + Result<?> lengthCheck = validator.apply(value.length()); + return toResult(value, !lengthCheck.isError()); + } + + /** + * Gets the maximum permissible length of the string. + * + * @return the maximum length of the string or null if there is no limit + */ + public Integer getMaxLength() { + return validator.getMaxValue(); + } + + /** + * Gets the minimum permissible length of the string. + * + * @return the minimum length of the string or null if there is no limit + */ + public Integer getMinLength() { + return validator.getMinValue(); + } + + /** + * Sets the maximum permissible length of the string. + * + * @param maxLength + * the maximum length to accept or null for no limit + */ + public void setMaxLength(Integer maxLength) { + validator.setMaxValue(maxLength); + } + + /** + * Sets the minimum permissible length. + * + * @param minLength + * the minimum length to accept or null for no limit + */ + public void setMinLength(Integer minLength) { + validator.setMaxValue(minLength); + } + + @Override + public String toString() { + return String.format("%s[%d, %d]", getClass().getSimpleName(), + getMinLength(), getMaxLength()); + } + +} diff --git a/server/src/test/java/com/vaadin/data/validator/BeanValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/BeanValidatorTest.java new file mode 100644 index 0000000000..2d3db77939 --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/BeanValidatorTest.java @@ -0,0 +1,82 @@ +package com.vaadin.data.validator; + +import java.util.Calendar; +import java.util.Locale; + +import org.junit.Test; + +import com.vaadin.tests.data.bean.Address; +import com.vaadin.tests.data.bean.BeanToValidate; + +public class BeanValidatorTest extends ValidatorTestBase { + + @Test + public void testFirstNameNullFails() { + assertFails(null, "may not be null", validator("firstname")); + } + + @Test + public void testFirstNameTooShortFails() { + assertFails("x", "size must be between 3 and 16", + validator("firstname")); + } + + @Test + public void testFirstNameLongEnoughPasses() { + assertPasses("Magi", validator("firstname")); + } + + @Test + public void testAgeTooYoungFails() { + assertFails(14, "Must be 18 or above", validator("age")); + } + + @Test + public void testDateOfBirthNullPasses() { + assertPasses(null, validator("dateOfBirth")); + } + + @Test + public void testDateOfBirthInTheFutureFails() { + Calendar year3k = Calendar.getInstance(); + year3k.set(3000, 0, 1); + assertFails(year3k, "must be in the past", validator("dateOfBirth")); + } + + @Test + public void testAddressesEmptyArrayPasses() { + Address[] noAddresses = {}; + assertPasses(noAddresses, validator("addresses")); + } + + @Test + public void testAddressesNullFails() { + assertFails(null, "may not be null", validator("addresses")); + } + + @Test + public void testInvalidDecimalsFailsInFrench() { + BeanValidator v = validator("decimals", Locale.FRENCH); + assertFails("1234.567", "Valeur numérique hors limite " + + "(<3 chiffres>.<2 chiffres> attendus)", v); + } + + @Test + public void testAddressNestedPropertyInvalidPostalCodeFails() { + assertFails(100_000, "must be less than or equal to 99999", + validator("address.postalCode")); + } + + @Test + public void testNullValuePasses() { + assertPasses(null, validator("nickname")); + } + + private BeanValidator validator(String propertyName) { + return new BeanValidator(BeanToValidate.class, propertyName); + } + + private BeanValidator validator(String propertyName, Locale locale) { + return new BeanValidator(BeanToValidate.class, propertyName, locale); + } +} diff --git a/server/src/test/java/com/vaadin/data/validator/BoVTest.java b/server/src/test/java/com/vaadin/data/validator/BoVTest.java new file mode 100644 index 0000000000..85e65faccc --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/BoVTest.java @@ -0,0 +1,142 @@ +/* + * 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.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Binder; +import com.vaadin.data.ValidationError; +import com.vaadin.server.AbstractErrorMessage; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.ui.AbstractField; + +/** + * Book of Vaadin tests. + * + * @author Vaadin Ltd + * + */ +public class BoVTest { + + static class TextField extends AbstractField<String> { + + String value = ""; + + @Override + public String getValue() { + return value; + } + + @Override + protected void doSetValue(String value) { + this.value = value; + } + } + + private Binder<Person> binder; + + private TextField field; + + private Person person = new Person(); + + @Before + public void setUp() { + binder = new Binder<>(); + field = new TextField(); + } + + @Test + public void simpleEmailValidator() { + binder.forField(field) + // Explicit validator instance + .withValidator(new EmailValidator( + "This doesn't look like a valid email address")) + .bind(Person::getEmail, Person::setEmail); + + field.setValue("not-email"); + List<ValidationError<?>> errors = binder.validate(); + Assert.assertEquals(1, errors.size()); + Assert.assertEquals("This doesn't look like a valid email address", + errors.get(0).getMessage()); + Assert.assertEquals("This doesn't look like a valid email address", + ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); + + field.setValue("abc@vaadin.com"); + errors = binder.validate(); + Assert.assertEquals(0, errors.size()); + Assert.assertNull(field.getErrorMessage()); + } + + @Test + public void nameLengthTest() { + binder.forField(field) + // Validator defined based on a lambda and an error message + .withValidator(name -> name.length() >= 3, + "Last name must contain at least three characters") + .bind(Person::getLastName, Person::setLastName); + + field.setValue("a"); + List<ValidationError<?>> errors = binder.validate(); + Assert.assertEquals(1, errors.size()); + Assert.assertEquals("Last name must contain at least three characters", + errors.get(0).getMessage()); + Assert.assertEquals("Last name must contain at least three characters", + ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); + + field.setValue("long last name"); + errors = binder.validate(); + Assert.assertEquals(0, errors.size()); + Assert.assertNull(field.getErrorMessage()); + } + + @Test + public void chainedEmailValidator() { + binder.forField(field) + // Explicit validator instance + .withValidator(new EmailValidator( + "This doesn't look like a valid email address")) + .withValidator(email -> email.endsWith("@acme.com"), + "Only acme.com email addresses are allowed") + .bind(Person::getEmail, Person::setEmail); + + field.setValue("not-email"); + List<ValidationError<?>> errors = binder.validate(); + Assert.assertEquals(2, errors.size()); + Assert.assertEquals("This doesn't look like a valid email address", + errors.get(0).getMessage()); + Assert.assertEquals("Only acme.com email addresses are allowed", + errors.get(1).getMessage()); + Assert.assertEquals("This doesn't look like a valid email address", + ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); + + field.setValue("abc@vaadin.com"); + errors = binder.validate(); + Assert.assertEquals(1, errors.size()); + Assert.assertEquals("Only acme.com email addresses are allowed", + errors.get(0).getMessage()); + Assert.assertEquals("Only acme.com email addresses are allowed", + ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); + + field.setValue("abc@acme.com"); + errors = binder.validate(); + Assert.assertEquals(0, errors.size()); + Assert.assertNull(field.getErrorMessage()); + } +} diff --git a/server/src/test/java/com/vaadin/data/validator/EmailValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/EmailValidatorTest.java new file mode 100644 index 0000000000..b71ccf541b --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/EmailValidatorTest.java @@ -0,0 +1,98 @@ +package com.vaadin.data.validator; + +import org.junit.Test; + +public class EmailValidatorTest extends ValidatorTestBase { + + @Test + public void testNullStringFails() { + assertPasses(null, shouldNotFail()); + } + + @Test + public void testEmptyStringFails() { + assertFails("", validator("empty string not allowed")); + } + + @Test + public void testStringWithoutAtSignFails() { + assertFails("johannesd.vaadin", validator("@ is required")); + } + + @Test + public void testMissingLocalPartFails() { + RegexpValidator v = validator("local part is required"); + assertFails("@localhost", v); + assertFails(" @localhost", v); + } + + @Test + public void testNonAsciiEmailFails() { + RegexpValidator v = validator("accented letters not allowed"); + assertFails("jöhännes@vaadin.com", v); + assertFails("johannes@váádìn.com", v); + assertFails("johannes@vaadin.cõm", v); + } + + @Test + public void testLocalPartWithPunctuationPasses() { + RegexpValidator v = shouldNotFail(); + assertPasses("johannesd+test@vaadin.com", v); + assertPasses("johannes.dahlstrom@vaadin.com", v); + assertPasses("johannes_d@vaadin.com", v); + } + + @Test + public void testEmailWithoutDomainPartFails() { + assertFails("johannesd@", validator("domain part is required")); + } + + @Test + public void testComplexDomainPasses() { + assertPasses("johannesd@foo.bar.baz.vaadin.com", shouldNotFail()); + } + + @Test + public void testDomainWithPunctuationPasses() { + assertPasses("johannesd@vaadin-dev.com", shouldNotFail()); + } + + @Test + public void testMissingTldFails() { + assertFails("johannesd@localhost", validator("tld is required")); + } + + @Test + public void testOneLetterTldFails() { + assertFails("johannesd@vaadin.f", + validator("one-letter tld not allowed")); + } + + @Test + public void testLongTldPasses() { + assertPasses("joonas@vaadin.management", shouldNotFail()); + } + + @Test + public void testIdnTldPasses() { + assertPasses("leif@vaadin.XN--VERMGENSBERATER-CTB", shouldNotFail()); + } + + @Test + public void testYelledEmailPasses() { + assertPasses("JOHANNESD@VAADIN.COM", shouldNotFail()); + } + + @Test + public void testEmailWithDigitsPasses() { + assertPasses("johannes84@v44d1n.com", shouldNotFail()); + } + + private EmailValidator validator(String errorMessage) { + return new EmailValidator(errorMessage); + } + + private EmailValidator shouldNotFail() { + return validator("this should not fail"); + } +} diff --git a/server/src/test/java/com/vaadin/data/validator/NullValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/NullValidatorTest.java new file mode 100644 index 0000000000..26c510523c --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/NullValidatorTest.java @@ -0,0 +1,42 @@ +/* + * 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.Result; + +public class NullValidatorTest { + + @Test + public void nullValueIsDisallowed() { + NotNullValidator validator = new NotNullValidator("foo"); + Result<String> result = validator.apply(null); + Assert.assertTrue(result.isError()); + Assert.assertEquals("foo", result.getMessage().get()); + } + + @Test + public void nonNullValueIsAllowed() { + NotNullValidator validator = new NotNullValidator("foo"); + Result<String> result = validator.apply("bar"); + Assert.assertFalse(result.isError()); + result.ifOk(value -> Assert.assertEquals("bar", value)); + result.ifError(msg -> Assert.fail()); + } + +} diff --git a/server/src/test/java/com/vaadin/data/validator/RangeValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/RangeValidatorTest.java new file mode 100644 index 0000000000..5174c1e2b6 --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/RangeValidatorTest.java @@ -0,0 +1,105 @@ +package com.vaadin.data.validator; + +import java.time.LocalDate; + +import org.junit.Test; + +public class RangeValidatorTest extends ValidatorTestBase { + + @Test + public void testIntegerRangeValidIntPasses() { + assertPasses(10, + RangeValidator.of("Must be between -123 and 42", -123, 42)); + } + + @Test + public void testIntegerRangeInvalidIntFails() { + assertFails(123, + RangeValidator.of("Must be between -123 and 42", -123, 42)); + } + + @Test + public void testRangeWithoutUpperBoundLargeIntegerPasses() { + assertPasses(Integer.MAX_VALUE, + RangeValidator.of("Must be at least 18", 18, null)); + } + + @Test + public void testRangeWithoutUpperBoundSmallIntegerFails() { + assertFails(17, RangeValidator.of("Must be at least 18", 18, null)); + } + + @Test + public void testRangeWithoutLowerBoundSmallIntegerPasses() { + assertPasses(Integer.MIN_VALUE, + RangeValidator.of("Must be at most 0", null, 0)); + } + + @Test + public void testRangeWithoutLowerBoundLargeIntegerFails() { + assertFails(1, RangeValidator.of("Must be at most 0", null, 0)); + } + + @Test + public void testUnboundedRangePassesEverything() { + RangeValidator<Integer> v = RangeValidator.of("This should not happen!", + null, null); + + assertPasses(Integer.MIN_VALUE, v); + assertPasses(0, v); + assertPasses(null, v); + assertPasses(Integer.MAX_VALUE, v); + } + + @Test + public void testBoundsInclusiveByDefault() { + RangeValidator<Integer> v = RangeValidator + .of("Must be between -10 and 10", -10, 10); + + assertPasses(-10, v); + assertPasses(10, v); + } + + @Test + public void testUpperBoundExclusive() { + RangeValidator<Integer> v = RangeValidator + .of("Must be between -10 and 10", -10, 10); + v.setMaxValueIncluded(false); + + assertPasses(-10, v); + assertPasses(9, v); + assertFails(10, v); + } + + @Test + public void testLowerBoundExclusive() { + RangeValidator<Integer> v = RangeValidator + .of("Must be between -10 and 10", -10, 10); + v.setMinValueIncluded(false); + + assertFails(-10, v); + assertPasses(-9, v); + assertPasses(10, v); + } + + @Test + public void testNullLessThanEverything() { + RangeValidator<Integer> v = RangeValidator.of("Must be any integer", + Integer.MIN_VALUE, Integer.MAX_VALUE); + assertPasses(null, v); + + v = RangeValidator.of("Must be very small", null, Integer.MIN_VALUE); + assertPasses(null, v); + } + + @Test + public void testDateRange() { + RangeValidator<LocalDate> v = RangeValidator.of("Date must be in 2016", + LocalDate.of(2016, 1, 1), LocalDate.of(2016, 12, 31)); + + assertFails(LocalDate.ofEpochDay(0), v); + assertPasses(LocalDate.of(2016, 7, 31), v); + assertFails(LocalDate.ofEpochDay(1_000_000_000), v); + } + +} diff --git a/server/src/test/java/com/vaadin/data/validator/RegexpValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/RegexpValidatorTest.java new file mode 100644 index 0000000000..077d8f3a6a --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/RegexpValidatorTest.java @@ -0,0 +1,71 @@ +package com.vaadin.data.validator; + +import org.junit.Test; + +public class RegexpValidatorTest extends ValidatorTestBase { + + @Test + public void testNullStringFails() { + assertPasses(null, new RegexpValidator("Should be 'abc'", "abc")); + } + + @Test + public void testEmptyPatternMatchesEmptyString() { + assertPasses("", new RegexpValidator("Should be empty", "", true)); + } + + @Test + public void testEmptyPatternDoesNotMatchNonEmptyString() { + assertFails("x", new RegexpValidator("Should be empty", "", true)); + } + + @Test + public void testPatternMatchesString() { + RegexpValidator v = new RegexpValidator( + "Should be foo and bar repeating", "(foo|bar)+", true); + + assertPasses("foo", v); + assertPasses("barfoo", v); + assertPasses("foobarbarbarfoobarfoofoobarbarfoofoofoobar", v); + } + + @Test + public void testPatternDoesNotMatchString() { + RegexpValidator v = new RegexpValidator( + "Should be foo and bar repeating", "(foo|bar)+", true); + + assertFails("", v); + assertFails("barf", v); + assertFails(" bar", v); + assertFails("foobarbarbarfoobar.foofoobarbarfoofoofoobar", v); + } + + @Test + public void testEmptyPatternFoundInAnyString() { + RegexpValidator v = new RegexpValidator("Should always pass", "", + false); + + assertPasses("", v); + assertPasses(" ", v); + assertPasses("qwertyuiopasdfghjklzxcvbnm", v); + } + + @Test + public void testPatternFoundInString() { + RegexpValidator v = new RegexpValidator("Should contain a number", + "\\d+", false); + + assertPasses("0", v); + assertPasses(" 123 ", v); + assertPasses("qwerty9iop", v); + } + + @Test + public void testPatternNotFoundInString() { + RegexpValidator v = new RegexpValidator("Should contain a number", + "\\d+", false); + + assertFails("", v); + assertFails("qwertyiop", v); + } +} diff --git a/server/src/test/java/com/vaadin/data/validator/StringLengthValidatorTest.java b/server/src/test/java/com/vaadin/data/validator/StringLengthValidatorTest.java new file mode 100644 index 0000000000..dd2b1be50b --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/StringLengthValidatorTest.java @@ -0,0 +1,41 @@ +package com.vaadin.data.validator; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; + +public class StringLengthValidatorTest extends ValidatorTestBase { + + private static String LONG_STRING = Stream.generate(() -> "x").limit(1000) + .collect(Collectors.joining()); + + @Test + public void testNullStringFails() { + assertPasses(null, new StringLengthValidator("", 0, 10)); + } + + @Test + public void testMaxLengthTooLongStringFails() { + assertFails(LONG_STRING, + new StringLengthValidator("Should be at most 10", null, 10)); + } + + @Test + public void testMaxLengthStringPasses() { + assertPasses(LONG_STRING, new StringLengthValidator( + "Should be at most 1000", null, 1000)); + } + + @Test + public void testMinLengthEmptyStringFails() { + assertFails("", + new StringLengthValidator("Should be at least 1", 1, null)); + } + + @Test + public void testMinLengthStringPasses() { + assertPasses("å", + new StringLengthValidator("Should be at least 1", 1, null)); + } +} diff --git a/server/src/test/java/com/vaadin/data/validator/ValidatorTestBase.java b/server/src/test/java/com/vaadin/data/validator/ValidatorTestBase.java new file mode 100644 index 0000000000..2845fda5c0 --- /dev/null +++ b/server/src/test/java/com/vaadin/data/validator/ValidatorTestBase.java @@ -0,0 +1,24 @@ +package com.vaadin.data.validator; + +import org.junit.Assert; + +import com.vaadin.data.Validator; + +public class ValidatorTestBase { + + protected <T> void assertPasses(T value, Validator<? super T> v) { + v.apply(value).handle(val -> Assert.assertEquals(value, val), + err -> Assert + .fail(value + " should pass " + v + " but got " + err)); + } + + protected <T> void assertFails(T value, String errorMessage, + Validator<? super T> v) { + v.apply(value).handle(val -> Assert.fail(value + " should fail " + v), + err -> Assert.assertEquals(errorMessage, err)); + } + + protected <T> void assertFails(T value, AbstractValidator<? super T> v) { + assertFails(value, v.getMessage(value), v); + } +} diff --git a/server/src/test/java/com/vaadin/tests/data/bean/Address.java b/server/src/test/java/com/vaadin/tests/data/bean/Address.java index 15cdf34ae5..37222a2218 100644 --- a/server/src/test/java/com/vaadin/tests/data/bean/Address.java +++ b/server/src/test/java/com/vaadin/tests/data/bean/Address.java @@ -2,13 +2,26 @@ package com.vaadin.tests.data.bean; import java.io.Serializable; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + @SuppressWarnings("serial") public class Address implements Serializable { + @NotNull private String streetAddress = ""; - private Integer postalCode = null; + + @NotNull + @Min(0) + @Max(99999) + private Integer postalCode = 0; + + @NotNull private String city = ""; - private Country country = null; + + @NotNull + private Country country = Country.FINLAND; public Address() { diff --git a/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java b/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java index 034609764f..fa8c438ee9 100644 --- a/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java +++ b/server/src/test/java/com/vaadin/tests/data/bean/BeanToValidate.java @@ -1,13 +1,18 @@ package com.vaadin.tests.data.bean; +import java.util.Calendar; + +import javax.validation.Valid; import javax.validation.constraints.Digits; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Past; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; public class BeanToValidate { + @NotNull @Size(min = 3, max = 16) private String firstname; @@ -26,6 +31,17 @@ public class BeanToValidate { @Size(min = 3, max = 6, message = "Must contain 3 - 6 letters") private String nickname; + @Past + private Calendar dateOfBirth; + + @NotNull + @Valid + private Address[] addresses; + + @NotNull + @Valid + private Address address; + public String getFirstname() { return firstname; } @@ -66,4 +82,27 @@ public class BeanToValidate { this.nickname = nickname; } + public Calendar getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(Calendar dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public Address[] getAddresses() { + return addresses; + } + + public void setAddresses(Address[] address) { + this.addresses = address; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } } diff --git a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java index 2aef09fa2a..753358d3eb 100644 --- a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java +++ b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java @@ -27,8 +27,7 @@ public class ClassesSerializableTest { private static String[] BASE_PACKAGES = { "com.vaadin" }; - private static String[] EXCLUDED_PATTERNS = { - "com\\.vaadin\\.demo\\..*", // + private static String[] EXCLUDED_PATTERNS = { "com\\.vaadin\\.demo\\..*", // "com\\.vaadin\\.external\\.org\\.apache\\.commons\\.fileupload\\..*", // "com\\.vaadin\\.launcher\\..*", // "com\\.vaadin\\.client\\..*", // @@ -65,6 +64,8 @@ public class ClassesSerializableTest { "com\\.vaadin\\.data\\.util\\.sqlcontainer\\.connection\\.MockInitialContextFactory", "com\\.vaadin\\.data\\.util\\.sqlcontainer\\.DataGenerator", "com\\.vaadin\\.data\\.util\\.sqlcontainer\\.FreeformQueryUtil", + // the JSR-303 constraint interpolation context + "com\\.vaadin\\.data\\.validator\\.BeanValidator\\$1", // "com\\.vaadin\\.sass.*", // "com\\.vaadin\\.testbench.*", // "com\\.vaadin\\.util\\.CurrentInstance\\$1", // @@ -149,8 +150,9 @@ public class ClassesSerializableTest { nonSerializableString += ")"; } } - Assert.fail("Serializable not implemented by the following classes and interfaces: " - + nonSerializableString); + Assert.fail( + "Serializable not implemented by the following classes and interfaces: " + + nonSerializableString); } } @@ -272,8 +274,8 @@ public class ClassesSerializableTest { while (e.hasMoreElements()) { JarEntry entry = e.nextElement(); if (entry.getName().endsWith(".class")) { - String nameWithoutExtension = entry.getName().replaceAll( - "\\.class", ""); + String nameWithoutExtension = entry.getName() + .replaceAll("\\.class", ""); String className = nameWithoutExtension.replace('/', '.'); classes.add(className); } diff --git a/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java b/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java index 70727f1690..241e7d4f7c 100644 --- a/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java +++ b/server/src/test/java/com/vaadin/tests/server/validation/BeanValidationTest.java @@ -12,56 +12,58 @@ import com.vaadin.tests.data.bean.BeanToValidate; public class BeanValidationTest { @Test(expected = InvalidValueException.class) public void testBeanValidationNull() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "firstname"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "firstname"); validator.validate(null); } @Test(expected = InvalidValueException.class) public void testBeanValidationStringTooShort() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "firstname"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "firstname"); validator.validate("aa"); } @Test public void testBeanValidationStringOk() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "firstname"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "firstname"); validator.validate("aaa"); } @Test(expected = InvalidValueException.class) public void testBeanValidationIntegerTooSmall() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, "age"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "age"); validator.validate(17); } @Test public void testBeanValidationIntegerOk() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, "age"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "age"); validator.validate(18); } @Test(expected = InvalidValueException.class) public void testBeanValidationTooManyDigits() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "decimals"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "decimals"); validator.validate("1234.567"); } @Test public void testBeanValidationDigitsOk() { - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "decimals"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "decimals"); validator.validate("123.45"); } @Test public void testBeanValidationException_OneValidationError() { InvalidValueException[] causes = null; - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "lastname"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "lastname"); try { validator.validate(null); } catch (InvalidValueException e) { @@ -74,8 +76,8 @@ public class BeanValidationTest { @Test public void testBeanValidationsException_TwoValidationErrors() { InvalidValueException[] causes = null; - LegacyBeanValidator validator = new LegacyBeanValidator(BeanToValidate.class, - "nickname"); + LegacyBeanValidator validator = new LegacyBeanValidator( + BeanToValidate.class, "nickname"); try { validator.validate("A"); } catch (InvalidValueException e) { diff --git a/uitest/src/main/java/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.java b/uitest/src/main/java/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.java index b1d0891eb6..9f2f066ab0 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.java +++ b/uitest/src/main/java/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.java @@ -27,7 +27,8 @@ public class AbstractFieldCommitWithInvalidValues extends TestBase { protected void setup() { tf = new TextField("A field, must contain 1-2 chars", new ObjectProperty<String>("a")); - tf.addValidator(new LegacyStringLengthValidator("Invalid length", 1, 2, false)); + tf.addValidator( + new LegacyStringLengthValidator("Invalid length", 1, 2, false)); tf.setBuffered(true); tf.setRequired(true); diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldRangeValidation.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldRangeValidation.java index 3f6498dc07..0e8ccd937f 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldRangeValidation.java +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldRangeValidation.java @@ -86,34 +86,34 @@ public class DateFieldRangeValidation extends TestBase { actualDateField = createDateField(); actualDateField.setValue(new Date(2011 - 1900, 12 - 1, 1)); - actualDateField.addValidator(new LegacyRangeValidator<Date>("", Date.class, - null, null) { - @Override - public boolean isMinValueIncluded() { - return range.isFromInclusive(); - } - - @Override - public boolean isMaxValueIncluded() { - return range.isToInclusive(); - } - - @Override - public Date getMaxValue() { - return range.getTo(); - } - - @Override - public Date getMinValue() { - return range.getFrom(); - } - - @Override - public String getErrorMessage() { - return "Date must be in range " + getMinValue() + " - " - + getMaxValue(); - } - }); + actualDateField.addValidator( + new LegacyRangeValidator<Date>("", Date.class, null, null) { + @Override + public boolean isMinValueIncluded() { + return range.isFromInclusive(); + } + + @Override + public boolean isMaxValueIncluded() { + return range.isToInclusive(); + } + + @Override + public Date getMaxValue() { + return range.getTo(); + } + + @Override + public Date getMinValue() { + return range.getFrom(); + } + + @Override + public String getErrorMessage() { + return "Date must be in range " + getMinValue() + " - " + + getMaxValue(); + } + }); addComponent(fromField); addComponent(fromInclusive); addComponent(toField); diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java index 03ee47d1eb..144e6fa945 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java @@ -25,10 +25,11 @@ public class DefaultHandleUnparsableDateField extends TestBase { } }); - final DateField validated = new DateField("Validated Default DateField"); + final DateField validated = new DateField( + "Validated Default DateField"); validated.setImmediate(true); - validated.addValidator(new LegacyNullValidator("Validator: Date is NULL", - false)); + validated.addValidator( + new LegacyNullValidator("Validator: Date is NULL", false)); addComponent(validated); } diff --git a/uitest/src/main/java/com/vaadin/tests/components/form/FormCommitWithInvalidValues.java b/uitest/src/main/java/com/vaadin/tests/components/form/FormCommitWithInvalidValues.java index b9a86a4c82..ae6ed721c1 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/form/FormCommitWithInvalidValues.java +++ b/uitest/src/main/java/com/vaadin/tests/components/form/FormCommitWithInvalidValues.java @@ -28,7 +28,8 @@ public class FormCommitWithInvalidValues extends TestBase { form = new Form(); form.setFooter(null); TextField tf = new TextField("A field, must contain 1-2 chars"); - tf.addValidator(new LegacyStringLengthValidator("Invalid length", 1, 2, false)); + tf.addValidator( + new LegacyStringLengthValidator("Invalid length", 1, 2, false)); tf.setRequired(true); form.addField("a", tf); diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridThemeUI.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridThemeUI.java index d4ead34506..016b0a2d95 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/grid/GridThemeUI.java +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridThemeUI.java @@ -96,11 +96,10 @@ public class GridThemeUI extends AbstractTestUIWithLog { getColumn("lastName").setEditable(false); setSizeFull(); getColumn("age").getEditorField().addValidator( - new LegacyIntegerRangeValidator("Must be between 0 and 100", 0, - 100)); - getColumn("birthDate").setRenderer( - new DateRenderer(DateFormat.getDateInstance( - DateFormat.MEDIUM, Locale.US))); + new LegacyIntegerRangeValidator("Must be between 0 and 100", + 0, 100)); + getColumn("birthDate").setRenderer(new DateRenderer( + DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US))); } } @@ -137,11 +136,10 @@ public class GridThemeUI extends AbstractTestUIWithLog { setEditorEnabled(true); setSizeFull(); getColumn("age").getEditorField().addValidator( - new LegacyIntegerRangeValidator("Must be between 0 and 100", 0, - 100)); - getColumn("birthDate").setRenderer( - new DateRenderer(DateFormat.getDateInstance( - DateFormat.MEDIUM, Locale.US))); + new LegacyIntegerRangeValidator("Must be between 0 and 100", + 0, 100)); + getColumn("birthDate").setRenderer(new DateRenderer( + DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US))); addFooterRowAt(0); } diff --git a/uitest/src/main/java/com/vaadin/tests/fieldgroup/AbstractBasicCrud.java b/uitest/src/main/java/com/vaadin/tests/fieldgroup/AbstractBasicCrud.java index 04206b7f07..8182f638b0 100644 --- a/uitest/src/main/java/com/vaadin/tests/fieldgroup/AbstractBasicCrud.java +++ b/uitest/src/main/java/com/vaadin/tests/fieldgroup/AbstractBasicCrud.java @@ -199,7 +199,8 @@ public abstract class AbstractBasicCrud extends AbstractTestUIWithLog { protected BeanFieldGroup<ComplexPerson> fieldGroup = new BeanFieldGroup<ComplexPerson>( ComplexPerson.class) { @Override - protected void configureField(com.vaadin.legacy.ui.LegacyField<?> field) { + protected void configureField( + com.vaadin.legacy.ui.LegacyField<?> field) { super.configureField(field); if (field.getCaption().equals("Postal code")) { // Last name editing is disabled through property. @@ -264,8 +265,8 @@ public abstract class AbstractBasicCrud extends AbstractTestUIWithLog { public AutoGeneratedForm(Class<? extends LegacyField> class1) { for (String p : columns) { - LegacyField f = fieldGroup.getFieldFactory().createField( - container.getType(p), class1); + LegacyField f = fieldGroup.getFieldFactory() + .createField(container.getType(p), class1); f.setCaption(SharedUtil.propertyIdToHumanFriendly(p)); fieldGroup.bind(f, p); addComponent(f); diff --git a/uitest/src/main/java/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRow.java b/uitest/src/main/java/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRow.java index c872269bbd..aa3b32a1b7 100644 --- a/uitest/src/main/java/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRow.java +++ b/uitest/src/main/java/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRow.java @@ -44,21 +44,18 @@ public class BasicCrudGridEditorRow extends AbstractBasicCrud { grid.addSelectionListener(new SelectionListener() { @Override public void select(SelectionEvent event) { - Item item = grid.getContainerDataSource().getItem( - grid.getSelectedRow()); + Item item = grid.getContainerDataSource() + .getItem(grid.getSelectedRow()); form.edit((BeanItem<ComplexPerson>) item); } }); grid.setEditorEnabled(true); grid.setSizeFull(); - grid.getColumn("age") - .getEditorField() - .addValidator( - new LegacyIntegerRangeValidator("Must be between 0 and 100", - 0, 100)); - grid.getColumn("birthDate").setRenderer( - new DateRenderer(DateFormat.getDateInstance(DateFormat.MEDIUM, - Locale.US))); + grid.getColumn("age").getEditorField().addValidator( + new LegacyIntegerRangeValidator("Must be between 0 and 100", 0, + 100)); + grid.getColumn("birthDate").setRenderer(new DateRenderer( + DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US))); addComponent(grid); getLayout().setExpandRatio(grid, 1); } diff --git a/uitest/src/main/java/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java b/uitest/src/main/java/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java index 74305cdaa3..97e7e53165 100644 --- a/uitest/src/main/java/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java +++ b/uitest/src/main/java/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java @@ -1,5 +1,7 @@ package com.vaadin.tests.fieldgroup; +import org.apache.commons.lang.StringEscapeUtils; + import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.util.BeanItem; import com.vaadin.legacy.data.Validator; @@ -10,7 +12,6 @@ import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Label; import com.vaadin.ui.TextField; -import org.apache.commons.lang.StringEscapeUtils; public class MultipleValidationErrors extends AbstractTestUI { @@ -39,8 +40,8 @@ public class MultipleValidationErrors extends AbstractTestUI { try { fieldGroup.commit(); } catch (FieldGroup.CommitException e) { - if (e.getCause() != null - && e.getCause() instanceof Validator.InvalidValueException) { + if (e.getCause() != null && e + .getCause() instanceof Validator.InvalidValueException) { validationErrors.setValue(StringEscapeUtils .unescapeHtml(AbstractErrorMessage .getErrorMessageForException( diff --git a/uitest/src/main/java/com/vaadin/tests/minitutorials/v70/SimpleLoginView.java b/uitest/src/main/java/com/vaadin/tests/minitutorials/v70/SimpleLoginView.java index 04e799049c..ea784b46fd 100644 --- a/uitest/src/main/java/com/vaadin/tests/minitutorials/v70/SimpleLoginView.java +++ b/uitest/src/main/java/com/vaadin/tests/minitutorials/v70/SimpleLoginView.java @@ -14,8 +14,8 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.Reindeer; -public class SimpleLoginView extends CustomComponent implements View, - Button.ClickListener { +public class SimpleLoginView extends CustomComponent + implements View, Button.ClickListener { public static final String NAME = "login"; @@ -33,8 +33,8 @@ public class SimpleLoginView extends CustomComponent implements View, user.setWidth("300px"); user.setRequired(true); user.setInputPrompt("Your username (eg. joe@email.com)"); - user.addValidator(new LegacyEmailValidator( - "Username must be an email address")); + user.addValidator( + new LegacyEmailValidator("Username must be an email address")); user.setInvalidAllowed(false); // Create the password input field @@ -50,7 +50,8 @@ public class SimpleLoginView extends CustomComponent implements View, // Add both to a panel VerticalLayout fields = new VerticalLayout(user, password, loginButton); - fields.setCaption("Please login to access the application. (test@test.com/passw0rd)"); + fields.setCaption( + "Please login to access the application. (test@test.com/passw0rd)"); fields.setSpacing(true); fields.setMargin(new MarginInfo(true, true, true, false)); fields.setSizeUndefined(); @@ -72,8 +73,8 @@ public class SimpleLoginView extends CustomComponent implements View, /* * Validator for validating the passwords */ - private static final class PasswordValidator extends - LegacyAbstractValidator<String> { + private static final class PasswordValidator + extends LegacyAbstractValidator<String> { public PasswordValidator() { super("The password provided is not valid"); diff --git a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket1878.java b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket1878.java index 0128725207..1b019e05fe 100644 --- a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket1878.java +++ b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket1878.java @@ -185,7 +185,8 @@ public class Ticket1878 extends LegacyApplication { form = createForm(l1, "200px", "500px"); BeanItem<FormObject> item = new BeanItem<FormObject>(new FormObject()); form.setItemDataSource(item); - for (Iterator<?> i = item.getItemPropertyIds().iterator(); i.hasNext();) { + for (Iterator<?> i = item.getItemPropertyIds().iterator(); i + .hasNext();) { Object property = i.next(); LegacyField<?> f = form.getField(property); @@ -197,7 +198,8 @@ public class Ticket1878 extends LegacyApplication { f.setCaption(null); } - f.addValidator(new LegacyStringLengthValidator("Error", 10, 8, false)); + f.addValidator( + new LegacyStringLengthValidator("Error", 10, 8, false)); } // createLayout(l1, new // ExpandLayout(ExpandLayout.ORIENTATION_HORIZONTAL), @@ -277,8 +279,9 @@ public class Ticket1878 extends LegacyApplication { } String alignText = align ? "-A" : ""; String cWidth = componentWidth == null ? "" : " - " + componentWidth; - Panel p = new Panel(type + "/" + dirText + alignText + " " + w + "x" - + h + cWidth, newLayout); + Panel p = new Panel( + type + "/" + dirText + alignText + " " + w + "x" + h + cWidth, + newLayout); p.setWidth(w); p.setHeight(h); @@ -310,8 +313,8 @@ public class Ticket1878 extends LegacyApplication { newLayout.addComponent(tf); if (align) { - ((AlignmentHandler) newLayout).setComponentAlignment( - tf, Alignment.BOTTOM_RIGHT); + ((AlignmentHandler) newLayout).setComponentAlignment(tf, + Alignment.BOTTOM_RIGHT); } } } diff --git a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket20.java b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket20.java index 1f7bc144f4..d1baceb17c 100644 --- a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket20.java +++ b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket20.java @@ -3,8 +3,8 @@ package com.vaadin.tests.tickets; import com.vaadin.data.util.MethodProperty; import com.vaadin.legacy.data.Validator; import com.vaadin.legacy.data.validator.LegacyCompositeValidator; -import com.vaadin.legacy.data.validator.LegacyIntegerValidator; import com.vaadin.legacy.data.validator.LegacyCompositeValidator.CombinationMode; +import com.vaadin.legacy.data.validator.LegacyIntegerValidator; import com.vaadin.server.LegacyApplication; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; @@ -41,19 +41,21 @@ public class Ticket20 extends LegacyApplication { @Override public void validate(Object value) throws InvalidValueException { if (!isValid(value)) { - throw new InvalidValueException(value - + " is not a non-negative number"); + throw new InvalidValueException( + value + " is not a non-negative number"); } } }); - LegacyCompositeValidator v2 = new LegacyCompositeValidator(CombinationMode.OR, null); + LegacyCompositeValidator v2 = new LegacyCompositeValidator( + CombinationMode.OR, null); v2.addValidator(v); v2.addValidator(new Validator() { @Override public void validate(Object value) throws InvalidValueException { if (!"".equals("" + value)) { - throw new InvalidValueException("Value is not empty string"); + throw new InvalidValueException( + "Value is not empty string"); } } }); @@ -69,8 +71,8 @@ public class Ticket20 extends LegacyApplication { mainWin.addComponent(b); } - mainWin.addComponent(new Button("Validate integer", - new Button.ClickListener() { + mainWin.addComponent( + new Button("Validate integer", new Button.ClickListener() { @Override public void buttonClick( com.vaadin.ui.Button.ClickEvent event) { diff --git a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket736.java b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket736.java index 3ea5d05f9d..833f794fdb 100644 --- a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket736.java +++ b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket736.java @@ -67,8 +67,8 @@ public class Ticket736 extends LegacyApplication { f.getField("zip").addValidator( new LegacyIntegerValidator("'{0}' is not a number")); ((AbstractComponent) f.getField("zip")).setDescription("Jepjep"); - ((AbstractComponent) f.getField("zip")).setIcon(new ThemeResource( - "../runo/icons/16/folder.png")); + ((AbstractComponent) f.getField("zip")) + .setIcon(new ThemeResource("../runo/icons/16/folder.png")); f.getField("state").addValidator(new IsValidState()); f.getField("name").setRequired(true); f.getField("street").setRequired(true); diff --git a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket846.java b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket846.java index c0ab1a39ad..2cb4f815ca 100644 --- a/uitest/src/main/java/com/vaadin/tests/tickets/Ticket846.java +++ b/uitest/src/main/java/com/vaadin/tests/tickets/Ticket846.java @@ -33,8 +33,8 @@ public class Ticket846 extends LegacyApplication { // tx.setIcon(new ThemeResource("icons/16/folder.png")); - mainWin.addComponent(new Button("Validate integer", - new Button.ClickListener() { + mainWin.addComponent( + new Button("Validate integer", new Button.ClickListener() { @Override public void buttonClick( com.vaadin.ui.Button.ClickEvent event) { diff --git a/uitest/src/main/java/com/vaadin/tests/validation/FieldErrorIndication.java b/uitest/src/main/java/com/vaadin/tests/validation/FieldErrorIndication.java index 8e2c006752..a182f8498b 100644 --- a/uitest/src/main/java/com/vaadin/tests/validation/FieldErrorIndication.java +++ b/uitest/src/main/java/com/vaadin/tests/validation/FieldErrorIndication.java @@ -17,10 +17,10 @@ package com.vaadin.tests.validation; import java.util.Set; -import com.vaadin.legacy.ui.LegacyField; import com.vaadin.legacy.data.Validator; import com.vaadin.legacy.data.validator.LegacyStringLengthValidator; import com.vaadin.legacy.ui.LegacyAbstractField; +import com.vaadin.legacy.ui.LegacyField; import com.vaadin.server.UserError; import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractTestUI; @@ -49,20 +49,22 @@ public class FieldErrorIndication extends AbstractTestUI { ComboBox comboBox = new ComboBox("ComboBox"); comboBox.addItem("ok"); comboBox.addItem("error"); - comboBox.addValidator(new LegacyStringLengthValidator("fail", 0, 2, false)); + comboBox.addValidator( + new LegacyStringLengthValidator("fail", 0, 2, false)); comboBox.setValue("error"); ListSelect listSelect = new ListSelect("ListSelect"); listSelect.addItem("ok"); listSelect.addItem("error"); - listSelect.addValidator(new LegacyStringLengthValidator("fail", 0, 2, false)); + listSelect.addValidator( + new LegacyStringLengthValidator("fail", 0, 2, false)); listSelect.setValue("error"); NativeSelect nativeSelect = new NativeSelect("NativeSelect"); nativeSelect.addItem("ok"); nativeSelect.addItem("error"); - nativeSelect - .addValidator(new LegacyStringLengthValidator("fail", 0, 2, false)); + nativeSelect.addValidator( + new LegacyStringLengthValidator("fail", 0, 2, false)); nativeSelect.setValue("error"); TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); twinColSelect.addItem("ok"); diff --git a/uitest/src/main/java/com/vaadin/tests/validation/TestValidators.java b/uitest/src/main/java/com/vaadin/tests/validation/TestValidators.java index 20425b3154..663d289cf2 100644 --- a/uitest/src/main/java/com/vaadin/tests/validation/TestValidators.java +++ b/uitest/src/main/java/com/vaadin/tests/validation/TestValidators.java @@ -3,12 +3,12 @@ package com.vaadin.tests.validation; import com.vaadin.legacy.data.Validator; import com.vaadin.legacy.data.validator.LegacyAbstractStringValidator; import com.vaadin.legacy.data.validator.LegacyCompositeValidator; +import com.vaadin.legacy.data.validator.LegacyCompositeValidator.CombinationMode; import com.vaadin.legacy.data.validator.LegacyDoubleValidator; import com.vaadin.legacy.data.validator.LegacyEmailValidator; import com.vaadin.legacy.data.validator.LegacyIntegerValidator; import com.vaadin.legacy.data.validator.LegacyRegexpValidator; import com.vaadin.legacy.data.validator.LegacyStringLengthValidator; -import com.vaadin.legacy.data.validator.LegacyCompositeValidator.CombinationMode; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; @@ -37,7 +37,8 @@ public class TestValidators extends TestBase { // simple validators TextField tf = new TextField("A field, must contain 1-2 chars"); - tf.addValidator(new LegacyStringLengthValidator("Invalid length", 1, 2, false)); + tf.addValidator( + new LegacyStringLengthValidator("Invalid length", 1, 2, false)); tf.setRequired(true); tf.setValue("ab"); form.addField("a", tf); @@ -67,7 +68,8 @@ public class TestValidators extends TestBase { // regular expressions - tf = new TextField("A field, must match the regular expression a.*b.*c"); + tf = new TextField( + "A field, must match the regular expression a.*b.*c"); tf.addValidator(new LegacyRegexpValidator("a.*b.*c", "{0} does not match the regular expression")); tf.setValue("aagsabeqgc"); @@ -97,10 +99,12 @@ public class TestValidators extends TestBase { // TODO CompositeValidator tf = new TextField( "A field, must be a floating point number with 4-5 chars"); - LegacyCompositeValidator cv = new LegacyCompositeValidator(CombinationMode.AND, + LegacyCompositeValidator cv = new LegacyCompositeValidator( + CombinationMode.AND, "The field must contain a floating point number with 4-5 characters"); cv.addValidator(new LegacyStringLengthValidator( - "String length of '{0}' should be 4-5 characters", 4, 5, false)); + "String length of '{0}' should be 4-5 characters", 4, 5, + false)); cv.addValidator(new LegacyDoubleValidator( "{0} must be a floating point number")); tf.addValidator(cv); @@ -112,7 +116,8 @@ public class TestValidators extends TestBase { cv = new LegacyCompositeValidator(CombinationMode.OR, "The field must contain a floating point or with 4-5 characters"); cv.addValidator(new LegacyStringLengthValidator( - "String length of '{0}' should be 4-5 characters", 4, 5, false)); + "String length of '{0}' should be 4-5 characters", 4, 5, + false)); cv.addValidator(new LegacyDoubleValidator( "{0} must be a floating point number")); tf.addValidator(cv); |