diff options
Diffstat (limited to 'compatibility-server')
45 files changed, 4658 insertions, 0 deletions
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyAbstractStringValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyAbstractStringValidator.java new file mode 100644 index 0000000000..c0eb3b5fa3 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyAbstractStringValidator.java @@ -0,0 +1,54 @@ +/* + * 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.v7.data.validator; + +/** + * Validator base class for validating strings. + * <p> + * To include the value that failed validation in the exception message you can + * use "{0}" in the error message. This will be replaced with the failed value + * (converted to string using {@link #toString()}) or "null" if the value is + * null. + * </p> + * + * @author Vaadin Ltd. + * @since 5.4 + */ +@SuppressWarnings("serial") +public abstract class LegacyAbstractStringValidator + extends LegacyAbstractValidator<String> { + + /** + * Constructs a validator for strings. + * + * <p> + * Null and empty string values are always accepted. To reject empty values, + * set the field being validated as required. + * </p> + * + * @param errorMessage + * the message to be included in an {@link InvalidValueException} + * (with "{0}" replaced by the value that failed validation). + */ + public LegacyAbstractStringValidator(String errorMessage) { + super(errorMessage); + } + + @Override + public Class<String> getType() { + return String.class; + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyAbstractValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyAbstractValidator.java new file mode 100644 index 0000000000..8c1cc56010 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyAbstractValidator.java @@ -0,0 +1,149 @@ +/* + * 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.v7.data.validator; + +import com.vaadin.v7.data.Validator; + +/** + * Abstract {@link com.vaadin.v7.data.Validator Validator} implementation + * that provides a basic Validator implementation except the + * {@link #isValidValue(Object)} method. + * <p> + * To include the value that failed validation in the exception message you can + * use "{0}" in the error message. This will be replaced with the failed value + * (converted to string using {@link #toString()}) or "null" if the value is + * null. + * </p> + * <p> + * The default implementation of AbstractValidator does not support HTML in + * error messages. To enable HTML support, override + * {@link InvalidValueException#getHtmlMessage()} and throw such exceptions from + * {@link #validate(Object)}. + * </p> + * <p> + * Since Vaadin 7, subclasses can either implement {@link #validate(Object)} + * directly or implement {@link #isValidValue(Object)} when migrating legacy + * applications. To check validity, {@link #validate(Object)} should be used. + * </p> + * + * @param <T> + * The type + * @author Vaadin Ltd. + * @since 5.4 + */ +public abstract class LegacyAbstractValidator<T> implements Validator { + + /** + * Error message that is included in an {@link InvalidValueException} if + * such is thrown. + */ + private String errorMessage; + + /** + * Constructs a validator with the given error message. + * + * @param errorMessage + * the message to be included in an {@link InvalidValueException} + * (with "{0}" replaced by the value that failed validation). + */ + public LegacyAbstractValidator(String errorMessage) { + this.errorMessage = errorMessage; + } + + /** + * Since Vaadin 7, subclasses of AbstractValidator should override + * {@link #isValidValue(Object)} or {@link #validate(Object)} instead of + * {@link #isValid(Object)}. {@link #validate(Object)} should normally be + * used to check values. + * + * @param value + * @return true if the value is valid + */ + public boolean isValid(Object value) { + try { + validate(value); + return true; + } catch (InvalidValueException e) { + return false; + } + } + + /** + * Internally check the validity of a value. This method can be used to + * perform validation in subclasses if customization of the error message is + * not needed. Otherwise, subclasses should override + * {@link #validate(Object)} and the return value of this method is ignored. + * + * This method should not be called from outside the validator class itself. + * + * @param value + * @return + */ + protected abstract boolean isValidValue(T value); + + @Override + public void validate(Object value) throws InvalidValueException { + // isValidType ensures that value can safely be cast to TYPE + if (!isValidType(value) || !isValidValue((T) value)) { + String message = getErrorMessage().replace("{0}", + String.valueOf(value)); + throw new InvalidValueException(message); + } + } + + /** + * Checks the type of the value to validate to ensure it conforms with + * getType. Enables sub classes to handle the specific type instead of + * Object. + * + * @param value + * The value to check + * @return true if the value can safely be cast to the type specified by + * {@link #getType()} + */ + protected boolean isValidType(Object value) { + if (value == null) { + return true; + } + + return getType().isAssignableFrom(value.getClass()); + } + + /** + * Returns the message to be included in the exception in case the value + * does not validate. + * + * @return the error message provided in the constructor or using + * {@link #setErrorMessage(String)}. + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * Sets the message to be included in the exception in case the value does + * not validate. The exception message is typically shown to the end user. + * + * @param errorMessage + * the error message. "{0}" is automatically replaced by the + * value that did not validate. + */ + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public abstract Class<T> getType(); +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBeanValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBeanValidator.java new file mode 100644 index 0000000000..dfc107280f --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBeanValidator.java @@ -0,0 +1,184 @@ +/* + * 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.v7.data.validator; + +import java.io.Serializable; +import java.util.Locale; +import java.util.Set; + +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.v7.data.Validator; + +/** + * Vaadin {@link Validator} using the JSR-303 (javax.validation) + * annotation-based bean validation. + * + * The annotations of the fields of the beans are used to determine the + * validation to perform. + * + * 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. + * + * @since 7.0 + * + * @author Petri Hakala + * @author Henri Sara + */ +public class LegacyBeanValidator implements Validator { + + private static final long serialVersionUID = 1L; + private static ValidatorFactory factory; + + private transient javax.validation.Validator javaxBeanValidator; + private String propertyName; + private Class<?> beanClass; + private Locale locale; + + /** + * Simple implementation of a message interpolator context that returns + * fixed values. + */ + protected static class SimpleContext implements Context, Serializable { + + private final Object value; + private final ConstraintDescriptor<?> descriptor; + + /** + * Create a simple immutable message interpolator context. + * + * @param value + * value being validated + * @param descriptor + * ConstraintDescriptor corresponding to the constraint being + * validated + */ + public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) { + this.value = value; + this.descriptor = descriptor; + } + + @Override + public ConstraintDescriptor<?> getConstraintDescriptor() { + return descriptor; + } + + @Override + public Object getValidatedValue() { + return value; + } + + } + + /** + * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation. + * + * @param beanClass + * bean class based on which the validation should be performed + * @param propertyName + * property to validate + */ + public LegacyBeanValidator(Class<?> beanClass, String propertyName) { + this.beanClass = beanClass; + this.propertyName = propertyName; + locale = Locale.getDefault(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Validator#validate(java.lang.Object) + */ + @Override + public void validate(final Object value) throws InvalidValueException { + Set<?> violations = getJavaxBeanValidator().validateValue(beanClass, + propertyName, value); + if (violations.size() > 0) { + InvalidValueException[] causes = new InvalidValueException[violations + .size()]; + int i = 0; + for (Object v : violations) { + final ConstraintViolation<?> violation = (ConstraintViolation<?>) v; + String msg = getJavaxBeanValidatorFactory() + .getMessageInterpolator() + .interpolate(violation.getMessageTemplate(), + new SimpleContext(value, + violation.getConstraintDescriptor()), + locale); + causes[i] = new InvalidValueException(msg); + ++i; + } + + throw new InvalidValueException(null, causes); + } + } + + /** + * Sets the locale used for validation error messages. + * + * Revalidation is not automatically triggered by setting the locale. + * + * @param locale + */ + public void setLocale(Locale locale) { + this.locale = locale; + } + + /** + * Gets the locale used for validation error messages. + * + * @return locale used for validation + */ + public Locale getLocale() { + return locale; + } + + /** + * Returns the underlying JSR-303 bean validator factory used. A factory is + * created using {@link Validation} if necessary. + * + * @return {@link ValidatorFactory} to use + */ + protected static ValidatorFactory getJavaxBeanValidatorFactory() { + if (factory == null) { + factory = Validation.buildDefaultValidatorFactory(); + } + + return factory; + } + + /** + * Returns a shared Validator instance to use. An instance is created using + * the validator factory if necessary and thereafter reused by the + * {@link LegacyBeanValidator} instance. + * + * @return the JSR-303 {@link javax.validation.Validator} to use + */ + protected javax.validation.Validator getJavaxBeanValidator() { + if (javaxBeanValidator == null) { + javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator(); + } + + return javaxBeanValidator; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBigDecimalRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBigDecimalRangeValidator.java new file mode 100644 index 0000000000..72c959e773 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBigDecimalRangeValidator.java @@ -0,0 +1,51 @@ +/* + * 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.v7.data.validator; + +import java.math.BigDecimal; + +/** + * Validator for validating that an {@link BigDecimal} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.4 + */ +@SuppressWarnings("serial") +public class LegacyBigDecimalRangeValidator + extends LegacyRangeValidator<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 LegacyBigDecimalRangeValidator(String errorMessage, + BigDecimal minValue, BigDecimal maxValue) { + super(errorMessage, BigDecimal.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBigIntegerRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBigIntegerRangeValidator.java new file mode 100644 index 0000000000..363a9bb82c --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyBigIntegerRangeValidator.java @@ -0,0 +1,51 @@ +/* + * 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.v7.data.validator; + +import java.math.BigInteger; + +/** + * Validator for validating that an {@link BigInteger} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.4 + */ +@SuppressWarnings("serial") +public class LegacyBigIntegerRangeValidator + extends LegacyRangeValidator<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 LegacyBigIntegerRangeValidator(String errorMessage, + BigInteger minValue, BigInteger maxValue) { + super(errorMessage, BigInteger.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyByteRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyByteRangeValidator.java new file mode 100644 index 0000000000..14694c4a52 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyByteRangeValidator.java @@ -0,0 +1,47 @@ +/* + * 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.v7.data.validator; + +/** + * Validator for validating that an {@link Byte} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.4 + */ +@SuppressWarnings("serial") +public class LegacyByteRangeValidator extends LegacyRangeValidator<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 LegacyByteRangeValidator(String errorMessage, Byte minValue, + Byte maxValue) { + super(errorMessage, Byte.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyCompositeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyCompositeValidator.java new file mode 100644 index 0000000000..ecf4d121f2 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyCompositeValidator.java @@ -0,0 +1,270 @@ +/* + * 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.v7.data.validator; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +import com.vaadin.v7.data.Validator; + +/** + * The <code>CompositeValidator</code> allows you to chain (compose) many + * validators to validate one field. The contained validators may be required to + * all validate the value to validate or it may be enough that one contained + * validator validates the value. This behaviour is controlled by the modes + * <code>AND</code> and <code>OR</code>. + * + * @author Vaadin Ltd. + * @since 3.0 + */ +@SuppressWarnings("serial") +public class LegacyCompositeValidator implements Validator { + + public enum CombinationMode { + /** + * The validators are combined with <code>AND</code> clause: validity of + * the composite implies validity of the all validators it is composed + * of must be valid. + */ + AND, + /** + * The validators are combined with <code>OR</code> clause: validity of + * the composite implies that some of validators it is composed of must + * be valid. + */ + OR; + } + + /** + * @deprecated As of 7.0, use {@link CombinationMode#AND} instead   + */ + @Deprecated + public static final CombinationMode MODE_AND = CombinationMode.AND; + /** + * @deprecated As of 7.0, use {@link CombinationMode#OR} instead   + */ + @Deprecated + public static final CombinationMode MODE_OR = CombinationMode.OR; + + private String errorMessage; + + /** + * Operation mode. + */ + private CombinationMode mode = CombinationMode.AND; + + /** + * List of contained validators. + */ + private final List<Validator> validators = new LinkedList<Validator>(); + + /** + * Construct a composite validator in <code>AND</code> mode without error + * message. + */ + public LegacyCompositeValidator() { + this(CombinationMode.AND, ""); + } + + /** + * Constructs a composite validator in given mode. + * + * @param mode + * @param errorMessage + */ + public LegacyCompositeValidator(CombinationMode mode, String errorMessage) { + setErrorMessage(errorMessage); + setMode(mode); + } + + /** + * Validates the given value. + * <p> + * The value is valid, if: + * <ul> + * <li><code>MODE_AND</code>: All of the sub-validators are valid + * <li><code>MODE_OR</code>: Any of the sub-validators are valid + * </ul> + * + * If the value is invalid, validation error is thrown. If the error message + * is set (non-null), it is used. If the error message has not been set, the + * first error occurred is thrown. + * </p> + * + * @param value + * the value to check. + * @throws Validator.InvalidValueException + * if the value is not valid. + */ + @Override + public void validate(Object value) throws Validator.InvalidValueException { + switch (mode) { + case AND: + for (Validator validator : validators) { + validator.validate(value); + } + return; + + case OR: + Validator.InvalidValueException first = null; + for (Validator v : validators) { + try { + v.validate(value); + return; + } catch (final Validator.InvalidValueException e) { + if (first == null) { + first = e; + } + } + } + if (first == null) { + return; + } + final String em = getErrorMessage(); + if (em != null) { + throw new Validator.InvalidValueException(em); + } else { + throw first; + } + } + } + + /** + * Gets the mode of the validator. + * + * @return Operation mode of the validator: {@link CombinationMode#AND} or + * {@link CombinationMode#OR}. + */ + public final CombinationMode getMode() { + return mode; + } + + /** + * Sets the mode of the validator. The valid modes are: + * <ul> + * <li>{@link CombinationMode#AND} (default) + * <li>{@link CombinationMode#OR} + * </ul> + * + * @param mode + * the mode to set. + */ + public void setMode(CombinationMode mode) { + if (mode == null) { + throw new IllegalArgumentException( + "The validator can't be set to null"); + } + this.mode = mode; + } + + /** + * Gets the error message for the composite validator. If the error message + * is null, original error messages of the sub-validators are used instead. + */ + public String getErrorMessage() { + if (errorMessage != null) { + return errorMessage; + } + + // TODO Return composite error message + + return null; + } + + /** + * Adds validator to the interface. + * + * @param validator + * the Validator object which performs validation checks on this + * set of data field values. + */ + public void addValidator(Validator validator) { + if (validator == null) { + return; + } + validators.add(validator); + } + + /** + * Removes a validator from the composite. + * + * @param validator + * the Validator object which performs validation checks on this + * set of data field values. + */ + public void removeValidator(Validator validator) { + validators.remove(validator); + } + + /** + * Gets sub-validators by class. + * + * <p> + * If the component contains directly or recursively (it contains another + * composite containing the validator) validators compatible with given type + * they are returned. This only applies to <code>AND</code> mode composite + * validators. + * </p> + * + * <p> + * If the validator is in <code>OR</code> mode or does not contain any + * validators of given type null is returned. + * </p> + * + * @param validatorType + * The type of validators to return + * + * @return Collection<Validator> of validators compatible with given type + * that must apply or null if none found. + */ + public Collection<Validator> getSubValidators(Class validatorType) { + if (mode != CombinationMode.AND) { + return null; + } + + final HashSet<Validator> found = new HashSet<Validator>(); + for (Validator v : validators) { + if (validatorType.isAssignableFrom(v.getClass())) { + found.add(v); + } + if (v instanceof LegacyCompositeValidator + && ((LegacyCompositeValidator) v).getMode() == MODE_AND) { + final Collection<Validator> c = ((LegacyCompositeValidator) v) + .getSubValidators(validatorType); + if (c != null) { + found.addAll(c); + } + } + } + + return found.isEmpty() ? null : found; + } + + /** + * Sets the message to be included in the exception in case the value does + * not validate. The exception message is typically shown to the end user. + * + * @param errorMessage + * the error message. + */ + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDateRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDateRangeValidator.java new file mode 100644 index 0000000000..94cc2f78e7 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDateRangeValidator.java @@ -0,0 +1,61 @@ +/* + * 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.v7.data.validator; + +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 7.0 + */ +public class LegacyDateRangeValidator extends LegacyRangeValidator<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 LegacyDateRangeValidator(String errorMessage, Date minValue, + Date maxValue, Resolution resolution) { + super(errorMessage, Date.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDoubleRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDoubleRangeValidator.java new file mode 100644 index 0000000000..7416ad60e6 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDoubleRangeValidator.java @@ -0,0 +1,47 @@ +/* + * 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.v7.data.validator; + +/** + * Validator for validating that a {@link Double} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.0 + */ +@SuppressWarnings("serial") +public class LegacyDoubleRangeValidator extends LegacyRangeValidator<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 LegacyDoubleRangeValidator(String errorMessage, Double minValue, + Double maxValue) { + super(errorMessage, Double.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDoubleValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDoubleValidator.java new file mode 100644 index 0000000000..fcc94f6e7c --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyDoubleValidator.java @@ -0,0 +1,73 @@ +/* + * 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.v7.data.validator; + +import com.vaadin.data.Property; +import com.vaadin.v7.data.util.converter.LegacyStringToDoubleConverter; + +/** + * String validator for a double precision floating point number. See + * {@link com.vaadin.v7.data.validator.LegacyAbstractStringValidator} for + * more information. + * + * @author Vaadin Ltd. + * @since 5.4 + * @deprecated As of 7.0. Use a {@link LegacyStringToDoubleConverter} converter + * on the field instead or bind the field to a {@link Property} of + * type {@link Double}. + */ +@Deprecated +@SuppressWarnings("serial") +public class LegacyDoubleValidator extends LegacyAbstractStringValidator { + + /** + * Creates a validator for checking that a string can be parsed as an + * double. + * + * @param errorMessage + * the message to display in case the value does not validate. + * @deprecated As of 7.0. Use a Double converter on the field instead and/or + * use a {@link LegacyDoubleRangeValidator} for validating that + * the value is inside a given range. + */ + @Deprecated + public LegacyDoubleValidator(String errorMessage) { + super(errorMessage); + } + + @Override + protected boolean isValidValue(String value) { + try { + Double.parseDouble(value); + return true; + } catch (Exception e) { + return false; + } + } + + @Override + public void validate(Object value) throws InvalidValueException { + if (value != null && value instanceof Double) { + // Allow Doubles to pass through the validator for easier + // migration. Otherwise a TextField connected to an double property + // with a DoubleValidator will fail. + return; + } + + super.validate(value); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyEmailValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyEmailValidator.java new file mode 100644 index 0000000000..836ff5ff15 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyEmailValidator.java @@ -0,0 +1,49 @@ +/* + * 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.v7.data.validator; + +/** + * 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. + * + * See {@link com.vaadin.v7.data.validator.LegacyAbstractStringValidator} + * for more information. + * + * <p> + * An empty string or a null is always accepted - use the required flag on + * fields or a separate validator (or override {@link #isValidValue(String)}) to + * fail on empty values. + * </p> + * + * @author Vaadin Ltd. + * @since 5.4 + */ +@SuppressWarnings("serial") +public class LegacyEmailValidator extends LegacyRegexpValidator { + + /** + * 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 LegacyEmailValidator(String errorMessage) { + super("^([a-zA-Z0-9_\\.\\-+])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,4})+$", + true, errorMessage); + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyFloatRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyFloatRangeValidator.java new file mode 100644 index 0000000000..9dc27d3727 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyFloatRangeValidator.java @@ -0,0 +1,47 @@ +/* + * 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.v7.data.validator; + +/** + * Validator for validating that a {@link Float} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.4 + */ +@SuppressWarnings("serial") +public class LegacyFloatRangeValidator extends LegacyRangeValidator<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 LegacyFloatRangeValidator(String errorMessage, Float minValue, + Float maxValue) { + super(errorMessage, Float.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyIntegerRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyIntegerRangeValidator.java new file mode 100644 index 0000000000..09de051e1d --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyIntegerRangeValidator.java @@ -0,0 +1,47 @@ +/* + * 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.v7.data.validator; + +/** + * Validator for validating that an {@link Integer} is inside a given range. + * + * @author Vaadin Ltd. + * @since 5.4 + */ +@SuppressWarnings("serial") +public class LegacyIntegerRangeValidator extends LegacyRangeValidator<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 LegacyIntegerRangeValidator(String errorMessage, Integer minValue, + Integer maxValue) { + super(errorMessage, Integer.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyIntegerValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyIntegerValidator.java new file mode 100644 index 0000000000..34d2e7e76b --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyIntegerValidator.java @@ -0,0 +1,73 @@ +/* + * 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.v7.data.validator; + +import com.vaadin.data.Property; +import com.vaadin.v7.data.util.converter.LegacyStringToIntegerConverter; + +/** + * String validator for integers. See + * {@link com.vaadin.v7.data.validator.LegacyAbstractStringValidator} for + * more information. + * + * @author Vaadin Ltd. + * @since 5.4 + * @deprecated As of 7.0. Use a {@link LegacyStringToIntegerConverter} converter + * on the field instead or bind the field to a {@link Property} of + * type {@link Integer}. + */ +@SuppressWarnings("serial") +@Deprecated +public class LegacyIntegerValidator extends LegacyAbstractStringValidator { + + /** + * Creates a validator for checking that a string can be parsed as an + * integer. + * + * @param errorMessage + * the message to display in case the value does not validate. + * @deprecated As of 7.0. Use an Integer converter on the field instead + * and/or use an {@link LegacyIntegerRangeValidator} for + * validating that the value is inside a given range. + */ + @Deprecated + public LegacyIntegerValidator(String errorMessage) { + super(errorMessage); + + } + + @Override + protected boolean isValidValue(String value) { + try { + Integer.parseInt(value); + return true; + } catch (Exception e) { + return false; + } + } + + @Override + public void validate(Object value) throws InvalidValueException { + if (value != null && value instanceof Integer) { + // Allow Integers to pass through the validator for easier + // migration. Otherwise a TextField connected to an integer property + // with an IntegerValidator will fail. + return; + } + + super.validate(value); + } +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyLongRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyLongRangeValidator.java new file mode 100644 index 0000000000..8e5523b46a --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyLongRangeValidator.java @@ -0,0 +1,47 @@ +/* + * 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.v7.data.validator; + +/** + * Validator for validating that an {@link Long} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.4 + */ +@SuppressWarnings("serial") +public class LegacyLongRangeValidator extends LegacyRangeValidator<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 LegacyLongRangeValidator(String errorMessage, Long minValue, + Long maxValue) { + super(errorMessage, Long.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyNullValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyNullValidator.java new file mode 100644 index 0000000000..282f5baf29 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyNullValidator.java @@ -0,0 +1,102 @@ +/* + * 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.v7.data.validator; + +import com.vaadin.v7.data.Validator; + +/** + * This validator is used for validating properties that do or do not allow null + * values. By default, nulls are not allowed. + * + * @author Vaadin Ltd. + * @since 3.0 + */ +@SuppressWarnings("serial") +public class LegacyNullValidator implements Validator { + + private boolean onlyNullAllowed; + + private String errorMessage; + + /** + * Creates a new NullValidator. + * + * @param errorMessage + * the error message to display on invalidation. + * @param onlyNullAllowed + * Are only nulls allowed? + */ + public LegacyNullValidator(String errorMessage, boolean onlyNullAllowed) { + setErrorMessage(errorMessage); + setNullAllowed(onlyNullAllowed); + } + + /** + * Validates the data given in value. + * + * @param value + * the value to validate. + * @throws Validator.InvalidValueException + * if the value was invalid. + */ + @Override + public void validate(Object value) throws Validator.InvalidValueException { + if ((onlyNullAllowed && value != null) + || (!onlyNullAllowed && value == null)) { + throw new Validator.InvalidValueException(errorMessage); + } + } + + /** + * Returns <code>true</code> if nulls are allowed otherwise + * <code>false</code>. + */ + public final boolean isNullAllowed() { + return onlyNullAllowed; + } + + /** + * Sets if nulls (and only nulls) are to be allowed. + * + * @param onlyNullAllowed + * If true, only nulls are allowed. If false only non-nulls are + * allowed. Do we allow nulls? + */ + public void setNullAllowed(boolean onlyNullAllowed) { + this.onlyNullAllowed = onlyNullAllowed; + } + + /** + * Gets the error message that is displayed in case the value is invalid. + * + * @return the Error Message. + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * Sets the error message to be displayed on invalid value. + * + * @param errorMessage + * the Error Message to set. + */ + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyRangeValidator.java new file mode 100644 index 0000000000..27830be7dd --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyRangeValidator.java @@ -0,0 +1,198 @@ +/* + * 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.v7.data.validator; + +/** + * An base implementation for validating any objects that implement + * {@link Comparable}. + * + * Verifies that the value is of the given type and within the (optionally) + * given limits. Typically you want to use a sub class of this like + * {@link LegacyIntegerRangeValidator}, {@link LegacyDoubleRangeValidator} or + * {@link LegacyDateRangeValidator} in applications. + * <p> + * Note that {@link LegacyRangeValidator} always accept null values. Make a + * field required to ensure that no empty values are accepted or override + * {@link #isValidValue(Comparable)}. + * </p> + * + * @param <T> + * The type of Number to validate. Must implement Comparable so that + * minimum and maximum checks work. + * @author Vaadin Ltd. + * @since 7.0 + */ +public class LegacyRangeValidator<T extends Comparable> + extends LegacyAbstractValidator<T> { + + private T minValue = null; + private boolean minValueIncluded = true; + private T maxValue = null; + private boolean maxValueIncluded = true; + private Class<T> type; + + /** + * Creates a new range validator of the given type. + * + * @param errorMessage + * The error message to use if validation fails + * @param type + * The type of object the validator can validate. + * @param minValue + * The minimum value that should be accepted or null for no limit + * @param maxValue + * The maximum value that should be accepted or null for no limit + */ + public LegacyRangeValidator(String errorMessage, Class<T> type, T minValue, + T maxValue) { + super(errorMessage); + this.type = type; + this.minValue = minValue; + this.maxValue = maxValue; + } + + /** + * Checks if 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 if 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; + } + + /** + * Checks if 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 if 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; + } + + /** + * Gets 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; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object + * ) + */ + @Override + protected boolean isValidValue(T value) { + if (value == null + || (String.class.equals(getType()) && "".equals(value))) { + return true; + } + + if (getMinValue() != null) { + // Ensure that the min limit is ok + int result = value.compareTo(getMinValue()); + if (result < 0) { + // value less than min value + return false; + } else if (result == 0 && !isMinValueIncluded()) { + // values equal and min value not included + return false; + } + } + if (getMaxValue() != null) { + // Ensure that the Max limit is ok + int result = value.compareTo(getMaxValue()); + if (result > 0) { + // value greater than max value + return false; + } else if (result == 0 && !isMaxValueIncluded()) { + // values equal and max value not included + return false; + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.validator.AbstractValidator#getType() + */ + @Override + public Class<T> getType() { + return type; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyRegexpValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyRegexpValidator.java new file mode 100644 index 0000000000..0649dd2f13 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyRegexpValidator.java @@ -0,0 +1,116 @@ +/* + * 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.v7.data.validator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 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#sum} + * </p> + * <p> + * See {@link com.vaadin.v7.data.validator.LegacyAbstractStringValidator} + * for more information. + * </p> + * <p> + * An empty string or a null is always accepted - use the required flag on + * fields or a separate validator (or override {@link #isValidValue(String)}) to + * fail on empty values. + * </p> + * + * @author Vaadin Ltd. + * @since 5.4 + */ +@SuppressWarnings("serial") +public class LegacyRegexpValidator extends LegacyAbstractStringValidator { + + 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 regexp + * a Java regular expression + * @param errorMessage + * the message to display in case the value does not validate. + */ + public LegacyRegexpValidator(String regexp, String errorMessage) { + this(regexp, true, errorMessage); + } + + /** + * Creates a validator for checking that the regular expression matches the + * string to validate. + * + * @param regexp + * a Java regular expression + * @param complete + * true to use check for a complete match, false to look for a + * matching substring + * @param errorMessage + * the message to display in case the value does not validate. + */ + public LegacyRegexpValidator(String regexp, boolean complete, + String errorMessage) { + super(errorMessage); + pattern = Pattern.compile(regexp); + this.complete = complete; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object + * ) + */ + @Override + protected boolean isValidValue(String value) { + if (value == null || value.isEmpty()) { + return true; + } + if (complete) { + return getMatcher(value).matches(); + } else { + return getMatcher(value).find(); + } + } + + /** + * Get a new or reused matcher for the pattern + * + * @param value + * the string to find matches in + * @return 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/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyShortRangeValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyShortRangeValidator.java new file mode 100644 index 0000000000..e23575e4d9 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyShortRangeValidator.java @@ -0,0 +1,47 @@ +/* + * 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.v7.data.validator; + +/** + * Validator for validating that an {@link Short} is inside a given range. + * + * @author Vaadin Ltd. + * @since 7.4 + */ +@SuppressWarnings("serial") +public class LegacyShortRangeValidator extends LegacyRangeValidator<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 LegacyShortRangeValidator(String errorMessage, Short minValue, + Short maxValue) { + super(errorMessage, Short.class, minValue, maxValue); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyStringLengthValidator.java b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyStringLengthValidator.java new file mode 100644 index 0000000000..4bf7d430ba --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/validator/LegacyStringLengthValidator.java @@ -0,0 +1,149 @@ +/* + * 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.v7.data.validator; + +/** + * This <code>StringLengthValidator</code> is used to validate the length of + * strings. + * + * @author Vaadin Ltd. + * @since 3.0 + */ +@SuppressWarnings("serial") +public class LegacyStringLengthValidator extends LegacyAbstractStringValidator { + + private Integer minLength = null; + + private Integer maxLength = null; + + private boolean allowNull = true; + + /** + * Creates a new StringLengthValidator with a given error message. + * + * @param errorMessage + * the message to display in case the value does not validate. + */ + public LegacyStringLengthValidator(String errorMessage) { + super(errorMessage); + } + + /** + * Creates a new StringLengthValidator with a given error message and + * minimum and maximum length limits. + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minLength + * the minimum permissible length of the string or null for no + * limit. A negative value for no limit is also supported for + * backwards compatibility. + * @param maxLength + * the maximum permissible length of the string or null for no + * limit. A negative value for no limit is also supported for + * backwards compatibility. + * @param allowNull + * Are null strings permissible? This can be handled better by + * setting a field as required or not. + */ + public LegacyStringLengthValidator(String errorMessage, Integer minLength, + Integer maxLength, boolean allowNull) { + this(errorMessage); + setMinLength(minLength); + setMaxLength(maxLength); + setNullAllowed(allowNull); + } + + /** + * Checks if the given value is valid. + * + * @param value + * the value to validate. + * @return <code>true</code> for valid value, otherwise <code>false</code>. + */ + @Override + protected boolean isValidValue(String value) { + if (value == null) { + return allowNull; + } + final int len = value.length(); + if ((minLength != null && minLength > -1 && len < minLength) + || (maxLength != null && maxLength > -1 && len > maxLength)) { + return false; + } + return true; + } + + /** + * Returns <code>true</code> if null strings are allowed. + * + * @return <code>true</code> if allows null string, otherwise + * <code>false</code>. + */ + @Deprecated + public final boolean isNullAllowed() { + return allowNull; + } + + /** + * 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 maxLength; + } + + /** + * 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 minLength; + } + + /** + * Sets whether null-strings are to be allowed. This can be better handled + * by setting a field as required or not. + */ + @Deprecated + public void setNullAllowed(boolean allowNull) { + this.allowNull = allowNull; + } + + /** + * 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) { + this.maxLength = maxLength; + } + + /** + * Sets the minimum permissible length. + * + * @param minLength + * the minimum length to accept or null for no limit + */ + public void setMinLength(Integer minLength) { + this.minLength = minLength; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyDateField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyDateField.java new file mode 100644 index 0000000000..0d094c28bf --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyDateField.java @@ -0,0 +1,1010 @@ +/* + * 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.v7.ui; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; +import java.util.logging.Logger; + +import org.jsoup.nodes.Element; + +import com.vaadin.data.Property; +import com.vaadin.event.FieldEvents; +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.BlurListener; +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.event.FieldEvents.FocusListener; +import com.vaadin.server.PaintException; +import com.vaadin.server.PaintTarget; +import com.vaadin.shared.ui.datefield.DateFieldConstants; +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.shared.ui.datefield.TextualDateFieldState; +import com.vaadin.ui.Component; +import com.vaadin.ui.LegacyComponent; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.v7.data.Validator; +import com.vaadin.v7.data.Validator.InvalidValueException; +import com.vaadin.v7.data.util.converter.LegacyConverter; +import com.vaadin.v7.data.validator.LegacyDateRangeValidator; + +/** + * <p> + * A date editor component that can be bound to any {@link Property} that is + * compatible with <code>java.util.Date</code>. + * </p> + * <p> + * Since <code>DateField</code> extends <code>LegacyAbstractField</code> it + * implements the {@link com.vaadin.data.Buffered}interface. + * </p> + * <p> + * A <code>DateField</code> is in write-through mode by default, so + * {@link com.vaadin.v7.ui.LegacyAbstractField#setWriteThrough(boolean)}must + * be called to enable buffering. + * </p> + * + * @author Vaadin Ltd. + * @since 3.0 + */ +@SuppressWarnings("serial") +public class LegacyDateField extends LegacyAbstractField<Date> implements + FieldEvents.BlurNotifier, FieldEvents.FocusNotifier, LegacyComponent { + + /** + * Resolution identifier: seconds. + * + * @deprecated As of 7.0, use {@link Resolution#SECOND} + */ + @Deprecated + public static final Resolution RESOLUTION_SEC = Resolution.SECOND; + + /** + * Resolution identifier: minutes. + * + * @deprecated As of 7.0, use {@link Resolution#MINUTE} + */ + @Deprecated + public static final Resolution RESOLUTION_MIN = Resolution.MINUTE; + + /** + * Resolution identifier: hours. + * + * @deprecated As of 7.0, use {@link Resolution#HOUR} + */ + @Deprecated + public static final Resolution RESOLUTION_HOUR = Resolution.HOUR; + + /** + * Resolution identifier: days. + * + * @deprecated As of 7.0, use {@link Resolution#DAY} + */ + @Deprecated + public static final Resolution RESOLUTION_DAY = Resolution.DAY; + + /** + * Resolution identifier: months. + * + * @deprecated As of 7.0, use {@link Resolution#MONTH} + */ + @Deprecated + public static final Resolution RESOLUTION_MONTH = Resolution.MONTH; + + /** + * Resolution identifier: years. + * + * @deprecated As of 7.0, use {@link Resolution#YEAR} + */ + @Deprecated + public static final Resolution RESOLUTION_YEAR = Resolution.YEAR; + + /** + * Specified smallest modifiable unit for the date field. + */ + private Resolution resolution = Resolution.DAY; + + /** + * The internal calendar to be used in java.utl.Date conversions. + */ + private transient Calendar calendar; + + /** + * Overridden format string + */ + private String dateFormat; + + private boolean lenient = false; + + private String dateString = null; + + /** + * Was the last entered string parsable? If this flag is false, datefields + * internal validator does not pass. + */ + private boolean uiHasValidDateString = true; + + /** + * Determines if week numbers are shown in the date selector. + */ + private boolean showISOWeekNumbers = false; + + private String currentParseErrorMessage; + + private String defaultParseErrorMessage = "Date format not recognized"; + + private TimeZone timeZone = null; + + private static Map<Resolution, String> variableNameForResolution = new HashMap<>(); + + private String dateOutOfRangeMessage = "Date is out of allowed range"; + + private LegacyDateRangeValidator currentRangeValidator; + + /** + * Determines whether the ValueChangeEvent should be fired. Used to prevent + * firing the event when UI has invalid string until uiHasValidDateString + * flag is set + */ + private boolean preventValueChangeEvent = false; + + static { + variableNameForResolution.put(Resolution.SECOND, "sec"); + variableNameForResolution.put(Resolution.MINUTE, "min"); + variableNameForResolution.put(Resolution.HOUR, "hour"); + variableNameForResolution.put(Resolution.DAY, "day"); + variableNameForResolution.put(Resolution.MONTH, "month"); + variableNameForResolution.put(Resolution.YEAR, "year"); + } + + /* Constructors */ + + /** + * Constructs an empty <code>DateField</code> with no caption. + */ + public LegacyDateField() { + } + + /** + * Constructs an empty <code>DateField</code> with caption. + * + * @param caption + * the caption of the datefield. + */ + public LegacyDateField(String caption) { + setCaption(caption); + } + + /** + * Constructs a new <code>DateField</code> that's bound to the specified + * <code>Property</code> and has the given caption <code>String</code>. + * + * @param caption + * the caption <code>String</code> for the editor. + * @param dataSource + * the Property to be edited with this editor. + */ + public LegacyDateField(String caption, Property dataSource) { + this(dataSource); + setCaption(caption); + } + + /** + * Constructs a new <code>DateField</code> that's bound to the specified + * <code>Property</code> and has no caption. + * + * @param dataSource + * the Property to be edited with this editor. + */ + public LegacyDateField(Property dataSource) + throws IllegalArgumentException { + if (!Date.class.isAssignableFrom(dataSource.getType())) { + throw new IllegalArgumentException( + "Can't use " + dataSource.getType().getName() + + " typed property as datasource"); + } + + setPropertyDataSource(dataSource); + } + + /** + * Constructs a new <code>DateField</code> with the given caption and + * initial text contents. The editor constructed this way will not be bound + * to a Property unless + * {@link com.vaadin.data.Property.Viewer#setPropertyDataSource(Property)} + * is called to bind it. + * + * @param caption + * the caption <code>String</code> for the editor. + * @param value + * the Date value. + */ + public LegacyDateField(String caption, Date value) { + setValue(value); + setCaption(caption); + } + + /* Component basic features */ + + /* + * Paints this component. Don't add a JavaDoc comment here, we use the + * default documentation from implemented interface. + */ + @Override + public void paintContent(PaintTarget target) throws PaintException { + + // Adds the locale as attribute + final Locale l = getLocale(); + if (l != null) { + target.addAttribute("locale", l.toString()); + } + + if (getDateFormat() != null) { + target.addAttribute("format", dateFormat); + } + + if (!isLenient()) { + target.addAttribute("strict", true); + } + + target.addAttribute(DateFieldConstants.ATTR_WEEK_NUMBERS, + isShowISOWeekNumbers()); + target.addAttribute("parsable", uiHasValidDateString); + /* + * TODO communicate back the invalid date string? E.g. returning back to + * app or refresh. + */ + + // Gets the calendar + final Calendar calendar = getCalendar(); + final Date currentDate = getValue(); + + // Only paint variables for the resolution and up, e.g. Resolution DAY + // paints DAY,MONTH,YEAR + for (Resolution res : Resolution + .getResolutionsHigherOrEqualTo(resolution)) { + int value = -1; + if (currentDate != null) { + value = calendar.get(res.getCalendarField()); + if (res == Resolution.MONTH) { + // Calendar month is zero based + value++; + } + } + target.addVariable(this, variableNameForResolution.get(res), value); + } + } + + @Override + protected boolean shouldHideErrors() { + return super.shouldHideErrors() && uiHasValidDateString; + } + + @Override + protected TextualDateFieldState getState() { + return (TextualDateFieldState) super.getState(); + } + + @Override + protected TextualDateFieldState getState(boolean markAsDirty) { + return (TextualDateFieldState) super.getState(markAsDirty); + } + + /** + * Sets the start range for this component. If the value is set before this + * date (taking the resolution into account), the component will not + * validate. If <code>startDate</code> is set to <code>null</code>, any + * value before <code>endDate</code> will be accepted by the range + * + * @param startDate + * - the allowed range's start date + */ + public void setRangeStart(Date startDate) { + if (startDate != null && getState().rangeEnd != null + && startDate.after(getState().rangeEnd)) { + throw new IllegalStateException( + "startDate cannot be later than endDate"); + } + + // Create a defensive copy against issues when using java.sql.Date (and + // also against mutable Date). + getState().rangeStart = startDate != null + ? new Date(startDate.getTime()) : null; + updateRangeValidator(); + } + + /** + * Sets the current error message if the range validation fails. + * + * @param dateOutOfRangeMessage + * - Localizable message which is shown when value (the date) is + * set outside allowed range + */ + public void setDateOutOfRangeMessage(String dateOutOfRangeMessage) { + this.dateOutOfRangeMessage = dateOutOfRangeMessage; + updateRangeValidator(); + } + + /** + * Gets the end range for a certain resolution. The range is inclusive, so + * if rangeEnd is set to zero milliseconds past year n and resolution is set + * to YEAR, any date in year n will be accepted. Resolutions lower than DAY + * will be interpreted on a DAY level. That is, everything below DATE is + * cleared + * + * @param forResolution + * - the range conforms to the resolution + * @return + */ + private Date getRangeEnd(Resolution forResolution) { + // We need to set the correct resolution for the dates, + // otherwise the range validator will complain + + Date rangeEnd = getState(false).rangeEnd; + if (rangeEnd == null) { + return null; + } + + Calendar endCal = Calendar.getInstance(); + endCal.setTime(rangeEnd); + + if (forResolution == Resolution.YEAR) { + // Adding one year (minresolution) and clearing the rest. + endCal.set(endCal.get(Calendar.YEAR) + 1, 0, 1, 0, 0, 0); + } else if (forResolution == Resolution.MONTH) { + // Adding one month (minresolution) and clearing the rest. + endCal.set(endCal.get(Calendar.YEAR), + endCal.get(Calendar.MONTH) + 1, 1, 0, 0, 0); + } else { + endCal.set(endCal.get(Calendar.YEAR), endCal.get(Calendar.MONTH), + endCal.get(Calendar.DATE) + 1, 0, 0, 0); + } + // removing one millisecond will now get the endDate to return to + // current resolution's set time span (year or month) + endCal.set(Calendar.MILLISECOND, -1); + return endCal.getTime(); + } + + /** + * Gets the start range for a certain resolution. The range is inclusive, so + * if <code>rangeStart</code> is set to one millisecond before year n and + * resolution is set to YEAR, any date in year n - 1 will be accepted. + * Lowest supported resolution is DAY. + * + * @param forResolution + * - the range conforms to the resolution + * @return + */ + private Date getRangeStart(Resolution forResolution) { + if (getState(false).rangeStart == null) { + return null; + } + Calendar startCal = Calendar.getInstance(); + startCal.setTime(getState(false).rangeStart); + + if (forResolution == Resolution.YEAR) { + startCal.set(startCal.get(Calendar.YEAR), 0, 1, 0, 0, 0); + } else if (forResolution == Resolution.MONTH) { + startCal.set(startCal.get(Calendar.YEAR), + startCal.get(Calendar.MONTH), 1, 0, 0, 0); + } else { + startCal.set(startCal.get(Calendar.YEAR), + startCal.get(Calendar.MONTH), startCal.get(Calendar.DATE), + 0, 0, 0); + } + + startCal.set(Calendar.MILLISECOND, 0); + return startCal.getTime(); + } + + private void updateRangeValidator() { + if (currentRangeValidator != null) { + removeValidator(currentRangeValidator); + currentRangeValidator = null; + } + if (getRangeStart() != null || getRangeEnd() != null) { + currentRangeValidator = new LegacyDateRangeValidator( + dateOutOfRangeMessage, getRangeStart(resolution), + getRangeEnd(resolution), null); + addValidator(currentRangeValidator); + } + } + + /** + * Sets the end range for this component. If the value is set after this + * date (taking the resolution into account), the component will not + * validate. If <code>endDate</code> is set to <code>null</code>, any value + * after <code>startDate</code> will be accepted by the range. + * + * @param endDate + * - the allowed range's end date (inclusive, based on the + * current resolution) + */ + public void setRangeEnd(Date endDate) { + if (endDate != null && getState().rangeStart != null + && getState().rangeStart.after(endDate)) { + throw new IllegalStateException( + "endDate cannot be earlier than startDate"); + } + + // Create a defensive copy against issues when using java.sql.Date (and + // also against mutable Date). + getState().rangeEnd = endDate != null ? new Date(endDate.getTime()) + : null; + updateRangeValidator(); + } + + /** + * Returns the precise rangeStart used. + * + * @param startDate + * + */ + public Date getRangeStart() { + return getState(false).rangeStart; + } + + /** + * Returns the precise rangeEnd used. + * + * @param startDate + */ + public Date getRangeEnd() { + return getState(false).rangeEnd; + } + + /* + * Invoked when a variable of the component changes. Don't add a JavaDoc + * comment here, we use the default documentation from implemented + * interface. + */ + @Override + public void changeVariables(Object source, Map<String, Object> variables) { + + if (!isReadOnly() && (variables.containsKey("year") + || variables.containsKey("month") + || variables.containsKey("day") || variables.containsKey("hour") + || variables.containsKey("min") || variables.containsKey("sec") + || variables.containsKey("msec") + || variables.containsKey("dateString"))) { + + // Old and new dates + final Date oldDate = getValue(); + Date newDate = null; + + // this enables analyzing invalid input on the server + final String newDateString = (String) variables.get("dateString"); + dateString = newDateString; + + // Gets the new date in parts + boolean hasChanges = false; + Map<Resolution, Integer> calendarFieldChanges = new HashMap<>(); + + for (Resolution r : Resolution + .getResolutionsHigherOrEqualTo(resolution)) { + // Only handle what the client is allowed to send. The same + // resolutions that are painted + String variableName = variableNameForResolution.get(r); + + if (variables.containsKey(variableName)) { + Integer value = (Integer) variables.get(variableName); + if (r == Resolution.MONTH) { + // Calendar MONTH is zero based + value--; + } + if (value >= 0) { + hasChanges = true; + calendarFieldChanges.put(r, value); + } + } + } + + // If no new variable values were received, use the previous value + if (!hasChanges) { + newDate = null; + } else { + // Clone the calendar for date operation + final Calendar cal = getCalendar(); + + // Update the value based on the received info + // Must set in this order to avoid invalid dates (or wrong + // dates if lenient is true) in calendar + for (int r = Resolution.YEAR.ordinal(); r >= 0; r--) { + Resolution res = Resolution.values()[r]; + if (calendarFieldChanges.containsKey(res)) { + + // Field resolution should be included. Others are + // skipped so that client can not make unexpected + // changes (e.g. day change even though resolution is + // year). + Integer newValue = calendarFieldChanges.get(res); + cal.set(res.getCalendarField(), newValue); + } + } + newDate = cal.getTime(); + } + + if (newDate == null && dateString != null + && !"".equals(dateString)) { + try { + Date parsedDate = handleUnparsableDateString(dateString); + setValue(parsedDate, true); + + /* + * Ensure the value is sent to the client if the value is + * set to the same as the previous (#4304). Does not repaint + * if handleUnparsableDateString throws an exception. In + * this case the invalid text remains in the DateField. + */ + markAsDirty(); + } catch (LegacyConverter.ConversionException e) { + + /* + * Datefield now contains some text that could't be parsed + * into date. ValueChangeEvent is fired after the value is + * changed and the flags are set + */ + if (oldDate != null) { + /* + * Set the logic value to null without firing the + * ValueChangeEvent + */ + preventValueChangeEvent = true; + try { + setValue(null); + } finally { + preventValueChangeEvent = false; + } + + /* + * Reset the dateString (overridden to null by setValue) + */ + dateString = newDateString; + } + + /* + * Saves the localized message of parse error. This can be + * overridden in handleUnparsableDateString. The message + * will later be used to show a validation error. + */ + currentParseErrorMessage = e.getLocalizedMessage(); + + /* + * The value of the DateField should be null if an invalid + * value has been given. Not using setValue() since we do + * not want to cause the client side value to change. + */ + uiHasValidDateString = false; + + /* + * If value was changed fire the ValueChangeEvent + */ + if (oldDate != null) { + fireValueChange(false); + } + + markAsDirty(); + } + } else if (newDate != oldDate + && (newDate == null || !newDate.equals(oldDate))) { + setValue(newDate, true); // Don't require a repaint, client + // updates itself + } else if (!uiHasValidDateString) { // oldDate == + // newDate == null + // Empty value set, previously contained unparsable date string, + // clear related internal fields + setValue(null); + } + } + + if (variables.containsKey(FocusEvent.EVENT_ID)) { + fireEvent(new FocusEvent(this)); + } + + if (variables.containsKey(BlurEvent.EVENT_ID)) { + fireEvent(new BlurEvent(this)); + } + } + + /* + * only fires the event if preventValueChangeEvent flag is false + */ + @Override + protected void fireValueChange(boolean repaintIsNotNeeded) { + if (!preventValueChangeEvent) { + super.fireValueChange(repaintIsNotNeeded); + } + } + + /** + * This method is called to handle a non-empty date string from the client + * if the client could not parse it as a Date. + * + * By default, a Converter.ConversionException is thrown, and the current + * value is not modified. + * + * This can be overridden to handle conversions, to return null (equivalent + * to empty input), to throw an exception or to fire an event. + * + * @param dateString + * @return parsed Date + * @throws Converter.ConversionException + * to keep the old value and indicate an error + */ + protected Date handleUnparsableDateString(String dateString) + throws LegacyConverter.ConversionException { + currentParseErrorMessage = null; + throw new LegacyConverter.ConversionException(getParseErrorMessage()); + } + + /* Property features */ + + /* + * Gets the edited property's type. Don't add a JavaDoc comment here, we use + * the default documentation from implemented interface. + */ + @Override + public Class<Date> getType() { + return Date.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object, boolean) + */ + @Override + protected void setValue(Date newValue, boolean repaintIsNotNeeded) + throws Property.ReadOnlyException { + + /* + * First handle special case when the client side component have a date + * string but value is null (e.g. unparsable date string typed in by the + * user). No value changes should happen, but we need to do some + * internal housekeeping. + */ + if (newValue == null && !uiHasValidDateString) { + /* + * Side-effects of setInternalValue clears possible previous strings + * and flags about invalid input. + */ + setInternalValue(null); + markAsDirty(); + return; + } + + super.setValue(newValue, repaintIsNotNeeded); + } + + @Override + protected void setInternalValue(Date newValue) { + // Also set the internal dateString + if (newValue != null) { + dateString = newValue.toString(); + } else { + dateString = null; + } + + if (!uiHasValidDateString) { + // clear component error and parsing flag + setComponentError(null); + uiHasValidDateString = true; + currentParseErrorMessage = null; + } + + super.setInternalValue(newValue); + } + + /** + * Gets the resolution. + * + * @return int + */ + public Resolution getResolution() { + return resolution; + } + + /** + * Sets the resolution of the DateField. + * + * The default resolution is {@link Resolution#DAY} since Vaadin 7.0. + * + * @param resolution + * the resolution to set. + */ + public void setResolution(Resolution resolution) { + this.resolution = resolution; + updateRangeValidator(); + markAsDirty(); + } + + /** + * Returns new instance calendar used in Date conversions. + * + * Returns new clone of the calendar object initialized using the the + * current date (if available) + * + * If this is no calendar is assigned the <code>Calendar.getInstance</code> + * is used. + * + * @return the Calendar. + * @see #setCalendar(Calendar) + */ + private Calendar getCalendar() { + + // Makes sure we have an calendar instance + if (calendar == null) { + calendar = Calendar.getInstance(); + // Start by a zeroed calendar to avoid having values for lower + // resolution variables e.g. time when resolution is day + int min, field; + for (Resolution r : Resolution + .getResolutionsLowerThan(resolution)) { + field = r.getCalendarField(); + min = calendar.getActualMinimum(field); + calendar.set(field, min); + } + calendar.set(Calendar.MILLISECOND, 0); + } + + // Clone the instance + final Calendar newCal = (Calendar) calendar.clone(); + + final TimeZone currentTimeZone = getTimeZone(); + if (currentTimeZone != null) { + newCal.setTimeZone(currentTimeZone); + } + + final Date currentDate = getValue(); + if (currentDate != null) { + newCal.setTime(currentDate); + } + return newCal; + } + + /** + * Sets formatting used by some component implementations. See + * {@link SimpleDateFormat} for format details. + * + * By default it is encouraged to used default formatting defined by Locale, + * but due some JVM bugs it is sometimes necessary to use this method to + * override formatting. See Vaadin issue #2200. + * + * @param dateFormat + * the dateFormat to set + * + * @see com.vaadin.ui.AbstractComponent#setLocale(Locale)) + */ + public void setDateFormat(String dateFormat) { + this.dateFormat = dateFormat; + markAsDirty(); + } + + /** + * Returns a format string used to format date value on client side or null + * if default formatting from {@link Component#getLocale()} is used. + * + * @return the dateFormat + */ + public String getDateFormat() { + return dateFormat; + } + + /** + * Specifies whether or not date/time interpretation in component is to be + * lenient. + * + * @see Calendar#setLenient(boolean) + * @see #isLenient() + * + * @param lenient + * true if the lenient mode is to be turned on; false if it is to + * be turned off. + */ + public void setLenient(boolean lenient) { + this.lenient = lenient; + markAsDirty(); + } + + /** + * Returns whether date/time interpretation is to be lenient. + * + * @see #setLenient(boolean) + * + * @return true if the interpretation mode of this calendar is lenient; + * false otherwise. + */ + public boolean isLenient() { + return lenient; + } + + @Override + public void addFocusListener(FocusListener listener) { + addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, + FocusListener.focusMethod); + } + + @Override + public void removeFocusListener(FocusListener listener) { + removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); + } + + @Override + public void addBlurListener(BlurListener listener) { + addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, + BlurListener.blurMethod); + } + + @Override + public void removeBlurListener(BlurListener listener) { + removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); + } + + /** + * Checks whether ISO 8601 week numbers are shown in the date selector. + * + * @return true if week numbers are shown, false otherwise. + */ + public boolean isShowISOWeekNumbers() { + return showISOWeekNumbers; + } + + /** + * Sets the visibility of ISO 8601 week numbers in the date selector. ISO + * 8601 defines that a week always starts with a Monday so the week numbers + * are only shown if this is the case. + * + * @param showWeekNumbers + * true if week numbers should be shown, false otherwise. + */ + public void setShowISOWeekNumbers(boolean showWeekNumbers) { + showISOWeekNumbers = showWeekNumbers; + markAsDirty(); + } + + /** + * Validates the current value against registered validators if the field is + * not empty. Note that DateField is considered empty (value == null) and + * invalid if it contains text typed in by the user that couldn't be parsed + * into a Date value. + * + * @see com.vaadin.v7.ui.LegacyAbstractField#validate() + */ + @Override + public void validate() throws InvalidValueException { + /* + * To work properly in form we must throw exception if there is + * currently a parsing error in the datefield. Parsing error is kind of + * an internal validator. + */ + if (!uiHasValidDateString) { + throw new UnparsableDateString(currentParseErrorMessage); + } + super.validate(); + } + + /** + * Return the error message that is shown if the user inputted value can't + * be parsed into a Date object. If + * {@link #handleUnparsableDateString(String)} is overridden and it throws a + * custom exception, the message returned by + * {@link Exception#getLocalizedMessage()} will be used instead of the value + * returned by this method. + * + * @see #setParseErrorMessage(String) + * + * @return the error message that the DateField uses when it can't parse the + * textual input from user to a Date object + */ + public String getParseErrorMessage() { + return defaultParseErrorMessage; + } + + /** + * Sets the default error message used if the DateField cannot parse the + * text input by user to a Date field. Note that if the + * {@link #handleUnparsableDateString(String)} method is overridden, the + * localized message from its exception is used. + * + * @see #getParseErrorMessage() + * @see #handleUnparsableDateString(String) + * @param parsingErrorMessage + */ + public void setParseErrorMessage(String parsingErrorMessage) { + defaultParseErrorMessage = parsingErrorMessage; + } + + /** + * Sets the time zone used by this date field. The time zone is used to + * convert the absolute time in a Date object to a logical time displayed in + * the selector and to convert the select time back to a Date object. + * + * If no time zone has been set, the current default time zone returned by + * {@code TimeZone.getDefault()} is used. + * + * @see #getTimeZone() + * @param timeZone + * the time zone to use for time calculations. + */ + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + markAsDirty(); + } + + /** + * Gets the time zone used by this field. The time zone is used to convert + * the absolute time in a Date object to a logical time displayed in the + * selector and to convert the select time back to a Date object. + * + * If {@code null} is returned, the current default time zone returned by + * {@code TimeZone.getDefault()} is used. + * + * @return the current time zone + */ + public TimeZone getTimeZone() { + return timeZone; + } + + public static class UnparsableDateString + extends Validator.InvalidValueException { + + public UnparsableDateString(String message) { + super(message); + } + + } + + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + if (design.hasAttr("value") && !design.attr("value").isEmpty()) { + Date date = DesignAttributeHandler.getFormatter() + .parse(design.attr("value"), Date.class); + // formatting will return null if it cannot parse the string + if (date == null) { + Logger.getLogger(LegacyDateField.class.getName()).info( + "cannot parse " + design.attr("value") + " as date"); + } + this.setValue(date, false, true); + } + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + if (getValue() != null) { + design.attr("value", + DesignAttributeHandler.getFormatter().format(getValue())); + } + } + + /** + * Returns current date-out-of-range error message. + * + * @see #setDateOutOfRangeMessage(String) + * @since 7.4 + * @return Current error message for dates out of range. + */ + public String getDateOutOfRangeMessage() { + return dateOutOfRangeMessage; + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyInlineDateField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyInlineDateField.java new file mode 100644 index 0000000000..4e1ad7e997 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyInlineDateField.java @@ -0,0 +1,57 @@ +/* + * 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.v7.ui; + +import java.util.Date; + +import com.vaadin.data.Property; + +/** + * <p> + * A date entry component, which displays the actual date selector inline. + * + * </p> + * + * @see LegacyDateField + * @see LegacyPopupDateField + * @author Vaadin Ltd. + * @since 5.0 + */ +public class LegacyInlineDateField extends LegacyDateField { + + public LegacyInlineDateField() { + super(); + } + + public LegacyInlineDateField(Property dataSource) + throws IllegalArgumentException { + super(dataSource); + } + + public LegacyInlineDateField(String caption, Date value) { + super(caption, value); + } + + public LegacyInlineDateField(String caption, Property dataSource) { + super(caption, dataSource); + } + + public LegacyInlineDateField(String caption) { + super(caption); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyPopupDateField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyPopupDateField.java new file mode 100644 index 0000000000..c2470daf26 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/LegacyPopupDateField.java @@ -0,0 +1,147 @@ +/* + * 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.v7.ui; + +import java.util.Date; + +import com.vaadin.data.Property; +import com.vaadin.server.PaintException; +import com.vaadin.server.PaintTarget; +import com.vaadin.shared.ui.datefield.PopupDateFieldState; + +/** + * <p> + * A date entry component, which displays the actual date selector as a popup. + * + * </p> + * + * @see LegacyDateField + * @see LegacyInlineDateField + * @author Vaadin Ltd. + * @since 5.0 + */ +public class LegacyPopupDateField extends LegacyDateField { + + private String inputPrompt = null; + + public LegacyPopupDateField() { + super(); + } + + public LegacyPopupDateField(Property dataSource) + throws IllegalArgumentException { + super(dataSource); + } + + public LegacyPopupDateField(String caption, Date value) { + super(caption, value); + } + + public LegacyPopupDateField(String caption, Property dataSource) { + super(caption, dataSource); + } + + public LegacyPopupDateField(String caption) { + super(caption); + } + + @Override + public void paintContent(PaintTarget target) throws PaintException { + super.paintContent(target); + + if (inputPrompt != null) { + target.addAttribute("prompt", inputPrompt); + } + } + + /** + * Gets the current input prompt. + * + * @see #setInputPrompt(String) + * @return the current input prompt, or null if not enabled + */ + public String getInputPrompt() { + return inputPrompt; + } + + /** + * Sets the input prompt - a textual prompt that is displayed when the field + * would otherwise be empty, to prompt the user for input. + * + * @param inputPrompt + */ + public void setInputPrompt(String inputPrompt) { + this.inputPrompt = inputPrompt; + markAsDirty(); + } + + @Override + protected PopupDateFieldState getState() { + return (PopupDateFieldState) super.getState(); + } + + @Override + protected PopupDateFieldState getState(boolean markAsDirty) { + return (PopupDateFieldState) super.getState(markAsDirty); + } + + /** + * Checks whether the text field is enabled (default) or not. + * + * @see PopupDateField#setTextFieldEnabled(boolean); + * + * @return <b>true</b> if the text field is enabled, <b>false</b> otherwise. + */ + public boolean isTextFieldEnabled() { + return getState(false).textFieldEnabled; + } + + /** + * Enables or disables the text field. By default the text field is enabled. + * Disabling it causes only the button for date selection to be active, thus + * preventing the user from entering invalid dates. + * + * See {@link http://dev.vaadin.com/ticket/6790}. + * + * @param state + * <b>true</b> to enable text field, <b>false</b> to disable it. + */ + public void setTextFieldEnabled(boolean state) { + getState().textFieldEnabled = state; + } + + /** + * Set a description that explains the usage of the Widget for users of + * assistive devices. + * + * @param description + * String with the description + */ + public void setAssistiveText(String description) { + getState().descriptionForAssistiveDevices = description; + } + + /** + * Get the description that explains the usage of the Widget for users of + * assistive devices. + * + * @return String with the description + */ + public String getAssistiveText() { + return getState(false).descriptionForAssistiveDevices; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java new file mode 100644 index 0000000000..3fe6d1f6ff --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/BigDecimalRangeValidatorTest.java @@ -0,0 +1,60 @@ +package com.vaadin.tests.data.validator; + +import java.math.BigDecimal; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyBigDecimalRangeValidator; + +public class BigDecimalRangeValidatorTest { + + private LegacyBigDecimalRangeValidator cleanValidator = new LegacyBigDecimalRangeValidator( + "no values", null, null); + private LegacyBigDecimalRangeValidator minValidator = new LegacyBigDecimalRangeValidator( + "no values", new BigDecimal(10.1), null); + private LegacyBigDecimalRangeValidator maxValidator = new LegacyBigDecimalRangeValidator( + "no values", null, new BigDecimal(100.1)); + private LegacyBigDecimalRangeValidator minMaxValidator = new LegacyBigDecimalRangeValidator( + "no values", new BigDecimal(10.5), new BigDecimal(100.5)); + + @Test + public void testNullValue() { + Assert.assertTrue("Didn't accept null", cleanValidator.isValid(null)); + Assert.assertTrue("Didn't accept null", minValidator.isValid(null)); + Assert.assertTrue("Didn't accept null", maxValidator.isValid(null)); + Assert.assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + Assert.assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(new BigDecimal(-15.0))); + Assert.assertTrue("Didn't accept valid value", + minValidator.isValid(new BigDecimal(10.1))); + Assert.assertFalse("Accepted too small value", + minValidator.isValid(new BigDecimal(10.0))); + } + + @Test + public void testMaxValue() { + Assert.assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(new BigDecimal(1120.0))); + Assert.assertTrue("Didn't accept valid value", + maxValidator.isValid(new BigDecimal(15.0))); + Assert.assertFalse("Accepted too large value", + maxValidator.isValid(new BigDecimal(100.6))); + } + + @Test + public void testMinMaxValue() { + Assert.assertTrue("Didn't accept valid value", + minMaxValidator.isValid(new BigDecimal(10.5))); + Assert.assertTrue("Didn't accept valid value", + minMaxValidator.isValid(new BigDecimal(100.5))); + Assert.assertFalse("Accepted too small value", + minMaxValidator.isValid(new BigDecimal(10.4))); + Assert.assertFalse("Accepted too large value", + minMaxValidator.isValid(new BigDecimal(100.6))); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java new file mode 100644 index 0000000000..c54e868e64 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/BigIntegerRangeValidatorTest.java @@ -0,0 +1,60 @@ +package com.vaadin.tests.data.validator; + +import java.math.BigInteger; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyBigIntegerRangeValidator; + +public class BigIntegerRangeValidatorTest { + + private LegacyBigIntegerRangeValidator cleanValidator = new LegacyBigIntegerRangeValidator( + "no values", null, null); + private LegacyBigIntegerRangeValidator minValidator = new LegacyBigIntegerRangeValidator( + "no values", BigInteger.valueOf(10), null); + private LegacyBigIntegerRangeValidator maxValidator = new LegacyBigIntegerRangeValidator( + "no values", null, BigInteger.valueOf(100)); + private LegacyBigIntegerRangeValidator minMaxValidator = new LegacyBigIntegerRangeValidator( + "no values", BigInteger.valueOf(10), BigInteger.valueOf(100)); + + @Test + public void testNullValue() { + Assert.assertTrue("Didn't accept null", cleanValidator.isValid(null)); + Assert.assertTrue("Didn't accept null", minValidator.isValid(null)); + Assert.assertTrue("Didn't accept null", maxValidator.isValid(null)); + Assert.assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + Assert.assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(BigInteger.valueOf(-15))); + Assert.assertTrue("Didn't accept valid value", + minValidator.isValid(BigInteger.valueOf(15))); + Assert.assertFalse("Accepted too small value", + minValidator.isValid(BigInteger.valueOf(9))); + } + + @Test + public void testMaxValue() { + Assert.assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(BigInteger.valueOf(1120))); + Assert.assertTrue("Didn't accept valid value", + maxValidator.isValid(BigInteger.valueOf(15))); + Assert.assertFalse("Accepted too large value", + maxValidator.isValid(BigInteger.valueOf(120))); + } + + @Test + public void testMinMaxValue() { + Assert.assertTrue("Didn't accept valid value", + minMaxValidator.isValid(BigInteger.valueOf(15))); + Assert.assertTrue("Didn't accept valid value", + minMaxValidator.isValid(BigInteger.valueOf(99))); + Assert.assertFalse("Accepted too small value", + minMaxValidator.isValid(BigInteger.valueOf(9))); + Assert.assertFalse("Accepted too large value", + minMaxValidator.isValid(BigInteger.valueOf(110))); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java new file mode 100644 index 0000000000..fa6dd8f098 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/ByteRangeValidatorTest.java @@ -0,0 +1,59 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyByteRangeValidator; + +public class ByteRangeValidatorTest { + + private LegacyByteRangeValidator cleanValidator = new LegacyByteRangeValidator( + "no values", null, null); + private LegacyByteRangeValidator minValidator = new LegacyByteRangeValidator( + "no values", (byte) 10, null); + private LegacyByteRangeValidator maxValidator = new LegacyByteRangeValidator( + "no values", null, (byte) 100); + private LegacyByteRangeValidator minMaxValidator = new LegacyByteRangeValidator( + "no values", (byte) 10, (byte) 100); + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid((byte) -15)); + assertTrue("Didn't accept valid value", + minValidator.isValid((byte) 15)); + assertFalse("Accepted too small value", minValidator.isValid((byte) 9)); + } + + @Test + public void testMaxValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid((byte) 112)); + assertTrue("Didn't accept valid value", + maxValidator.isValid((byte) 15)); + assertFalse("Accepted too large value", + maxValidator.isValid((byte) 120)); + } + + @Test + public void testMinMaxValue() { + assertTrue("Didn't accept valid value", + minMaxValidator.isValid((byte) 15)); + assertTrue("Didn't accept valid value", + minMaxValidator.isValid((byte) 99)); + assertFalse("Accepted too small value", + minMaxValidator.isValid((byte) 9)); + assertFalse("Accepted too large value", + minMaxValidator.isValid((byte) 110)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java new file mode 100644 index 0000000000..2975331e8a --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/CompositeValidatorTest.java @@ -0,0 +1,124 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.v7.data.Validator; +import com.vaadin.v7.data.validator.LegacyCompositeValidator; +import com.vaadin.v7.data.validator.LegacyCompositeValidator.CombinationMode; +import com.vaadin.v7.data.validator.LegacyEmailValidator; +import com.vaadin.v7.data.validator.LegacyRegexpValidator; + +public class CompositeValidatorTest { + + LegacyCompositeValidator and = new LegacyCompositeValidator( + CombinationMode.AND, "One validator not valid"); + LegacyCompositeValidator or = new LegacyCompositeValidator( + CombinationMode.OR, "No validators are valid"); + LegacyEmailValidator email = new LegacyEmailValidator("Faulty email"); + LegacyRegexpValidator regex = new LegacyRegexpValidator("@mail.com", false, + "Partial match validator error"); + + @Before + public void setUp() { + and.addValidator(email); + and.addValidator(regex); + + or.addValidator(email); + or.addValidator(regex); + } + + @Test + public void testCorrectValue() { + String testString = "user@mail.com"; + assertTrue(email.isValid(testString)); + assertTrue(regex.isValid(testString)); + try { + // notNull.validate(null); + // fail("expected null to fail with an exception"); + and.validate(testString); + } catch (Validator.InvalidValueException ex) { + // assertEquals("Null not accepted", ex.getMessage()); + fail("And validator should be valid"); + } + try { + or.validate(testString); + } catch (Validator.InvalidValueException ex) { + // assertEquals("Null not accepted", ex.getMessage()); + fail("And validator should be valid"); + } + } + + @Test + public void testCorrectRegex() { + + String testString = "@mail.com"; + assertFalse(testString + " should not validate", + email.isValid(testString)); + assertTrue(testString + "should validate", regex.isValid(testString)); + try { + // notNull.validate(null); + and.validate(testString); + fail("expected and to fail with an exception"); + } catch (Validator.InvalidValueException ex) { + assertEquals("Faulty email", ex.getMessage()); + // fail("And validator should be valid"); + } + try { + or.validate(testString); + } catch (Validator.InvalidValueException ex) { + // assertEquals("Null not accepted", ex.getMessage()); + fail("Or validator should be valid"); + } + } + + @Test + public void testCorrectEmail() { + + String testString = "user@gmail.com"; + + assertTrue(testString + " should validate", email.isValid(testString)); + assertFalse(testString + " should not validate", + regex.isValid(testString)); + try { + and.validate(testString); + fail("expected and to fail with an exception"); + } catch (Validator.InvalidValueException ex) { + assertEquals("Partial match validator error", ex.getMessage()); + } + try { + or.validate(testString); + } catch (Validator.InvalidValueException ex) { + fail("Or validator should be valid"); + } + } + + @Test + public void testBothFaulty() { + + String testString = "gmail.com"; + + assertFalse(testString + " should not validate", + email.isValid(testString)); + assertFalse(testString + " should not validate", + regex.isValid(testString)); + try { + and.validate(testString); + fail("expected and to fail with an exception"); + } catch (Validator.InvalidValueException ex) { + assertEquals("Faulty email", ex.getMessage()); + } + try { + or.validate(testString); + fail("expected or to fail with an exception"); + } catch (Validator.InvalidValueException ex) { + assertEquals("No validators are valid", ex.getMessage()); + } + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java new file mode 100644 index 0000000000..a0afc9c617 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/DateRangeValidatorTest.java @@ -0,0 +1,106 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.v7.data.validator.LegacyDateRangeValidator; + +public class DateRangeValidatorTest { + Calendar startDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"), + Locale.ENGLISH); + Calendar endDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"), + Locale.ENGLISH); + + private LegacyDateRangeValidator cleanValidator; + private LegacyDateRangeValidator minValidator; + private LegacyDateRangeValidator maxValidator; + private LegacyDateRangeValidator minMaxValidator; + + @Before + public void setUp() { + startDate.set(2000, Calendar.JANUARY, 1, 12, 0, 0); + endDate.set(2000, Calendar.FEBRUARY, 20, 12, 0, 0); + + cleanValidator = new LegacyDateRangeValidator( + "Given date outside range", null, null, Resolution.DAY); + minValidator = new LegacyDateRangeValidator( + "Given date before startDate", startDate.getTime(), null, + Resolution.DAY); + maxValidator = new LegacyDateRangeValidator("Given date after endDate", + null, endDate.getTime(), Resolution.DAY); + minMaxValidator = new LegacyDateRangeValidator( + "Given date outside range", startDate.getTime(), + endDate.getTime(), Resolution.DAY); + } + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"), + Locale.ENGLISH); + cal.setTime(startDate.getTime()); + cal.add(Calendar.SECOND, 1); + + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(cal.getTime())); + assertTrue("Didn't accept valid value", + minValidator.isValid(cal.getTime())); + + cal.add(Calendar.SECOND, -3); + + assertFalse("Accepted too small value", + minValidator.isValid(cal.getTime())); + } + + @Test + public void testMaxValue() { + Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"), + Locale.ENGLISH); + cal.setTime(endDate.getTime()); + cal.add(Calendar.SECOND, -1); + + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(cal.getTime())); + assertTrue("Didn't accept valid value", + maxValidator.isValid(cal.getTime())); + + cal.add(Calendar.SECOND, 2); + assertFalse("Accepted too large value", + maxValidator.isValid(cal.getTime())); + } + + @Test + public void testMinMaxValue() { + Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"), + Locale.ENGLISH); + cal.setTime(endDate.getTime()); + + assertTrue("Didn't accept valid value", + minMaxValidator.isValid(cal.getTime())); + cal.add(Calendar.SECOND, 1); + assertFalse("Accepted too large value", + minMaxValidator.isValid(cal.getTime())); + cal.setTime(startDate.getTime()); + assertTrue("Didn't accept valid value", + minMaxValidator.isValid(cal.getTime())); + cal.add(Calendar.SECOND, -1); + assertFalse("Accepted too small value", + minMaxValidator.isValid(cal.getTime())); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java new file mode 100644 index 0000000000..ec3a34bfa6 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/DoubleRangeValidatorTest.java @@ -0,0 +1,52 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyDoubleRangeValidator; + +public class DoubleRangeValidatorTest { + + private LegacyDoubleRangeValidator cleanValidator = new LegacyDoubleRangeValidator( + "no values", null, null); + private LegacyDoubleRangeValidator minValidator = new LegacyDoubleRangeValidator( + "no values", 10.1, null); + private LegacyDoubleRangeValidator maxValidator = new LegacyDoubleRangeValidator( + "no values", null, 100.1); + private LegacyDoubleRangeValidator minMaxValidator = new LegacyDoubleRangeValidator( + "no values", 10.5, 100.5); + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(-15.0)); + assertTrue("Didn't accept valid value", minValidator.isValid(10.1)); + assertFalse("Accepted too small value", minValidator.isValid(10.0)); + } + + @Test + public void testMaxValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(1120.0)); + assertTrue("Didn't accept valid value", maxValidator.isValid(15.0)); + assertFalse("Accepted too large value", maxValidator.isValid(100.6)); + } + + @Test + public void testMinMaxValue() { + assertTrue("Didn't accept valid value", minMaxValidator.isValid(10.5)); + assertTrue("Didn't accept valid value", minMaxValidator.isValid(100.5)); + assertFalse("Accepted too small value", minMaxValidator.isValid(10.4)); + assertFalse("Accepted too large value", minMaxValidator.isValid(100.6)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java new file mode 100644 index 0000000000..92eef3d4b8 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/EmailValidatorTest.java @@ -0,0 +1,31 @@ +package com.vaadin.tests.data.validator; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyEmailValidator; + +public class EmailValidatorTest { + + private LegacyEmailValidator validator = new LegacyEmailValidator("Error"); + + @Test + public void testEmailValidatorWithNull() { + Assert.assertTrue(validator.isValid(null)); + } + + @Test + public void testEmailValidatorWithEmptyString() { + Assert.assertTrue(validator.isValid("")); + } + + @Test + public void testEmailValidatorWithFaultyString() { + Assert.assertFalse(validator.isValid("not.an.email")); + } + + @Test + public void testEmailValidatorWithOkEmail() { + Assert.assertTrue(validator.isValid("my.name@email.com")); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java new file mode 100644 index 0000000000..36bd41864c --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/FloatRangeValidatorTest.java @@ -0,0 +1,54 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyFloatRangeValidator; + +public class FloatRangeValidatorTest { + + private LegacyFloatRangeValidator cleanValidator = new LegacyFloatRangeValidator( + "no values", null, null); + private LegacyFloatRangeValidator minValidator = new LegacyFloatRangeValidator( + "no values", 10.1f, null); + private LegacyFloatRangeValidator maxValidator = new LegacyFloatRangeValidator( + "no values", null, 100.1f); + private LegacyFloatRangeValidator minMaxValidator = new LegacyFloatRangeValidator( + "no values", 10.5f, 100.5f); + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(-15.0f)); + assertTrue("Didn't accept valid value", minValidator.isValid(10.1f)); + assertFalse("Accepted too small value", minValidator.isValid(10.0f)); + } + + @Test + public void testMaxValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(1120.0f)); + assertTrue("Didn't accept valid value", maxValidator.isValid(15.0f)); + assertFalse("Accepted too large value", maxValidator.isValid(100.6f)); + } + + @Test + public void testMinMaxValue() { + assertTrue("Didn't accept valid value", minMaxValidator.isValid(10.5f)); + assertTrue("Didn't accept valid value", + minMaxValidator.isValid(100.5f)); + assertFalse("Accepted too small value", minMaxValidator.isValid(10.4f)); + assertFalse("Accepted too large value", + minMaxValidator.isValid(100.6f)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java new file mode 100644 index 0000000000..595d5f4ab8 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/IntegerRangeValidatorTest.java @@ -0,0 +1,52 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyIntegerRangeValidator; + +public class IntegerRangeValidatorTest { + + private LegacyIntegerRangeValidator cleanValidator = new LegacyIntegerRangeValidator( + "no values", null, null); + private LegacyIntegerRangeValidator minValidator = new LegacyIntegerRangeValidator( + "no values", 10, null); + private LegacyIntegerRangeValidator maxValidator = new LegacyIntegerRangeValidator( + "no values", null, 100); + private LegacyIntegerRangeValidator minMaxValidator = new LegacyIntegerRangeValidator( + "no values", 10, 100); + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(-15)); + assertTrue("Didn't accept valid value", minValidator.isValid(15)); + assertFalse("Accepted too small value", minValidator.isValid(9)); + } + + @Test + public void testMaxValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(1120)); + assertTrue("Didn't accept valid value", maxValidator.isValid(15)); + assertFalse("Accepted too large value", maxValidator.isValid(120)); + } + + @Test + public void testMinMaxValue() { + assertTrue("Didn't accept valid value", minMaxValidator.isValid(15)); + assertTrue("Didn't accept valid value", minMaxValidator.isValid(99)); + assertFalse("Accepted too small value", minMaxValidator.isValid(9)); + assertFalse("Accepted too large value", minMaxValidator.isValid(110)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java new file mode 100644 index 0000000000..6ecd21984c --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/LongRangeValidatorTest.java @@ -0,0 +1,52 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyLongRangeValidator; + +public class LongRangeValidatorTest { + + private LegacyLongRangeValidator cleanValidator = new LegacyLongRangeValidator( + "no values", null, null); + private LegacyLongRangeValidator minValidator = new LegacyLongRangeValidator( + "no values", 10l, null); + private LegacyLongRangeValidator maxValidator = new LegacyLongRangeValidator( + "no values", null, 100l); + private LegacyLongRangeValidator minMaxValidator = new LegacyLongRangeValidator( + "no values", 10l, 100l); + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(-15l)); + assertTrue("Didn't accept valid value", minValidator.isValid(15l)); + assertFalse("Accepted too small value", minValidator.isValid(9l)); + } + + @Test + public void testMaxValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid(1120l)); + assertTrue("Didn't accept valid value", maxValidator.isValid(15l)); + assertFalse("Accepted too large value", maxValidator.isValid(120l)); + } + + @Test + public void testMinMaxValue() { + assertTrue("Didn't accept valid value", minMaxValidator.isValid(15l)); + assertTrue("Didn't accept valid value", minMaxValidator.isValid(99l)); + assertFalse("Accepted too small value", minMaxValidator.isValid(9l)); + assertFalse("Accepted too large value", minMaxValidator.isValid(110l)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java new file mode 100644 index 0000000000..6e43b30cdf --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/NullValidatorTest.java @@ -0,0 +1,47 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import com.vaadin.v7.data.Validator; +import com.vaadin.v7.data.validator.LegacyNullValidator; + +public class NullValidatorTest { + + LegacyNullValidator notNull = new LegacyNullValidator("Null not accepted", + false); + LegacyNullValidator onlyNull = new LegacyNullValidator("Only null accepted", + true); + + @Test + public void testNullValue() { + try { + notNull.validate(null); + fail("expected null to fail with an exception"); + } catch (Validator.InvalidValueException ex) { + assertEquals("Null not accepted", ex.getMessage()); + } + try { + onlyNull.validate(null); + } catch (Validator.InvalidValueException ex) { + fail("onlyNull should not throw exception for null"); + } + } + + @Test + public void testNonNullValue() { + try { + onlyNull.validate("Not a null value"); + fail("expected onlyNull validator to fail with an exception"); + } catch (Validator.InvalidValueException ex) { + assertEquals("Only null accepted", ex.getMessage()); + } + try { + notNull.validate("Not a null value"); + } catch (Validator.InvalidValueException ex) { + fail("notNull should not throw exception for \"Not a null value\""); + } + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java new file mode 100644 index 0000000000..1768999969 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/RegexpValidatorTest.java @@ -0,0 +1,53 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyRegexpValidator; + +public class RegexpValidatorTest { + + private LegacyRegexpValidator completeValidator = new LegacyRegexpValidator( + "pattern", true, "Complete match validator error"); + private LegacyRegexpValidator partialValidator = new LegacyRegexpValidator( + "pattern", false, "Partial match validator error"); + + @Test + public void testRegexpValidatorWithNull() { + assertTrue(completeValidator.isValid(null)); + assertTrue(partialValidator.isValid(null)); + } + + @Test + public void testRegexpValidatorWithEmptyString() { + assertTrue(completeValidator.isValid("")); + assertTrue(partialValidator.isValid("")); + } + + @Test + public void testCompleteRegexpValidatorWithFaultyString() { + assertFalse(completeValidator.isValid("mismatch")); + assertFalse(completeValidator.isValid("pattern2")); + assertFalse(completeValidator.isValid("1pattern")); + } + + @Test + public void testCompleteRegexpValidatorWithOkString() { + assertTrue(completeValidator.isValid("pattern")); + } + + @Test + public void testPartialRegexpValidatorWithFaultyString() { + assertFalse(partialValidator.isValid("mismatch")); + } + + @Test + public void testPartialRegexpValidatorWithOkString() { + assertTrue(partialValidator.isValid("pattern")); + assertTrue(partialValidator.isValid("1pattern")); + assertTrue(partialValidator.isValid("pattern2")); + assertTrue(partialValidator.isValid("1pattern2")); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java new file mode 100644 index 0000000000..41c3e67942 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/ShortRangeValidatorTest.java @@ -0,0 +1,60 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyShortRangeValidator; + +public class ShortRangeValidatorTest { + + private LegacyShortRangeValidator cleanValidator = new LegacyShortRangeValidator( + "no values", null, null); + private LegacyShortRangeValidator minValidator = new LegacyShortRangeValidator( + "no values", (short) 10, null); + private LegacyShortRangeValidator maxValidator = new LegacyShortRangeValidator( + "no values", null, (short) 100); + private LegacyShortRangeValidator minMaxValidator = new LegacyShortRangeValidator( + "no values", (short) 10, (short) 100); + + @Test + public void testNullValue() { + assertTrue("Didn't accept null", cleanValidator.isValid(null)); + assertTrue("Didn't accept null", minValidator.isValid(null)); + assertTrue("Didn't accept null", maxValidator.isValid(null)); + assertTrue("Didn't accept null", minMaxValidator.isValid(null)); + } + + @Test + public void testMinValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid((short) -15)); + assertTrue("Didn't accept valid value", + minValidator.isValid((short) 15)); + assertFalse("Accepted too small value", + minValidator.isValid((short) 9)); + } + + @Test + public void testMaxValue() { + assertTrue("Validator without ranges didn't accept value", + cleanValidator.isValid((short) 1120)); + assertTrue("Didn't accept valid value", + maxValidator.isValid((short) 15)); + assertFalse("Accepted too large value", + maxValidator.isValid((short) 120)); + } + + @Test + public void testMinMaxValue() { + assertTrue("Didn't accept valid value", + minMaxValidator.isValid((short) 15)); + assertTrue("Didn't accept valid value", + minMaxValidator.isValid((short) 99)); + assertFalse("Accepted too small value", + minMaxValidator.isValid((short) 9)); + assertFalse("Accepted too large value", + minMaxValidator.isValid((short) 110)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java new file mode 100644 index 0000000000..e24e8fcd5d --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/data/validator/StringLengthValidatorTest.java @@ -0,0 +1,77 @@ +package com.vaadin.tests.data.validator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyStringLengthValidator; + +public class StringLengthValidatorTest { + + private LegacyStringLengthValidator validator = new LegacyStringLengthValidator( + "Error"); + private LegacyStringLengthValidator validatorNoNull = new LegacyStringLengthValidator( + "Error", 1, 5, false); + private LegacyStringLengthValidator validatorMinValue = new LegacyStringLengthValidator( + "Error", 5, null, true); + private LegacyStringLengthValidator validatorMaxValue = new LegacyStringLengthValidator( + "Error", null, 15, true); + + @Test + public void testValidatorWithNull() { + assertTrue("Didn't accept null", validator.isValid(null)); + assertTrue("Didn't accept null", validatorMinValue.isValid(null)); + } + + @Test + public void testValidatorNotAcceptingNull() { + assertFalse("Accepted null", validatorNoNull.isValid(null)); + } + + @Test + public void testEmptyString() { + assertTrue("Didn't accept empty String", validator.isValid("")); + assertTrue("Didn't accept empty String", validatorMaxValue.isValid("")); + assertFalse("Accepted empty string even though has lower bound of 1", + validatorNoNull.isValid("")); + assertFalse("Accepted empty string even though has lower bound of 5", + validatorMinValue.isValid("")); + } + + @Test + public void testTooLongString() { + assertFalse("Too long string was accepted", + validatorNoNull.isValid("This string is too long")); + assertFalse("Too long string was accepted", + validatorMaxValue.isValid("This string is too long")); + } + + @Test + public void testNoUpperBound() { + assertTrue("String not accepted even though no upper bound", + validatorMinValue.isValid( + "This is a really long string to test that no upper bound exists")); + } + + @Test + public void testNoLowerBound() { + assertTrue("Didn't accept short string", validatorMaxValue.isValid("")); + assertTrue("Didn't accept short string", + validatorMaxValue.isValid("1")); + } + + @Test + public void testStringLengthValidatorWithOkStringLength() { + assertTrue("Didn't accept string of correct length", + validatorNoNull.isValid("OK!")); + assertTrue("Didn't accept string of correct length", + validatorMaxValue.isValid("OK!")); + } + + @Test + public void testTooShortStringLength() { + assertFalse("Accepted a string that was too short.", + validatorMinValue.isValid("shot")); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java new file mode 100644 index 0000000000..5b4e8c7352 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldConverterTest.java @@ -0,0 +1,79 @@ +/* + * 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.tests.server.component.datefield; + +import java.util.Date; +import java.util.Locale; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Property; +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.v7.data.util.converter.LegacyConverter; +import com.vaadin.v7.ui.LegacyDateField; + +public class DateFieldConverterTest { + + private Property<Long> date; + private LegacyDateField datefield; + + @Before + public void setUp() { + date = new ObjectProperty<Long>(0L); + datefield = new LegacyDateField(); + datefield.setBuffered(false); + datefield.setConverter(new LegacyConverter<Date, Long>() { + + @Override + public Long convertToModel(Date value, + Class<? extends Long> targetType, Locale locale) + throws ConversionException { + return value.getTime(); + } + + @Override + public Date convertToPresentation(Long value, + Class<? extends Date> targetType, Locale locale) + throws ConversionException { + return new Date(value); + } + + @Override + public Class<Long> getModelType() { + return Long.class; + } + + @Override + public Class<Date> getPresentationType() { + return Date.class; + } + }); + datefield.setPropertyDataSource(date); + } + + /* + * See #12193. + */ + @Test + public void testResolution() { + datefield.setValue(new Date(110, 0, 1)); + datefield.setResolution(Resolution.MINUTE); + datefield.validate(); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/LegacyDateFieldDeclarativeTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/LegacyDateFieldDeclarativeTest.java new file mode 100644 index 0000000000..97e944a0a7 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/LegacyDateFieldDeclarativeTest.java @@ -0,0 +1,124 @@ +/* + * 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.tests.server.component.datefield; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.junit.Test; + +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.v7.ui.LegacyDateField; + +/** + * Tests the declarative support for implementations of {@link LegacyDateField}. + * + * @author Vaadin Ltd + * @since 7.4 + */ +public class LegacyDateFieldDeclarativeTest + extends DeclarativeTestBase<LegacyDateField> { + + private static final String TAG_NAME = "com_vaadin_v7_ui-legacy-date-field"; + + private String getYearResolutionDesign() { + return "<" + TAG_NAME + " resolution='year' value='2020'/>"; + } + + private LegacyDateField getYearResolutionExpected() { + LegacyDateField df = new LegacyDateField(); + df.setResolution(Resolution.YEAR); + df.setValue(new Date(2020 - 1900, 1 - 1, 1)); + return df; + } + + private String getTimezoneDesign() { + String timeZone = new SimpleDateFormat("Z").format(new Date()); + return String.format( + "<" + TAG_NAME + + " range-start=\"2014-05-05 00:00:00%1$s\" range-end=\"2014-06-05 00:00:00%1$s\" date-out-of-range-message=\"Please select a sensible date\" date-format=\"yyyy-MM-dd\" lenient show-iso-week-numbers parse-error-message=\"You are doing it wrong\" time-zone=\"GMT+05:00\" value=\"2014-05-15 00:00:00%1$s\"/>", + timeZone); + } + + private LegacyDateField getTimezoneExpected() { + LegacyDateField df = new LegacyDateField(); + + df.setRangeStart(new Date(2014 - 1900, 5 - 1, 5)); + df.setRangeEnd(new Date(2014 - 1900, 6 - 1, 5)); + df.setDateOutOfRangeMessage("Please select a sensible date"); + df.setResolution(Resolution.DAY); + df.setDateFormat("yyyy-MM-dd"); + df.setLenient(true); + df.setShowISOWeekNumbers(true); + df.setParseErrorMessage("You are doing it wrong"); + df.setTimeZone(TimeZone.getTimeZone("GMT+5")); + df.setValue(new Date(2014 - 1900, 5 - 1, 15)); + + return df; + } + + @Test + public void readTimezone() { + testRead(getTimezoneDesign(), getTimezoneExpected()); + } + + @Test + public void writeTimezone() { + testWrite(getTimezoneDesign(), getTimezoneExpected()); + } + + @Test + public void readYearResolution() { + testRead(getYearResolutionDesign(), getYearResolutionExpected()); + } + + @Test + public void writeYearResolution() { + // Writing is always done in full resolution.. + String timeZone = new SimpleDateFormat("Z") + .format(new Date(2020 - 1900, 1 - 1, 1)); + testWrite( + getYearResolutionDesign().replace("2020", + "2020-01-01 00:00:00" + timeZone), + getYearResolutionExpected()); + } + + @Test + public void testReadOnlyValue() { + Date date = new Date(2020 - 1900, 1 - 1, 1); + String timeZone = new SimpleDateFormat("Z").format(date); + String design = "<" + TAG_NAME + + " readonly resolution='year' value='2020-01-01 00:00:00" + + timeZone + "'/>"; + LegacyDateField df = new LegacyDateField(); + df.setResolution(Resolution.YEAR); + df.setValue(date); + df.setReadOnly(true); + + testRead(design, df); + testWrite(design, df); + } + + @Override + public LegacyDateField testRead(String design, LegacyDateField expected) { + return super.testRead( + "<html><head><meta charset='UTF-8' name='package-mapping' content='com_vaadin_v7_ui:com.vaadin.v7.ui'></head> " + + design + "</html>", + expected); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/LegacyPopupDateFieldDeclarativeTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/LegacyPopupDateFieldDeclarativeTest.java new file mode 100644 index 0000000000..0777a0c782 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/datefield/LegacyPopupDateFieldDeclarativeTest.java @@ -0,0 +1,73 @@ +/* + * 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.tests.server.component.datefield; + +import java.util.Date; + +import org.junit.Test; + +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.v7.ui.LegacyPopupDateField; + +/** + * Tests the declarative support for implementations of + * {@link LegacyPopupDateField}. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class LegacyPopupDateFieldDeclarativeTest + extends DeclarativeTestBase<LegacyPopupDateField> { + + private static final String TAG_NAME = "com_vaadin_v7_ui-legacy-popup-date-field"; + + private String getBasicDesign() { + return "<" + TAG_NAME + + " assistive-text='at' text-field-enabled='false' show-iso-week-numbers resolution=\"MINUTE\" range-end=\"2019-01-15\" input-prompt=\"Pick a day\" value=\"2003-02-27 07:15\"></vaadin-popup-date-field>"; + } + + private LegacyPopupDateField getBasicExpected() { + LegacyPopupDateField pdf = new LegacyPopupDateField(); + pdf.setShowISOWeekNumbers(true); + pdf.setResolution(Resolution.MINUTE); + pdf.setRangeEnd(new Date(2019 - 1900, 1 - 1, 15)); + pdf.setInputPrompt("Pick a day"); + pdf.setValue(new Date(2003 - 1900, 2 - 1, 27, 7, 15)); + pdf.setTextFieldEnabled(false); + pdf.setAssistiveText("at"); + return pdf; + } + + @Test + public void readBasic() throws Exception { + testRead(getBasicDesign(), getBasicExpected()); + } + + @Test + public void writeBasic() throws Exception { + testRead(getBasicDesign(), getBasicExpected()); + } + + @Override + public LegacyPopupDateField testRead(String design, + LegacyPopupDateField expected) { + return super.testRead( + "<html><head><meta charset='UTF-8' name='package-mapping' content='com_vaadin_v7_ui:com.vaadin.v7.ui'></head> " + + design + "</html>", + expected); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java new file mode 100644 index 0000000000..caea12d024 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidatorTest.java @@ -0,0 +1,49 @@ +package com.vaadin.tests.server.component.textfield; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.tests.data.converter.ConverterFactoryTest.ConvertTo42; +import com.vaadin.v7.data.validator.LegacyRangeValidator; +import com.vaadin.v7.ui.LegacyTextField; + +public class TextFieldWithConverterAndValidatorTest { + + private LegacyTextField field; + private ObjectProperty<Integer> property; + + @Before + public void setUp() { + field = new LegacyTextField(); + field.setInvalidAllowed(false); + } + + @Test + public void testConvert42AndValidator() { + property = new ObjectProperty<Integer>(123); + field.setConverter(new ConvertTo42()); + field.setPropertyDataSource(property); + + field.addValidator(new LegacyRangeValidator<Integer>("Incorrect value", + Integer.class, 42, 42)); + + // succeeds + field.setValue("a"); + // succeeds + field.setValue("42"); + // succeeds - no validation + property.setValue(42); + + // nulls + + // succeeds - validate() converts field value back to property type + // before validation + property.setValue(null); + field.validate(); + // succeeds + field.setValue(null); + } + + // TODO test converter changing value to null with validator +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java new file mode 100644 index 0000000000..633269a0ab --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatterTest.java @@ -0,0 +1,111 @@ +package com.vaadin.tests.server.component.textfield; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.Property; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.data.util.PropertyFormatter; +import com.vaadin.v7.ui.LegacyTextField; + +public class TextFieldWithPropertyFormatterTest { + + private static final String INPUT_VALUE = "foo"; + private static final String PARSED_VALUE = "BAR"; + private static final String FORMATTED_VALUE = "FOOBAR"; + private static final String ORIGINAL_VALUE = "Original"; + private LegacyTextField field; + private PropertyFormatter<String> formatter; + private ObjectProperty<String> property; + private ValueChangeListener listener; + private int listenerCalled; + private int repainted; + + @Before + public void setUp() { + + field = new LegacyTextField() { + @Override + public void markAsDirty() { + repainted++; + super.markAsDirty(); + } + }; + + formatter = new PropertyFormatter<String>() { + + @Override + public String parse(String formattedValue) throws Exception { + assertEquals(INPUT_VALUE, formattedValue); + return PARSED_VALUE; + } + + @Override + public String format(String value) { + return FORMATTED_VALUE; + } + }; + + property = new ObjectProperty<String>(ORIGINAL_VALUE); + + formatter.setPropertyDataSource(property); + field.setPropertyDataSource(formatter); + + listener = new Property.ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + listenerCalled++; + assertEquals(1, listenerCalled); + assertEquals(FORMATTED_VALUE, event.getProperty().getValue()); + } + }; + + field.addListener(listener); + listenerCalled = 0; + repainted = 0; + } + + @Test + public void testWithServerApi() { + checkInitialState(); + + field.setValue(INPUT_VALUE); + + checkEndState(); + + } + + private void checkEndState() { + assertEquals(1, listenerCalled); + assertTrue(repainted >= 1); + assertEquals(FORMATTED_VALUE, field.getValue()); + assertEquals(FORMATTED_VALUE, formatter.getValue()); + assertEquals(PARSED_VALUE, property.getValue()); + } + + private void checkInitialState() { + assertEquals(ORIGINAL_VALUE, property.getValue()); + assertEquals(FORMATTED_VALUE, formatter.getValue()); + assertEquals(FORMATTED_VALUE, field.getValue()); + } + + @Test + public void testWithSimulatedClientSideChange() { + checkInitialState(); + + field.changeVariables(null, + Collections.singletonMap("text", (Object) INPUT_VALUE)); + + checkEndState(); + + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java new file mode 100644 index 0000000000..6fc2108b63 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/textfield/TextFieldWithValidatorTest.java @@ -0,0 +1,179 @@ +package com.vaadin.tests.server.component.textfield; + +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.v7.data.Validator; +import com.vaadin.v7.data.Validator.InvalidValueException; +import com.vaadin.v7.data.validator.LegacyEmailValidator; +import com.vaadin.v7.data.validator.LegacyRegexpValidator; +import com.vaadin.v7.data.validator.LegacyStringLengthValidator; +import com.vaadin.v7.ui.LegacyTextField; + +public class TextFieldWithValidatorTest { + + private LegacyTextField field; + private ObjectProperty<String> property; + + @Before + public void setUp() { + + field = new LegacyTextField(); + field.setInvalidAllowed(false); + property = new ObjectProperty<String>("original"); + field.setPropertyDataSource(property); + } + + @Test + public void testMultipleValidators() { + field.addValidator(new LegacyStringLengthValidator( + "Length not between 1 and 3", 1, 3, false)); + field.addValidator(new LegacyStringLengthValidator( + "Length not between 2 and 4", 2, 4, false)); + + // fails + try { + field.setValue("a"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue("ab"); + // fails + try { + field.setValue("abcd"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + } + + @Test + public void testRemoveValidator() { + Validator validator1 = new LegacyStringLengthValidator( + "Length not between 1 and 3", 1, 3, false); + Validator validator2 = new LegacyStringLengthValidator( + "Length not between 2 and 4", 2, 4, false); + + field.addValidator(validator1); + field.addValidator(validator2); + field.removeValidator(validator1); + + // fails + try { + field.setValue("a"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue("ab"); + // succeeds + field.setValue("abcd"); + } + + @Test + public void testRemoveAllValidators() { + Validator validator1 = new LegacyStringLengthValidator( + "Length not between 1 and 3", 1, 3, false); + Validator validator2 = new LegacyStringLengthValidator( + "Length not between 2 and 4", 2, 4, false); + + field.addValidator(validator1); + field.addValidator(validator2); + field.removeAllValidators(); + + // all should succeed now + field.setValue("a"); + field.setValue("ab"); + field.setValue("abcd"); + } + + @Test + public void testEmailValidator() { + field.addValidator(new LegacyEmailValidator("Invalid e-mail address")); + + // not required + + field.setRequired(false); + // succeeds + field.setValue(""); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue(null); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue("test@example.com"); + // fails + try { + field.setValue("invalid e-mail"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + + // required + + field.setRequired(true); + // fails + try { + field.setValue(""); + // needed as required flag not checked by setValue() + field.validate(); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // fails + try { + field.setValue(null); + // needed as required flag not checked by setValue() + field.validate(); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue("test@example.com"); + // fails + try { + field.setValue("invalid e-mail"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + } + + @Test + public void testRegexpValidator() { + field.addValidator(new LegacyRegexpValidator("pattern", true, + "Validation failed")); + field.setRequired(false); + + // succeeds + field.setValue(""); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue(null); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue("pattern"); + + // fails + try { + field.setValue("mismatch"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/validation/RangeValidatorTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/validation/RangeValidatorTest.java new file mode 100644 index 0000000000..1d5032e956 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/validation/RangeValidatorTest.java @@ -0,0 +1,63 @@ +package com.vaadin.tests.server.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyIntegerRangeValidator; + +public class RangeValidatorTest { + + // This test uses IntegerRangeValidator for simplicity. + // IntegerRangeValidator contains no code so we really are testing + // RangeValidator + @Test + public void testMinValueNonInclusive() { + LegacyIntegerRangeValidator iv = new LegacyIntegerRangeValidator( + "Failed", 0, 10); + iv.setMinValueIncluded(false); + assertFalse(iv.isValid(0)); + assertTrue(iv.isValid(10)); + assertFalse(iv.isValid(11)); + assertFalse(iv.isValid(-1)); + } + + @Test + public void testMinMaxValuesInclusive() { + LegacyIntegerRangeValidator iv = new LegacyIntegerRangeValidator( + "Failed", 0, 10); + assertTrue(iv.isValid(0)); + assertTrue(iv.isValid(1)); + assertTrue(iv.isValid(10)); + assertFalse(iv.isValid(11)); + assertFalse(iv.isValid(-1)); + } + + @Test + public void testMaxValueNonInclusive() { + LegacyIntegerRangeValidator iv = new LegacyIntegerRangeValidator( + "Failed", 0, 10); + iv.setMaxValueIncluded(false); + assertTrue(iv.isValid(0)); + assertTrue(iv.isValid(9)); + assertFalse(iv.isValid(10)); + assertFalse(iv.isValid(11)); + assertFalse(iv.isValid(-1)); + } + + @Test + public void testMinMaxValuesNonInclusive() { + LegacyIntegerRangeValidator iv = new LegacyIntegerRangeValidator( + "Failed", 0, 10); + iv.setMinValueIncluded(false); + iv.setMaxValueIncluded(false); + + assertFalse(iv.isValid(0)); + assertTrue(iv.isValid(1)); + assertTrue(iv.isValid(9)); + assertFalse(iv.isValid(10)); + assertFalse(iv.isValid(11)); + assertFalse(iv.isValid(-1)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.java b/compatibility-server/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.java new file mode 100644 index 0000000000..503ba455fd --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/validation/ReadOnlyValidationTest.java @@ -0,0 +1,17 @@ +package com.vaadin.tests.server.validation; + +import org.junit.Test; + +import com.vaadin.v7.data.validator.LegacyIntegerValidator; +import com.vaadin.v7.ui.LegacyTextField; + +public class ReadOnlyValidationTest { + + @Test + public void testIntegerValidation() { + LegacyTextField field = new LegacyTextField(); + field.addValidator(new LegacyIntegerValidator("Enter a Valid Number")); + field.setValue(String.valueOf(10)); + field.validate(); + } +} |