001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.utils.configuration;
020
021/**
022 * Implementation of {@link JPPFProperty} for numeric properties.
023 * Instances of this class or its subclasses manage a minimum and maximum accepted value for numeric properties. 
024 * @param <T> the type of the value of this property.
025 * @author Laurent Cohen
026 * @since 5.2
027 */
028public abstract class NumberProperty<T extends Number> extends AbstractJPPFProperty<T> {
029  /**
030   * Explicit serialVersionUID.
031   */
032  private static final long serialVersionUID = 1L;
033  /**
034   * The minimum accepted value for this property.
035   */
036  final Comparable<T> minValue;
037  /**
038   * The maximum accepted value for this property.
039   */
040  final Comparable<T> maxValue;
041  /**
042   * 
043   */
044  final boolean hasMinAndMax;
045
046  /**
047   * Initialize this property with the specified name and default value.
048   * @param name the name of this property.
049   * @param defaultValue the default value of this property, used when the proeprty is not defined.
050   * @param aliases other names that may be given to this property (e.g. older names from previous versions).
051   */
052  public NumberProperty(final String name, final T defaultValue, final String... aliases) {
053    super(name, defaultValue, aliases);
054    this.minValue = null;
055    this.maxValue = null;
056    this.hasMinAndMax = false;
057  }
058
059  /**
060   * Initialize this property with the specified name and default value.
061   * @param name the name of this property.
062   * @param defaultValue the default value of this property, used when the proeprty is not defined.
063   * @param aliases other names that may be given to this property (e.g. older names from previous versions).
064   * @param minValue the minimum accepted value for this property.
065   * @param maxValue the maximum accepted value for this property.
066   */
067  @SuppressWarnings("unchecked")
068  public NumberProperty(final String name, final T defaultValue, final T minValue, final T maxValue, final String... aliases) {
069    super(name, defaultValue, aliases);
070    if ((minValue == null) || (maxValue == null)) throw new IllegalArgumentException(String.format("min and max values cannot be null (name=%s; min=%s; max=%s", name, minValue, minValue));
071    if (minValue.doubleValue() > maxValue.doubleValue()) throw new IllegalArgumentException(String.format("min value must be <= max value (name=%s; min=%s; max=%s)", name, minValue, minValue));
072    this.minValue = (Comparable<T>) minValue;
073    this.maxValue = (Comparable<T>) maxValue;
074    this.hasMinAndMax = (this.minValue != null) && (this.maxValue != null);
075  }
076
077  /**
078   * Get the minimum accepted value for this property.
079   * @return the minimum value.
080   */
081  @SuppressWarnings("unchecked")
082  public T getMinValue() {
083    return (T) minValue;
084  }
085
086  /**
087   * Get the maximum accepted value for this property.
088   * @return the maximum value.
089   */
090  @SuppressWarnings("unchecked")
091  public T getMaxValue() {
092    return (T) maxValue;
093  }
094
095  /**
096   * Whether this property has a min and max values.
097   * @return {@code true} if min and max values are defined, {@code false} otherwise.
098   */
099  public boolean hasMinAndMax() {
100    return hasMinAndMax;
101  }
102
103  /**
104   * Validate a value with regards to min and max and return the default value if it doesn't fit in the range.
105   * @param value the value to validate.
106   * @return the default value if the value is < minValue or > maxValue, or the value itself otherwise.
107   */
108  @SuppressWarnings("unchecked")
109  T validate(final T value) {
110    final Comparable<T> cv = (Comparable<T>) value;
111    if ((value != null) && hasMinAndMax() && ((cv.compareTo((T) minValue) < 0) || (cv.compareTo((T) maxValue) > 0))) return getDefaultValue();
112    return value;
113  }
114}