/* * Geotools 2 - OpenSource mapping toolkit * (C) 2004, Geotools Project Managment Committee (PMC) * (C) 2004, Institut de Recherche pour le Développement * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * This package contains documentation from OpenGIS specifications. * OpenGIS consortium's work is fully acknowledged here. */ package org.geotools.parameter; // J2SE dependencies and extensions import java.net.URI; import javax.units.Unit; // OpenGIS dependencies import org.opengis.parameter.InvalidParameterTypeException; import org.opengis.parameter.InvalidParameterValueException; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterValue; // Geotools dependencies import org.geotools.resources.Utilities; import org.geotools.resources.i18n.Errors; import org.geotools.resources.i18n.ErrorKeys; /** * A parameter value as a floating point (double precision) number. * This class provides the same functionalities than {@link Parameter}, except that: *
{@linkplain Double}.class
.
*
* @param descriptor The abstract definition of this parameter.
* @throws IllegalArgumentException if the value class is not {@code Double.class}.
*/
public FloatParameter(final ParameterDescriptor descriptor) {
super(descriptor);
final Class type = descriptor.getValueClass();
final Class expected = Double.class;
if (!expected.equals(type) && !Double.TYPE.equals(type)) {
throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_CLASS_$2,
Utilities.getShortName(type), Utilities.getShortName(expected)));
}
final Number value = (Number) descriptor.getDefaultValue();
this.value = (value!=null) ? value.doubleValue() : Double.NaN;
}
/**
* Constructs a parameter from the specified descriptor and value. This convenience
* constructor is equivalents to the one-argument constructor followed by a call to
* {@link #setValue(double)}.
*
* @param descriptor The abstract definition of this parameter.
* @param value The parameter value.
* @throws IllegalArgumentException if the value class is not {@code Double.class}.
*/
public FloatParameter(final ParameterDescriptor descriptor, final double value) {
this(descriptor);
setValue(value);
}
/**
* Returns the unit of measure of the {@linkplain #doubleValue() parameter value}. The default
* implementation always delegates to {@link ParameterDescriptor#getUnit}.
*
* @return The unit of measure, or {@code null} if none.
*/
public Unit getUnit() {
return ((ParameterDescriptor) descriptor).getUnit();
}
/**
* Returns the numeric value of the coordinate operation parameter in the specified unit
* of measure. This convenience method apply unit conversion on the fly as needed.
*
* @param unit The unit of measure for the value to be returned.
* @return The numeric value represented by this parameter after conversion to type
* {@code double} and conversion to {@code unit}.
* @throws IllegalArgumentException if the specified unit is invalid for this parameter.
*/
public double doubleValue(final Unit unit) throws IllegalArgumentException {
ensureNonNull("unit", unit);
final Unit thisUnit = getUnit();
if (thisUnit == null) {
throw unitlessParameter(descriptor);
}
final int expectedID = Parameter.getUnitMessageID(thisUnit);
if (Parameter.getUnitMessageID(unit) != expectedID) {
throw new IllegalArgumentException(Errors.format(expectedID, unit));
}
return thisUnit.getConverterTo(unit).convert(value);
}
/**
* Returns the numeric value of the coordinate operation parameter with its
* associated {@linkplain #getUnit unit of measure}.
*
* @return The numeric value represented by this parameter after conversion to type {@code double}.
*/
public double doubleValue() {
return value;
}
/**
* Returns the numeric value rounded to the nearest integer.
*
* @return The numeric value represented by this parameter after conversion to type {@code int}.
*/
public int intValue() {
return (int)Math.round(value);
}
/**
* Returns {@code true} if the value is different from 0, {@code false} otherwise.
*
* @return The boolean value represented by this parameter.
*/
public boolean booleanValue() {
return value!=0 && !Double.isNaN(value);
}
/**
* Returns the string representation of the value.
*
* @return The string value represented by this parameter.
*/
public String stringValue() {
return String.valueOf(value);
}
/**
* Wraps the value in an array of length 1.
*
* @param unit The unit of measure for the value to be returned.
* @return The sequence of values represented by this parameter after conversion to type
* {@code double} and conversion to {@code unit}.
* @throws IllegalArgumentException if the specified unit is invalid for this parameter.
*/
public double[] doubleValueList(final Unit unit) throws IllegalArgumentException {
return new double[] {doubleValue(unit)};
}
/**
* Wraps the value in an array of length 1.
*
* @return The sequence of values represented by this parameter.
*/
public double[] doubleValueList() {
return new double[] {doubleValue()};
}
/**
* Wraps the value in an array of length 1.
*
* @return The sequence of values represented by this parameter.
*/
public int[] intValueList() {
return new int[] {intValue()};
}
/**
* Always throws an exception, since this parameter is not an URI.
*
* @return Never return.
* @throws InvalidParameterTypeException The value is not a reference to a file or an URI.
*/
public URI valueFile() throws InvalidParameterTypeException {
throw new InvalidParameterTypeException(getClassTypeError(),
Parameter.getName(descriptor));
}
/**
* Format an error message for illegal method call for the current value type.
*/
private static String getClassTypeError() {
return Errors.format(ErrorKeys.ILLEGAL_OPERATION_FOR_VALUE_CLASS_$1, "Double");
}
/**
* Returns the parameter value as {{@link Double},
*
* @return The parameter value as an object.
*/
public Object getValue() {
return new Double(value);
}
/**
* Set the parameter value as a floating point and its associated unit.
*
* @param value The parameter value.
* @param unit The unit for the specified value.
* @throws InvalidParameterValueException if the value is illegal for some reason
* (for example a value out of range).
*/
public void setValue(double value, final Unit unit) throws InvalidParameterValueException {
ensureNonNull("unit", unit);
final Unit thisUnit = ((ParameterDescriptor) descriptor).getUnit();
if (thisUnit == null) {
throw unitlessParameter(descriptor);
}
final int expectedID = Parameter.getUnitMessageID(thisUnit);
if (Parameter.getUnitMessageID(unit) != expectedID) {
throw new IllegalArgumentException(Errors.format(expectedID, unit));
}
value = unit.getConverterTo(thisUnit).convert(value);
Parameter.ensureValidValue((ParameterDescriptor) descriptor, new Double(value));
this.value = value;
}
/**
* Set the parameter value as a floating point.
*
* @param value The parameter value.
* @throws InvalidParameterValueException if the value is illegal for some reason
* (for example a value out of range).
*/
public void setValue(final double value) throws InvalidParameterValueException {
Parameter.ensureValidValue((ParameterDescriptor) descriptor, new Double(value));
this.value = value;
}
/**
* Set the parameter value as an integer.
*
* @param value The parameter value.
* @throws InvalidParameterValueException if the value is illegal for some reason
* (for example a value out of range).
*/
public void setValue(final int value) throws InvalidParameterValueException {
setValue((double) value);
}
/**
* Set the parameter value as a boolean.
*
* @param value The parameter value.
* @throws InvalidParameterValueException if the boolean type is inappropriate for this parameter.
*/
public void setValue(final boolean value) throws InvalidParameterValueException {
setValue(value ? 1.0 : 0.0);
}
/**
* Set the parameter value as a {@link Double} object.
*
* @param value The parameter value.
* @throws InvalidParameterValueException if the type of {@code value} is inappropriate
* for this parameter, or if the value is illegal for some other reason (for example
* the value is numeric and out of range).
*/
public void setValue(final Object value) throws InvalidParameterValueException {
Parameter.ensureValidValue((ParameterDescriptor) descriptor, value);
this.value = ((Number) value).doubleValue();
}
/**
* Always throws an exception, since this parameter is not an array.
*/
public void setValue(double[] values, final Unit unit) throws InvalidParameterValueException {
throw new InvalidParameterTypeException(getClassTypeError(),
Parameter.getName(descriptor));
}
/**
* Compares the specified object with this parameter for equality.
*
* @param object The object to compare to {@code this}.
* @return {@code true} if both objects are equal.
*/
public boolean equals(final Object object) {
if (super.equals(object)) {
final FloatParameter that = (FloatParameter) object;
return Double.doubleToLongBits(this.value) ==
Double.doubleToLongBits(that.value);
}
return false;
}
/**
* Returns a hash value for this parameter.
*
* @return The hash code value. This value doesn't need to be the same
* in past or future versions of this class.
*/
public int hashCode() {
final long code = Double.doubleToLongBits(value);
return (int)code ^ (int)(code >>> 32) + super.hashCode()*37;
}
}