ucar.units.UnitImpl Maven / Gradle / Ivy
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.
*/
private static boolean equals(final String s1, final String s2) {
return (s1 == null && s2 == null) || (s1 != 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).
*/
private static boolean equalsIgnoreCase(final String s1, final String s2) {
return (s1 == null && s2 == null) || (s1 != 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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy