InputParameterFloatScalar.java
package nl.tudelft.simulation.dsol.model.inputparameters;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.djunits.unit.Unit;
import org.djunits.value.vfloat.scalar.base.FloatScalar;
import org.djutils.exceptions.Throw;
import org.djutils.reflection.ClassUtil;
/**
* InputParameterFloatScalar: float parameter with a unit. The number and the value are stored in an InputParameterMap as two
* input variables of type InputFieldFloat (name: value), and InputFieldUnit (name: unit). <br>
* <br>
* Copyright (c) 2003-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information <a href="https://www.simulation.tudelft.nl/" target="_blank">www.simulation.tudelft.nl</a>. The
* source code and binary code of this software is proprietary information of Delft University of Technology.
* @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
* @param <U> the unit type
* @param <T> the scalar type
*/
public class InputParameterFloatScalar<U extends Unit<U>, T extends FloatScalar<U, T>>
extends AbstractInputParameterTypedMap<T>
{
/** */
private static final long serialVersionUID = 1L;
/** The minimum value of the input parameter (SI units). */
private float minimumValueSI = -Float.MAX_VALUE;
/** The maximum value of the input parameter (SI units). */
private float maximumValueSI = Float.MAX_VALUE;
/** Is the minimum value included or excluded in the allowed interval? */
private boolean minIncluded = true;
/** Is the maximum value included or excluded in the allowed interval? */
private boolean maxIncluded = true;
/**
* Construct a new InputParameterFloatScalar.
* @param key String; unique (within the parent's input parameter map) name of the new InputParameterFloatUnit
* @param shortName String; concise description of the input parameter
* @param description String; float description of the input parameter (may use HTML markup)
* @param defaultValue T; the default value of this input parameter
* @param displayPriority double; sorting order when properties are displayed to the user
* @throws NullPointerException when key, shortName, defaultValue, or description is null
* @throws IllegalArgumentException when displayPriority is NaN
* @throws InputParameterException when unit for the default value cannot be found in the unit definition
*/
public InputParameterFloatScalar(final String key, final String shortName, final String description, final T defaultValue,
final double displayPriority) throws InputParameterException
{
this(key, shortName, description, defaultValue, -Float.MAX_VALUE, Float.MAX_VALUE, false, false, "%d", displayPriority);
}
/**
* Construct a new InputParameterFloatScalar.
* @param key String; unique (within the parent's input parameter map) name of the new InputParameterFloatUnit
* @param shortName String; concise description of the input parameter
* @param description String; float description of the input parameter (may use HTML markup)
* @param defaultValue T; the default value of this input parameter
* @param minimumValue T; the lowest value allowed as input
* @param maximumValue T; the highest value allowed as input
* @param minIncluded boolean; is the minimum value included or excluded in the allowed interval?
* @param maxIncluded boolean; is the maximum value included or excluded in the allowed interval?
* @param format String; the format to use in displaying the float
* @param displayPriority double; sorting order when properties are displayed to the user
* @throws NullPointerException when key, shortName, defaultValue, description, format, minimumValue, maximumValue, or
* defaultValue is null
* @throws IllegalArgumentException when displayPriority is NaN
* @throws InputParameterException when unit for the default value cannot be found in the unit definition
*/
@SuppressWarnings("checkstyle:parameternumber")
public InputParameterFloatScalar(final String key, final String shortName, final String description, final T defaultValue,
final T minimumValue, final T maximumValue, final boolean minIncluded, final boolean maxIncluded,
final String format, final double displayPriority) throws InputParameterException
{
this(key, shortName, description, defaultValue, minimumValue.si, maximumValue.si, minIncluded, maxIncluded, format,
displayPriority);
Throw.whenNull(format, "format cannot be null");
Throw.whenNull(defaultValue, "defaultValue cannot be null");
Throw.whenNull(minimumValue, "minimumValue cannot be null");
Throw.whenNull(maximumValue, "maximumValue cannot be null");
}
/**
* Construct a new InputParameterFloatScalar.
* @param key String; unique (within the parent's input parameter map) name of the new InputParameterFloatUnit
* @param shortName String; concise description of the input parameter
* @param description String; float description of the input parameter (may use HTML markup)
* @param defaultValue T; the default value of this input parameter
* @param minimumValueSI float; the lowest value allowed as input (in SI units)
* @param maximumValueSI float; the highest value allowed as input (in SI units)
* @param minIncluded boolean; is the minimum value included or excluded in the allowed interval?
* @param maxIncluded boolean; is the maximum value included or excluded in the allowed interval?
* @param format String; the format to use in displaying the float
* @param displayPriority double; sorting order when properties are displayed to the user
* @throws NullPointerException when key, shortName, defaultValue, description, format, or defaultValue is null
* @throws IllegalArgumentException when displayPriority is NaN
* @throws InputParameterException when unit for the default value cannot be found in the unit definition
*/
@SuppressWarnings("checkstyle:parameternumber")
public InputParameterFloatScalar(final String key, final String shortName, final String description, final T defaultValue,
final float minimumValueSI, final float maximumValueSI, final boolean minIncluded, final boolean maxIncluded,
final String format, final double displayPriority) throws InputParameterException
{
super(key, shortName, description, defaultValue, displayPriority);
Throw.whenNull(format, "format cannot be null");
Throw.whenNull(defaultValue, "defaultValue cannot be null");
add(new InputParameterFloat("value", "value", "float value in the given unit", defaultValue.getInUnit(),
-Float.MAX_VALUE, Float.MAX_VALUE, false, false, format, 1.0));
add(new InputParameterUnit<U>("unit", "unit", "unit for the value", defaultValue.getDisplayUnit(), 2.0));
this.minimumValueSI = minimumValueSI;
this.maximumValueSI = maximumValueSI;
this.minIncluded = minIncluded;
this.maxIncluded = maxIncluded;
}
/**
* @return the unit sub-parameter
* @throws RuntimeException when parameter map has been corrupted and no unit parameter can be found
*/
@SuppressWarnings("unchecked")
public InputParameterUnit<U> getUnitParameter()
{
try
{
return (InputParameterUnit<U>) get("unit");
}
catch (InputParameterException exception)
{
throw new RuntimeException(
"Parameter map has been corrupted and no unit parameter can be found for field " + getShortName(),
exception);
}
}
/**
* @return the float sub-parameter
* @throws RuntimeException when parameter map has been corrupted and no value parameter can be found
*/
public InputParameterFloat getFloatParameter()
{
try
{
return (InputParameterFloat) get("value");
}
catch (InputParameterException exception)
{
throw new RuntimeException(
"Parameter map has been corrupted and no value parameter can be found for field " + getShortName(),
exception);
}
}
/**
* Construct the scalar value with reflection, and set it as the current value. The unit is specified as Unit<?>
* because the input using fields cannot guarantee conformance to the right unit type.
* @throws InputParameterException when an operation is attempted that is not compatible with the indicated input parameter,
* or when the scalar does not have a constructor Scalar(float, unit)
*/
@Override
public void setCalculatedValue() throws InputParameterException
{
float floatValue = ((InputParameterFloat) get("value")).getValue();
@SuppressWarnings("unchecked")
U unit = ((InputParameterUnit<U>) get("unit")).getValue();
T newValue;
try
{
@SuppressWarnings("unchecked")
Constructor<T> constructor = (Constructor<T>) ClassUtil.resolveConstructor(getDefaultTypedValue().getClass(),
new Object[] {floatValue, unit});
newValue = constructor.newInstance(floatValue, unit);
}
catch (IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InstantiationException
| InvocationTargetException exception)
{
throw new InputParameterException(exception);
}
if (this.minimumValueSI > newValue.si || this.maximumValueSI < newValue.si
|| (this.minimumValueSI == newValue.si && !this.minIncluded)
|| (this.maximumValueSI == newValue.si && !this.maxIncluded) || Float.isNaN(newValue.si))
{
throw new InputParameterException(
"new value for InputParameterFloatUnit with key " + getKey() + " with value " + newValue
+ " is out of valid range [" + this.minimumValueSI + ".." + this.maximumValueSI + "] (SI units)");
}
this.typedValue = newValue;
}
/**
* @return minimumValue (SI units)
*/
public Float getMinimumValueSI()
{
return this.minimumValueSI;
}
/**
* @param minimumValueSI float; set minimumValue (SI units)
*/
public void setMinimumValueSI(final float minimumValueSI)
{
this.minimumValueSI = minimumValueSI;
}
/**
* @return maximumValue (SI units)
*/
public Float getMaximumValueSI()
{
return this.maximumValueSI;
}
/**
* @param maximumValueSI float; set maximumValue (SI units)
*/
public void setMaximumValueSI(final float maximumValueSI)
{
this.maximumValueSI = maximumValueSI;
}
/**
* @return minIncluded
*/
public boolean isMinIncluded()
{
return this.minIncluded;
}
/**
* @param minIncluded boolean; set minIncluded
*/
public void setMinIncluded(final boolean minIncluded)
{
this.minIncluded = minIncluded;
}
/**
* @return maxIncluded
*/
public boolean isMaxIncluded()
{
return this.maxIncluded;
}
/**
* @param maxIncluded boolean; set maxIncluded
*/
public void setMaxIncluded(final boolean maxIncluded)
{
this.maxIncluded = maxIncluded;
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public InputParameterFloatScalar<U, T> clone()
{
InputParameterFloatScalar<U, T> clonedMap = (InputParameterFloatScalar<U, T>) super.clone();
clonedMap.minimumValueSI = this.minimumValueSI;
clonedMap.maximumValueSI = this.maximumValueSI;
clonedMap.minIncluded = this.minIncluded;
clonedMap.maxIncluded = this.maxIncluded;
return clonedMap;
}
}