Updated Branches: refs/heads/master 54ec77248 -> ed0cf1c25
WICKET-4584 NumberTextField does not have default minimum and maximum Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/ed0cf1c2 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/ed0cf1c2 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/ed0cf1c2 Branch: refs/heads/master Commit: ed0cf1c25338d9ead43cd7676bd5fadb19b0ebc3 Parents: 54ec772 Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Wed Jun 27 12:09:31 2012 +0300 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Wed Jun 27 12:21:41 2012 +0300 ---------------------------------------------------------------------- .../wicket/markup/html/form/NumberTextField.java | 60 +++++++-- .../validator/AbstractRangeValidator.java | 10 +- .../validation/validator/RangeValidatorTest.java | 22 +++- .../java/org/apache/wicket/util/lang/Numbers.java | 108 +++++++++++++++ .../org/apache/wicket/util/lang/NumbersTest.java | 69 +++++++++ 5 files changed, 257 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/ed0cf1c2/wicket-core/src/main/java/org/apache/wicket/markup/html/form/NumberTextField.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/NumberTextField.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/NumberTextField.java index 01d8b4e..ae3706b 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/NumberTextField.java +++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/NumberTextField.java @@ -23,6 +23,7 @@ import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.model.IModel; import org.apache.wicket.util.convert.IConverter; import org.apache.wicket.util.convert.converter.AbstractDecimalConverter; +import org.apache.wicket.util.lang.Numbers; import org.apache.wicket.util.value.IValueMap; import org.apache.wicket.validation.validator.RangeValidator; @@ -30,14 +31,13 @@ import org.apache.wicket.validation.validator.RangeValidator; * A {@link TextField} for HTML5 <input> with type <em>number</em>. * * <p> - * Automatically validates the input against the configured {@link #setMinimum(Number) min} and - * {@link #setMaximum(Number) max} attributes. If any of them is <code>null</code> then - * {@link Double#MIN_VALUE} and {@link Double#MAX_VALUE} are used respectfully. - * - * Note: {@link #setType(Class)} must be called explicitly! + * Automatically validates the input against the configured {@link #setMinimum(N) min} and + * {@link #setMaximum(N) max} attributes. If any of them is <code>null</code> then respective + * MIN_VALUE or MAX_VALUE for the number type is used. If the number type has no minimum and/or maximum + * value then {@link Double#MIN_VALUE} and {@link Double#MAX_VALUE} are used respectfully. * * @param <N> - * the number type + * the type of the number */ public class NumberTextField<N extends Number & Comparable<N>> extends TextField<N> { @@ -135,10 +135,50 @@ public class NumberTextField<N extends Number & Comparable<N>> extends TextField remove(validator); } - validator = new RangeValidator<N>(minimum, maximum); + validator = new RangeValidator<N>(getMinValue(), getMaxValue()); add(validator); } + private N getMinValue() + { + N result; + if (minimum != null) + { + result = minimum; + } + else + { + Class<N> numberType = getNumberType(); + result = (N) Numbers.getMinValue(numberType); + } + return result; + } + + private N getMaxValue() + { + N result; + if (maximum != null) + { + result = maximum; + } + else + { + Class<N> numberType = getNumberType(); + result = (N) Numbers.getMaxValue(numberType); + } + return result; + } + + private Class<N> getNumberType() + { + Class<N> numberType = getType(); + if (numberType == null && getModelObject() != null) + { + numberType = (Class<N>) getModelObject().getClass(); + } + return numberType; + } + @Override protected void onComponentTag(final ComponentTag tag) { @@ -148,7 +188,8 @@ public class NumberTextField<N extends Number & Comparable<N>> extends TextField if (minimum != null) { - attributes.put("min", minimum); + IConverter<N> converter = getConverter(getNumberType()); + attributes.put("min", converter.convertToString(minimum, HTML5_LOCALE)); } else { @@ -157,7 +198,8 @@ public class NumberTextField<N extends Number & Comparable<N>> extends TextField if (maximum != null) { - attributes.put("max", maximum); + IConverter<N> converter = getConverter(getNumberType()); + attributes.put("max", converter.convertToString(maximum, HTML5_LOCALE)); } else { http://git-wip-us.apache.org/repos/asf/wicket/blob/ed0cf1c2/wicket-core/src/main/java/org/apache/wicket/validation/validator/AbstractRangeValidator.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/validation/validator/AbstractRangeValidator.java b/wicket-core/src/main/java/org/apache/wicket/validation/validator/AbstractRangeValidator.java index 7e08575..babc170 100644 --- a/wicket-core/src/main/java/org/apache/wicket/validation/validator/AbstractRangeValidator.java +++ b/wicket-core/src/main/java/org/apache/wicket/validation/validator/AbstractRangeValidator.java @@ -110,8 +110,14 @@ public abstract class AbstractRangeValidator<R extends Comparable<R> & Serializa if ((min != null && value.compareTo(min) < 0) || (max != null && value.compareTo(max) > 0)) { ValidationError error = new ValidationError(this, getMode().getVariation()); - error.setVariable("minimum", min); - error.setVariable("maximum", max); + if (min != null) + { + error.setVariable("minimum", min); + } + if (max != null) + { + error.setVariable("maximum", max); + } validatable.error(decorate(error, validatable)); } } http://git-wip-us.apache.org/repos/asf/wicket/blob/ed0cf1c2/wicket-core/src/test/java/org/apache/wicket/validation/validator/RangeValidatorTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/validation/validator/RangeValidatorTest.java b/wicket-core/src/test/java/org/apache/wicket/validation/validator/RangeValidatorTest.java index 4828154..524b40a 100644 --- a/wicket-core/src/test/java/org/apache/wicket/validation/validator/RangeValidatorTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/validation/validator/RangeValidatorTest.java @@ -117,7 +117,27 @@ public class RangeValidatorTest } - private ValidationError getError(Validatable validatable) + @Test + public void onlyMinValue() + { + IValidator<Integer> validator = new RangeValidator<Integer>(1, null); + + Validatable<Integer> validatable = new Validatable<Integer>(0); + validator.validate(validatable); + assertEquals(1, validatable.getErrors().size()); + } + + @Test + public void onlyMaxValue() + { + IValidator<Integer> validator = new RangeValidator<Integer>(null, 1); + + Validatable<Integer> validatable = new Validatable<Integer>(2); + validator.validate(validatable); + assertEquals(1, validatable.getErrors().size()); + } + + private ValidationError getError(Validatable<?> validatable) { return (ValidationError)validatable.getErrors().get(0); } http://git-wip-us.apache.org/repos/asf/wicket/blob/ed0cf1c2/wicket-util/src/main/java/org/apache/wicket/util/lang/Numbers.java ---------------------------------------------------------------------- diff --git a/wicket-util/src/main/java/org/apache/wicket/util/lang/Numbers.java b/wicket-util/src/main/java/org/apache/wicket/util/lang/Numbers.java new file mode 100644 index 0000000..22590de --- /dev/null +++ b/wicket-util/src/main/java/org/apache/wicket/util/lang/Numbers.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.util.lang; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @since 1.5.8 + */ +public final class Numbers +{ + private static final Logger LOG = LoggerFactory.getLogger(Numbers.class); + + /** + * Prevent instantiation. + */ + private Numbers() {} + + /** + * Returns the minimum value for the numberType's type + * @param numberType + * the type of the number for which the minimum value will be returned + * * @return the minimum value of the numberType or {@value Double#MIN_VALUE} + * if the numberType itself is either {@code null} or has no minimum value + */ + public static Number getMinValue(Class<? extends Number> numberType) + { + Number result; + if (Integer.class == numberType || int.class == numberType) + { + result = Integer.MIN_VALUE; + } + else if (Long.class == numberType || long.class == numberType) { + result = Long.MIN_VALUE; + } + else if (Float.class == numberType || float.class == numberType) { + result = Float.MIN_VALUE; + } + else if (Double.class == numberType || double.class == numberType) { + result = Double.MIN_VALUE; + } + else if (Byte.class == numberType || byte.class == numberType) { + result = Byte.MIN_VALUE; + } + else if (Short.class == numberType || short.class == numberType) { + result = Short.MIN_VALUE; + } + else { // null of any other Number + LOG.debug("'{}' has no maximum value. Falling back to Double.MIN_VALUE.", numberType); + result = Double.MIN_VALUE; + } + + return result; + } + + + /** + * Returns the maximum value for the numberType's type + * @param numberType + * the type of the number for which the maximum value will be returned + * @return the maximum value of the numberType or {@value Double#MAX_VALUE} + * if the numberType itself is either {@code null} or has no maximum value + */ + public static Number getMaxValue(Class<? extends Number> numberType) + { + Number result; + if (Integer.class == numberType || int.class == numberType) + { + result = Integer.MAX_VALUE; + } + else if (Long.class == numberType || long.class == numberType) { + result = Long.MAX_VALUE; + } + else if (Float.class == numberType || float.class == numberType) { + result = Float.MAX_VALUE; + } + else if (Double.class == numberType || double.class == numberType) { + result = Double.MAX_VALUE; + } + else if (Byte.class == numberType || byte.class == numberType) { + result = Byte.MAX_VALUE; + } + else if (Short.class == numberType || short.class == numberType) { + result = Short.MAX_VALUE; + } + else { // null of any other Number + LOG.debug("'{}' has no maximum value. Falling back to Double.MAX_VALUE."); + result = Double.MAX_VALUE; + } + + return result; + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/ed0cf1c2/wicket-util/src/test/java/org/apache/wicket/util/lang/NumbersTest.java ---------------------------------------------------------------------- diff --git a/wicket-util/src/test/java/org/apache/wicket/util/lang/NumbersTest.java b/wicket-util/src/test/java/org/apache/wicket/util/lang/NumbersTest.java new file mode 100644 index 0000000..9093e17 --- /dev/null +++ b/wicket-util/src/test/java/org/apache/wicket/util/lang/NumbersTest.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.util.lang; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @since 1.5.8 + */ +public class NumbersTest extends Assert +{ + @Test + public void getMinValue() + { + assertEquals((Object) Integer.MIN_VALUE, Numbers.getMinValue(Integer.class)); + assertEquals((Object) Integer.MIN_VALUE, Numbers.getMinValue(int.class)); + assertEquals((Object) Long.MIN_VALUE, Numbers.getMinValue(Long.class)); + assertEquals((Object) Long.MIN_VALUE, Numbers.getMinValue(long.class)); + assertEquals((Object) Float.MIN_VALUE, Numbers.getMinValue(Float.class)); + assertEquals((Object) Float.MIN_VALUE, Numbers.getMinValue(float.class)); + assertEquals((Object) Double.MIN_VALUE, Numbers.getMinValue(Double.class)); + assertEquals((Object) Double.MIN_VALUE, Numbers.getMinValue(double.class)); + assertEquals((Object) Byte.MIN_VALUE, Numbers.getMinValue(Byte.class)); + assertEquals((Object) Byte.MIN_VALUE, Numbers.getMinValue(byte.class)); + assertEquals((Object) Short.MIN_VALUE, Numbers.getMinValue(Short.class)); + assertEquals((Object) Short.MIN_VALUE, Numbers.getMinValue(short.class)); + assertEquals((Object) Double.MIN_VALUE, Numbers.getMinValue(BigDecimal.class)); + assertEquals((Object) Double.MIN_VALUE, Numbers.getMinValue(BigInteger.class)); + assertEquals((Object) Double.MIN_VALUE, Numbers.getMinValue(null)); + } + + @Test + public void getMaxValue() + { + assertEquals((Object) Integer.MAX_VALUE, Numbers.getMaxValue(Integer.class)); + assertEquals((Object) Integer.MAX_VALUE, Numbers.getMaxValue(int.class)); + assertEquals((Object) Long.MAX_VALUE, Numbers.getMaxValue(Long.class)); + assertEquals((Object) Long.MAX_VALUE, Numbers.getMaxValue(long.class)); + assertEquals((Object) Float.MAX_VALUE, Numbers.getMaxValue(Float.class)); + assertEquals((Object) Float.MAX_VALUE, Numbers.getMaxValue(float.class)); + assertEquals((Object) Double.MAX_VALUE, Numbers.getMaxValue(Double.class)); + assertEquals((Object) Double.MAX_VALUE, Numbers.getMaxValue(double.class)); + assertEquals((Object) Byte.MAX_VALUE, Numbers.getMaxValue(Byte.class)); + assertEquals((Object) Byte.MAX_VALUE, Numbers.getMaxValue(byte.class)); + assertEquals((Object) Short.MAX_VALUE, Numbers.getMaxValue(Short.class)); + assertEquals((Object) Short.MAX_VALUE, Numbers.getMaxValue(short.class)); + assertEquals((Object) Double.MAX_VALUE, Numbers.getMaxValue(BigDecimal.class)); + assertEquals((Object) Double.MAX_VALUE, Numbers.getMaxValue(BigInteger.class)); + assertEquals((Object) Double.MAX_VALUE, Numbers.getMaxValue(null)); + } +}
