001/**
002 * UnitParameter -- Any parameter that has units associated with it.
003 *
004 * Copyright (C) 2003-2017, by Joseph A. Huwaldt. All rights reserved.
005 *
006 * This library is free software; you can redistribute it and/or modify it under the terms
007 * of the GNU Lesser General Public License as published by the Free Software Foundation;
008 * either version 2 of the License, or (at your option) any later version.
009 *
010 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
012 * PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License along with
015 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
016 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
017 */
018package jahuwaldt.js.datareader;
019
020import java.util.Objects;
021import javax.measure.converter.ConversionException;
022import javax.measure.quantity.Quantity;
023import javax.measure.unit.Unit;
024import javolution.lang.ValueType;
025
026/**
027 * A class that represents a parameter in a case that has units associated with it.
028 *
029 * <p> Modified by: Joseph A. Huwaldt </p>
030 *
031 * @author Joseph A. Huwaldt, Date: March 5, 2003
032 * @version March 18, 2017
033 * @param <Q> The unit Quantity type.
034 * @param <E> The unit parameter sub-type.
035 */
036public abstract class UnitParameter<Q extends Quantity, E extends UnitParameter>
037        extends DataParam implements ValueType {
038
039    /**
040     * The units of the parameter (may NOT be null!).
041     */
042    protected Unit<Q> _unit;
043
044    /**
045     * Construct a parameter with no name or units.
046     */
047    protected UnitParameter() {
048    }
049
050    /**
051     * Returns the unit in which the value is stated.
052     *
053     * @return the parameter unit.
054     */
055    public Unit<Q> getUnit() {
056        return _unit;
057    }
058
059    /**
060     * Returns the parameter equivalent to this parameter but stated in the specified
061     * unit.
062     *
063     * @param unit the unit of the parameter to be returned.
064     * @return a parameter equivalent to this parameter but stated in the specified unit.
065     * @throws ConversionException if the current model does not allows for conversion to
066     * the specified unit.
067     */
068    public abstract E to(Unit<Q> unit) throws ConversionException;
069
070    /**
071     * Returns the parameter that has the same values as this parameter but with the units
072     * changed (<em>without</em> converting the values).
073     *
074     * @param <R> The unit of measure type (or Quantity) for the input units.
075     * @param unit the unit of the parameter to be returned.
076     * @return a parameter equivalent to this parameter but stated in the specified unit.
077     * @throws ConversionException if the current model does not allows for conversion to
078     * the specified unit.
079     */
080    public abstract <R extends Quantity> E changeTo(Unit<R> unit) throws ConversionException;
081
082    /**
083     * Compares the specified object with this parameter for strict equality same value,
084     * same units, same name, same user data.
085     *
086     * @param obj the object to compare with.
087     * @return <code>true</code> if this parameter is identical to that parameter;
088     *         <code>false</code> otherwise.
089     */
090    @Override
091    public boolean equals(Object obj) {
092        if (this == obj)
093            return true;
094        if ((obj == null) || (obj.getClass() != this.getClass()))
095            return false;
096
097        UnitParameter that = (UnitParameter)obj;
098        if (!Objects.equals(this._unit,that._unit))
099            return false;
100
101        return super.equals(obj);
102    }
103
104    /**
105     * Returns the hash code for this <code>UnitParameter</code>.
106     *
107     * @return the hash code value.
108     */
109    @Override
110    public int hashCode() {
111        int hash = super.hashCode();
112
113        hash = hash * 31 + _unit.hashCode();
114
115        return hash;
116    }
117
118}