001: /*
002: * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003: * Copyright (C) 2006 - JScience (http://jscience.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package javax.measure.unit;
010:
011: import javax.measure.converter.UnitConverter;
012: import javax.measure.quantity.Quantity;
013:
014: /**
015: * <p> This class represents the units used in expressions to distinguish
016: * between quantities of a different nature but of the same dimensions.</p>
017: *
018: * <p> Instances of this class are created through the
019: * {@link Unit#alternate(String)} method.</p>
020: *
021: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
022: * @version 4.2, August 26, 2007
023: */
024: public final class AlternateUnit<Q extends Quantity> extends
025: DerivedUnit<Q> {
026:
027: /**
028: * Holds the symbol.
029: */
030: private final String _symbol;
031:
032: /**
033: * Holds the parent unit (a system unit).
034: */
035: private final Unit<?> _parent;
036:
037: /**
038: * Creates an alternate unit for the specified unit identified by the
039: * specified symbol.
040: *
041: * @param symbol the symbol for this alternate unit.
042: * @param parent the system unit from which this alternate unit is
043: * derived.
044: * @throws UnsupportedOperationException if the source is not
045: * a standard unit.
046: * @throws IllegalArgumentException if the specified symbol is
047: * associated to a different unit.
048: */
049: AlternateUnit(String symbol, Unit<?> parent) {
050: if (!parent.isStandardUnit())
051: throw new UnsupportedOperationException(this
052: + " is not a standard unit");
053: _symbol = symbol;
054: _parent = parent;
055: // Checks if the symbol is associated to a different unit.
056: synchronized (Unit.SYMBOL_TO_UNIT) {
057: Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
058: if (unit == null) {
059: Unit.SYMBOL_TO_UNIT.put(symbol, this );
060: return;
061: }
062: if (unit instanceof AlternateUnit) {
063: AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit;
064: if (symbol.equals(existingUnit._symbol)
065: && _parent.equals(existingUnit._parent))
066: return; // OK, same unit.
067: }
068: throw new IllegalArgumentException("Symbol " + symbol
069: + " is associated to a different unit");
070: }
071: }
072:
073: /**
074: * Returns the symbol for this alternate unit.
075: *
076: * @return this alternate unit symbol.
077: */
078: public final String getSymbol() {
079: return _symbol;
080: }
081:
082: /**
083: * Returns the parent unit from which this alternate unit is derived
084: * (a system unit itself).
085: *
086: * @return the parent of the alternate unit.
087: */
088: @SuppressWarnings("unchecked")
089: public final Unit<? super Q> getParent() {
090: return (Unit<? super Q>) _parent;
091: }
092:
093: @Override
094: public final Unit<? super Q> getStandardUnit() {
095: return this ;
096: }
097:
098: @Override
099: public final UnitConverter toStandardUnit() {
100: return UnitConverter.IDENTITY;
101: }
102:
103: /**
104: * Indicates if this alternate unit is considered equals to the specified
105: * object (both are alternate units with equal symbol, equal base units
106: * and equal converter to base units).
107: *
108: * @param that the object to compare for equality.
109: * @return <code>true</code> if <code>this</code> and <code>that</code>
110: * are considered equals; <code>false</code>otherwise.
111: */
112: public boolean equals(Object that) {
113: if (this == that)
114: return true;
115: if (!(that instanceof AlternateUnit))
116: return false;
117: AlternateUnit<?> thatUnit = (AlternateUnit<?>) that;
118: return this ._symbol.equals(thatUnit._symbol); // Symbols are unique.
119: }
120:
121: // Implements abstract method.
122: public int hashCode() {
123: return _symbol.hashCode();
124: }
125:
126: private static final long serialVersionUID = 1L;
127: }
|