ucar.units.UnitImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of udunits Show documentation
Show all versions of udunits Show documentation
The ucar.units Java package is for decoding and encoding formatted unit specifications (e.g. "m/s"), converting numeric values between compatible units (e.g. between "m/s" and "knot"), and for performing arithmetic operations on units (e.g. dividing one unit by another, or raising a unit to a power).
The newest version!
/*
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package ucar.units;
import javax.annotation.concurrent.Immutable;
import java.io.Serializable;
import java.util.Date;
/**
* Provides support for classes that implement units.
*
* @author Steven R. Emmerson
*/
@Immutable
public abstract class UnitImpl implements Unit, Serializable {
private static final long serialVersionUID = 1L;
/**
* The unit identifier.
*
* @serial
*/
private final UnitName id;
/**
* Constructs with no ID.
*/
protected UnitImpl() {
this(null);
}
/**
* Constructs with the given ID.
*
* @param id
* The id of the unit (e.g. "foot"). May be null.
*/
protected UnitImpl(final UnitName id) {
this.id = id;
}
/**
* Gets the identifier of this unit.
*
* @return The ID of this unit. May be null
.
*/
public final UnitName getUnitName() {
return id;
}
/**
* Gets the name of the unit.
*
* @return The name of the unit. May be null
.
*/
public final String getName() {
return id == null
? null
: id.getName();
}
/**
* Gets the plural form of the name of the unit.
*
* @return The plural of the name of the unit. May be null
.
*/
public final String getPlural() {
return id == null
? null
: id.getPlural();
}
/**
* Gets the symbol for the unit.
*
* @return The symbol of the unit. May be null
.
*/
public final String getSymbol() {
return id == null
? null
: id.getSymbol();
}
public Unit shiftTo(final double origin) throws ShiftException {
return OffsetUnit.getInstance(this, origin);
}
public Unit shiftTo(final Date origin) throws ShiftException {
return TimeScaleUnit.getInstance(this, origin);
}
/**
* Multiplies this unit by another.
*
* @param that
* The other unit.
* @return The product of this unit multiplied by the other unit.
* @throws MultiplyException
* Can't multiply these units.
*/
public final Unit multiplyBy(final Unit that) throws MultiplyException {
return myMultiplyBy(that);
}
public Unit multiplyBy(final double scale) throws MultiplyException {
return ScaledUnit.getInstance(scale, this);
}
/**
* Multiplies this unit by another.
*
* @param that
* The other unit.
* @return The product of this unit multiplied by the other unit.
* @throws MultiplyException
* Can't multiply these units.
*/
protected abstract Unit myMultiplyBy(Unit that) throws MultiplyException;
/**
* Divides this unit by another.
*
* @param that
* The other unit.
* @return The quotient of this unit divided by the other unit.
* @throws OperationException
* Can't divide these units.
*/
public final Unit divideBy(final Unit that) throws OperationException {
return myDivideBy(that);
}
/**
* Divides this unit by another.
*
* @param unit
* The other unit.
* @return The quotient of this unit divided by the other unit.
* @throws OperationException
* Can't divide these units.
*/
protected abstract Unit myDivideBy(Unit unit) throws OperationException;
/**
* Divides this unit into another.
*
* @param that
* The other unit.
* @return The quotient of this unit divided into the other unit.
* @throws OperationException
* Can't divide these units.
*/
public final Unit divideInto(final Unit that) throws OperationException {
return myDivideInto(that);
}
/**
* Divides this unit into another.
*
* @param unit
* The other unit.
* @return The quotient of this unit divided into the other unit.
* @throws OperationException
* Can't divide these units.
*/
protected abstract Unit myDivideInto(Unit unit) throws OperationException;
/**
* Raises this unit to a power.
*
* @param power
* The power.
* @return The result of raising this unit to the power.
* @throws RaiseException
* Can't raise this unit to a power.
*/
public final Unit raiseTo(final int power) throws RaiseException {
return myRaiseTo(power);
}
/**
* Raises this unit to a power.
*
* @param power
* The power.
* @return The result of raising this unit to the power.
* @throws RaiseException
* Can't raise this unit to a power.
*/
protected abstract Unit myRaiseTo(int power) throws RaiseException;
/*
* Default implementation.
*
* @see ucar.units.Unit#log(double)
*/
public Unit log(final double base) {
return LogarithmicUnit.getInstance(this, base);
}
/**
* Provides support for converting numeric values from this unit to another
* unit.
*/
protected static class MyConverter extends ConverterImpl {
private final DerivableUnit fromUnit;
private final DerivableUnit toUnit;
protected MyConverter(final Unit fromUnit, final Unit toUnit)
throws ConversionException {
super(fromUnit, toUnit);
if (!(fromUnit instanceof DerivableUnit)
|| !(toUnit instanceof DerivableUnit)) {
throw new ConversionException(fromUnit, toUnit);
}
this.fromUnit = (DerivableUnit) fromUnit;
this.toUnit = (DerivableUnit) toUnit;
}
public double convert(final double amount) {
double output;
try {
output = toUnit.fromDerivedUnit(fromUnit.toDerivedUnit(amount));
}
catch (final ConversionException e) {
output = 0;
} // can't happen because isCompatible() vetted
return output;
}
public float[] convert(final float[] input, final float[] output) {
try {
toUnit.fromDerivedUnit(fromUnit.toDerivedUnit(input, output),
output);
}
catch (final ConversionException e) {
} // can't happen because isCompatible() vetted
return output;
}
public double[] convert(final double[] input, final double[] output) {
try {
toUnit.fromDerivedUnit(fromUnit.toDerivedUnit(input, output),
output);
}
catch (final ConversionException e) {
} // can't happen because isCompatible() vetted
return output;
}
}
/**
* Gets a Converter for converting numeric values from this unit to another,
* compatible unit.
*
* @param outputUnit
* The unit to which to convert the numeric values.
* @return A converter of values from this unit to the other unit.
* @throws ConversionException
* The units aren't convertible.
*/
public Converter getConverterTo(final Unit outputUnit)
throws ConversionException {
return new MyConverter(this, outputUnit);
}
/**
* Converts a numeric value from this unit to another unit.
*
* @param amount
* The numeric value.
* @param outputUnit
* The unit to which to convert the numeric value.
* @return The numeric value in the output unit.
* @throws ConversionException
* The units aren't convertible.
*/
public float convertTo(final float amount, final Unit outputUnit)
throws ConversionException {
return (float) convertTo((double) amount, outputUnit);
}
/**
* Converts a numeric value from this unit to another unit.
*
* @param amount
* The numeric value.
* @param outputUnit
* The unit to which to convert the numeric value.
* @return The numeric value in the output unit.
* @throws ConversionException
* The units aren't convertible.
*/
public double convertTo(final double amount, final Unit outputUnit)
throws ConversionException {
return getConverterTo(outputUnit).convert(amount);
}
/**
* Converts numeric values from this unit to another unit.
*
* @param amounts
* The numeric values.
* @param outputUnit
* The unit to which to convert the numeric values.
* @return The numeric values in the output unit in allocated space.
* @throws ConversionException
* The units aren't convertible.
*/
public float[] convertTo(final float[] amounts, final Unit outputUnit)
throws ConversionException {
return convertTo(amounts, outputUnit, new float[amounts.length]);
}
/**
* Converts numeric values from this unit to another unit.
*
* @param amounts
* The numeric values.
* @param outputUnit
* The unit to which to convert the numeric values.
* @return The numeric values in the output unit in allocated space.
* @throws ConversionException
* The units aren't convertible.
*/
public double[] convertTo(final double[] amounts, final Unit outputUnit)
throws ConversionException {
return convertTo(amounts, outputUnit, new double[amounts.length]);
}
/**
* Converts numeric values from this unit to another unit.
*
* @param input
* The input numeric values.
* @param outputUnit
* The unit to which to convert the numeric values.
* @param output
* The output numeric values. May be the same array as the input
* values.
* @return The numeric values in the output unit.
* @throws ConversionException
* The units aren't convertible.
*/
public float[] convertTo(final float[] input, final Unit outputUnit,
final float[] output) throws ConversionException {
return getConverterTo(outputUnit).convert(input, output);
}
/**
* Converts numeric values from this unit to another unit.
*
* @param input
* The input numeric values.
* @param outputUnit
* The unit to which to convert the numeric values.
* @param output
* The output numeric values. May be the same array as the input
* values.
* @return The numeric values in the output unit.
* @throws ConversionException
* The units aren't convertible.
*/
public double[] convertTo(final double[] input, final Unit outputUnit,
final double[] output) throws ConversionException {
return getConverterTo(outputUnit).convert(input, output);
}
/**
* Indicates if numeric values in this unit are convertible with another
* unit.
*
* @param that
* The other unit.
* @return true
if and only if numeric values in this unit are
* convertible the other unit.
*/
public boolean isCompatible(final Unit that) {
// jeffm: for some reason just calling getDerivedUnit().equals(...)
// with jikes 1.1.7 as the compiler causes the jvm to crash.
// The Unit u1=... does not crash.
final Unit u1 = getDerivedUnit();
return u1.equals(that.getDerivedUnit());
// return getDerivedUnit().equals(that.getDerivedUnit());
}
/**
* Returns the hash code of this instance.
*
* @return The hash code of this instance.
*/
@Override
public abstract int hashCode();
/**
* Indicates if two string are equal.
*
* @param s1
* One string. May be null
.
* @param s2
* The other string. May be null
.
* @return true
if an only if both strings are
* null
or both strings are identical.
*/
static private boolean equals(final String s1, final String s2) {
return (s1 == null && s2 == null)
|| (s1 != null && s2 != null && s1.equals(s2));
}
/**
* Indicates if two string are equal (ignoring case).
*
* @param s1
* One string. May be null
.
* @param s2
* The other string. May be null
.
* @return true
if an only if both strings are
* null
or both strings are identical (ignoring case).
*/
static private boolean equalsIgnoreCase(final String s1,
final String s2) {
return (s1 == null && s2 == null)
|| (s1 != null && s2 != null && s1.equalsIgnoreCase(s2));
}
/**
* Returns the string representation of this unit.
*
* @return The string representation of this unit.
*/
@Override
public String toString() {
final String string = getSymbol();
return string != null
? string
: getName();
}
/**
* Returns a label for a quantity in this unit.
*
* @param quantityID
* The identifier for the quantity (e.g. "altitude").
* @return The appropriate label (e.g. "altitude/m").
*/
public String makeLabel(final String quantityID) {
final StringBuilder buf = new StringBuilder(quantityID);
if (quantityID.contains(" ")) {
buf.insert(0, '(').append(')');
}
buf.append('/');
final int start = buf.length();
buf.append(toString());
if (buf.substring(start).indexOf(' ') != -1) {
buf.insert(start, '(').append(')');
}
return buf.toString();
}
}