fix crash on converter dialogue

This vendors the jscience javax.measure package, extracted from
https://repo1.maven.org/maven2/org/jscience/jscience/4.3.1/jscience-4.3.1-sources.jar

Using this package as a dependency leads to conflicting classes, which
we can't solve from gradle. Instead of repackaging the jar file the
easiest solution seems to be to vendor the sources we need.
This commit is contained in:
Marcus Hoffmann 2020-03-16 15:52:46 +01:00
parent e00b18a0e6
commit c67dc96d57
78 changed files with 7344 additions and 1 deletions

View File

@ -74,7 +74,7 @@ dependencies {
implementation "com.android.support:support-v4:${versions.supportLib}"
implementation "com.android.support:appcompat-v7:${versions.supportLib}"
implementation "com.android.support:design:${versions.supportLib}"
implementation "javax.measure:jsr-275:0.9.1"
implementation project(":measure")
implementation 'com.squareup:otto:1.3.9-SNAPSHOT'
annotationProcessor 'com.squareup:otto:1.3.9-SNAPSHOT'
annotationProcessor 'com.squareup:otto-compiler:1.3.9-SNAPSHOT'

1
measure/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

9
measure/build.gradle Normal file
View File

@ -0,0 +1,9 @@
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
sourceCompatibility = "7"
targetCompatibility = "7"

View File

@ -0,0 +1,178 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.measure.converter.AddConverter;
import javax.measure.converter.RationalConverter;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
import javax.measure.unit.Unit;
/**
* <p> This class represents a measure whose value is an arbitrary-precision
* decimal number.</p>
*
* <p> When converting, applications may supply the
* <code>java.math.Context</code>:[code]
* DecimalMeasure<Velocity> c = DecimalMeasure.valueOf("299792458 m/s");
* DecimalMeasure<Velocity> milesPerHour = c.to(MILES_PER_HOUR, MathContext.DECIMAL128);
* System.out.println(milesPerHour);
*
* > 670616629.3843951324266284896206156 mph
* [/code]
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.3, October 3, 2007
*/
public class DecimalMeasure<Q extends Quantity> extends Measure<BigDecimal, Q> {
/**
* Holds the BigDecimal value.
*/
private final BigDecimal _value;
/**
* Holds the unit.
*/
private final Unit<Q> _unit;
/**
* Creates a decimal measure for the specified number stated in the
* specified unit.
*/
public DecimalMeasure(BigDecimal value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
/**
* Returns the decimal measure for the specified number stated in the
* specified unit.
*
* @param decimal the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> DecimalMeasure<Q> valueOf(
BigDecimal decimal, Unit<Q> unit) {
return new DecimalMeasure<Q>(decimal, unit);
}
/**
* Returns the decimal measure for the specified textual representation.
* This method first reads the <code>BigDecimal</code> value, then
* the unit if any (value and unit should be separated by white spaces).
*
* @param csq the decimal measure representation (including unit if any).
* @throws NumberFormatException if the specified character sequence is
* not a valid representation of decimal measure.
*/
@SuppressWarnings("unchecked")
public static <Q extends Quantity> DecimalMeasure<Q> valueOf(CharSequence csq) {
String str = csq.toString();
int numberLength = str.length();
int unitStartIndex = -1;
for (int i=0; i < str.length(); i++) {
if (Character.isWhitespace(str.charAt(i))) {
for (int j=i+1; j < str.length(); j++) {
if (!Character.isWhitespace(str.charAt(j))) {
unitStartIndex = j;
break;
}
}
numberLength = i;
break;
}
}
BigDecimal decimal = new BigDecimal(str.substring(0, numberLength));
Unit unit = Unit.ONE;
if (unitStartIndex > 0) {
unit = Unit.valueOf(str.substring(unitStartIndex));
}
return new DecimalMeasure<Q>(decimal, unit);
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public BigDecimal getValue() {
return _value;
}
/**
* Returns the decimal measure equivalent to this measure but stated in the
* specified unit. This method will raise an ArithmeticException if the
* resulting measure does not have a terminating decimal expansion.
*
* @param unit the new measurement unit.
* @return the measure stated in the specified unit.
* @throws ArithmeticException if the converted measure value does not have
* a terminating decimal expansion
* @see #to(Unit, MathContext)
*/
@Override
public DecimalMeasure<Q> to(Unit<Q> unit) {
return to(unit, null);
}
/**
* Returns the decimal measure equivalent to this measure but stated in the
* specified unit, the conversion is performed using the specified math
* context.
*
* @param unit the new measurement unit.
* @param mathContext the mathContext used to convert
* <code>BigDecimal</code> values or <code>null</code> if none.
* @return the measure stated in the specified unit.
* @throws ArithmeticException if the result is inexact but the
* rounding mode is <code>MathContext.UNNECESSARY</code> or
* <code>mathContext.precision == 0</tt> and the quotient has a
* non-terminating decimal expansion.
*/
public DecimalMeasure<Q> to(Unit<Q> unit, MathContext mathContext) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
if (cvtr instanceof RationalConverter) {
RationalConverter factor = (RationalConverter) cvtr;
BigDecimal dividend = BigDecimal.valueOf(factor.getDividend());
BigDecimal divisor = BigDecimal.valueOf(factor.getDivisor());
BigDecimal result = mathContext == null ?
_value.multiply(dividend).divide(divisor) :
_value.multiply(dividend, mathContext).divide(divisor, mathContext);
return new DecimalMeasure<Q>(result, unit);
} else if (cvtr.isLinear()) {
BigDecimal factor = BigDecimal.valueOf(cvtr.convert(1.0));
BigDecimal result = mathContext == null ?
_value.multiply(factor) : _value.multiply(factor, mathContext);
return new DecimalMeasure<Q>(result, unit);
} else if (cvtr instanceof AddConverter) {
BigDecimal offset = BigDecimal.valueOf(((AddConverter)cvtr).getOffset());
BigDecimal result = mathContext == null ?
_value.add(offset) : _value.add(offset, mathContext);
return new DecimalMeasure<Q>(result, unit);
} else { // Non-linear and not an offset, convert the double value.
BigDecimal result = BigDecimal.valueOf(cvtr.convert(_value.doubleValue()));
return new DecimalMeasure<Q>(result, unit);
}
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value.doubleValue();
return _unit.getConverterTo(unit).convert(_value.doubleValue());
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,76 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import javax.measure.quantity.Quantity;
import javax.measure.unit.Unit;
/**
* <p> This interface represents the measurable, countable, or comparable
* property or aspect of a thing.</p>
*
* <p> Implementing instances are typically the result of a measurement:[code]
* Measurable<Mass> weight = Measure.valueOf(180.0, POUND);
* [/code]
* They can also be created from custom classes:[code]
* class Delay implements Measurable<Duration> {
* private long nanoSeconds; // Implicit internal unit.
* public double doubleValue(Unit<Velocity> unit) { ... }
* public long longValue(Unit<Velocity> unit) { ... }
* }
* Thread.wait(new Delay(24, HOUR)); // Assuming Thread.wait(Measurable<Duration>) method.
* [/code]</p>
*
* <p> Although measurable instances are for the most part scalar quantities;
* more complex implementations (e.g. vectors, data set) are allowed as
* long as an aggregate magnitude can be determined. For example:[code]
* class Velocity3D implements Measurable<Velocity> {
* private double x, y, z; // Meter per seconds.
* public double doubleValue(Unit<Velocity> unit) { ... } // Returns vector norm.
* ...
* }
* class Sensors<Q extends Quantity> extends Measure<double[], Q> {
* public doubleValue(Unit<Q> unit) { ... } // Returns median value.
* ...
* } [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.1, June 8, 2007
*/
public interface Measurable<Q extends Quantity> extends Comparable<Measurable<Q>> {
/**
* Returns the value of this measurable stated in the specified unit as
* a <code>double</code>. If the measurable has too great a magnitude to
* be represented as a <code>double</code>, it will be converted to
* <code>Double.NEGATIVE_INFINITY</code> or
* <code>Double.POSITIVE_INFINITY</code> as appropriate.
*
* @param unit the unit in which this measurable value is stated.
* @return the numeric value after conversion to type <code>double</code>.
*/
double doubleValue(Unit<Q> unit);
/**
* Returns the estimated integral value of this measurable stated in
* the specified unit as a <code>long</code>.
*
* <p> Note: This method differs from the <code>Number.longValue()</code>
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).</p>
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type <code>long</code>.
* @throws ArithmeticException if this quantity cannot be represented
* as a <code>long</code> number in the specified unit.
*/
long longValue(Unit<Q> unit) throws ArithmeticException;
}

View File

@ -0,0 +1,449 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.measure.quantity.Quantity;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
/**
* <p> This class represents the result of a measurement stated in a
* known unit.</p>
*
* <p> There is no constraint upon the measurement value itself: scalars,
* vectors, or even data sets are valid values as long as
* an aggregate magnitude can be determined (see {@link Measurable}).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public abstract class Measure<V, Q extends Quantity> implements Measurable<Q>,
Serializable {
/**
* Default constructor.
*/
protected Measure() {
}
/**
* Returns the scalar measure for the specified <code>double</code>
* stated in the specified unit.
*
* @param doubleValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Double, Q> valueOf(
double doubleValue, Unit<Q> unit) {
return new Double<Q>(doubleValue, unit);
}
/**
* Returns the scalar measure for the specified <code>double</code>
* stated in the specified unit.
*
* @param longValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Long, Q> valueOf(
long longValue, Unit<Q> unit) {
return new Long<Q>(longValue, unit);
}
/**
* Returns the scalar measure for the specified <code>float</code>
* stated in the specified unit.
*
* @param floatValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Float, Q> valueOf(
float floatValue, Unit<Q> unit) {
return new Float<Q>(floatValue, unit);
}
/**
* Returns the scalar measure for the specified <code>int</code>
* stated in the specified unit.
*
* @param intValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Integer, Q> valueOf(
int intValue, Unit<Q> unit) {
return new Integer<Q>(intValue, unit);
}
/**
* Returns the measurement value of this measure.
*
* @return the measurement value.
*/
public abstract V getValue();
/**
* Returns the measurement unit of this measure.
*
* @return the measurement unit.
*/
public abstract Unit<Q> getUnit();
/**
* Returns the measure equivalent to this measure but stated in the
* specified unit. This method may result in lost of precision
* (e.g. measure of integral value).
*
* @param unit the new measurement unit.
* @return the measure stated in the specified unit.
*/
public abstract Measure<V, Q> to(Unit<Q> unit);
/**
* Returns the value of this measure stated in the specified unit as
* a <code>double</code>. If the measure has too great a magnitude to
* be represented as a <code>double</code>, it will be converted to
* <code>Double.NEGATIVE_INFINITY</code> or
* <code>Double.POSITIVE_INFINITY</code> as appropriate.
*
* @param unit the unit in which this measure is stated.
* @return the numeric value after conversion to type <code>double</code>.
*/
public abstract double doubleValue(Unit<Q> unit);
/**
* Returns the estimated integral value of this measure stated in
* the specified unit as a <code>long</code>.
*
* <p> Note: This method differs from the <code>Number.longValue()</code>
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).</p>
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type <code>long</code>.
* @throws ArithmeticException if this quantity cannot be represented
* as a <code>long</code> number in the specified unit.
*/
public long longValue(Unit<Q> unit) throws ArithmeticException {
double doubleValue = doubleValue(unit);
if (java.lang.Double.isNaN(doubleValue)
|| (doubleValue < java.lang.Long.MIN_VALUE)
|| (doubleValue > java.lang.Long.MAX_VALUE))
throw new ArithmeticException(doubleValue + " " + unit
+ " cannot be represented as long");
return Math.round(doubleValue);
}
/**
* Returns the value of this measure stated in the specified unit as a
* <code>float</code>. If the measure has too great a magnitude to be
* represented as a <code>float</code>, it will be converted to
* <code>Float.NEGATIVE_INFINITY</code> or
* <code>Float.POSITIVE_INFINITY</code> as appropriate.
*
* @param unit the unit in which the measure is stated.
* @return the numeric value after conversion to type <code>float</code>.
*/
public float floatValue(Unit<Q> unit) {
return (float) doubleValue(unit);
}
/**
* Returns the estimated integral value of this measure stated in
* the specified unit as a <code>int</code>.
*
* <p> Note: This method differs from the <code>Number.intValue()</code>
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).</p>
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type <code>int</code>.
* @throws ArithmeticException if this quantity cannot be represented
* as a <code>int</code> number in the specified unit.
*/
public int intValue(Unit<Q> unit) {
long longValue = longValue(unit);
if ((longValue > java.lang.Integer.MAX_VALUE)
|| (longValue < java.lang.Integer.MIN_VALUE))
throw new ArithmeticException("Overflow");
return (int) longValue;
}
/**
* Compares this measure against the specified object for
* strict equality (same unit and amount).
* To compare measures stated using different units the
* {@link #compareTo} method should be used.
*
* @param obj the object to compare with.
* @return <code>true</code> if both objects are identical (same
* unit and same amount); <code>false</code> otherwise.
*/
@SuppressWarnings("unchecked")
public boolean equals(Object obj) {
if (!(obj instanceof Measure))
return false;
Measure that = (Measure) obj;
return this.getUnit().equals(that.getUnit())
&& this.getValue().equals(that.getValue());
}
/**
* Returns the hash code for this scalar.
*
* @return the hash code value.
*/
public int hashCode() {
return getUnit().hashCode() + getValue().hashCode();
}
/**
* Returns the <code>String</code> representation of this measure
* The string produced for a given measure is always the same;
* it is not affected by locale. This means that it can be used
* as a canonical string representation for exchanging data,
* or as a key for a Hashtable, etc. Locale-sensitive
* measure formatting and parsing is handled by the {@link
* MeasureFormat} class and its subclasses.
*
* @return the string representation of this measure.
*/
public String toString() {
if (getUnit() instanceof CompoundUnit)
return MeasureFormat.DEFAULT.formatCompound(doubleValue(getUnit()),
getUnit(), new StringBuffer(), null).toString();
return getValue() + " " + getUnit();
}
/**
* Compares this measure to the specified measurable quantity.
* This method compares the {@link Measurable#doubleValue(Unit)} of
* both this measure and the specified measurable stated in the
* same unit (this measure's {@link #getUnit() unit}).
*
* @return a negative integer, zero, or a positive integer as this measure
* is less than, equal to, or greater than the specified measurable
* quantity.
* @return <code>Double.compare(this.doubleValue(getUnit()),
* that.doubleValue(getUnit()))</code>
*/
public int compareTo(Measurable<Q> that) {
return java.lang.Double.compare(doubleValue(getUnit()), that
.doubleValue(getUnit()));
}
/**
* Holds scalar implementation for <code>double</code> values.
*/
private static final class Double<Q extends Quantity> extends
Measure<java.lang.Double, Q> {
private final double _value;
private final Unit<Q> _unit;
public Double(double value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Double getValue() {
return _value;
}
@Override
public Measure<java.lang.Double, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Double<Q>(doubleValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for <code>long</code> values.
*/
private static final class Long<Q extends Quantity> extends
Measure<java.lang.Long, Q> {
private final long _value;
private final Unit<Q> _unit;
public Long(long value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Long getValue() {
return _value;
}
@Override
public Measure<java.lang.Long, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Long<Q>(longValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
public long longValue(Unit<Q> unit) throws ArithmeticException {
if ((unit == _unit) || (unit.equals(_unit)))
return _value; // No conversion, returns value directly.
return super.longValue(unit);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for <code>float</code> values.
*/
private static final class Float<Q extends Quantity> extends
Measure<java.lang.Float, Q> {
private final float _value;
private final Unit<Q> _unit;
public Float(float value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Float getValue() {
return _value;
}
@Override
public Measure<java.lang.Float, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Float<Q>(floatValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for <code>long</code> values.
*/
private static final class Integer<Q extends Quantity> extends
Measure<java.lang.Integer, Q> {
private final int _value;
private final Unit<Q> _unit;
public Integer(int value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Integer getValue() {
return _value;
}
@Override
public Measure<java.lang.Integer, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Integer<Q>(intValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
public long longValue(Unit<Q> unit) throws ArithmeticException {
if ((unit == _unit) || (unit.equals(_unit)))
return _value; // No conversion, returns value directly.
return super.longValue(unit);
}
private static final long serialVersionUID = 1L;
}
/**
* @deprecated {@link DecimalMeasure} should be used directly.
*/
public static <Q extends Quantity> Measure<BigDecimal, Q> valueOf(
BigDecimal decimal, Unit<Q> unit) {
return DecimalMeasure.valueOf(decimal, unit);
}
/**
* @deprecated {@link DecimalMeasure} should be used directly and
* <code>MathContext</code> specified explicitly when
* {@link DecimalMeasure#to(Unit, MathContext) converting}.
*/
public static <Q extends Quantity> Measure<BigDecimal, Q> valueOf(
BigDecimal decimal, Unit<Q> unit, MathContext mathContext) {
return DecimalMeasure.valueOf(decimal, unit);
}
/**
* @deprecated {@link VectorMeasure} should be used directly.
*/
public static <Q extends Quantity> Measure<double[], Q> valueOf(
double[] components, Unit<Q> unit) {
return VectorMeasure.valueOf(components, unit);
}
}

View File

@ -0,0 +1,169 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.math.BigDecimal;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
/**
* <p> This class provides the interface for formatting and parsing {@link
* Measure measures}.</p>
*
* <p> As a minimum, instances of this class should be able to parse/format
* measure using {@link CompoundUnit}. </p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public abstract class MeasureFormat extends Format {
/**
* Returns the measure format for the default locale.
*
* @return <code>getInstance(Number.getInstance(), Unit.getInstance())</code>
*/
public static MeasureFormat getInstance() {
return DEFAULT;
}
static final NumberUnit DEFAULT = new NumberUnit(NumberFormat
.getInstance(), UnitFormat.getInstance());
/**
* Returns the measure format using the specified number format and
* unit format (the number and unit are separated by a space).
*
* @param numberFormat the number format.
* @param unitFormat the unit format.
* @return the corresponding format.
*/
public static MeasureFormat getInstance(NumberFormat numberFormat,
UnitFormat unitFormat) {
return new NumberUnit(numberFormat, unitFormat);
}
// Holds default implementation.
static final class NumberUnit extends MeasureFormat {
private final NumberFormat _numberFormat;
private final UnitFormat _unitFormat;
private NumberUnit(NumberFormat numberFormat, UnitFormat unitFormat) {
_numberFormat = numberFormat;
_unitFormat = unitFormat;
}
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
Measure<?, ?> measure = (Measure<?, ?>) obj;
Object value = measure.getValue();
Unit<?> unit = measure.getUnit();
if (value instanceof Number) {
if (unit instanceof CompoundUnit)
return formatCompound(((Number) value).doubleValue(),
(CompoundUnit<?>) unit, toAppendTo, pos);
_numberFormat.format(value, toAppendTo, pos);
} else {
toAppendTo.append(value);
}
if (!measure.getUnit().equals(Unit.ONE)) {
toAppendTo.append(' ');
_unitFormat.format(unit, toAppendTo, pos);
}
return toAppendTo;
}
// Measure using Compound unit have no separators in their representation.
StringBuffer formatCompound(double value, Unit<?> unit,
StringBuffer toAppendTo, FieldPosition pos) {
if (!(unit instanceof CompoundUnit)) {
toAppendTo.append((long) value);
return _unitFormat.format(unit, toAppendTo, pos);
}
Unit<?> high = ((CompoundUnit<?>) unit).getHigher();
Unit<?> low = ((CompoundUnit<?>) unit).getLower(); // The unit in which the value is stated.
long highValue = (long) low.getConverterTo(high).convert(value);
double lowValue = value
- high.getConverterTo(low).convert(highValue);
formatCompound(highValue, high, toAppendTo, pos);
formatCompound(lowValue, low, toAppendTo, pos);
return toAppendTo;
}
@Override
public Object parseObject(String source, ParsePosition pos) {
int start = pos.getIndex();
try {
int i = start;
Number value = _numberFormat.parse(source, pos);
if (i == pos.getIndex())
return null; // Cannot parse.
i = pos.getIndex();
if (i >= source.length())
return measureOf(value, Unit.ONE); // No unit.
boolean isCompound = !Character.isWhitespace(source.charAt(i));
if (isCompound)
return parseCompound(value, source, pos);
if (++i >= source.length())
return measureOf(value, Unit.ONE); // No unit.
pos.setIndex(i); // Skips separator.
Unit<?> unit = _unitFormat.parseProductUnit(source, pos);
return measureOf(value, unit);
} catch (ParseException e) {
pos.setIndex(start);
pos.setErrorIndex(e.getErrorOffset());
return null;
}
}
@SuppressWarnings("unchecked")
private Object parseCompound(Number highValue, String source,
ParsePosition pos) throws ParseException {
Unit high = _unitFormat.parseSingleUnit(source, pos);
int i = pos.getIndex();
if (i >= source.length()
|| Character.isWhitespace(source.charAt(i)))
return measureOf(highValue, high);
Measure lowMeasure = (Measure) parseObject(source, pos);
Unit unit = lowMeasure.getUnit();
long l = lowMeasure.longValue(unit)
+ (long) high.getConverterTo(unit).convert(
highValue.longValue());
return Measure.valueOf(l, unit);
}
@SuppressWarnings("unchecked")
private static Measure measureOf(Number value, Unit unit) {
if (value instanceof Double) {
return Measure.valueOf(value.doubleValue(), unit);
} else if (value instanceof Long) {
return Measure.valueOf(value.longValue(), unit);
} else if (value instanceof Float) {
return Measure.valueOf(value.floatValue(), unit);
} else if (value instanceof Integer) {
return Measure.valueOf(value.intValue(), unit);
} else if (value instanceof BigDecimal) {
return DecimalMeasure.valueOf((BigDecimal) value, unit);
} else {
return Measure.valueOf(value.doubleValue(), unit);
}
}
private static final long serialVersionUID = 1L;
}
}

View File

@ -0,0 +1,273 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
/**
* <p> This class represents a measurement vector of two or more dimensions.
* For example:[code]
* VectorMeasure<Length> dimension = VectorMeasure.valueOf(12.0, 30.0, 40.0, MILLIMETER);
* VectorMeasure<Velocity> v2d = VectorMeasure.valueOf(-2.2, -3.0, KNOTS);
* VectorMeasure<ElectricCurrent> c2d = VectorMeasure.valueOf(-7.3, 3.5, NANOAMPERE);
* [/code]
* </p>
*
* <p> Subclasses may provide fixed dimensions specializations:[code]
* class Velocity2D extends VectorMeasure<Velocity> {
* public Velocity2D(double x, double y, Unit<Velocity> unit) {
* ...
* }
* }
* [/code]</p>
*
* <p> Measurement vectors may use {@link CompoundUnit compound units}:[code]
* VectorMeasure<Angle> latLong = VectorMeasure.valueOf(12.345, 22.23, DEGREE_ANGLE);
* Unit<Angle> HOUR_MINUTE_SECOND_ANGLE = DEGREE_ANGLE.compound(MINUTE_ANGLE).compound(SECOND_ANGLE);
* System.out.println(latLong.to(HOUR_MINUTE_SECOND_ANGLE));
*
* > [12°19'42", 22°12'48"] [/code]</p>
*
* <p> Instances of this class (and sub-classes) are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.3, October 3, 2007
*/
public abstract class VectorMeasure<Q extends Quantity> extends Measure<double[], Q> {
/**
* Default constructor (for sub-classes).
*/
protected VectorMeasure() {
}
/**
* Returns a 2-dimensional measurement vector.
*
* @param x the first vector component value.
* @param y the second vector component value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> VectorMeasure<Q> valueOf(
double x, double y, Unit<Q> unit) {
return new TwoDimensional<Q>(x, y, unit);
}
/**
* Returns a 3-dimensional measurement vector.
*
* @param x the first vector component value.
* @param y the second vector component value.
* @param z the third vector component value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> VectorMeasure<Q> valueOf(
double x, double y, double z, Unit<Q> unit) {
return new ThreeDimensional<Q>(x, y, z, unit);
}
/**
* Returns a multi-dimensional measurement vector.
*
* @param components the vector component values.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> VectorMeasure<Q> valueOf(double[] components,
Unit<Q> unit) {
return new MultiDimensional<Q>(components, unit);
}
/**
* Returns the measurement vector equivalent to this one but stated in the
* specified unit.
*
* @param unit the new measurement unit.
* @return the vector measure stated in the specified unit.
*/
public abstract VectorMeasure<Q> to(Unit<Q> unit);
/**
* Returns the norm of this measurement vector stated in the specified
* unit.
*
* @param unit the unit in which the norm is stated.
* @return <code>|this|</code>
*/
public abstract double doubleValue(Unit<Q> unit);
/**
* Returns the <code>String</code> representation of this measurement
* vector (for example <code>[2.3 m/s, 5.6 m/s]</code>).
*
* @return the textual representation of the measurement vector.
*/
public String toString() {
double[] values = getValue();
Unit<Q> unit = getUnit();
StringBuffer tmp = new StringBuffer();
tmp.append('[');
for (double v : values) {
if (tmp.length() > 1) {
tmp.append(", ");
}
if (unit instanceof CompoundUnit) {
MeasureFormat.DEFAULT.formatCompound(v, unit, tmp, null);
} else {
tmp.append(v).append(" ").append(unit);
}
}
tmp.append("] ");
return tmp.toString();
}
// Holds 2-dimensional implementation.
private static class TwoDimensional<Q extends Quantity> extends VectorMeasure<Q> {
private final double _x;
private final double _y;
private final Unit<Q> _unit;
private TwoDimensional(double x, double y, Unit<Q> unit) {
_x = x;
_y = y;
_unit = unit;
}
@Override
public double doubleValue(Unit<Q> unit) {
double norm = Math.sqrt(_x * _x + _y * _y);
if ((unit == _unit) || (unit.equals(_unit)))
return norm;
return _unit.getConverterTo(unit).convert(norm);
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public double[] getValue() {
return new double[] { _x, _y };
}
@Override
public TwoDimensional<Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
return new TwoDimensional<Q>(cvtr.convert(_x), cvtr.convert(_y), unit);
}
private static final long serialVersionUID = 1L;
}
// Holds 3-dimensional implementation.
private static class ThreeDimensional<Q extends Quantity> extends VectorMeasure<Q> {
private final double _x;
private final double _y;
private final double _z;
private final Unit<Q> _unit;
private ThreeDimensional(double x, double y, double z, Unit<Q> unit) {
_x = x;
_y = y;
_z = z;
_unit = unit;
}
@Override
public double doubleValue(Unit<Q> unit) {
double norm = Math.sqrt(_x * _x + _y * _y + _z * _z);
if ((unit == _unit) || (unit.equals(_unit)))
return norm;
return _unit.getConverterTo(unit).convert(norm);
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public double[] getValue() {
return new double[] { _x, _y, _z };
}
@Override
public ThreeDimensional<Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
return new ThreeDimensional<Q>(cvtr.convert(_x), cvtr.convert(_y), cvtr.convert(_z), unit);
}
private static final long serialVersionUID = 1L;
}
// Holds multi-dimensional implementation.
private static class MultiDimensional<Q extends Quantity> extends VectorMeasure<Q> {
private final double[] _components;
private final Unit<Q> _unit;
private MultiDimensional(double[] components, Unit<Q> unit) {
_components = components.clone();
_unit = unit;
}
@Override
public double doubleValue(Unit<Q> unit) {
double normSquare = _components[0] * _components[0];
for (int i=1, n=_components.length; i < n;) {
double d = _components[i++];
normSquare += d * d;
}
if ((unit == _unit) || (unit.equals(_unit)))
return Math.sqrt(normSquare);
return _unit.getConverterTo(unit).convert(Math.sqrt(normSquare));
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public double[] getValue() {
return _components.clone();
}
@Override
public MultiDimensional<Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
double[] newValues = new double[_components.length];
for (int i=0; i < _components.length; i++) {
newValues[i] = cvtr.convert(_components[i]);
}
return new MultiDimensional<Q>(newValues, unit);
}
private static final long serialVersionUID = 1L;
}
}

View File

@ -0,0 +1,80 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a converter adding a constant offset
* (approximated as a <code>double</code>) to numeric values.</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class AddConverter extends UnitConverter {
/**
* Holds the offset.
*/
private final double _offset;
/**
* Creates an add converter with the specified offset.
*
* @param offset the offset value.
* @throws IllegalArgumentException if offset is zero (or close to zero).
*/
public AddConverter(double offset) {
if ((float)offset == 0.0)
throw new IllegalArgumentException("Identity converter not allowed");
_offset = offset;
}
/**
* Returns the offset value for this add converter.
*
* @return the offset value.
*/
public double getOffset() {
return _offset;
}
@Override
public UnitConverter inverse() {
return new AddConverter(- _offset);
}
@Override
public double convert(double amount) {
return amount + _offset;
}
@Override
public boolean isLinear() {
return false;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
if (converter instanceof AddConverter) {
double offset = _offset + ((AddConverter)converter)._offset;
return valueOf(offset);
} else {
return super.concatenate(converter);
}
}
private static UnitConverter valueOf(double offset) {
float asFloat = (float) offset;
return asFloat == 0.0f ? UnitConverter.IDENTITY : new AddConverter(offset);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,38 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* Signals that a problem of some sort has occurred either when creating a
* converter between two units or during the conversion itself.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 2, 2006
*/
public class ConversionException extends RuntimeException {
/**
* Constructs a <code>ConversionException</code> with no detail message.
*/
public ConversionException() {
super();
}
/**
* Constructs a <code>ConversionException</code> with the specified detail
* message.
*
* @param message the detail message.
*/
public ConversionException(String message) {
super(message);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,107 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a logarithmic converter. Such converter
* is typically used to create logarithmic unit. For example:[code]
* Unit<Dimensionless> BEL = Unit.ONE.transform(new LogConverter(10).inverse());
* [/code]</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class LogConverter extends UnitConverter {
/**
* Holds the logarithmic base.
*/
private final double _base;
/**
* Holds the natural logarithm of the base.
*/
private final double _logBase;
/**
* Holds the inverse of the natural logarithm of the base.
*/
private final double _invLogBase;
/**
* Holds the inverse of this converter.
*/
private final Inverse _inverse = new Inverse();
/**
* Creates a logarithmic converter having the specified base.
*
* @param base the logarithmic base (e.g. <code>Math.E</code> for
* the Natural Logarithm).
*/
public LogConverter(double base) {
_base = base;
_logBase = Math.log(base);
_invLogBase = 1.0 / _logBase;
}
/**
* Returns the logarithmic base of this converter.
*
* @return the logarithmic base (e.g. <code>Math.E</code> for
* the Natural Logarithm).
*/
public double getBase() {
return _base;
}
@Override
public UnitConverter inverse() {
return _inverse;
}
@Override
public double convert(double amount) {
return _invLogBase * Math.log(amount);
}
@Override
public boolean isLinear() {
return false;
}
/**
* This inner class represents the inverse of the logarithmic converter
* (exponentiation converter).
*/
private class Inverse extends UnitConverter {
@Override
public UnitConverter inverse() {
return LogConverter.this;
}
@Override
public double convert(double amount) {
return Math.exp(_logBase * amount);
}
@Override
public boolean isLinear() {
return false;
}
private static final long serialVersionUID = 1L;
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,86 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a converter multiplying numeric values by a
* constant scaling factor (approximated as a <code>double</code>).
* For exact scaling conversions {@link RationalConverter} is preferred.</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class MultiplyConverter extends UnitConverter {
/**
* Holds the scale factor.
*/
private final double _factor;
/**
* Creates a multiply converter with the specified scale factor.
*
* @param factor the scale factor.
* @throws IllegalArgumentException if offset is one (or close to one).
*/
public MultiplyConverter(double factor) {
if ((float)factor == 1.0)
throw new IllegalArgumentException("Identity converter not allowed");
_factor = factor;
}
/**
* Returns the scale factor.
*
* @return the scale factor.
*/
public double getFactor() {
return _factor;
}
@Override
public UnitConverter inverse() {
return new MultiplyConverter(1.0 / _factor);
}
@Override
public double convert(double amount) {
return _factor * amount;
}
@Override
public boolean isLinear() {
return true;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
if (converter instanceof MultiplyConverter) {
double factor = _factor * ((MultiplyConverter) converter)._factor;
return valueOf(factor);
} else if (converter instanceof RationalConverter) {
double factor = _factor
* ((RationalConverter) converter).getDividend()
/ ((RationalConverter) converter).getDivisor();
return valueOf(factor);
} else {
return super.concatenate(converter);
}
}
private static UnitConverter valueOf(double factor) {
float asFloat = (float) factor;
return asFloat == 1.0f ? UnitConverter.IDENTITY
: new MultiplyConverter(factor);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,127 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a converter multiplying numeric values by an
* exact scaling factor (represented as the quotient of two
* <code>long</code> numbers).</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class RationalConverter extends UnitConverter {
/**
* Holds the converter dividend.
*/
private final long _dividend;
/**
* Holds the converter divisor (always positive).
*/
private final long _divisor;
/**
* Creates a rational converter with the specified dividend and
* divisor.
*
* @param dividend the dividend.
* @param divisor the positive divisor.
* @throws IllegalArgumentException if <code>divisor &lt; 0</code>
* @throws IllegalArgumentException if <code>dividend == divisor</code>
*/
public RationalConverter(long dividend, long divisor) {
if (divisor < 0)
throw new IllegalArgumentException("Negative divisor");
if (dividend == divisor)
throw new IllegalArgumentException("Identity converter not allowed");
_dividend = dividend;
_divisor = divisor;
}
/**
* Returns the dividend for this rational converter.
*
* @return this converter dividend.
*/
public long getDividend() {
return _dividend;
}
/**
* Returns the positive divisor for this rational converter.
*
* @return this converter divisor.
*/
public long getDivisor() {
return _divisor;
}
@Override
public UnitConverter inverse() {
return _dividend < 0 ? new RationalConverter(-_divisor, -_dividend)
: new RationalConverter(_divisor, _dividend);
}
@Override
public double convert(double amount) {
return amount * _dividend / _divisor;
}
@Override
public boolean isLinear() {
return true;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
if (converter instanceof RationalConverter) {
RationalConverter that = (RationalConverter) converter;
long dividendLong = this._dividend * that._dividend;
long divisorLong = this._divisor * that._divisor;
double dividendDouble = ((double)this._dividend) * that._dividend;
double divisorDouble = ((double)this._divisor) * that._divisor;
if ((dividendLong != dividendDouble) ||
(divisorLong != divisorDouble)) { // Long overflows.
return new MultiplyConverter(dividendDouble / divisorDouble);
}
long gcd = gcd(dividendLong, divisorLong);
return RationalConverter.valueOf(dividendLong / gcd, divisorLong / gcd);
} else if (converter instanceof MultiplyConverter) {
return converter.concatenate(this);
} else {
return super.concatenate(converter);
}
}
private static UnitConverter valueOf(long dividend, long divisor) {
return (dividend == 1L) && (divisor == 1L) ? UnitConverter.IDENTITY
: new RationalConverter(dividend, divisor);
}
/**
* Returns the greatest common divisor (Euclid's algorithm).
*
* @param m the first number.
* @param nn the second number.
* @return the greatest common divisor.
*/
private static long gcd(long m, long n) {
if (n == 0L) {
return m;
} else {
return gcd(n, m % n);
}
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,188 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
import java.io.Serializable;
/**
* <p> This class represents a converter of numeric values.</p>
*
* <p> It is not required for sub-classes to be immutable
* (e.g. currency converter).</p>
*
* <p> Sub-classes must ensure unicity of the {@link #IDENTITY identity}
* converter. In other words, if the result of an operation is equivalent
* to the identity converter, then the unique {@link #IDENTITY} instance
* should be returned.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public abstract class UnitConverter implements Serializable {
/**
* Holds the identity converter (unique). This converter does nothing
* (<code>ONE.convert(x) == x</code>).
*/
public static final UnitConverter IDENTITY = new Identity();
/**
* Default constructor.
*/
protected UnitConverter() {
}
/**
* Returns the inverse of this converter. If <code>x</code> is a valid
* value, then <code>x == inverse().convert(convert(x))</code> to within
* the accuracy of computer arithmetic.
*
* @return the inverse of this converter.
*/
public abstract UnitConverter inverse();
/**
* Converts a double value.
*
* @param x the numeric value to convert.
* @return the converted numeric value.
* @throws ConversionException if an error occurs during conversion.
*/
public abstract double convert(double x) throws ConversionException;
/**
* Indicates if this converter is linear. A converter is linear if
* <code>convert(u + v) == convert(u) + convert(v)</code> and
* <code>convert(r * u) == r * convert(u)</code>.
* For linear converters the following property always hold:[code]
* y1 = c1.convert(x1);
* y2 = c2.convert(x2);
* then y1*y2 = c1.concatenate(c2).convert(x1*x2)[/code]
*
* @return <code>true</code> if this converter is linear;
* <code>false</code> otherwise.
*/
public abstract boolean isLinear();
/**
* Indicates whether this converter is considered the same as the
* converter specified. To be considered equal this converter
* concatenated with the one specified must returns the {@link #IDENTITY}.
*
* @param cvtr the converter with which to compare.
* @return <code>true</code> if the specified object is a converter
* considered equals to this converter;<code>false</code> otherwise.
*/
public boolean equals(Object cvtr) {
if (!(cvtr instanceof UnitConverter)) return false;
return this.concatenate(((UnitConverter)cvtr).inverse()) == IDENTITY;
}
/**
* Returns a hash code value for this converter. Equals object have equal
* hash codes.
*
* @return this converter hash code value.
* @see #equals
*/
public int hashCode() {
return Float.floatToIntBits((float)convert(1.0));
}
/**
* Concatenates this converter with another converter. The resulting
* converter is equivalent to first converting by the specified converter,
* and then converting by this converter.
*
* <p>Note: Implementations must ensure that the {@link #IDENTITY} instance
* is returned if the resulting converter is an identity
* converter.</p>
*
* @param converter the other converter.
* @return the concatenation of this converter with the other converter.
*/
public UnitConverter concatenate(UnitConverter converter) {
return (converter == IDENTITY) ? this : new Compound(converter, this);
}
/**
* This inner class represents the identity converter (singleton).
*/
private static final class Identity extends UnitConverter {
@Override
public UnitConverter inverse() {
return this;
}
@Override
public double convert(double x) {
return x;
}
@Override
public boolean isLinear() {
return true;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
return converter;
}
private static final long serialVersionUID = 1L;
}
/**
* This inner class represents a compound converter.
*/
private static final class Compound extends UnitConverter {
/**
* Holds the first converter.
*/
private final UnitConverter _first;
/**
* Holds the second converter.
*/
private final UnitConverter _second;
/**
* Creates a compound converter resulting from the combined
* transformation of the specified converters.
*
* @param first the first converter.
* @param second the second converter.
*/
private Compound(UnitConverter first, UnitConverter second) {
_first = first;
_second = second;
}
@Override
public UnitConverter inverse() {
return new Compound(_second.inverse(), _first.inverse());
}
@Override
public double convert(double x) {
return _second.convert(_first.convert(x));
}
@Override
public boolean isLinear() {
return _first.isLinear() && _second.isLinear();
}
private static final long serialVersionUID = 1L;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -0,0 +1,5 @@
<body>
<p> Provides support for unit conversion.</p>
<h3>UML Diagram</h3>
<IMG alt="UML Diagram" src="doc-files/converter.png">
</body>

View File

@ -0,0 +1,77 @@
<body>
<p> Provides strongly typed measurements to enforce compile-time
check of parameters consistency and avoid interface errors.</p>
<p> Let's take the following example:[code]
class Person {
void setWeight(double weight);
}[/code]
Should the weight be in pound, kilogram ??<br>
Using measures there is no room for error:[code]
class Person {
void setWeight(Measurable<Mass> weight);
}[/code]
Not only the interface is cleaner (the weight has to be of mass type);
but also there is no confusion on the measurement unit:[code]
double weightInKg = weight.doubleValue(KILOGRAM);
double weightInLb = weight.doubleValue(POUND);[/code]
Measurable work hand-in-hand with units (also parameterized).
For example, the following would result in compile-time error:[code]
double weightInLiter = weight.doubleValue(LITER); // Compile error, Unit<Mass> required.
[/code]</p>
<p> Users may create their own {@link javax.measure.Measurable
Measurable} implementation:[code]
public class Period implements Measurable<Duration> {
long nanoseconds;
...
}
public class Distance implements Measurable<Length> {
double meters;
...
}
public class Velocity3D implements Measurable<Velocity> {
double x, y, z; // In meters.
...
}
[/code]</p>
<p> Users may also combine a definite amount (scalar, vector, collection, etc.)
to a unit and make it a {@link javax.measure.Measure Measure} (and
a {@link javax.measure.Measurable Measurable} instance). For example:
[code]
// Scalar measurement (numerical).
person.setWeight(Measure.valueOf(180.0, POUND)); // Measure<Double, Mass>
timer.setPeriod(Measure.valueOf(20, MILLI(SECOND)); // Measure<Integer, Duration>
circuit.setCurrent(Measure.valueOf(Complex.valueOf(2, -3), AMPERE); // (2 - 3i) A
bottle.setPression(Measure.valueOf(Rational.valueOf(20, 100), ATMOSPHERE)); // (20/100) Atm
// Vector measurement.
abstract class MeasureVector<E, Q extends Quantity> extends Measure<E[], Q> {
... // doubleValue(Unit) returns vector norm.
}
MeasureVector<Double, Velocity> v = MeasureVector.valueOf(METRE_PER_SECOND, 1.0, 2.0, 3.0);
plane.setVelocity(v);
// Statistical measurement.
class Average<Q extends Quantity> extends Measure<double[], Q>{
... // doubleValue(Unit) returns average value.
}
sea.setTemperature(Average.valueOf(new double[] { 33.4, 44.55, 32.33} , CELCIUS));
// Measurement with uncertainty (and additional operations).
public class Amount<Q extends Quantity> extends Measurable<Q> {
public Amount(double value, double error, Unit<Q> unit) { ... }
public Amount<Q> plus(Amount<Q> that) {...}
public Amount<?> times(Amount<?> that) {...}
... // doubleValue(Unit) returns estimated value.
}
[/code]</p>
</body>

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate of change of velocity with respect to
* time. The system unit for this quantity is "m/s²" (meter per square second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Acceleration extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Acceleration> UNIT = SI.METRES_PER_SQUARE_SECOND;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the number of elementary entities (molecules, for
* example) of a substance. The system unit for this quantity is "mol" (mole).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface AmountOfSubstance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<AmountOfSubstance> UNIT = SI.MOLE;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the figure formed by two lines diverging from a
* common point. The system unit for this quantity is "rad" (radian).
* This quantity is dimensionless.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Angle extends Dimensionless {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Angle> UNIT = SI.RADIAN;
}

View File

@ -0,0 +1,30 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate of change of angular velocity with respect
* to time. The system unit for this quantity is "rad/s²" (radian per
* square second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface AngularAcceleration extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<AngularAcceleration> UNIT
= new ProductUnit<AngularAcceleration>(SI.RADIAN.divide(SI.SECOND.pow(2)));
}

View File

@ -0,0 +1,30 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate of change of angular displacement
* with respect to time. The system unit for this quantity is "rad/s"
* (radian per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface AngularVelocity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<AngularVelocity> UNIT
= new ProductUnit<AngularVelocity>(SI.RADIAN.divide(SI.SECOND));
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the extent of a planar region or of the surface of
* a solid measured in square units. The system unit for this quantity
* is "" (square meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Area extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Area> UNIT = SI.SQUARE_METRE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a catalytic activity. The system unit for this
* quantity is "kat" (katal).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface CatalyticActivity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<CatalyticActivity> UNIT = SI.KATAL;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a measure of data amount.
* The system unit for this quantity is "bit". This quantity is dimensionless.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface DataAmount extends Dimensionless {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<DataAmount> UNIT = SI.BIT;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the speed of data-transmission.
* The system unit for this quantity is "bit/s" (bit per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface DataRate extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<DataRate> UNIT = new ProductUnit<DataRate>(SI.BIT.divide(SI.SECOND));
}

View File

@ -0,0 +1,25 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.Unit;
/**
* This interface represents a dimensionless quantity.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Dimensionless extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Dimensionless> UNIT = Unit.ONE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a period of existence or persistence. The system
* unit for this quantity is "s" (second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Duration extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Duration> UNIT = SI.SECOND;
}

View File

@ -0,0 +1,32 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the dynamic viscosity.
* The system unit for this quantity is "Pa·s" (Pascal-Second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Viscosity">
* Wikipedia: Viscosity</a>
*/
public interface DynamicViscosity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<DynamicViscosity> UNIT
= new ProductUnit<DynamicViscosity>(SI.PASCAL.times(SI.SECOND));
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric capacitance. The system unit for this
* quantity is "F" (Farad).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricCapacitance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricCapacitance> UNIT = SI.FARAD;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric charge. The system unit for this
* quantity is "C" (Coulomb).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricCharge extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricCharge> UNIT = SI.COULOMB;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric conductance. The system unit for this
* quantity "S" (Siemens).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricConductance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricConductance> UNIT = SI.SIEMENS;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the amount of electric charge flowing past
* a specified circuit point per unit time. The system unit for
* this quantity is "A" (Ampere).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricCurrent extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricCurrent> UNIT = SI.AMPERE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric inductance. The system unit for this
* quantity is "H" (Henry).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricInductance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricInductance> UNIT = SI.HENRY;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric potential or electromotive force.
* The system unit for this quantity is "V" (Volt).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricPotential extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricPotential> UNIT = SI.VOLT;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric resistance.
* The system unit for this quantity is "Ω" (Ohm).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricResistance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricResistance> UNIT = SI.OHM;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the capacity of a physical system to do work.
* The system unit for this quantity "J" (Joule).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Energy extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Energy> UNIT = SI.JOULE;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a quantity that tends to produce an acceleration
* of a body in the direction of its application. The system unit for
* this quantity is "N" (Newton).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Force extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Force> UNIT = SI.NEWTON;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the number of times a specified phenomenon occurs
* within a specified interval. The system unit for this quantity is "Hz"
* (Hertz).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Frequency extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Frequency> UNIT = SI.HERTZ;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an illuminance. The system unit for this quantity
* is "lx" (lux).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Illuminance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Illuminance> UNIT = SI.LUX;
}

View File

@ -0,0 +1,31 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the diffusion of momentum.
* The system unit for this quantity is "m²/s".
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Viscosity">
* Wikipedia: Viscosity</a>
*/
public interface KinematicViscosity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<KinematicViscosity> UNIT
= new ProductUnit<KinematicViscosity>(SI.METRE.pow(2).divide(SI.SECOND));
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the extent of something along its greatest
* dimension or the extent of space between two objects or places.
* The system unit for this quantity is "m" (meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Length extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Length> UNIT = SI.METRE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a luminous flux. The system unit for this quantity
* is "lm" (lumen).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface LuminousFlux extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<LuminousFlux> UNIT = SI.LUMEN;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the luminous flux density per solid angle as
* measured in a given direction relative to the emitting source.
* The system unit for this quantity is "cd" (candela).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface LuminousIntensity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<LuminousIntensity> UNIT = SI.CANDELA;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a magnetic flux. The system unit for this quantity
* is "Wb" (Weber).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface MagneticFlux extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<MagneticFlux> UNIT = SI.WEBER;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a magnetic flux density. The system unit for this
* quantity is "T" (Tesla).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface MagneticFluxDensity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<MagneticFluxDensity> UNIT = SI.TESLA;
}

View File

@ -0,0 +1,29 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the measure of the quantity of matter that a body
* or an object contains. The mass of the body is not dependent on gravity
* and therefore is different from but proportional to its weight.
* The system unit for this quantity is "kg" (kilogram).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Mass extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Mass> UNIT = SI.KILOGRAM;
}

View File

@ -0,0 +1,31 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the movement of mass per time.
* The system unit for this quantity is "kg/s" (kilogram per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Mass_flow_rate">
* Wikipedia: Mass Flow Rate</a>
*/
public interface MassFlowRate extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
@SuppressWarnings("unchecked")
public final static Unit<MassFlowRate> UNIT
= (Unit<MassFlowRate>) SI.KILOGRAM.divide(SI.SECOND);
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate at which work is done. The system unit
* for this quantity is "W" (Watt).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Power extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Power> UNIT = SI.WATT;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a force applied uniformly over a surface.
* The system unit for this quantity is "Pa" (Pascal).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Pressure extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Pressure> UNIT = SI.PASCAL;
}

View File

@ -0,0 +1,31 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
/**
* <p> This interface represents any type of quantitative properties or
* attributes of thing. Mass, time, distance, heat, and angular separation
* are among the familiar examples of quantitative properties.</p>
*
* <p> Distinct quantities have usually different physical dimensions; although
* it is not required nor necessary, for example {@link Torque} and
* {@link Energy} have same dimension but are of different nature
* (vector for torque, scalar for energy).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.0, February 25, 2007
* @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a>
* @see <a href="http://en.wikipedia.org/wiki/Dimensional_analysis">
* Wikipedia: Dimensional Analysis</a>
*/
public interface Quantity {
// No method - Tagging interface.
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the amount of energy deposited per unit of
* mass. The system unit for this quantity is "Gy" (Gray).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface RadiationDoseAbsorbed extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<RadiationDoseAbsorbed> UNIT = SI.GRAY;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the effective (or "equivalent") dose of radiation
* received by a human or some other living organism. The system unit for
* this quantity is "Sv" (Sievert).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface RadiationDoseEffective extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<RadiationDoseEffective> UNIT = SI.SIEVERT;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a radioactive activity. The system unit for
* this quantity is "Bq" (Becquerel).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface RadioactiveActivity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<RadioactiveActivity> UNIT = SI.BECQUEREL;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the angle formed by three or more planes intersecting
* at a common point. The system unit for this quantity is "sr" (steradian).
* This quantity is dimensionless.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface SolidAngle extends Dimensionless {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<SolidAngle> UNIT = SI.STERADIAN;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This class represents the degree of hotness or coldness of a body or
* an environment. The system unit for this quantity is "K" (Kelvin).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Temperature extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Temperature> UNIT = SI.KELVIN;
}

View File

@ -0,0 +1,34 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the moment of a force. The system unit for this
* quantity is "N·m" (Newton-Meter).
*
* <p> Note: The Newton-metre ("N·m") is also a way of exressing a Joule (unit
* of energy). However, torque is not energy. So, to avoid confusion, we
* will use the units "N·m" for torque and not "J". This distinction occurs
* due to the scalar nature of energy and the vector nature of torque.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Torque extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Torque> UNIT =
new ProductUnit<Torque>(SI.NEWTON.times(SI.METRE));
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a distance traveled divided by the time of travel.
* The system unit for this quantity is "m/s" (meter per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Velocity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Velocity> UNIT = SI.METRES_PER_SECOND;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the amount of space occupied by a three-dimensional
* object or region of space, expressed in cubic units. The system unit for
* this quantity is "" (cubic meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Volume extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Volume> UNIT = SI.CUBIC_METRE;
}

View File

@ -0,0 +1,30 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a mass per unit volume of a substance under
* specified conditions of pressure and temperature. The system unit for
* this quantity is "kg/m³" (kilogram per cubic meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface VolumetricDensity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<VolumetricDensity> UNIT = new ProductUnit<VolumetricDensity>(
SI.KILOGRAM.divide(SI.METRE.pow(3)));
}

View File

@ -0,0 +1,32 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the volume of fluid passing a point in a system
* per unit of time. The system unit for this quantity is "m³/s"
* (cubic meter per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Rate_of_fluid_flow">
* Wikipedia: Volumetric Flow Rate</a>
*/
public interface VolumetricFlowRate extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
@SuppressWarnings("unchecked")
public final static Unit<VolumetricFlowRate> UNIT
= (Unit<VolumetricFlowRate>) SI.METRE.pow(3).divide(SI.SECOND);
}

View File

@ -0,0 +1,6 @@
<body>
<p> Provides quantitative properties or attributes of thing such as
mass, time, distance, heat, and angular separation.</p>
<p> Each quantity sub-interface holds a static <code>UNIT</code> field
holding the standard unit for the quantity.</p>
</body>

View File

@ -0,0 +1,126 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the units used in expressions to distinguish
* between quantities of a different nature but of the same dimensions.</p>
*
* <p> Instances of this class are created through the
* {@link Unit#alternate(String)} method.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public final class AlternateUnit<Q extends Quantity> extends DerivedUnit<Q> {
/**
* Holds the symbol.
*/
private final String _symbol;
/**
* Holds the parent unit (a system unit).
*/
private final Unit<?> _parent;
/**
* Creates an alternate unit for the specified unit identified by the
* specified symbol.
*
* @param symbol the symbol for this alternate unit.
* @param parent the system unit from which this alternate unit is
* derived.
* @throws UnsupportedOperationException if the source is not
* a standard unit.
* @throws IllegalArgumentException if the specified symbol is
* associated to a different unit.
*/
AlternateUnit(String symbol, Unit<?> parent) {
if (!parent.isStandardUnit())
throw new UnsupportedOperationException(this
+ " is not a standard unit");
_symbol = symbol;
_parent = parent;
// Checks if the symbol is associated to a different unit.
synchronized (Unit.SYMBOL_TO_UNIT) {
Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
if (unit == null) {
Unit.SYMBOL_TO_UNIT.put(symbol, this);
return;
}
if (unit instanceof AlternateUnit) {
AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit;
if (symbol.equals(existingUnit._symbol)
&& _parent.equals(existingUnit._parent))
return; // OK, same unit.
}
throw new IllegalArgumentException("Symbol " + symbol
+ " is associated to a different unit");
}
}
/**
* Returns the symbol for this alternate unit.
*
* @return this alternate unit symbol.
*/
public final String getSymbol() {
return _symbol;
}
/**
* Returns the parent unit from which this alternate unit is derived
* (a system unit itself).
*
* @return the parent of the alternate unit.
*/
@SuppressWarnings("unchecked")
public final Unit<? super Q> getParent() {
return (Unit<? super Q>) _parent;
}
@Override
public final Unit<? super Q> getStandardUnit() {
return this;
}
@Override
public final UnitConverter toStandardUnit() {
return UnitConverter.IDENTITY;
}
/**
* Indicates if this alternate unit is considered equals to the specified
* object (both are alternate units with equal symbol, equal base units
* and equal converter to base units).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof AlternateUnit))
return false;
AlternateUnit<?> thatUnit = (AlternateUnit<?>) that;
return this._symbol.equals(thatUnit._symbol); // Symbols are unique.
}
// Implements abstract method.
public int hashCode() {
return _symbol.hashCode();
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,112 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the building blocks on top of which all others
* units are created. Base units are typically dimensionally independent.
* The actual unit dimension is determinated by the current
* {@link Dimension.Model model}. For example using the {@link
* Dimension.Model#STANDARD standard} model, {@link SI#CANDELA}
* has the dimension of {@link SI#WATT watt}:[code]
* // Standard model.
* BaseUnit<Length> METER = new BaseUnit<Length>("m");
* BaseUnit<LuminousIntensity> CANDELA = new BaseUnit<LuminousIntensity>("cd");
* System.out.println(METER.getDimension());
* System.out.println(CANDELA.getDimension());
*
* > [L]
* > [L]²·[M]/[T]³
* [/code]</p>
* <p> This class represents the "standard base units" which includes SI base
* units and possibly others user-defined base units. It does not represent
* the base units of any specific {@link SystemOfUnits} (they would have
* be base units accross all possible systems otherwise).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
* @see <a href="http://en.wikipedia.org/wiki/SI_base_unit">
* Wikipedia: SI base unit</a>
*/
public class BaseUnit<Q extends Quantity> extends Unit<Q> {
/**
* Holds the symbol.
*/
private final String _symbol;
/**
* Creates a base unit having the specified symbol.
*
* @param symbol the symbol of this base unit.
* @throws IllegalArgumentException if the specified symbol is
* associated to a different unit.
*/
public BaseUnit(String symbol) {
_symbol = symbol;
// Checks if the symbol is associated to a different unit.
synchronized (Unit.SYMBOL_TO_UNIT) {
Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
if (unit == null) {
Unit.SYMBOL_TO_UNIT.put(symbol, this);
return;
}
if (!(unit instanceof BaseUnit))
throw new IllegalArgumentException("Symbol " + symbol
+ " is associated to a different unit");
}
}
/**
* Returns the unique symbol for this base unit.
*
* @return this base unit symbol.
*/
public final String getSymbol() {
return _symbol;
}
/**
* Indicates if this base unit is considered equals to the specified
* object (both are base units with equal symbol, standard dimension and
* standard transform).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof BaseUnit))
return false;
BaseUnit<?> thatUnit = (BaseUnit<?>) that;
return this._symbol.equals(thatUnit._symbol);
}
@Override
public int hashCode() {
return _symbol.hashCode();
}
@Override
public Unit<? super Q> getStandardUnit() {
return this;
}
@Override
public UnitConverter toStandardUnit() {
return UnitConverter.IDENTITY;
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,109 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the multi-radix units (such as "hour:min:sec").
* Instances of this class are created using the {@link Unit#compound
* Unit.compound} method.</p>
*
* <p> Examples of compound units:[code]
* Unit<Duration> HOUR_MINUTE_SECOND = HOUR.compound(MINUTE).compound(SECOND);
* Unit<Angle> DEGREE_MINUTE_ANGLE = DEGREE_ANGLE.compound(MINUTE_ANGLE);
* [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class CompoundUnit<Q extends Quantity> extends DerivedUnit<Q> {
/**
* Holds the higher unit.
*/
private final Unit<Q> _high;
/**
* Holds the lower unit.
*/
private final Unit<Q> _low;
/**
* Creates a compound unit from the specified units.
*
* @param high the high unit.
* @param low the lower unit(s)
* @throws IllegalArgumentException if both units do not the same system
* unit.
*/
CompoundUnit(Unit<Q> high, Unit<Q> low) {
if (!high.getStandardUnit().equals(low.getStandardUnit()))
throw new IllegalArgumentException(
"Both units do not have the same system unit");
_high = high;
_low = low;
}
/**
* Returns the lower unit of this compound unit.
*
* @return the lower unit.
*/
public Unit<Q> getLower() {
return _low;
}
/**
* Returns the higher unit of this compound unit.
*
* @return the higher unit.
*/
public Unit<Q> getHigher() {
return _high;
}
/**
* Indicates if this compound unit is considered equals to the specified
* object (both are compound units with same composing units in the
* same order).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof CompoundUnit))
return false;
CompoundUnit<?> thatUnit = (CompoundUnit<?>) that;
return this._high.equals(thatUnit._high)
&& this._low.equals(thatUnit._low);
}
@Override
public int hashCode() {
return _high.hashCode() ^ _low.hashCode();
}
@Override
public Unit<? super Q> getStandardUnit() {
return _low.getStandardUnit();
}
@Override
public UnitConverter toStandardUnit() {
return _low.toStandardUnit();
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.quantity.Quantity;
/**
* <p> This class identifies the units created by combining or transforming
* other units.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public abstract class DerivedUnit<Q extends Quantity> extends Unit<Q> {
/**
* Default constructor.
*/
protected DerivedUnit() {
}
}

View File

@ -0,0 +1,259 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.io.Serializable;
import javax.measure.converter.RationalConverter;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Dimensionless;
/**
* <p> This class represents the dimension of an unit. Two units <code>u1</code>
* and <code>u2</code> are {@link Unit#isCompatible compatible} if and
* only if <code>(u1.getDimension().equals(u2.getDimension())))</code>
* </p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
* @see <a href="http://en.wikipedia.org/wiki/Dimensional_analysis">
* Wikipedia: Dimensional Analysis</a>
*/
public final class Dimension implements Serializable {
/**
* Holds the current physical model.
*/
private static Model CurrentModel = Model.STANDARD;
/**
* Holds dimensionless.
*/
public static final Dimension NONE = new Dimension(Unit.ONE);
/**
* Holds length dimension (L).
*/
public static final Dimension LENGTH = new Dimension('L');
/**
* Holds mass dimension (M).
*/
public static final Dimension MASS = new Dimension('M');
/**
* Holds time dimension (T).
*/
public static final Dimension TIME = new Dimension('T');
/**
* Holds electric current dimension (I).
*/
public static final Dimension ELECTRIC_CURRENT = new Dimension('I');
/**
* Holds temperature dimension (θ).
*/
public static final Dimension TEMPERATURE = new Dimension('θ');
/**
* Holds amount of substance dimension (N).
*/
public static final Dimension AMOUNT_OF_SUBSTANCE = new Dimension('N');
/**
* Holds the pseudo unit associated to this dimension.
*/
private final Unit<?> _pseudoUnit;
/**
* Creates a new dimension associated to the specified symbol.
*
* @param symbol the associated symbol.
*/
public Dimension(char symbol) {
_pseudoUnit = new BaseUnit<Dimensionless>("[" + symbol + "]");
}
/**
* Creates a dimension having the specified pseudo-unit
* (base unit or product of base unit).
*
* @param pseudoUnit the pseudo-unit identifying this dimension.
*/
private Dimension(Unit<?> pseudoUnit) {
_pseudoUnit = pseudoUnit;
}
/**
* Returns the product of this dimension with the one specified.
*
* @param that the dimension multiplicand.
* @return <code>this * that</code>
*/
public final Dimension times(Dimension that) {
return new Dimension(this._pseudoUnit.times(that._pseudoUnit));
}
/**
* Returns the quotient of this dimension with the one specified.
*
* @param that the dimension divisor.
* @return <code>this / that</code>
*/
public final Dimension divide(Dimension that) {
return new Dimension(this._pseudoUnit.divide(that._pseudoUnit));
}
/**
* Returns this dimension raised to an exponent.
*
* @param n the exponent.
* @return the result of raising this dimension to the exponent.
*/
public final Dimension pow(int n) {
return new Dimension(this._pseudoUnit.pow(n));
}
/**
* Returns the given root of this dimension.
*
* @param n the root's order.
* @return the result of taking the given root of this dimension.
* @throws ArithmeticException if <code>n == 0</code>.
*/
public final Dimension root(int n) {
return new Dimension(this._pseudoUnit.root(n));
}
/**
* Returns the representation of this dimension.
*
* @return the representation of this dimension.
*/
public String toString() {
return _pseudoUnit.toString();
}
/**
* Indicates if the specified dimension is equals to the one specified.
*
* @param that the object to compare to.
* @return <code>true</code> if this dimension is equals to that dimension;
* <code>false</code> otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
return (that instanceof Dimension)
&& _pseudoUnit.equals(((Dimension) that)._pseudoUnit);
}
/**
* Returns the hash code for this dimension.
*
* @return this dimension hashcode value.
*/
public int hashCode() {
return _pseudoUnit.hashCode();
}
/**
* Sets the model used to determinate the units dimensions.
*
* @param model the new model to be used when calculating unit dimensions.
*/
public static void setModel(Model model) {
Dimension.CurrentModel = model;
}
/**
* Returns the model used to determinate the units dimensions
* (default {@link Model#STANDARD STANDARD}).
*
* @return the model used when calculating unit dimensions.
*/
public static Model getModel() {
return Dimension.CurrentModel;
}
/**
* This interface represents the mapping between {@link BaseUnit base units}
* and {@link Dimension dimensions}. Custom models may allow
* conversions not possible using the {@link #STANDARD standard} model.
* For example:[code]
* public static void main(String[] args) {
* Dimension.Model relativistic = new Dimension.Model() {
* RationalConverter meterToSecond = new RationalConverter(1, 299792458); // 1/c
*
* public Dimension getDimension(BaseUnit unit) {
* if (unit.equals(SI.METER)) return Dimension.TIME;
* return Dimension.Model.STANDARD.getDimension(unit);
* }
*
* public UnitConverter getTransform(BaseUnit unit) {
* if (unit.equals(SI.METER)) return meterToSecond;
* return Dimension.Model.STANDARD.getTransform(unit);
* }};
* Dimension.setModel(relativistic);
*
* // Converts 1.0 GeV (energy) to kg (mass).
* System.out.println(Unit.valueOf("GeV").getConverterTo(KILOGRAM).convert(1.0));
* }
*
* > 1.7826617302520883E-27[/code]
*/
public interface Model {
/**
* Holds the standard model (default).
*/
public Model STANDARD = new Model() {
public Dimension getDimension(BaseUnit<?> unit) {
if (unit.equals(SI.METRE)) return Dimension.LENGTH;
if (unit.equals(SI.KILOGRAM)) return Dimension.MASS;
if (unit.equals(SI.KELVIN)) return Dimension.TEMPERATURE;
if (unit.equals(SI.SECOND)) return Dimension.TIME;
if (unit.equals(SI.AMPERE)) return Dimension.ELECTRIC_CURRENT;
if (unit.equals(SI.MOLE)) return Dimension.AMOUNT_OF_SUBSTANCE;
if (unit.equals(SI.CANDELA)) return SI.WATT.getDimension();
return new Dimension(new BaseUnit<Dimensionless>("[" + unit.getSymbol() + "]"));
}
public UnitConverter getTransform(BaseUnit<?> unit) {
if (unit.equals(SI.CANDELA)) return new RationalConverter(1, 683);
return UnitConverter.IDENTITY;
}
};
/**
* Returns the dimension of the specified base unit (a dimension
* particular to the base unit if the base unit is not recognized).
*
* @param unit the base unit for which the dimension is returned.
* @return the dimension of the specified unit.
*/
Dimension getDimension(BaseUnit<?> unit);
/**
* Returns the normalization transform of the specified base unit
* ({@link UnitConverter#IDENTITY IDENTITY} if the base unit is
* not recognized).
*
* @param unit the base unit for which the transform is returned.
* @return the normalization transform.
*/
UnitConverter getTransform(BaseUnit<?> unit);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,758 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.measure.converter.LogConverter;
import javax.measure.converter.RationalConverter;
import javax.measure.quantity.*;
import static javax.measure.unit.SI.*;
/**
* <p> This class contains units that are not part of the International
* System of Units, that is, they are outside the SI, but are important
* and widely used.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public final class NonSI extends SystemOfUnits {
/**
* Holds collection of NonSI units.
*/
private static HashSet<Unit<?>> UNITS = new HashSet<Unit<?>>();
/**
* Holds the standard gravity constant: 9.80665 m/s² exact.
*/
private static final int STANDARD_GRAVITY_DIVIDEND = 980665;
private static final int STANDARD_GRAVITY_DIVISOR = 100000;
/**
* Holds the international foot: 0.3048 m exact.
*/
private static final int INTERNATIONAL_FOOT_DIVIDEND = 3048;
private static final int INTERNATIONAL_FOOT_DIViSOR = 10000;
/**
* Holds the avoirdupois pound: 0.45359237 kg exact
*/
private static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
private static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
/**
* Holds the Avogadro constant.
*/
private static final double AVOGADRO_CONSTANT = 6.02214199e23; // (1/mol).
/**
* Holds the electric charge of one electron.
*/
private static final double ELEMENTARY_CHARGE = 1.602176462e-19; // (C).
/**
* Default constructor (prevents this class from being instantiated).
*/
private NonSI() {
}
/**
* Returns the unique instance of this class.
*
* @return the NonSI instance.
*/
public static NonSI getInstance() {
return INSTANCE;
}
private static final NonSI INSTANCE = new NonSI();
///////////////////
// Dimensionless //
///////////////////
/**
* A dimensionless unit equals to <code>0.01</code>
* (standard name <code>%</code>).
*/
public static final Unit<Dimensionless> PERCENT = nonSI(Unit.ONE.divide(100));
/**
* A logarithmic unit used to describe a ratio
* (standard name <code>dB</code>).
*/
public static final Unit<Dimensionless> DECIBEL = nonSI(Unit.ONE
.transform(new LogConverter(10).inverse().concatenate(
new RationalConverter(1, 10))));
/////////////////////////
// Amount of substance //
/////////////////////////
/**
* A unit of amount of substance equals to one atom
* (standard name <code>atom</code>).
*/
public static final Unit<AmountOfSubstance> ATOM = nonSI(MOLE
.divide(AVOGADRO_CONSTANT));
////////////
// Length //
////////////
/**
* A unit of length equal to <code>0.3048 m</code>
* (standard name <code>ft</code>).
*/
public static final Unit<Length> FOOT = nonSI(METRE.times(INTERNATIONAL_FOOT_DIVIDEND).divide(INTERNATIONAL_FOOT_DIViSOR));
/**
* A unit of length equal to <code>1200/3937 m</code>
* (standard name <code>foot_survey_us</code>).
* See also: <a href="http://www.sizes.com/units/foot.htm">foot</a>
*/
public static final Unit<Length> FOOT_SURVEY_US = nonSI(METRE
.times(1200).divide(3937));
/**
* A unit of length equal to <code>0.9144 m</code>
* (standard name <code>yd</code>).
*/
public static final Unit<Length> YARD = nonSI(FOOT.times(3));
/**
* A unit of length equal to <code>0.0254 m</code>
* (standard name <code>in</code>).
*/
public static final Unit<Length> INCH = nonSI(FOOT.divide(12));
/**
* A unit of length equal to <code>1609.344 m</code>
* (standard name <code>mi</code>).
*/
public static final Unit<Length> MILE = nonSI(METRE.times(1609344).divide(1000));
/**
* A unit of length equal to <code>1852.0 m</code>
* (standard name <code>nmi</code>).
*/
public static final Unit<Length> NAUTICAL_MILE = nonSI(METRE.times(1852));
/**
* A unit of length equal to <code>1E-10 m</code>
* (standard name <code>Å</code>).
*/
public static final Unit<Length> ANGSTROM = nonSI(METRE.divide(10000000000L));
/**
* A unit of length equal to the average distance from the center of the
* Earth to the center of the Sun (standard name <code>ua</code>).
*/
public static final Unit<Length> ASTRONOMICAL_UNIT = nonSI(METRE
.times(149597870691.0));
/**
* A unit of length equal to the distance that light travels in one year
* through a vacuum (standard name <code>ly</code>).
*/
public static final Unit<Length> LIGHT_YEAR = nonSI(METRE.times(9.460528405e15));
/**
* A unit of length equal to the distance at which a star would appear to
* shift its position by one arcsecond over the course the time
* (about 3 months) in which the Earth moves a distance of
* {@link #ASTRONOMICAL_UNIT} in the direction perpendicular to the
* direction to the star (standard name <code>pc</code>).
*/
public static final Unit<Length> PARSEC = nonSI(METRE.times(30856770e9));
/**
* A unit of length equal to <code>0.013837 {@link #INCH}</code> exactly
* (standard name <code>pt</code>).
* @see #PIXEL
*/
public static final Unit<Length> POINT = nonSI(INCH.times(13837).divide(1000000));
/**
* A unit of length equal to <code>1/72 {@link #INCH}</code>
* (standard name <code>pixel</code>).
* It is the American point rounded to an even 1/72 inch.
* @see #POINT
*/
public static final Unit<Length> PIXEL = nonSI(INCH.divide(72));
/**
* Equivalent {@link #PIXEL}
*/
public static final Unit<Length> COMPUTER_POINT = PIXEL;
//////////////
// Duration //
//////////////
/**
* A unit of duration equal to <code>60 s</code>
* (standard name <code>min</code>).
*/
public static final Unit<Duration> MINUTE = nonSI(SI.SECOND.times(60));
/**
* A unit of duration equal to <code>60 {@link #MINUTE}</code>
* (standard name <code>h</code>).
*/
public static final Unit<Duration> HOUR = nonSI(MINUTE.times(60));
/**
* A unit of duration equal to <code>24 {@link #HOUR}</code>
* (standard name <code>d</code>).
*/
public static final Unit<Duration> DAY = nonSI(HOUR.times(24));
/**
* A unit of duration equal to <code>7 {@link #DAY}</code>
* (standard name <code>week</code>).
*/
public static final Unit<Duration> WEEK = nonSI(DAY.times(7));
/**
* A unit of duration equal to 365 days, 5 hours, 49 minutes,
* and 12 seconds (standard name <code>year</code>).
*/
public static final Unit<Duration> YEAR = nonSI(SECOND.times(31556952));
/**
* A unit of duration equal to one twelfth of a year
* (standard name <code>month</code>).
*/
public static final Unit<Duration> MONTH = nonSI(YEAR.divide(12));
/**
* A unit of duration equal to the time required for a complete rotation of
* the earth in reference to any star or to the vernal equinox at the
* meridian, equal to 23 hours, 56 minutes, 4.09 seconds
* (standard name <code>day_sidereal</code>).
*/
public static final Unit<Duration> DAY_SIDEREAL = nonSI(SECOND.times(86164.09));
/**
* A unit of duration equal to one complete revolution of the
* earth about the sun, relative to the fixed stars, or 365 days, 6 hours,
* 9 minutes, 9.54 seconds (standard name <code>year_sidereal</code>).
*/
public static final Unit<Duration> YEAR_SIDEREAL = nonSI(SECOND
.times(31558149.54));
/**
* A unit of duration equal to <code>365 {@link #DAY}</code>
* (standard name <code>year_calendar</code>).
*/
public static final Unit<Duration> YEAR_CALENDAR = nonSI(DAY.times(365));
//////////
// Mass //
//////////
/**
* A unit of mass equal to 1/12 the mass of the carbon-12 atom
* (standard name <code>u</code>).
*/
public static final Unit<Mass> ATOMIC_MASS = nonSI(KILOGRAM
.times(1e-3 / AVOGADRO_CONSTANT));
/**
* A unit of mass equal to the mass of the electron
* (standard name <code>me</code>).
*/
public static final Unit<Mass> ELECTRON_MASS = nonSI(KILOGRAM
.times(9.10938188e-31));
/**
* A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
* standard name <code>lb</code>).
*/
public static final Unit<Mass> POUND = nonSI(KILOGRAM.times(AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR));
/**
* A unit of mass equal to <code>1 / 16 {@link #POUND}</code>
* (standard name <code>oz</code>).
*/
public static final Unit<Mass> OUNCE = nonSI(POUND.divide(16));
/**
* A unit of mass equal to <code>2000 {@link #POUND}</code> (short ton,
* standard name <code>ton_us</code>).
*/
public static final Unit<Mass> TON_US = nonSI(POUND.times(2000));
/**
* A unit of mass equal to <code>2240 {@link #POUND}</code> (long ton,
* standard name <code>ton_uk</code>).
*/
public static final Unit<Mass> TON_UK = nonSI(POUND.times(2240));
/**
* A unit of mass equal to <code>1000 kg</code> (metric ton,
* standard name <code>t</code>).
*/
public static final Unit<Mass> METRIC_TON = nonSI(KILOGRAM.times(1000));
/////////////////////
// Electric charge //
/////////////////////
/**
* A unit of electric charge equal to the charge on one electron
* (standard name <code>e</code>).
*/
public static final Unit<ElectricCharge> E = nonSI(COULOMB
.times(ELEMENTARY_CHARGE));
/**
* A unit of electric charge equal to equal to the product of Avogadro's
* number (see {@link SI#MOLE}) and the charge (1 e) on a single electron
* (standard name <code>Fd</code>).
*/
public static final Unit<ElectricCharge> FARADAY = nonSI(COULOMB
.times(ELEMENTARY_CHARGE * AVOGADRO_CONSTANT)); // e/mol
/**
* A unit of electric charge which exerts a force of one dyne on an equal
* charge at a distance of one centimeter
* (standard name <code>Fr</code>).
*/
public static final Unit<ElectricCharge> FRANKLIN = nonSI(COULOMB
.times(3.3356e-10));
/////////////////
// Temperature //
/////////////////
/**
* A unit of temperature equal to <code>5/9 °K</code>
* (standard name <code>°R</code>).
*/
public static final Unit<Temperature> RANKINE = nonSI(KELVIN.times(5).divide(9));
/**
* A unit of temperature equal to degree Rankine minus
* <code>459.67 °R</code> (standard name <code>°F</code>).
* @see #RANKINE
*/
public static final Unit<Temperature> FAHRENHEIT = nonSI(RANKINE.plus(459.67));
///////////
// Angle //
///////////
/**
* A unit of angle equal to a full circle or <code>2<i>&pi;</i>
* {@link SI#RADIAN}</code> (standard name <code>rev</code>).
*/
public static final Unit<Angle> REVOLUTION = nonSI(RADIAN.times(2.0 * Math.PI));
/**
* A unit of angle equal to <code>1/360 {@link #REVOLUTION}</code>
* (standard name <code>°</code>).
*/
public static final Unit<Angle> DEGREE_ANGLE = nonSI(REVOLUTION.divide(360));
/**
* A unit of angle equal to <code>1/60 {@link #DEGREE_ANGLE}</code>
* (standard name <code></code>).
*/
public static final Unit<Angle> MINUTE_ANGLE = nonSI(DEGREE_ANGLE.divide(60));
/**
* A unit of angle equal to <code>1/60 {@link #MINUTE_ANGLE}</code>
* (standard name <code>"</code>).
*/
public static final Unit<Angle> SECOND_ANGLE = nonSI(MINUTE_ANGLE.divide(60));
/**
* A unit of angle equal to <code>0.01 {@link SI#RADIAN}</code>
* (standard name <code>centiradian</code>).
*/
public static final Unit<Angle> CENTIRADIAN = nonSI(RADIAN.divide(100));
/**
* A unit of angle measure equal to <code>1/400 {@link #REVOLUTION}</code>
* (standard name <code>grade</code>).
*/
public static final Unit<Angle> GRADE = nonSI(REVOLUTION.divide(400));
//////////////
// Velocity //
//////////////
/**
* A unit of velocity expressing the number of international {@link
* #MILE miles} per {@link #HOUR hour} (abbreviation <code>mph</code>).
*/
public static final Unit<Velocity> MILES_PER_HOUR
= nonSI(NonSI.MILE.divide(NonSI.HOUR)).asType(Velocity.class);
/**
* A unit of velocity expressing the number of {@link SI#KILOMETRE} per
* {@link #HOUR hour}.
*/
public static final Unit<Velocity> KILOMETRES_PER_HOUR
= nonSI(SI.KILOMETRE.divide(NonSI.HOUR)).asType(Velocity.class);
/**
* Equivalent to {@link #KILOMETRES_PER_HOUR}.
*/
public static final Unit<Velocity> KILOMETERS_PER_HOUR = KILOMETRES_PER_HOUR;
/**
* A unit of velocity expressing the number of {@link #NAUTICAL_MILE
* nautical miles} per {@link #HOUR hour} (abbreviation <code>kn</code>).
*/
public static final Unit<Velocity> KNOT
= nonSI(NonSI.NAUTICAL_MILE.divide(NonSI.HOUR)).asType(Velocity.class);
/**
* A unit of velocity to express the speed of an aircraft relative to
* the speed of sound (standard name <code>Mach</code>).
*/
public static final Unit<Velocity> MACH = nonSI(METRES_PER_SECOND.times(331.6));
/**
* A unit of velocity relative to the speed of light
* (standard name <code>c</code>).
*/
public static final Unit<Velocity> C = nonSI(METRES_PER_SECOND.times(299792458));
//////////////////
// Acceleration //
//////////////////
/**
* A unit of acceleration equal to the gravity at the earth's surface
* (standard name <code>grav</code>).
*/
public static final Unit<Acceleration> G = nonSI(METRES_PER_SQUARE_SECOND
.times(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR));
//////////
// Area //
//////////
/**
* A unit of area equal to <code>100 m²</code>
* (standard name <code>a</code>).
*/
public static final Unit<Area> ARE = nonSI(SQUARE_METRE.times(100));
/**
* A unit of area equal to <code>100 {@link #ARE}</code>
* (standard name <code>ha</code>).
*/
public static final Unit<Area> HECTARE = nonSI(ARE.times(100)); // Exact.
/////////////////
// Data Amount //
/////////////////
/**
* A unit of data amount equal to <code>8 {@link SI#BIT}</code>
* (BinarY TErm, standard name <code>byte</code>).
*/
public static final Unit<DataAmount> BYTE = nonSI(BIT.times(8));
/**
* Equivalent {@link #BYTE}
*/
public static final Unit<DataAmount> OCTET = BYTE;
//////////////////////
// Electric current //
//////////////////////
/**
* A unit of electric charge equal to the centimeter-gram-second
* electromagnetic unit of magnetomotive force, equal to <code>10/4
* &pi;ampere-turn</code> (standard name <code>Gi</code>).
*/
public static final Unit<ElectricCurrent> GILBERT = nonSI(SI.AMPERE
.times(10.0 / (4.0 * Math.PI)));
////////////
// Energy //
////////////
/**
* A unit of energy equal to <code>1E-7 J</code>
* (standard name <code>erg</code>).
*/
public static final Unit<Energy> ERG = nonSI(JOULE.divide(10000000));
/**
* A unit of energy equal to one electron-volt (standard name
* <code>eV</code>, also recognized <code>keV, MeV, GeV</code>).
*/
public static final Unit<Energy> ELECTRON_VOLT = nonSI(JOULE
.times(ELEMENTARY_CHARGE));
/////////////////
// Illuminance //
/////////////////
/**
* A unit of illuminance equal to <code>1E4 Lx</code>
* (standard name <code>La</code>).
*/
public static final Unit<Illuminance> LAMBERT = nonSI(LUX.times(10000));
///////////////////
// Magnetic Flux //
///////////////////
/**
* A unit of magnetic flux equal <code>1E-8 Wb</code>
* (standard name <code>Mx</code>).
*/
public static final Unit<MagneticFlux> MAXWELL = nonSI(WEBER.divide(100000000));
///////////////////////////
// Magnetic Flux Density //
///////////////////////////
/**
* A unit of magnetic flux density equal <code>1000 A/m</code>
* (standard name <code>G</code>).
*/
public static final Unit<MagneticFluxDensity> GAUSS = nonSI(TESLA.divide(10000));
///////////
// Force //
///////////
/**
* A unit of force equal to <code>1E-5 N</code>
* (standard name <code>dyn</code>).
*/
public static final Unit<Force> DYNE = nonSI(NEWTON.divide(100000));
/**
* A unit of force equal to <code>9.80665 N</code>
* (standard name <code>kgf</code>).
*/
public static final Unit<Force> KILOGRAM_FORCE = nonSI(NEWTON
.times(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR));
/**
* A unit of force equal to <code>{@link #POUND}·{@link #G}</code>
* (standard name <code>lbf</code>).
*/
public static final Unit<Force> POUND_FORCE = nonSI(NEWTON
.times(1L * AVOIRDUPOIS_POUND_DIVIDEND * STANDARD_GRAVITY_DIVIDEND).divide(
1L * AVOIRDUPOIS_POUND_DIVISOR * STANDARD_GRAVITY_DIVISOR));
///////////
// Power //
///////////
/**
* A unit of power equal to the power required to raise a mass of 75
* kilograms at a velocity of 1 meter per second (metric,
* standard name <code>hp</code>).
*/
public static final Unit<Power> HORSEPOWER = nonSI(WATT.times(735.499));
//////////////
// Pressure //
//////////////
/**
* A unit of pressure equal to the average pressure of the Earth's
* atmosphere at sea level (standard name <code>atm</code>).
*/
public static final Unit<Pressure> ATMOSPHERE = nonSI(PASCAL.times(101325));
/**
* A unit of pressure equal to <code>100 kPa</code>
* (standard name <code>bar</code>).
*/
public static final Unit<Pressure> BAR = nonSI(PASCAL.times(100000));
/**
* A unit of pressure equal to the pressure exerted at the Earth's
* surface by a column of mercury 1 millimeter high
* (standard name <code>mmHg</code>).
*/
public static final Unit<Pressure> MILLIMETER_OF_MERCURY =nonSI(PASCAL
.times(133.322));
/**
* A unit of pressure equal to the pressure exerted at the Earth's
* surface by a column of mercury 1 inch high
* (standard name <code>inHg</code>).
*/
public static final Unit<Pressure> INCH_OF_MERCURY = nonSI(PASCAL.times(3386.388));
/////////////////////////////
// Radiation dose absorbed //
/////////////////////////////
/**
* A unit of radiation dose absorbed equal to a dose of 0.01 joule of
* energy per kilogram of mass (J/kg) (standard name <code>rd</code>).
*/
public static final Unit<RadiationDoseAbsorbed> RAD = nonSI(GRAY.divide(100));
/**
* A unit of radiation dose effective equal to <code>0.01 Sv</code>
* (standard name <code>rem</code>).
*/
public static final Unit<RadiationDoseEffective> REM = nonSI(SIEVERT.divide(100));
//////////////////////////
// Radioactive activity //
//////////////////////////
/**
* A unit of radioctive activity equal to the activity of a gram of radium
* (standard name <code>Ci</code>).
*/
public static final Unit<RadioactiveActivity> CURIE = nonSI(BECQUEREL
.times(37000000000L));
/**
* A unit of radioctive activity equal to 1 million radioactive
* disintegrations per second (standard name <code>Rd</code>).
*/
public static final Unit<RadioactiveActivity> RUTHERFORD = nonSI(SI.BECQUEREL
.times(1000000));
/////////////////
// Solid angle //
/////////////////
/**
* A unit of solid angle equal to <code>4 <i>&pi;</i> steradians</code>
* (standard name <code>sphere</code>).
*/
public static final Unit<SolidAngle> SPHERE = nonSI(STERADIAN
.times(4.0 * Math.PI));
////////////
// Volume //
////////////
/**
* A unit of volume equal to one cubic decimeter (default label
* <code>L</code>, also recognized <code>µL, mL, cL, dL</code>).
*/
public static final Unit<Volume> LITRE = nonSI(CUBIC_METRE.divide(1000));
/**
* Equivalent to {@link #LITRE} (American spelling).
*/
public static final Unit<Volume> LITER = LITRE;
/**
* A unit of volume equal to one cubic inch (<code>in³</code>).
*/
public static final Unit<Volume> CUBIC_INCH = nonSI(
INCH.pow(3).asType(Volume.class));
/**
* A unit of volume equal to one US gallon, Liquid Unit. The U.S. liquid
* gallon is based on the Queen Anne or Wine gallon occupying 231 cubic
* inches (standard name <code>gal</code>).
*/
public static final Unit<Volume> GALLON_LIQUID_US = nonSI(CUBIC_INCH.times(231));
/**
* A unit of volume equal to <code>1 / 128 {@link #GALLON_LIQUID_US}</code>
* (standard name <code>oz_fl</code>).
*/
public static final Unit<Volume> OUNCE_LIQUID_US = nonSI(GALLON_LIQUID_US
.divide(128));
/**
* A unit of volume equal to one US dry gallon.
* (standard name <code>gallon_dry_us</code>).
*/
public static final Unit<Volume> GALLON_DRY_US = nonSI(CUBIC_INCH.times(2688025).divide(10000));
/**
* A unit of volume equal to <code>4.546 09 {@link #LITRE}</code>
* (standard name <code>gal_uk</code>).
*/
public static final Unit<Volume> GALLON_UK = nonSI(LITRE.times(454609).divide(100000));
/**
* A unit of volume equal to <code>1 / 160 {@link #GALLON_UK}</code>
* (standard name <code>oz_fl_uk</code>).
*/
public static final Unit<Volume> OUNCE_LIQUID_UK = nonSI(GALLON_UK.divide(160));
///////////////
// Viscosity //
///////////////
/**
* A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code>
* (cgs unit).
*/
@SuppressWarnings("unchecked")
public static final Unit<DynamicViscosity>
POISE = nonSI((Unit<DynamicViscosity>) GRAM.divide(CENTI(METRE).times(SECOND)));
/**
* A unit of kinematic viscosity equal to <code>1 cm²/s</code>
* (cgs unit).
*/
@SuppressWarnings("unchecked")
public static final Unit<KinematicViscosity>
STOKE = nonSI((Unit<KinematicViscosity>) CENTI(METRE).pow(2).divide(SECOND));
////////////
// Others //
////////////
/**
* A unit used to measure the ionizing ability of radiation
* (standard name <code>Roentgen</code>).
*/
public static final Unit<?> ROENTGEN = nonSI(COULOMB.divide(KILOGRAM).times(2.58e-4));
/////////////////////
// Collection View //
/////////////////////
/**
* Returns a read only view over the units defined in this class.
*
* @return the collection of NonSI units.
*/
public Set<Unit<?>> getUnits() {
return Collections.unmodifiableSet(UNITS);
}
/**
* Adds a new unit to the collection.
*
* @param unit the unit being added.
* @return <code>unit</code>.
*/
private static <U extends Unit<?>> U nonSI(U unit) {
UNITS.add(unit);
return unit;
}
}

View File

@ -0,0 +1,471 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.io.Serializable;
import javax.measure.converter.ConversionException;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents units formed by the product of rational powers of
* existing units.</p>
*
* <p> This class maintains the canonical form of this product (simplest
* form after factorization). For example:
* <code>METER.pow(2).divide(METER)</code> returns
* <code>METER</code>.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
* @see Unit#times(Unit)
* @see Unit#divide(Unit)
* @see Unit#pow(int)
* @see Unit#root(int)
*/
public final class ProductUnit<Q extends Quantity> extends DerivedUnit<Q> {
/**
* Holds the units composing this product unit.
*/
private final Element[] _elements;
/**
* Holds the hashcode (optimization).
*/
private int _hashCode;
/**
* Default constructor (used solely to create <code>ONE</code> instance).
*/
ProductUnit() {
_elements = new Element[0];
}
/**
* Copy constructor (allows for parameterization of product units).
*
* @param productUnit the product unit source.
* @throws ClassCastException if the specified unit is not
* a product unit.
*/
public ProductUnit(Unit<?> productUnit) {
_elements = ((ProductUnit<?>)productUnit)._elements;
}
/**
* Product unit constructor.
*
* @param elements the product elements.
*/
private ProductUnit(Element[] elements) {
_elements = elements;
}
/**
* Returns the unit defined from the product of the specifed elements.
*
* @param leftElems left multiplicand elements.
* @param rightElems right multiplicand elements.
* @return the corresponding unit.
*/
@SuppressWarnings("unchecked")
private static Unit<? extends Quantity> getInstance(Element[] leftElems,
Element[] rightElems) {
// Merges left elements with right elements.
Element[] result = new Element[leftElems.length + rightElems.length];
int resultIndex = 0;
for (int i = 0; i < leftElems.length; i++) {
Unit unit = leftElems[i]._unit;
int p1 = leftElems[i]._pow;
int r1 = leftElems[i]._root;
int p2 = 0;
int r2 = 1;
for (int j = 0; j < rightElems.length; j++) {
if (unit.equals(rightElems[j]._unit)) {
p2 = rightElems[j]._pow;
r2 = rightElems[j]._root;
break; // No duplicate.
}
}
int pow = (p1 * r2) + (p2 * r1);
int root = r1 * r2;
if (pow != 0) {
int gcd = gcd(Math.abs(pow), root);
result[resultIndex++] = new Element(unit, pow / gcd, root / gcd);
}
}
// Appends remaining right elements not merged.
for (int i = 0; i < rightElems.length; i++) {
Unit unit = rightElems[i]._unit;
boolean hasBeenMerged = false;
for (int j = 0; j < leftElems.length; j++) {
if (unit.equals(leftElems[j]._unit)) {
hasBeenMerged = true;
break;
}
}
if (!hasBeenMerged) {
result[resultIndex++] = rightElems[i];
}
}
// Returns or creates instance.
if (resultIndex == 0) {
return ONE;
} else if ((resultIndex == 1) && (result[0]._pow == result[0]._root)) {
return result[0]._unit;
} else {
Element[] elems = new Element[resultIndex];
for (int i = 0; i < resultIndex; i++) {
elems[i] = result[i];
}
return new ProductUnit<Quantity>(elems);
}
}
/**
* Returns the product of the specified units.
*
* @param left the left unit operand.
* @param right the right unit operand.
* @return <code>left * right</code>
*/
static Unit<? extends Quantity> getProductInstance(Unit<?> left, Unit<?> right) {
Element[] leftElems;
if (left instanceof ProductUnit) {
leftElems = ((ProductUnit<?>) left)._elements;
} else {
leftElems = new Element[] { new Element(left, 1, 1) };
}
Element[] rightElems;
if (right instanceof ProductUnit) {
rightElems = ((ProductUnit<?>) right)._elements;
} else {
rightElems = new Element[] { new Element(right, 1, 1) };
}
return getInstance(leftElems, rightElems);
}
/**
* Returns the quotient of the specified units.
*
* @param left the dividend unit operand.
* @param right the divisor unit operand.
* @return <code>dividend / divisor</code>
*/
static Unit<? extends Quantity> getQuotientInstance(Unit<?> left, Unit<?> right) {
Element[] leftElems;
if (left instanceof ProductUnit) {
leftElems = ((ProductUnit<?>) left)._elements;
} else {
leftElems = new Element[] { new Element(left, 1, 1) };
}
Element[] rightElems;
if (right instanceof ProductUnit) {
Element[] elems = ((ProductUnit<?>) right)._elements;
rightElems = new Element[elems.length];
for (int i = 0; i < elems.length; i++) {
rightElems[i] = new Element(elems[i]._unit, -elems[i]._pow,
elems[i]._root);
}
} else {
rightElems = new Element[] { new Element(right, -1, 1) };
}
return getInstance(leftElems, rightElems);
}
/**
* Returns the product unit corresponding to the specified root of
* the specified unit.
*
* @param unit the unit.
* @param n the root's order (n &gt; 0).
* @return <code>unit^(1/nn)</code>
* @throws ArithmeticException if <code>n == 0</code>.
*/
static Unit<? extends Quantity> getRootInstance(Unit<?> unit, int n) {
Element[] unitElems;
if (unit instanceof ProductUnit) {
Element[] elems = ((ProductUnit<?>) unit)._elements;
unitElems = new Element[elems.length];
for (int i = 0; i < elems.length; i++) {
int gcd = gcd(Math.abs(elems[i]._pow), elems[i]._root * n);
unitElems[i] = new Element(elems[i]._unit, elems[i]._pow / gcd,
elems[i]._root * n / gcd);
}
} else {
unitElems = new Element[] { new Element(unit, 1, n) };
}
return getInstance(unitElems, new Element[0]);
}
/**
* Returns the product unit corresponding to this unit raised to
* the specified exponent.
*
* @param unit the unit.
* @param nn the exponent (nn &gt; 0).
* @return <code>unit^n</code>
*/
static Unit<? extends Quantity> getPowInstance(Unit<?> unit, int n) {
Element[] unitElems;
if (unit instanceof ProductUnit) {
Element[] elems = ((ProductUnit<?>) unit)._elements;
unitElems = new Element[elems.length];
for (int i = 0; i < elems.length; i++) {
int gcd = gcd(Math.abs(elems[i]._pow * n), elems[i]._root);
unitElems[i] = new Element(elems[i]._unit, elems[i]._pow * n
/ gcd, elems[i]._root / gcd);
}
} else {
unitElems = new Element[] { new Element(unit, n, 1) };
}
return getInstance(unitElems, new Element[0]);
}
/**
* Returns the number of units in this product.
*
* @return the number of units being multiplied.
*/
public int getUnitCount() {
return _elements.length;
}
/**
* Returns the unit at the specified position.
*
* @param index the index of the unit to return.
* @return the unit at the specified position.
* @throws IndexOutOfBoundsException if index is out of range
* <code>(index &lt; 0 || index &gt;= size())</code>.
*/
@SuppressWarnings("unchecked")
public Unit<? extends Quantity> getUnit(int index) {
return _elements[index].getUnit();
}
/**
* Returns the power exponent of the unit at the specified position.
*
* @param index the index of the unit to return.
* @return the unit power exponent at the specified position.
* @throws IndexOutOfBoundsException if index is out of range
* <code>(index &lt; 0 || index &gt;= size())</code>.
*/
public int getUnitPow(int index) {
return _elements[index].getPow();
}
/**
* Returns the root exponent of the unit at the specified position.
*
* @param index the index of the unit to return.
* @return the unit root exponent at the specified position.
* @throws IndexOutOfBoundsException if index is out of range
* <code>(index &lt; 0 || index &gt;= size())</code>.
*/
public int getUnitRoot(int index) {
return _elements[index].getRoot();
}
/**
* Indicates if this product unit is considered equals to the specified
* object.
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (that instanceof ProductUnit) {
// Two products are equals if they have the same elements
// regardless of the elements' order.
Element[] elems = ((ProductUnit<?>) that)._elements;
if (_elements.length == elems.length) {
for (int i = 0; i < _elements.length; i++) {
boolean unitFound = false;
for (int j = 0; j < elems.length; j++) {
if (_elements[i]._unit.equals(elems[j]._unit)) {
if ((_elements[i]._pow != elems[j]._pow)
|| (_elements[i]._root != elems[j]._root)) {
return false;
} else {
unitFound = true;
break;
}
}
}
if (!unitFound) {
return false;
}
}
return true;
}
}
return false;
}
@Override
// Implements abstract method.
public int hashCode() {
if (_hashCode != 0)
return _hashCode;
int code = 0;
for (int i = 0; i < _elements.length; i++) {
code += _elements[i]._unit.hashCode()
* (_elements[i]._pow * 3 - _elements[i]._root * 2);
}
_hashCode = code;
return code;
}
@Override
@SuppressWarnings("unchecked")
public Unit<? super Q> getStandardUnit() {
if (hasOnlyStandardUnit())
return this;
Unit systemUnit = ONE;
for (int i = 0; i < _elements.length; i++) {
Unit unit = _elements[i]._unit.getStandardUnit();
unit = unit.pow(_elements[i]._pow);
unit = unit.root(_elements[i]._root);
systemUnit = systemUnit.times(unit);
}
return systemUnit;
}
@Override
public UnitConverter toStandardUnit() {
if (hasOnlyStandardUnit())
return UnitConverter.IDENTITY;
UnitConverter converter = UnitConverter.IDENTITY;
for (int i = 0; i < _elements.length; i++) {
UnitConverter cvtr = _elements[i]._unit.toStandardUnit();
if (!cvtr.isLinear())
throw new ConversionException(_elements[i]._unit
+ " is non-linear, cannot convert");
if (_elements[i]._root != 1)
throw new ConversionException(_elements[i]._unit
+ " holds a base unit with fractional exponent");
int pow = _elements[i]._pow;
if (pow < 0) { // Negative power.
pow = -pow;
cvtr = cvtr.inverse();
}
for (int j = 0; j < pow; j++) {
converter = converter.concatenate(cvtr);
}
}
return converter;
}
/**
* Indicates if this product unit is a standard unit.
*
* @return <code>true</code> if all elements are standard units;
* <code>false</code> otherwise.
*/
private boolean hasOnlyStandardUnit() {
for (int i = 0; i < _elements.length; i++) {
Unit<?> u = _elements[i]._unit;
if (!u.isStandardUnit())
return false;
}
return true;
}
/**
* Returns the greatest common divisor (Euclid's algorithm).
*
* @param m the first number.
* @param nn the second number.
* @return the greatest common divisor.
*/
private static int gcd(int m, int n) {
if (n == 0) {
return m;
} else {
return gcd(n, m % n);
}
}
/**
* Inner product element represents a rational power of a single unit.
*/
private final static class Element implements Serializable {
/**
* Holds the single unit.
*/
private final Unit<?> _unit;
/**
* Holds the power exponent.
*/
private final int _pow;
/**
* Holds the root exponent.
*/
private final int _root;
/**
* Structural constructor.
*
* @param unit the unit.
* @param pow the power exponent.
* @param root the root exponent.
*/
private Element(Unit<?> unit, int pow, int root) {
_unit = unit;
_pow = pow;
_root = root;
}
/**
* Returns this element's unit.
*
* @return the single unit.
*/
public Unit<?> getUnit() {
return _unit;
}
/**
* Returns the power exponent. The power exponent can be negative
* but is always different from zero.
*
* @return the power exponent of the single unit.
*/
public int getPow() {
return _pow;
}
/**
* Returns the root exponent. The root exponent is always greater
* than zero.
*
* @return the root exponent of the single unit.
*/
public int getRoot() {
return _root;
}
private static final long serialVersionUID = 1L;
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,719 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.measure.converter.MultiplyConverter;
import javax.measure.converter.RationalConverter;
import javax.measure.quantity.*;
/**
* <p> This class contains SI (Système International d'Unités) base units,
* and derived units.</p>
*
* <p> It also defines the 20 SI prefixes used to form decimal multiples and
* submultiples of SI units. For example:[code]
* import static org.jscience.physics.units.SI.*; // Static import.
* ...
* Unit<Pressure> HECTO_PASCAL = HECTO(PASCAL);
* Unit<Length> KILO_METER = KILO(METER);
* [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2006
* @see <a href="http://en.wikipedia.org/wiki/SI">Wikipedia: SI</a>
* @see <a href="http://en.wikipedia.org/wiki/SI_prefix">Wikipedia: SI prefix</a>
*/
public final class SI extends SystemOfUnits {
/**
* Holds collection of SI units.
*/
private static HashSet<Unit<?>> UNITS = new HashSet<Unit<?>>();
/**
* Default constructor (prevents this class from being instantiated).
*/
private SI() {
}
/**
* Returns the unique instance of this class.
*
* @return the SI instance.
*/
public static SI getInstance() {
return INSTANCE;
}
private static final SI INSTANCE = new SI();
////////////////
// BASE UNITS //
////////////////
/**
* The base unit for electric current quantities (<code>A</code>).
* The Ampere is that constant current which, if maintained in two straight
* parallel conductors of infinite length, of negligible circular
* cross-section, and placed 1 metre apart in vacuum, would produce between
* these conductors a force equal to 2 × 10-7 newton per metre of length.
* It is named after the French physicist Andre Ampere (1775-1836).
*/
public static final BaseUnit<ElectricCurrent> AMPERE = si(new BaseUnit<ElectricCurrent>(
"A"));
/**
* The base unit for luminous intensity quantities (<code>cd</code>).
* The candela is the luminous intensity, in a given direction,
* of a source that emits monochromatic radiation of frequency
* 540 × 1012 hertz and that has a radiant intensity in that
* direction of 1/683 watt per steradian
* @see <a href="http://en.wikipedia.org/wiki/Candela">
* Wikipedia: Candela</a>
*/
public static final BaseUnit<LuminousIntensity> CANDELA = si(new BaseUnit<LuminousIntensity>(
"cd"));
/**
* The base unit for thermodynamic temperature quantities (<code>K</code>).
* The kelvin is the 1/273.16th of the thermodynamic temperature of the
* triple point of water. It is named after the Scottish mathematician and
* physicist William Thomson 1st Lord Kelvin (1824-1907)
*/
public static final BaseUnit<Temperature> KELVIN = si(new BaseUnit<Temperature>(
"K"));
/**
* The base unit for mass quantities (<code>kg</code>).
* It is the only SI unit with a prefix as part of its name and symbol.
* The kilogram is equal to the mass of an international prototype in the
* form of a platinum-iridium cylinder kept at Sevres in France.
* @see #GRAM
*/
public static final BaseUnit<Mass> KILOGRAM = si(new BaseUnit<Mass>("kg"));
/**
* The base unit for length quantities (<code>m</code>).
* One meter was redefined in 1983 as the distance traveled by light in
* a vacuum in 1/299,792,458 of a second.
*/
public static final BaseUnit<Length> METRE = si(new BaseUnit<Length>("m"));
/**
* Equivalent to {@link #METRE} (American spelling).
*/
public static final Unit<Length> METER = METRE;
/**
* The base unit for amount of substance quantities (<code>mol</code>).
* The mole is the amount of substance of a system which contains as many
* elementary entities as there are atoms in 0.012 kilogram of carbon 12.
*/
public static final BaseUnit<AmountOfSubstance> MOLE = si(new BaseUnit<AmountOfSubstance>(
"mol"));
/**
* The base unit for duration quantities (<code>s</code>).
* It is defined as the duration of 9,192,631,770 cycles of radiation
* corresponding to the transition between two hyperfine levels of
* the ground state of cesium (1967 Standard).
*/
public static final BaseUnit<Duration> SECOND = si(new BaseUnit<Duration>(
"s"));
////////////////////////////////
// SI DERIVED ALTERNATE UNITS //
////////////////////////////////
/**
* The derived unit for mass quantities (<code>g</code>).
* The base unit for mass quantity is {@link #KILOGRAM}.
*/
public static final Unit<Mass> GRAM = KILOGRAM.divide(1000);
/**
* The unit for plane angle quantities (<code>rad</code>).
* One radian is the angle between two radii of a circle such that the
* length of the arc between them is equal to the radius.
*/
public static final AlternateUnit<Angle> RADIAN = si(new AlternateUnit<Angle>(
"rad", Unit.ONE));
/**
* The unit for solid angle quantities (<code>sr</code>).
* One steradian is the solid angle subtended at the center of a sphere by
* an area on the surface of the sphere that is equal to the radius squared.
* The total solid angle of a sphere is 4*Pi steradians.
*/
public static final AlternateUnit<SolidAngle> STERADIAN = si(new AlternateUnit<SolidAngle>(
"sr", Unit.ONE));
/**
* The unit for binary information (<code>bit</code>).
*/
public static final AlternateUnit<DataAmount> BIT = si(new AlternateUnit<DataAmount>(
"bit", Unit.ONE));
/**
* The derived unit for frequency (<code>Hz</code>).
* A unit of frequency equal to one cycle per second.
* After Heinrich Rudolf Hertz (1857-1894), German physicist who was the
* first to produce radio waves artificially.
*/
public static final AlternateUnit<Frequency> HERTZ = si(new AlternateUnit<Frequency>(
"Hz", Unit.ONE.divide(SECOND)));
/**
* The derived unit for force (<code>N</code>).
* One newton is the force required to give a mass of 1 kilogram an Force
* of 1 metre per second per second. It is named after the English
* mathematician and physicist Sir Isaac Newton (1642-1727).
*/
public static final AlternateUnit<Force> NEWTON = si(new AlternateUnit<Force>(
"N", METRE.times(KILOGRAM).divide(SECOND.pow(2))));
/**
* The derived unit for pressure, stress (<code>Pa</code>).
* One pascal is equal to one newton per square meter. It is named after
* the French philosopher and mathematician Blaise Pascal (1623-1662).
*/
public static final AlternateUnit<Pressure> PASCAL = si(new AlternateUnit<Pressure>(
"Pa", NEWTON.divide(METRE.pow(2))));
/**
* The derived unit for energy, work, quantity of heat (<code>J</code>).
* One joule is the amount of work done when an applied force of 1 newton
* moves through a distance of 1 metre in the direction of the force.
* It is named after the English physicist James Prescott Joule (1818-1889).
*/
public static final AlternateUnit<Energy> JOULE = si(new AlternateUnit<Energy>(
"J", NEWTON.times(METRE)));
/**
* The derived unit for power, radiant, flux (<code>W</code>).
* One watt is equal to one joule per second. It is named after the British
* scientist James Watt (1736-1819).
*/
public static final AlternateUnit<Power> WATT = si(new AlternateUnit<Power>(
"W", JOULE.divide(SECOND)));
/**
* The derived unit for electric charge, quantity of electricity
* (<code>C</code>).
* One Coulomb is equal to the quantity of charge transferred in one second
* by a steady current of one ampere. It is named after the French physicist
* Charles Augustin de Coulomb (1736-1806).
*/
public static final AlternateUnit<ElectricCharge> COULOMB = si(new AlternateUnit<ElectricCharge>(
"C", SECOND.times(AMPERE)));
/**
* The derived unit for electric potential difference, electromotive force
* (<code>V</code>).
* One Volt is equal to the difference of electric potential between two
* points on a conducting wire carrying a constant current of one ampere
* when the power dissipated between the points is one watt. It is named
* after the Italian physicist Count Alessandro Volta (1745-1827).
*/
public static final AlternateUnit<ElectricPotential> VOLT = si(new AlternateUnit<ElectricPotential>(
"V", WATT.divide(AMPERE)));
/**
* The derived unit for capacitance (<code>F</code>).
* One Farad is equal to the capacitance of a capacitor having an equal
* and opposite charge of 1 coulomb on each plate and a potential difference
* of 1 volt between the plates. It is named after the British physicist
* and chemist Michael Faraday (1791-1867).
*/
public static final AlternateUnit<ElectricCapacitance> FARAD = si(new AlternateUnit<ElectricCapacitance>(
"F", COULOMB.divide(VOLT)));
/**
* The derived unit for electric resistance (<code>Ω</code> or
* <code>Ohm</code>).
* One Ohm is equal to the resistance of a conductor in which a current of
* one ampere is produced by a potential of one volt across its terminals.
* It is named after the German physicist Georg Simon Ohm (1789-1854).
*/
public static final AlternateUnit<ElectricResistance> OHM = si(new AlternateUnit<ElectricResistance>(
"Ω", VOLT.divide(AMPERE)));
/**
* The derived unit for electric conductance (<code>S</code>).
* One Siemens is equal to one ampere per volt. It is named after
* the German engineer Ernst Werner von Siemens (1816-1892).
*/
public static final AlternateUnit<ElectricConductance> SIEMENS = si(new AlternateUnit<ElectricConductance>(
"S", AMPERE.divide(VOLT)));
/**
* The derived unit for magnetic flux (<code>Wb</code>).
* One Weber is equal to the magnetic flux that in linking a circuit of one
* turn produces in it an electromotive force of one volt as it is uniformly
* reduced to zero within one second. It is named after the German physicist
* Wilhelm Eduard Weber (1804-1891).
*/
public static final AlternateUnit<MagneticFlux> WEBER = si(new AlternateUnit<MagneticFlux>(
"Wb", VOLT.times(SECOND)));
/**
* The derived unit for magnetic flux density (<code>T</code>).
* One Tesla is equal equal to one weber per square meter. It is named
* after the Serbian-born American electrical engineer and physicist
* Nikola Tesla (1856-1943).
*/
public static final AlternateUnit<MagneticFluxDensity> TESLA = si(new AlternateUnit<MagneticFluxDensity>(
"T", WEBER.divide(METRE.pow(2))));
/**
* The derived unit for inductance (<code>H</code>).
* One Henry is equal to the inductance for which an induced electromotive
* force of one volt is produced when the current is varied at the rate of
* one ampere per second. It is named after the American physicist
* Joseph Henry (1791-1878).
*/
public static final AlternateUnit<ElectricInductance> HENRY = si(new AlternateUnit<ElectricInductance>(
"H", WEBER.divide(AMPERE)));
/**
* The derived unit for Celsius temperature (<code></code>).
* This is a unit of temperature such as the freezing point of water
* (at one atmosphere of pressure) is 0 , while the boiling point is
* 100 .
*/
public static final Unit<Temperature> CELSIUS = si(KELVIN.plus(273.15));
/**
* The derived unit for luminous flux (<code>lm</code>).
* One Lumen is equal to the amount of light given out through a solid angle
* by a source of one candela intensity radiating equally in all directions.
*/
public static final AlternateUnit<LuminousFlux> LUMEN = si(new AlternateUnit<LuminousFlux>(
"lm", CANDELA.times(STERADIAN)));
/**
* The derived unit for illuminance (<code>lx</code>).
* One Lux is equal to one lumen per square meter.
*/
public static final AlternateUnit<Illuminance> LUX = si(new AlternateUnit<Illuminance>(
"lx", LUMEN.divide(METRE.pow(2))));
/**
* The derived unit for activity of a radionuclide (<code>Bq</code>).
* One becquerel is the radiation caused by one disintegration per second.
* It is named after the French physicist, Antoine-Henri Becquerel
* (1852-1908).
*/
public static final AlternateUnit<RadioactiveActivity> BECQUEREL = si(new AlternateUnit<RadioactiveActivity>(
"Bq", Unit.ONE.divide(SECOND)));
/**
* The derived unit for absorbed dose, specific energy (imparted), kerma
* (<code>Gy</code>).
* One gray is equal to the dose of one joule of energy absorbed per one
* kilogram of matter. It is named after the British physician
* L. H. Gray (1905-1965).
*/
public static final AlternateUnit<RadiationDoseAbsorbed> GRAY = si(new AlternateUnit<RadiationDoseAbsorbed>(
"Gy", JOULE.divide(KILOGRAM)));
/**
* The derived unit for dose equivalent (<code>Sv</code>).
* One Sievert is equal is equal to the actual dose, in grays, multiplied
* by a "quality factor" which is larger for more dangerous forms of
* radiation. It is named after the Swedish physicist Rolf Sievert
* (1898-1966).
*/
public static final AlternateUnit<RadiationDoseEffective> SIEVERT = si(new AlternateUnit<RadiationDoseEffective>(
"Sv", JOULE.divide(KILOGRAM)));
/**
* The derived unit for catalytic activity (<code>kat</code>).
*/
public static final AlternateUnit<CatalyticActivity> KATAL = si(new AlternateUnit<CatalyticActivity>(
"kat", MOLE.divide(SECOND)));
//////////////////////////////
// SI DERIVED PRODUCT UNITS //
//////////////////////////////
/**
* The metric unit for velocity quantities (<code>m/s</code>).
*/
public static final Unit<Velocity> METRES_PER_SECOND = si(new ProductUnit<Velocity>(
METRE.divide(SECOND)));
/**
* Equivalent to {@link #METRES_PER_SECOND}.
*/
public static final Unit<Velocity> METERS_PER_SECOND = METRES_PER_SECOND;
/**
* The metric unit for acceleration quantities (<code>m/s²</code>).
*/
public static final Unit<Acceleration> METRES_PER_SQUARE_SECOND = si(new ProductUnit<Acceleration>(
METRES_PER_SECOND.divide(SECOND)));
/**
* Equivalent to {@link #METRES_PER_SQUARE_SECOND}.
*/
public static final Unit<Acceleration> METERS_PER_SQUARE_SECOND = METRES_PER_SQUARE_SECOND;
/**
* The metric unit for area quantities (<code>m²</code>).
*/
public static final Unit<Area> SQUARE_METRE = si(new ProductUnit<Area>(
METRE.times(METRE)));
/**
* The metric unit for volume quantities (<code>m³</code>).
*/
public static final Unit<Volume> CUBIC_METRE = si(new ProductUnit<Volume>(
SQUARE_METRE.times(METRE)));
/**
* Equivalent to <code>KILO(METRE)</code>.
*/
public static final Unit<Length> KILOMETRE = METER.times(1000);
/**
* Equivalent to {@link #KILOMETRE}.
*/
public static final Unit<Length> KILOMETER = KILOMETRE;
/**
* Equivalent to <code>CENTI(METRE)</code>.
*/
public static final Unit<Length> CENTIMETRE = METRE.divide(100);
/**
* Equivalent to {@link #CENTIMETRE}.
*/
public static final Unit<Length> CENTIMETER = CENTIMETRE;
/**
* Equivalent to <code>MILLI(METRE)</code>.
*/
public static final Unit<Length> MILLIMETRE = METRE.divide(1000);
/**
* Equivalent to {@link #MILLIMETRE}.
*/
public static final Unit<Length> MILLIMETER = MILLIMETRE;
/////////////////
// SI PREFIXES //
/////////////////
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>24</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e24)</code>.
*/
public static <Q extends Quantity> Unit<Q> YOTTA(Unit<Q> unit) {
return unit.transform(E24);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>21</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e21)</code>.
*/
public static <Q extends Quantity> Unit<Q> ZETTA(Unit<Q> unit) {
return unit.transform(E21);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>18</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e18)</code>.
*/
public static <Q extends Quantity> Unit<Q> EXA(Unit<Q> unit) {
return unit.transform(E18);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>15</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e15)</code>.
*/
public static <Q extends Quantity> Unit<Q> PETA(Unit<Q> unit) {
return unit.transform(E15);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>12</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e12)</code>.
*/
public static <Q extends Quantity> Unit<Q> TERA(Unit<Q> unit) {
return unit.transform(E12);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>9</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e9)</code>.
*/
public static <Q extends Quantity> Unit<Q> GIGA(Unit<Q> unit) {
return unit.transform(E9);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>6</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e6)</code>.
*/
public static <Q extends Quantity> Unit<Q> MEGA(Unit<Q> unit) {
return unit.transform(E6);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>3</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e3)</code>.
*/
public static <Q extends Quantity> Unit<Q> KILO(Unit<Q> unit) {
return unit.transform(E3);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>2</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e2)</code>.
*/
public static <Q extends Quantity> Unit<Q> HECTO(Unit<Q> unit) {
return unit.transform(E2);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>1</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e1)</code>.
*/
public static <Q extends Quantity> Unit<Q> DEKA(Unit<Q> unit) {
return unit.transform(E1);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-1</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-1)</code>.
*/
public static <Q extends Quantity> Unit<Q> DECI(Unit<Q> unit) {
return unit.transform(Em1);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-2</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-2)</code>.
*/
public static <Q extends Quantity> Unit<Q> CENTI(Unit<Q> unit) {
return unit.transform(Em2);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-3</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-3)</code>.
*/
public static <Q extends Quantity> Unit<Q> MILLI(Unit<Q> unit) {
return unit.transform(Em3);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-6</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-6)</code>.
*/
public static <Q extends Quantity> Unit<Q> MICRO(Unit<Q> unit) {
return unit.transform(Em6);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-9</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-9)</code>.
*/
public static <Q extends Quantity> Unit<Q> NANO(Unit<Q> unit) {
return unit.transform(Em9);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-12</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-12)</code>.
*/
public static <Q extends Quantity> Unit<Q> PICO(Unit<Q> unit) {
return unit.transform(Em12);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-15</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-15)</code>.
*/
public static <Q extends Quantity> Unit<Q> FEMTO(Unit<Q> unit) {
return unit.transform(Em15);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-18</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-18)</code>.
*/
public static <Q extends Quantity> Unit<Q> ATTO(Unit<Q> unit) {
return unit.transform(Em18);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-21</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-21)</code>.
*/
public static <Q extends Quantity> Unit<Q> ZEPTO(Unit<Q> unit) {
return unit.transform(Em21);
}
/**
* Returns the specified unit multiplied by the factor
* <code>10<sup>-24</sup></code>
*
* @param unit any unit.
* @return <code>unit.multiply(1e-24)</code>.
*/
public static <Q extends Quantity> Unit<Q> YOCTO(Unit<Q> unit) {
return unit.transform(Em24);
}
/////////////////////
// Collection View //
/////////////////////
/**
* Returns a read only view over theunits defined in this class.
*
* @return the collection of SI units.
*/
public Set<Unit<?>> getUnits() {
return Collections.unmodifiableSet(UNITS);
}
/**
* Adds a new unit to the collection.
*
* @param unit the unit being added.
* @return <code>unit</code>.
*/
private static <U extends Unit<?>> U si(U unit) {
UNITS.add(unit);
return unit;
}
// Holds prefix converters (optimization).
static final MultiplyConverter E24 = new MultiplyConverter(1E24);
static final MultiplyConverter E21 = new MultiplyConverter(1E21);
static final RationalConverter E18 = new RationalConverter(
1000000000000000000L, 1);
static final RationalConverter E15 = new RationalConverter(
1000000000000000L, 1);
static final RationalConverter E12 = new RationalConverter(1000000000000L,
1);
static final RationalConverter E9 = new RationalConverter(1000000000L, 1);
static final RationalConverter E6 = new RationalConverter(1000000L, 1);
static final RationalConverter E3 = new RationalConverter(1000L, 1);
static final RationalConverter E2 = new RationalConverter(100L, 1);
static final RationalConverter E1 = new RationalConverter(10L, 1);
static final RationalConverter Em1 = new RationalConverter(1, 10L);
static final RationalConverter Em2 = new RationalConverter(1, 100L);
static final RationalConverter Em3 = new RationalConverter(1, 1000L);
static final RationalConverter Em6 = new RationalConverter(1, 1000000L);
static final RationalConverter Em9 = new RationalConverter(1, 1000000000L);
static final RationalConverter Em12 = new RationalConverter(1,
1000000000000L);
static final RationalConverter Em15 = new RationalConverter(1,
1000000000000000L);
static final RationalConverter Em18 = new RationalConverter(1,
1000000000000000000L);
static final MultiplyConverter Em21 = new MultiplyConverter(1E-21);
static final MultiplyConverter Em24 = new MultiplyConverter(1E-24);
/**
* @deprecated replaced by {@link #METRES_PER_SECOND}.
*/
public static final Unit<Velocity> METRE_PER_SECOND = METRES_PER_SECOND;
/**
* @deprecated replaced by {@link #METRES_PER_SQUARE_SECOND}.
*/
public static final Unit<Acceleration> METRE_PER_SQUARE_SECOND = METRES_PER_SQUARE_SECOND;
}

View File

@ -0,0 +1,32 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.util.Set;
/**
* <p> This class represents a system of units, it groups units together
* for historical or cultural reasons. Nothing prevents a unit from
* belonging to several system of units at the same time
* (for example an imperial system would have many of the units
* held by {@link NonSI}).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public abstract class SystemOfUnits {
/**
* Returns a read only view over the units defined in this system.
*
* @return the collection of units.
*/
public abstract Set<Unit<?>> getUnits();
}

View File

@ -0,0 +1,121 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the units derived from other units using
* {@link UnitConverter converters}.</p>
*
* <p> Examples of transformed units:[code]
* CELSIUS = KELVIN.add(273.15);
* FOOT = METER.multiply(0.3048);
* MILLISECOND = MILLI(SECOND);
* [/code]</p>
*
* <p> Transformed units have no label. But like any other units,
* they may have labels attached to them:[code]
* UnitFormat.getStandardInstance().label(FOOT, "ft");
* [/code]
* or aliases: [code]
* UnitFormat.getStandardInstance().alias(CENTI(METER)), "centimeter");
* UnitFormat.getStandardInstance().alias(CENTI(METER)), "centimetre");
* [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
* @see Unit#plus(double)
* @see Unit#times(double)
* @see Unit#transform(UnitConverter)
* @see UnitFormat
*/
public final class TransformedUnit<Q extends Quantity> extends DerivedUnit<Q> {
/**
* Holds the parent unit (not a transformed unit).
*/
private final Unit<Q> _parentUnit;
/**
* Holds the converter to the parent unit.
*/
private final UnitConverter _toParentUnit;
/**
* Creates a transformed unit from the specified parent unit.
*
* @param parentUnit the untransformed unit from which this unit is
* derived.
* @param toParentUnit the converter to the parent units.
* @throws IllegalArgumentException if <code>toParentUnit ==
* {@link UnitConverter#IDENTITY UnitConverter.IDENTITY}</code>
*/
TransformedUnit(Unit<Q> parentUnit, UnitConverter toParentUnit) {
if (toParentUnit == UnitConverter.IDENTITY)
throw new IllegalArgumentException("Identity not allowed");
_parentUnit = parentUnit;
_toParentUnit = toParentUnit;
}
/**
* Returns the parent unit for this unit. The parent unit is the
* untransformed unit from which this unit is derived.
*
* @return the untransformed unit from which this unit is derived.
*/
public Unit<Q> getParentUnit() {
return _parentUnit;
}
/**
* Returns the converter to the parent unit.
*
* @return the converter to the parent unit.
*/
public UnitConverter toParentUnit() {
return _toParentUnit;
}
/**
* Indicates if this transformed unit is considered equals to the specified
* object (both are transformed units with equal parent unit and equal
* converter to parent unit).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that) return true;
if (!(that instanceof TransformedUnit)) return false;
TransformedUnit<?> thatUnit = (TransformedUnit<?>) that;
return this._parentUnit.equals(thatUnit._parentUnit) &&
this._toParentUnit.equals(thatUnit._toParentUnit);
}
// Implements abstract method.
public int hashCode() {
return _parentUnit.hashCode() + _toParentUnit.hashCode();
}
// Implements abstract method.
public Unit<? super Q> getStandardUnit() {
return _parentUnit.getStandardUnit();
}
// Implements abstract method.
public UnitConverter toStandardUnit() {
return _parentUnit.toStandardUnit().concatenate(_toParentUnit);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,501 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.io.Serializable;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.HashMap;
import javax.measure.MeasureFormat;
import javax.measure.converter.AddConverter;
import javax.measure.converter.ConversionException;
import javax.measure.converter.MultiplyConverter;
import javax.measure.converter.RationalConverter;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Dimensionless;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents a determinate {@link javax.measure.quantity.Quantity
* quantity} (as of length, time, heat, or value) adopted as a standard
* of measurement.</p>
*
* <p> It is helpful to think of instances of this class as recording the
* history by which they are created. Thus, for example, the string
* "g/kg" (which is a dimensionless unit) would result from invoking
* the method toString() on a unit that was created by dividing a
* gram unit by a kilogram unit. Yet, "kg" divided by "kg" returns
* {@link #ONE} and not "kg/kg" due to automatic unit factorization.</p>
*
* <p> This class supports the multiplication of offsets units. The result is
* usually a unit not convertible to its {@link #getStandardUnit standard unit}.
* Such units may appear in derivative quantities. For example °C/m is an
* unit of gradient, which is common in atmospheric and oceanographic
* research.</p>
*
* <p> Units raised at rational powers are also supported. For example
* the cubic root of "liter" is a unit compatible with meter.</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @author <a href="mailto:steve@unidata.ucar.edu">Steve Emmerson</a>
* @author Martin Desruisseaux
* @version 3.2, August 28, 2006
* @see <a href="http://en.wikipedia.org/wiki/Units_of_measurement">
* Wikipedia: Units of measurement</a>
*/
public abstract class Unit<Q extends Quantity> implements Serializable {
/**
* Holds the dimensionless unit <code>ONE</code>.
*/
public static final Unit<Dimensionless> ONE = new ProductUnit<Dimensionless>();
/**
* Holds the unique symbols collection (base unit or alternate units).
*/
static final HashMap<String, Unit<?>> SYMBOL_TO_UNIT = new HashMap<String, Unit<?>>();
/**
* Default constructor.
*/
protected Unit() {
}
//////////////////////////////////////////////////////
// Contract methods (for sub-classes to implement). //
//////////////////////////////////////////////////////
/**
* Returns the {@link BaseUnit base unit}, {@link AlternateUnit alternate
* unit} or product of base units and alternate units this unit is derived
* from. The standard unit identifies the "type" of
* {@link javax.measure.quantity.Quantity quantity} for which this unit is employed.
* For example:[code]
* boolean isAngularVelocity(Unit<?> u) {
* return u.getStandardUnit().equals(RADIAN.divide(SECOND));
* }
* assert(REVOLUTION.divide(MINUTE).isAngularVelocity());
* [/code]
*
* <p><i> Note: Having the same system unit is not sufficient to ensure
* that a converter exists between the two units
* (e.g. °C/m and K/m).</i></p>
* @return the system unit this unit is derived from.
*/
public abstract Unit<? super Q> getStandardUnit();
/**
* Returns the converter from this unit to its system unit.
*
* @return <code>this.getConverterTo(this.getSystemUnit())</code>
*/
public abstract UnitConverter toStandardUnit();
/**
* Returns the hash code for this unit.
*
* @return this unit hashcode value.
*/
public abstract int hashCode();
/**
* Indicates if the specified unit can be considered equals to
* the one specified.
*
* @param that the object to compare to.
* @return <code>true</code> if this unit is considered equal to
* that unit; <code>false</code> otherwise.
*/
public abstract boolean equals(Object that);
/**
* Indicates if this unit is a standard unit (base units and
* alternate units are standard units). The standard unit identifies
* the "type" of {@link javax.measure.quantity.Quantity quantity} for
* which the unit is employed.
*
* @return <code>getStandardUnit().equals(this)</code>
*/
public boolean isStandardUnit() {
return getStandardUnit().equals(this);
}
/**
* Indicates if this unit is compatible with the unit specified.
* Units don't need to be equals to be compatible. For example:[code]
* RADIAN.equals(ONE) == false
* RADIAN.isCompatible(ONE) == true
* [/code]
* @param that the other unit.
* @return <code>this.getDimension().equals(that.getDimension())</code>
* @see #getDimension()
*/
public final boolean isCompatible(Unit<?> that) {
return (this == that)
|| this.getStandardUnit().equals(that.getStandardUnit())
|| this.getDimension().equals(that.getDimension());
}
/**
* Casts this unit to a parameterized unit of specified nature or
* throw a <code>ClassCastException</code> if the dimension of the
* specified quantity and this unit's dimension do not match.
* For example:[code]
* Unit<Length> LIGHT_YEAR = NonSI.C.times(NonSI.YEAR).asType(Length.class);
* [/code]
*
* @param type the quantity class identifying the nature of the unit.
* @return this unit parameterized with the specified type.
* @throws ClassCastException if the dimension of this unit is different
* from the specified quantity dimension.
* @throws UnsupportedOperationException if the specified quantity class
* does not have a public static field named "UNIT" holding the
* standard unit for the quantity.
*/
@SuppressWarnings("unchecked")
public final <T extends Quantity> Unit<T> asType(Class<T> type) throws ClassCastException {
Dimension dim1 = this.getDimension();
Unit<T> u = null;
try {
u = (Unit<T>)type.getField("UNIT").get(null);
} catch (Exception e) {
throw new Error(e);
}
Dimension dim2 = u.getDimension();
if (!dim1.equals(dim2))
throw new ClassCastException();
return (Unit<T>)this;
}
/**
* Returns the dimension of this unit (depends upon the current
* dimensional {@link Dimension.Model model}).
*
* @return the dimension of this unit for the current model.
*/
public final Dimension getDimension() {
Unit<?> systemUnit = this.getStandardUnit();
if (systemUnit instanceof BaseUnit)
return Dimension.getModel().getDimension((BaseUnit<?>) systemUnit);
if (systemUnit instanceof AlternateUnit)
return ((AlternateUnit<?>) systemUnit).getParent().getDimension();
// Product of units.
ProductUnit<?> productUnit = (ProductUnit<?>) systemUnit;
Dimension dimension = Dimension.NONE;
for (int i = 0; i < productUnit.getUnitCount(); i++) {
Unit<?> unit = productUnit.getUnit(i);
Dimension d = unit.getDimension().pow(productUnit.getUnitPow(i))
.root(productUnit.getUnitRoot(i));
dimension = dimension.times(d);
}
return dimension;
}
/**
* Returns a converter of numeric values from this unit to another unit.
*
* @param that the unit to which to convert the numeric values.
* @return the converter from this unit to <code>that</code> unit.
* @throws ConversionException if the conveter cannot be constructed
* (e.g. <code>!this.isCompatible(that)</code>).
*/
public final UnitConverter getConverterTo(Unit<?> that)
throws ConversionException {
if (this.equals(that))
return UnitConverter.IDENTITY;
Unit<?> thisSystemUnit = this.getStandardUnit();
Unit<?> thatSystemUnit = that.getStandardUnit();
if (thisSystemUnit.equals(thatSystemUnit))
return that.toStandardUnit().inverse().concatenate(
this.toStandardUnit());
// Use dimensional transforms.
if (!thisSystemUnit.getDimension()
.equals(thatSystemUnit.getDimension()))
throw new ConversionException(this + " is not compatible with "
+ that);
// Transform between SystemUnit and BaseUnits is Identity.
UnitConverter thisTransform = this.toStandardUnit().concatenate(
transformOf(this.getBaseUnits()));
UnitConverter thatTransform = that.toStandardUnit().concatenate(
transformOf(that.getBaseUnits()));
return thatTransform.inverse().concatenate(thisTransform);
}
private Unit<?> getBaseUnits() {
Unit<?> systemUnit = this.getStandardUnit();
if (systemUnit instanceof BaseUnit) return systemUnit;
if (systemUnit instanceof AlternateUnit)
return ((AlternateUnit<?>)systemUnit).getParent().getBaseUnits();
if (systemUnit instanceof ProductUnit) {
ProductUnit<?> productUnit = (ProductUnit<?>)systemUnit;
Unit<?> baseUnits = ONE;
for (int i = 0; i < productUnit.getUnitCount(); i++) {
Unit<?> unit = productUnit.getUnit(i).getBaseUnits();
unit = unit.pow(productUnit.getUnitPow(i));
unit = unit.root(productUnit.getUnitRoot(i));
baseUnits = baseUnits.times(unit);
}
return baseUnits;
} else {
throw new InternalError(
"System Unit cannot be an instance of " + this.getClass());
}
}
private static UnitConverter transformOf(Unit<?> baseUnits) {
if (baseUnits instanceof BaseUnit)
return Dimension.getModel().getTransform((BaseUnit<?>) baseUnits);
// Product of units.
ProductUnit<?> productUnit = (ProductUnit<?>) baseUnits;
UnitConverter converter = UnitConverter.IDENTITY;
for (int i = 0; i < productUnit.getUnitCount(); i++) {
Unit<?> unit = productUnit.getUnit(i);
UnitConverter cvtr = transformOf(unit);
if (!cvtr.isLinear())
throw new ConversionException(baseUnits
+ " is non-linear, cannot convert");
if (productUnit.getUnitRoot(i) != 1)
throw new ConversionException(productUnit
+ " holds a base unit with fractional exponent");
int pow = productUnit.getUnitPow(i);
if (pow < 0) { // Negative power.
pow = -pow;
cvtr = cvtr.inverse();
}
for (int j = 0; j < pow; j++) {
converter = converter.concatenate(cvtr);
}
}
return converter;
}
/**
* Returns a unit equivalent to this unit but used in expressions to
* distinguish between quantities of a different nature but of the same
* dimensions.
*
* <p> Examples of alternate units:[code]
* Unit<Angle> RADIAN = ONE.alternate("rad");
* Unit<Force> NEWTON = METER.times(KILOGRAM).divide(SECOND.pow(2)).alternate("N");
* Unit<Pressure> PASCAL = NEWTON.divide(METER.pow(2)).alternate("Pa");
* [/code]</p>
*
* @param symbol the new symbol for the alternate unit.
* @return the alternate unit.
* @throws UnsupportedOperationException if this unit is not a standard unit.
* @throws IllegalArgumentException if the specified symbol is already
* associated to a different unit.
*/
public final <A extends Quantity> AlternateUnit<A> alternate(String symbol) {
return new AlternateUnit<A>(symbol, this);
}
/**
* Returns the combination of this unit with the specified sub-unit.
* Compound units are typically used for formatting purpose.
* Examples of compound units:[code]
* HOUR_MINUTE = NonSI.HOUR.compound(NonSI.MINUTE);
* DEGREE_MINUTE_SECOND_ANGLE = NonSI.DEGREE_ANGLE.compound(
* NonSI.DEGREE_MINUTE).compound(NonSI.SECOND_ANGLE);
* [/code]
*
* @param subunit the sub-unit to combine with this unit.
* @return the corresponding compound unit.
*/
public final CompoundUnit<Q> compound(Unit<Q> subunit) {
return new CompoundUnit<Q>(this, subunit);
}
/**
* Returns the unit derived from this unit using the specified converter.
* The converter does not need to be linear. For example:[code]
* Unit<Dimensionless> DECIBEL = Unit.ONE.transform(
* new LogConverter(10).inverse().concatenate(
* new RationalConverter(1, 10)));[/code]
*
* @param operation the converter from the transformed unit to this unit.
* @return the unit after the specified transformation.
*/
public final Unit<Q> transform(UnitConverter operation) {
if (this instanceof TransformedUnit) {
TransformedUnit<Q> tf = (TransformedUnit<Q>) this;
Unit<Q> parent = tf.getParentUnit();
UnitConverter toParent = tf.toParentUnit().concatenate(operation);
if (toParent == UnitConverter.IDENTITY)
return parent;
return new TransformedUnit<Q>(parent, toParent);
}
if (operation == UnitConverter.IDENTITY)
return this;
return new TransformedUnit<Q>(this, operation);
}
/**
* Returns the result of adding an offset to this unit. The returned unit
* is convertible with all units that are convertible with this unit.
*
* @param offset the offset added (expressed in this unit,
* e.g. <code>CELSIUS = KELVIN.plus(273.15)</code>).
* @return <code>this.transform(new AddConverter(offset))</code>
*/
public final Unit<Q> plus(double offset) {
return transform(new AddConverter(offset));
}
/**
* Returns the result of multiplying this unit by an exact factor.
*
* @param factor the exact scale factor
* (e.g. <code>KILOMETER = METER.times(1000)</code>).
* @return <code>this.transform(new RationalConverter(factor, 1))</code>
*/
public final Unit<Q> times(long factor) {
return transform(new RationalConverter(factor, 1));
}
/**
* Returns the result of multiplying this unit by a an approximate factor
*
* @param factor the approximate factor (e.g.
* <code>ELECTRON_MASS = KILOGRAM.times(9.10938188e-31)</code>).
* @return <code>this.transform(new MultiplyConverter(factor))</code>
*/
public final Unit<Q> times(double factor) {
return transform(new MultiplyConverter(factor));
}
/**
* Returns the product of this unit with the one specified.
*
* @param that the unit multiplicand.
* @return <code>this * that</code>
*/
public final Unit<? extends Quantity> times(Unit<?> that) {
return ProductUnit.getProductInstance(this, that);
}
/**
* Returns the inverse of this unit.
*
* @return <code>1 / this</code>
*/
public final Unit<? extends Quantity> inverse() {
return ProductUnit.getQuotientInstance(ONE, this);
}
/**
* Returns the result of dividing this unit by an exact divisor.
*
* @param divisor the exact divisor.
* (e.g. <code>QUART = GALLON_LIQUID_US.divide(4)</code>).
* @return <code>this.transform(new RationalConverter(1 , divisor))</code>
*/
public final Unit<Q> divide(long divisor) {
return transform(new RationalConverter(1, divisor));
}
/**
* Returns the result of dividing this unit by an approximate divisor.
*
* @param divisor the approximate divisor.
* @return <code>this.transform(new MultiplyConverter(1.0 / divisor))</code>
*/
public final Unit<Q> divide(double divisor) {
return transform(new MultiplyConverter(1.0 / divisor));
}
/**
* Returns the quotient of this unit with the one specified.
*
* @param that the unit divisor.
* @return <code>this / that</code>
*/
public final Unit<? extends Quantity> divide(Unit<?> that) {
return this.times(that.inverse());
}
/**
* Returns a unit equals to the given root of this unit.
*
* @param n the root's order.
* @return the result of taking the given root of this unit.
* @throws ArithmeticException if <code>n == 0</code>.
*/
public final Unit<? extends Quantity> root(int n) {
if (n > 0) {
return ProductUnit.getRootInstance(this, n);
} else if (n == 0) {
throw new ArithmeticException("Root's order of zero");
} else { // n < 0
return ONE.divide(this.root(-n));
}
}
/**
* Returns a unit equals to this unit raised to an exponent.
*
* @param n the exponent.
* @return the result of raising this unit to the exponent.
*/
public final Unit<? extends Quantity> pow(int n) {
if (n > 0) {
return this.times(this.pow(n - 1));
} else if (n == 0) {
return ONE;
} else { // n < 0
return ONE.divide(this.pow(-n));
}
}
/**
* Returns a unit instance that is defined from the specified
* character sequence using the {@link UnitFormat#getInstance()
* standard unit format}.
* <p> Examples of valid entries (all for meters per second squared) are:
* <code><ul>
* <li>m*s-2</li>
* <li>m/s²</li>
* <li>m·s-²</li>
* <li>m*s**-2</li>
* <li>m^+1 s^-2</li>
* </ul></code></p>
*
* @param csq the character sequence to parse.
* @return <code>UnitFormat.getStandardInstance().parse(csq, new ParsePosition(0))</code>
* @throws IllegalArgumentException if the specified character sequence
* cannot be correctly parsed (e.g. symbol unknown).
*/
public static Unit<? extends Quantity> valueOf(CharSequence csq) {
try {
return UnitFormat.getInstance()
.parseProductUnit(csq, new ParsePosition(0));
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}
//////////////////////
// GENERAL CONTRACT //
//////////////////////
/**
* Returns the standard <code>String</code> representation of this unit.
* This representation is not affected by locale. Locale-sensitive
* unit formatting and parsing is handled by the {@link MeasureFormat}
* class and its subclasses.
*
* @return <code>UnitFormat.getStandardInstance().format(this)</code>
*/
public final String toString() {
return UnitFormat.getInstance().format(this);
}
}

View File

@ -0,0 +1,940 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import java.io.IOException;
import java.lang.CharSequence;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.HashMap;
import java.util.Locale;
//@RETROWEAVER import javolution.text.Appendable;
import javax.measure.converter.AddConverter;
import javax.measure.converter.MultiplyConverter;
import javax.measure.converter.RationalConverter;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
import static javax.measure.unit.SI.*;
/**
* <p> This class provides the interface for formatting and parsing {@link
* Unit units}.</p>
*
* <p> For all {@link SI} units, the 20 SI prefixes used to form decimal
* multiples and sub-multiples of SI units are recognized.
* {@link NonSI} units are directly recognized. For example:[code]
* Unit.valueOf("m°C").equals(SI.MILLI(SI.CELSIUS))
* Unit.valueOf("kW").equals(SI.KILO(SI.WATT))
* Unit.valueOf("ft").equals(SI.METER.multiply(0.3048))[/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @author Eric Russell
* @version 1.3, August 29, 2006
*/
public abstract class UnitFormat extends Format {
/**
* Holds the standard unit format.
*/
private static final DefaultFormat DEFAULT = new DefaultFormat();
/**
* Holds the ASCIIFormat unit format.
*/
private static final ASCIIFormat ASCII = new ASCIIFormat();
/**
* Returns the unit format for the default locale (format used by
* {@link Unit#valueOf(CharSequence) Unit.valueOf(CharSequence)} and
* {@link Unit#toString() Unit.toString()}).
*
* @return the default unit format (locale sensitive).
*/
public static UnitFormat getInstance() {
return UnitFormat.getInstance(Locale.getDefault());
}
/**
* Returns the unit format for the specified locale.
*
* @return the unit format for the specified locale.
*/
public static UnitFormat getInstance(Locale inLocale) {
return DEFAULT; // TBD: Implement Locale Format.
}
/**
* Returns the <a href="http://aurora.regenstrief.org/UCUM/ucum.html">UCUM
* </a> international unit format; this format uses characters range
* <code>0000-007F</code> exclusively and <b>is not</b> locale-sensitive.
* For example: <code>kg.m/s2</code>
*
* @return the UCUM international format.
*/
public static UnitFormat getUCUMInstance() {
return UnitFormat.ASCII; // TBD - Provide UCUM implementation.
}
/**
* Base constructor.
*/
protected UnitFormat() {
}
/**
* Formats the specified unit.
*
* @param unit the unit to format.
* @param appendable the appendable destination.
* @throws IOException if an error occurs.
*/
public abstract Appendable format(Unit<?> unit, Appendable appendable)
throws IOException;
/**
* Parses a sequence of character to produce a unit or a rational product
* of unit.
*
* @param csq the <code>CharSequence</code> to parse.
* @param pos an object holding the parsing index and error position.
* @return an {@link Unit} parsed from the character sequence.
* @throws IllegalArgumentException if the character sequence contains
* an illegal syntax.
*/
public abstract Unit<? extends Quantity> parseProductUnit(CharSequence csq, ParsePosition pos)
throws ParseException;
/**
* Parses a sequence of character to produce a single unit.
*
* @param csq the <code>CharSequence</code> to parse.
* @param pos an object holding the parsing index and error position.
* @return an {@link Unit} parsed from the character sequence.
* @throws IllegalArgumentException if the character sequence does not contain
* a valid unit identifier.
*/
public abstract Unit<? extends Quantity> parseSingleUnit(CharSequence csq, ParsePosition pos)
throws ParseException;
/**
* Attaches a system-wide label to the specified unit. For example:
* [code]
* UnitFormat.getInstance().label(DAY.multiply(365), "year");
* UnitFormat.getInstance().label(METER.multiply(0.3048), "ft");
* [/code]
* If the specified label is already associated to an unit the previous
* association is discarded or ignored.
*
* @param unit the unit being labelled.
* @param label the new label for this unit.
* @throws IllegalArgumentException if the label is not a
* {@link UnitFormat#isValidIdentifier(String)} valid identifier.
*/
public abstract void label(Unit<?> unit, String label);
/**
* Attaches a system-wide alias to this unit. Multiple aliases may
* be attached to the same unit. Aliases are used during parsing to
* recognize different variants of the same unit. For example:
* [code]
* UnitFormat.getLocaleInstance().alias(METER.multiply(0.3048), "foot");
* UnitFormat.getLocaleInstance().alias(METER.multiply(0.3048), "feet");
* UnitFormat.getLocaleInstance().alias(METER, "meter");
* UnitFormat.getLocaleInstance().alias(METER, "metre");
* [/code]
* If the specified label is already associated to an unit the previous
* association is discarded or ignored.
*
* @param unit the unit being aliased.
* @param alias the alias attached to this unit.
* @throws IllegalArgumentException if the label is not a
* {@link UnitFormat#isValidIdentifier(String)} valid identifier.
*/
public abstract void alias(Unit<?> unit, String alias);
/**
* Indicates if the specified name can be used as unit identifier.
*
* @param name the identifier to be tested.
* @return <code>true</code> if the name specified can be used as
* label or alias for this format;<code>false</code> otherwise.
*/
public abstract boolean isValidIdentifier(String name);
/**
* Formats an unit and appends the resulting text to a given string
* buffer (implements <code>java.text.Format</code>).
*
* @param unit the unit to format.
* @param toAppendTo where the text is to be appended
* @param pos the field position (not used).
* @return <code>toAppendTo</code>
*/
public final StringBuffer format(Object unit, final StringBuffer toAppendTo,
FieldPosition pos) {
try {
Object dest = toAppendTo;
if (dest instanceof Appendable) {
format((Unit<?>) unit, (Appendable)dest);
} else { // When retroweaver is used to produce 1.4 binaries.
format((Unit<?>) unit, new Appendable() {
public Appendable append(char arg0) throws IOException {
toAppendTo.append(arg0);
return null;
}
public Appendable append(CharSequence arg0) throws IOException {
toAppendTo.append(arg0);
return null;
}
public Appendable append(CharSequence arg0, int arg1, int arg2) throws IOException {
toAppendTo.append(arg0.subSequence(arg1, arg2));
return null;
}});
}
return toAppendTo;
} catch (IOException e) {
throw new Error(e); // Should never happen.
}
}
/**
* Parses the text from a string to produce an object
* (implements <code>java.text.Format</code>).
*
* @param source the string source, part of which should be parsed.
* @param pos the cursor position.
* @return the corresponding unit or <code>null</code> if the string
* cannot be parsed.
*/
public final Unit<?> parseObject(String source, ParsePosition pos) {
int start = pos.getIndex();
try {
return parseProductUnit(source, pos);
} catch (ParseException e) {
pos.setIndex(start);
pos.setErrorIndex(e.getErrorOffset());
return null;
}
}
/**
* This class represents an exponent with both a power (numerator)
* and a root (denominator).
*/
private static class Exponent {
public final int pow;
public final int root;
public Exponent (int pow, int root) {
this.pow = pow;
this.root = root;
}
}
/**
* This class represents the standard format.
*/
protected static class DefaultFormat extends UnitFormat {
/**
* Holds the name to unit mapping.
*/
final HashMap<String, Unit<?>> _nameToUnit = new HashMap<String, Unit<?>>();
/**
* Holds the unit to name mapping.
*/
final HashMap<Unit<?>, String> _unitToName = new HashMap<Unit<?>, String>();
@Override
public void label(Unit<?> unit, String label) {
if (!isValidIdentifier(label))
throw new IllegalArgumentException("Label: " + label
+ " is not a valid identifier.");
synchronized (this) {
_nameToUnit.put(label, unit);
_unitToName.put(unit, label);
}
}
@Override
public void alias(Unit<?> unit, String alias) {
if (!isValidIdentifier(alias))
throw new IllegalArgumentException("Alias: " + alias
+ " is not a valid identifier.");
synchronized (this) {
_nameToUnit.put(alias, unit);
}
}
@Override
public boolean isValidIdentifier(String name) {
if ((name == null) || (name.length() == 0))
return false;
for (int i = 0; i < name.length(); i++) {
if (!isUnitIdentifierPart(name.charAt(i)))
return false;
}
return true;
}
static boolean isUnitIdentifierPart(char ch) {
return Character.isLetter(ch) ||
(!Character.isWhitespace(ch) && !Character.isDigit(ch)
&& (ch != '·') && (ch != '*') && (ch != '/')
&& (ch != '(') && (ch != ')') && (ch != '[') && (ch != ']')
&& (ch != '¹') && (ch != '²') && (ch != '³')
&& (ch != '^') && (ch != '+') && (ch != '-'));
}
// Returns the name for the specified unit or null if product unit.
public String nameFor(Unit<?> unit) {
// Searches label database.
String label = _unitToName.get(unit);
if (label != null)
return label;
if (unit instanceof BaseUnit)
return ((BaseUnit<?>) unit).getSymbol();
if (unit instanceof AlternateUnit)
return ((AlternateUnit<?>) unit).getSymbol();
if (unit instanceof TransformedUnit) {
TransformedUnit<?> tfmUnit = (TransformedUnit<?>) unit;
Unit<?> baseUnits = tfmUnit.getStandardUnit();
UnitConverter cvtr = tfmUnit.toStandardUnit();
StringBuffer result = new StringBuffer();
String baseUnitName = baseUnits.toString();
if ((baseUnitName.indexOf('·') >= 0) ||
(baseUnitName.indexOf('*') >= 0) ||
(baseUnitName.indexOf('/') >= 0)) {
// We could use parentheses whenever baseUnits is an
// instanceof ProductUnit, but most ProductUnits have aliases,
// so we'd end up with a lot of unnecessary parentheses.
result.append('(');
result.append(baseUnitName);
result.append(')');
} else {
result.append(baseUnitName);
}
if (cvtr instanceof AddConverter) {
result.append('+');
result.append(((AddConverter) cvtr).getOffset());
} else if (cvtr instanceof RationalConverter) {
long dividend = ((RationalConverter) cvtr).getDividend();
if (dividend != 1) {
result.append('*');
result.append(dividend);
}
long divisor = ((RationalConverter) cvtr).getDivisor();
if (divisor != 1) {
result.append('/');
result.append(divisor);
} ;
} else if (cvtr instanceof MultiplyConverter) {
result.append('*');
result.append(((MultiplyConverter) cvtr).getFactor());
} else { // Other converters.
return "[" + baseUnits + "?]";
}
return result.toString();
}
// Compound unit.
if (unit instanceof CompoundUnit) {
CompoundUnit<?> cpdUnit = (CompoundUnit<?>) unit;
return nameFor(cpdUnit.getHigher()).toString() + ":"
+ nameFor(cpdUnit.getLower());
}
return null; // Product unit.
}
// Returns the unit for the specified name.
public Unit<?> unitFor(String name) {
Unit<?> unit = _nameToUnit.get(name);
if (unit != null)
return unit;
unit = Unit.SYMBOL_TO_UNIT.get(name);
return unit;
}
////////////////////////////
// Parsing.
@SuppressWarnings("unchecked")
public Unit<? extends Quantity> parseSingleUnit(CharSequence csq, ParsePosition pos)
throws ParseException {
int startIndex = pos.getIndex();
String name = readIdentifier(csq, pos);
Unit unit = unitFor(name);
check(unit != null, name + " not recognized", csq, startIndex);
return unit;
}
@SuppressWarnings("unchecked")
@Override
public Unit<? extends Quantity> parseProductUnit(CharSequence csq, ParsePosition pos)
throws ParseException {
Unit result = Unit.ONE;
int token = nextToken(csq, pos);
switch (token) {
case IDENTIFIER:
result = parseSingleUnit(csq, pos);
break;
case OPEN_PAREN:
pos.setIndex(pos.getIndex() + 1);
result = parseProductUnit(csq, pos);
token = nextToken(csq, pos);
check(token == CLOSE_PAREN, "')' expected", csq, pos.getIndex());
pos.setIndex(pos.getIndex() + 1);
break;
}
token = nextToken(csq, pos);
while (true) {
switch (token) {
case EXPONENT:
Exponent e = readExponent(csq, pos);
if (e.pow != 1) {
result = result.pow(e.pow);
}
if (e.root != 1) {
result = result.root(e.root);
}
break;
case MULTIPLY:
pos.setIndex(pos.getIndex() + 1);
token = nextToken(csq, pos);
if (token == INTEGER) {
long n = readLong(csq, pos);
if (n != 1) {
result = result.times(n);
}
} else if (token == FLOAT) {
double d = readDouble(csq, pos);
if (d != 1.0) {
result = result.times(d);
}
} else {
result = result.times(parseProductUnit(csq, pos));
}
break;
case DIVIDE:
pos.setIndex(pos.getIndex() + 1);
token = nextToken(csq, pos);
if (token == INTEGER) {
long n = readLong(csq, pos);
if (n != 1) {
result = result.divide(n);
}
} else if (token == FLOAT) {
double d = readDouble(csq, pos);
if (d != 1.0) {
result = result.divide(d);
}
} else {
result = result.divide(parseProductUnit(csq, pos));
}
break;
case PLUS:
pos.setIndex(pos.getIndex() + 1);
token = nextToken(csq, pos);
if (token == INTEGER) {
long n = readLong(csq, pos);
if (n != 1) {
result = result.plus(n);
}
} else if (token == FLOAT) {
double d = readDouble(csq, pos);
if (d != 1.0) {
result = result.plus(d);
}
} else {
throw new ParseException("not a number", pos.getIndex());
}
break;
case EOF:
case CLOSE_PAREN:
return result;
default:
throw new ParseException("unexpected token " + token, pos.getIndex());
}
token = nextToken(csq, pos);
}
}
private static final int EOF = 0;
private static final int IDENTIFIER = 1;
private static final int OPEN_PAREN= 2;
private static final int CLOSE_PAREN= 3;
private static final int EXPONENT = 4;
private static final int MULTIPLY = 5;
private static final int DIVIDE = 6;
private static final int PLUS = 7;
private static final int INTEGER = 8;
private static final int FLOAT = 9;
private int nextToken(CharSequence csq, ParsePosition pos) {
final int length = csq.length();
while (pos.getIndex() < length) {
char c = csq.charAt(pos.getIndex());
if (isUnitIdentifierPart(c)) {
return IDENTIFIER;
} else if (c == '(') {
return OPEN_PAREN;
} else if (c == ')') {
return CLOSE_PAREN;
} else if ((c == '^') || (c == '¹') || (c == '²') || (c == '³')) {
return EXPONENT;
} else if (c == '*') {
char c2 = csq.charAt(pos.getIndex() + 1);
if (c2 == '*') {
return EXPONENT;
} else {
return MULTIPLY;
}
} else if (c == '·') {
return MULTIPLY;
} else if (c == '/') {
return DIVIDE;
} else if (c == '+') {
return PLUS;
} else if ((c == '-') || Character.isDigit(c)) {
int index = pos.getIndex()+1;
while ((index < length) &&
(Character.isDigit(c) || (c == '-') || (c == '.') || (c == 'E'))) {
c = csq.charAt(index++);
if (c == '.') {
return FLOAT;
}
}
return INTEGER;
}
pos.setIndex(pos.getIndex() + 1);
}
return EOF;
}
private void check(boolean expr, String message, CharSequence csq,
int index) throws ParseException {
if (!expr) {
throw new ParseException(message + " (in " + csq
+ " at index " + index + ")", index);
}
}
private Exponent readExponent (CharSequence csq, ParsePosition pos) {
char c = csq.charAt(pos.getIndex());
if (c == '^') {
pos.setIndex(pos.getIndex()+1);
} else if (c == '*') {
pos.setIndex(pos.getIndex()+2);
}
final int length = csq.length();
int pow = 0;
boolean isPowNegative = false;
int root = 0;
boolean isRootNegative = false;
boolean isRoot = false;
while (pos.getIndex() < length) {
c = csq.charAt(pos.getIndex());
if (c == '¹') {
if (isRoot) {
root = root * 10 + 1;
} else {
pow = pow * 10 + 1;
}
} else if (c == '²') {
if (isRoot) {
root = root * 10 + 2;
} else {
pow = pow * 10 + 2;
}
} else if (c == '³') {
if (isRoot) {
root = root * 10 + 3;
} else {
pow = pow * 10 + 3;
}
} else if (c == '-') {
if (isRoot) {
isRootNegative = true;
} else {
isPowNegative = true;
}
} else if ((c >= '0') && (c <= '9')) {
if (isRoot) {
root = root * 10 + (c - '0');
} else {
pow = pow * 10 + (c - '0');
}
} else if (c == ':') {
isRoot = true;
} else {
break;
}
pos.setIndex(pos.getIndex()+1);
}
if (pow == 0) pow = 1;
if (root == 0) root = 1;
return new Exponent(isPowNegative ? -pow : pow,
isRootNegative ? -root : root);
}
private long readLong (CharSequence csq, ParsePosition pos) {
final int length = csq.length();
int result = 0;
boolean isNegative = false;
while (pos.getIndex() < length) {
char c = csq.charAt(pos.getIndex());
if (c == '-') {
isNegative = true;
} else if ((c >= '0') && (c <= '9')) {
result = result * 10 + (c - '0');
} else {
break;
}
pos.setIndex(pos.getIndex()+1);
}
return isNegative ? -result : result;
}
private double readDouble (CharSequence csq, ParsePosition pos) {
final int length = csq.length();
int start = pos.getIndex();
int end = start+1;
while (end < length) {
if ("012356789+-.E".indexOf(csq.charAt(end)) < 0) {
break;
}
end += 1;
}
pos.setIndex(end+1);
return Double.parseDouble(csq.subSequence(start,end).toString());
}
private String readIdentifier(CharSequence csq, ParsePosition pos) {
final int length = csq.length();
int start = pos.getIndex();
int i = start;
while ((++i < length) && isUnitIdentifierPart(csq.charAt(i))) { }
pos.setIndex(i);
return csq.subSequence(start, i).toString();
}
////////////////////////////
// Formatting.
@Override
public Appendable format(Unit<?> unit, Appendable appendable)
throws IOException {
String name = nameFor(unit);
if (name != null)
return appendable.append(name);
if (!(unit instanceof ProductUnit))
throw new IllegalArgumentException("Cannot format given Object as a Unit");
// Product unit.
ProductUnit<?> productUnit = (ProductUnit<?>) unit;
int invNbr = 0;
// Write positive exponents first.
boolean start = true;
for (int i = 0; i < productUnit.getUnitCount(); i++) {
int pow = productUnit.getUnitPow(i);
if (pow >= 0) {
if (!start) {
appendable.append('·'); // Separator.
}
name = nameFor(productUnit.getUnit(i));
int root = productUnit.getUnitRoot(i);
append(appendable, name, pow, root);
start = false;
} else {
invNbr++;
}
}
// Write negative exponents.
if (invNbr != 0) {
if (start) {
appendable.append('1'); // e.g. 1/s
}
appendable.append('/');
if (invNbr > 1) {
appendable.append('(');
}
start = true;
for (int i = 0; i < productUnit.getUnitCount(); i++) {
int pow = productUnit.getUnitPow(i);
if (pow < 0) {
name = nameFor(productUnit.getUnit(i));
int root = productUnit.getUnitRoot(i);
if (!start) {
appendable.append('·'); // Separator.
}
append(appendable, name, -pow, root);
start = false;
}
}
if (invNbr > 1) {
appendable.append(')');
}
}
return appendable;
}
private void append(Appendable appendable, CharSequence symbol,
int pow, int root) throws IOException {
appendable.append(symbol);
if ((pow != 1) || (root != 1)) {
// Write exponent.
if ((pow == 2) && (root == 1)) {
appendable.append('²'); // Square
} else if ((pow == 3) && (root == 1)) {
appendable.append('³'); // Cubic
} else {
// Use general exponent form.
appendable.append('^');
appendable.append(String.valueOf(pow));
if (root != 1) {
appendable.append(':');
appendable.append(String.valueOf(root));
}
}
}
}
private static final long serialVersionUID = 1L;
}
/**
* This class represents the ASCIIFormat format.
*/
protected static class ASCIIFormat extends DefaultFormat {
@Override
public String nameFor(Unit<?> unit) {
// First search if specific ASCII name should be used.
String name = _unitToName.get(unit);
if (name != null)
return name;
// Else returns default name.
return DEFAULT.nameFor(unit);
}
@Override
public Unit<?> unitFor(String name) {
// First search if specific ASCII name.
Unit<?> unit = _nameToUnit.get(name);
if (unit != null)
return unit;
// Else returns default mapping.
return DEFAULT.unitFor(name);
}
@Override
public Appendable format(Unit<?> unit, Appendable appendable)
throws IOException {
String name = nameFor(unit);
if (name != null)
return appendable.append(name);
if (!(unit instanceof ProductUnit))
throw new IllegalArgumentException(
"Cannot format given Object as a Unit");
ProductUnit<?> productUnit = (ProductUnit<?>) unit;
for (int i = 0; i < productUnit.getUnitCount(); i++) {
if (i != 0) {
appendable.append('*'); // Separator.
}
name = nameFor(productUnit.getUnit(i));
int pow = productUnit.getUnitPow(i);
int root = productUnit.getUnitRoot(i);
appendable.append(name);
if ((pow != 1) || (root != 1)) {
// Use general exponent form.
appendable.append('^');
appendable.append(String.valueOf(pow));
if (root != 1) {
appendable.append(':');
appendable.append(String.valueOf(root));
}
}
}
return appendable;
}
private static final long serialVersionUID = 1L;
}
////////////////////////////////////////////////////////////////////////////
// Initializes the standard unit database for SI units.
private static final Unit<?>[] SI_UNITS = { SI.AMPERE, SI.BECQUEREL,
SI.CANDELA, SI.COULOMB, SI.FARAD, SI.GRAY, SI.HENRY, SI.HERTZ,
SI.JOULE, SI.KATAL, SI.KELVIN, SI.LUMEN, SI.LUX, SI.METRE, SI.MOLE,
SI.NEWTON, SI.OHM, SI.PASCAL, SI.RADIAN, SI.SECOND, SI.SIEMENS,
SI.SIEVERT, SI.STERADIAN, SI.TESLA, SI.VOLT, SI.WATT, SI.WEBER };
private static final String[] PREFIXES = { "Y", "Z", "E", "P", "T", "G",
"M", "k", "h", "da", "d", "c", "m", "µ", "n", "p", "f", "a", "z",
"y" };
private static final UnitConverter[] CONVERTERS = { E24, E21, E18, E15, E12,
E9, E6, E3, E2, E1, Em1, Em2, Em3, Em6, Em9, Em12,
Em15, Em18, Em21, Em24 };
private static String asciiPrefix(String prefix) {
return prefix == "µ" ? "micro" : prefix;
}
static {
for (int i = 0; i < SI_UNITS.length; i++) {
for (int j = 0; j < PREFIXES.length; j++) {
Unit<?> si = SI_UNITS[i];
Unit<?> u = si.transform(CONVERTERS[j]);
String symbol = (si instanceof BaseUnit) ? ((BaseUnit<?>) si)
.getSymbol() : ((AlternateUnit<?>) si).getSymbol();
DEFAULT.label(u, PREFIXES[j] + symbol);
if (PREFIXES[j] == "µ") {
ASCII.label(u, "micro" + symbol);
}
}
}
// Special case for KILOGRAM.
DEFAULT.label(SI.GRAM, "g");
for (int i = 0; i < PREFIXES.length; i++) {
if (CONVERTERS[i] == E3) continue; // kg is already defined.
DEFAULT.label(SI.KILOGRAM.transform(CONVERTERS[i].concatenate(Em3)),
PREFIXES[i] + "g");
if (PREFIXES[i] == "µ") {
ASCII.label(SI.KILOGRAM.transform(CONVERTERS[i].concatenate(Em3)), "microg");
}
}
// Alias and ASCIIFormat for Ohm
DEFAULT.alias(SI.OHM, "Ohm");
ASCII.label(SI.OHM, "Ohm");
for (int i = 0; i < PREFIXES.length; i++) {
DEFAULT.alias(SI.OHM.transform(CONVERTERS[i]), PREFIXES[i] + "Ohm");
ASCII.label(SI.OHM.transform(CONVERTERS[i]), asciiPrefix(PREFIXES[i]) + "Ohm");
}
// Special case for DEGREE_CElSIUS.
DEFAULT.label(SI.CELSIUS, "");
DEFAULT.alias(SI.CELSIUS, "°C");
ASCII.label(SI.CELSIUS, "Celsius");
for (int i = 0; i < PREFIXES.length; i++) {
DEFAULT.label(SI.CELSIUS.transform(CONVERTERS[i]), PREFIXES[i] + "");
DEFAULT.alias(SI.CELSIUS.transform(CONVERTERS[i]), PREFIXES[i] + "°C");
ASCII.label(SI.CELSIUS.transform(CONVERTERS[i]), asciiPrefix(PREFIXES[i]) + "Celsius");
}
}
////////////////////////////////////////////////////////////////////////////
// To be moved in resource bundle in future release (locale dependent).
static {
DEFAULT.label(NonSI.PERCENT, "%");
DEFAULT.label(NonSI.DECIBEL, "dB");
DEFAULT.label(NonSI.G, "grav");
DEFAULT.label(NonSI.ATOM, "atom");
DEFAULT.label(NonSI.REVOLUTION, "rev");
DEFAULT.label(NonSI.DEGREE_ANGLE, "°");
ASCII.label(NonSI.DEGREE_ANGLE, "degree_angle");
DEFAULT.label(NonSI.MINUTE_ANGLE, "'");
DEFAULT.label(NonSI.SECOND_ANGLE, "\"");
DEFAULT.label(NonSI.CENTIRADIAN, "centiradian");
DEFAULT.label(NonSI.GRADE, "grade");
DEFAULT.label(NonSI.ARE, "a");
DEFAULT.label(NonSI.HECTARE, "ha");
DEFAULT.label(NonSI.BYTE, "byte");
DEFAULT.label(NonSI.MINUTE, "min");
DEFAULT.label(NonSI.HOUR, "h");
DEFAULT.label(NonSI.DAY, "day");
DEFAULT.label(NonSI.WEEK, "week");
DEFAULT.label(NonSI.YEAR, "year");
DEFAULT.label(NonSI.MONTH, "month");
DEFAULT.label(NonSI.DAY_SIDEREAL, "day_sidereal");
DEFAULT.label(NonSI.YEAR_SIDEREAL, "year_sidereal");
DEFAULT.label(NonSI.YEAR_CALENDAR, "year_calendar");
DEFAULT.label(NonSI.E, "e");
DEFAULT.label(NonSI.FARADAY, "Fd");
DEFAULT.label(NonSI.FRANKLIN, "Fr");
DEFAULT.label(NonSI.GILBERT, "Gi");
DEFAULT.label(NonSI.ERG, "erg");
DEFAULT.label(NonSI.ELECTRON_VOLT, "eV");
DEFAULT.label(SI.KILO(NonSI.ELECTRON_VOLT), "keV");
DEFAULT.label(SI.MEGA(NonSI.ELECTRON_VOLT), "MeV");
DEFAULT.label(SI.GIGA(NonSI.ELECTRON_VOLT), "GeV");
DEFAULT.label(NonSI.LAMBERT, "La");
DEFAULT.label(NonSI.FOOT, "ft");
DEFAULT.label(NonSI.FOOT_SURVEY_US, "foot_survey_us");
DEFAULT.label(NonSI.YARD, "yd");
DEFAULT.label(NonSI.INCH, "in");
DEFAULT.label(NonSI.MILE, "mi");
DEFAULT.label(NonSI.NAUTICAL_MILE, "nmi");
DEFAULT.label(NonSI.MILES_PER_HOUR, "mph");
DEFAULT.label(NonSI.ANGSTROM, "Å");
ASCII.label(NonSI.ANGSTROM, "Angstrom");
DEFAULT.label(NonSI.ASTRONOMICAL_UNIT, "ua");
DEFAULT.label(NonSI.LIGHT_YEAR, "ly");
DEFAULT.label(NonSI.PARSEC, "pc");
DEFAULT.label(NonSI.POINT, "pt");
DEFAULT.label(NonSI.PIXEL, "pixel");
DEFAULT.label(NonSI.MAXWELL, "Mx");
DEFAULT.label(NonSI.GAUSS, "G");
DEFAULT.label(NonSI.ATOMIC_MASS, "u");
DEFAULT.label(NonSI.ELECTRON_MASS, "me");
DEFAULT.label(NonSI.POUND, "lb");
DEFAULT.label(NonSI.OUNCE, "oz");
DEFAULT.label(NonSI.TON_US, "ton_us");
DEFAULT.label(NonSI.TON_UK, "ton_uk");
DEFAULT.label(NonSI.METRIC_TON, "t");
DEFAULT.label(NonSI.DYNE, "dyn");
DEFAULT.label(NonSI.KILOGRAM_FORCE, "kgf");
DEFAULT.label(NonSI.POUND_FORCE, "lbf");
DEFAULT.label(NonSI.HORSEPOWER, "hp");
DEFAULT.label(NonSI.ATMOSPHERE, "atm");
DEFAULT.label(NonSI.BAR, "bar");
DEFAULT.label(NonSI.MILLIMETER_OF_MERCURY, "mmHg");
DEFAULT.label(NonSI.INCH_OF_MERCURY, "inHg");
DEFAULT.label(NonSI.RAD, "rd");
DEFAULT.label(NonSI.REM, "rem");
DEFAULT.label(NonSI.CURIE, "Ci");
DEFAULT.label(NonSI.RUTHERFORD, "Rd");
DEFAULT.label(NonSI.SPHERE, "sphere");
DEFAULT.label(NonSI.RANKINE, "°R");
ASCII.label(NonSI.RANKINE, "degree_rankine");
DEFAULT.label(NonSI.FAHRENHEIT, "°F");
ASCII.label(NonSI.FAHRENHEIT, "degree_fahrenheit");
DEFAULT.label(NonSI.KNOT, "kn");
DEFAULT.label(NonSI.MACH, "Mach");
DEFAULT.label(NonSI.C, "c");
DEFAULT.label(NonSI.LITRE, "L");
DEFAULT.label(SI.MICRO(NonSI.LITRE), "µL");
ASCII.label(SI.MICRO(NonSI.LITRE), "microL");
DEFAULT.label(SI.MILLI(NonSI.LITRE), "mL");
DEFAULT.label(SI.CENTI(NonSI.LITRE), "cL");
DEFAULT.label(SI.DECI(NonSI.LITRE), "dL");
DEFAULT.label(NonSI.GALLON_LIQUID_US, "gal");
DEFAULT.label(NonSI.OUNCE_LIQUID_US, "oz");
DEFAULT.label(NonSI.GALLON_DRY_US, "gallon_dry_us");
DEFAULT.label(NonSI.GALLON_UK, "gallon_uk");
DEFAULT.label(NonSI.OUNCE_LIQUID_UK, "oz_uk");
DEFAULT.label(NonSI.ROENTGEN, "Roentgen");
if (Locale.getDefault().getCountry().equals("GB")) {
DEFAULT.label(NonSI.GALLON_UK, "gal");
DEFAULT.label(NonSI.OUNCE_LIQUID_UK, "oz");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

View File

@ -0,0 +1,61 @@
<body>
<p> Provides support for programatic unit handling.</p>
<h3> Standart/NonStandard Units</h3>
Standard units and prefixes are provided by the
{@link javax.measure.unit.SI SI} class (Système International d'Unités) and
about 50 non-standard units are available through the
{@link javax.measure.unit.NonSI NonSI} class.
<h3>Usage examples:</h3>
[code]
import javax.measure.Scalar;
import javax.measure.Measure;
import javax.measure.unit.*;
import javax.measure.quantity.*;
import static javax.measure.unit.SI.*;
import static javax.measure.unit.NonSI.*;
import static javax.measure.unit.Dimension.*;
public class Main {
public void main(String[] args) {
// Conversion between units.
System.out.println(KILO(METRE).getConverterTo(MILE).convert(10));
// Retrieval of the system unit (identifies the measurement type).
System.out.println(REVOLUTION.divide(MINUTE).getSystemUnit());
// Dimension checking (allows/disallows conversions)
System.out.println(ELECTRON_VOLT.isCompatible(WATT.times(HOUR)));
// Retrieval of the unit dimension (depends upon the current model).
System.out.println(ELECTRON_VOLT.getDimension());
}
}
> 6.2137119223733395
> rad/s
> true
> [L]²·[M]/[T]²
[/code]
<h3>Unit Parameterization</h3>
Units are parameterized (&lt;Q extends {@link javax.measure.quantity.Quantity Quantity}>) to
enforce compile-time checks of units/measures consistency, for example:[code]
Unit<Duration> MINUTE = SECONDS.times(60); // Ok.
Unit<Duration> MINUTE = METRE.times(60); // Compile error.
Unit<Pressure> HECTOPASCAL = HECTO(PASCAL); // Ok.
Unit<Pressure> HECTOPASCAL = HECTO(NEWTON); // Compile error.
Measurable<Duration> duration = Measure.valueOf(2, MINUTE); // Ok.
Measurable<Duration> duration = Measure.valueOf(2, CELSIUS); // Compile error.
long milliseconds = duration.longValue(MILLI(SECOND)); // Ok.
long milliseconds = duration.longValue(POUND); // Compile error.
[/code]</p>
<h3>UML Diagram</h3>
<IMG alt="UML Diagram" src="doc-files/unit.png">
</body>

View File

@ -1 +1,2 @@
include ':app', ':jscl', ':translations', ':dragbutton'
include ':measure'