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 */ 009package javax.measure.unit; 010 011import javax.measure.converter.UnitConverter; 012import 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 */ 024public final class AlternateUnit<Q extends Quantity> extends DerivedUnit<Q> { 025 026 /** 027 * Holds the symbol. 028 */ 029 private final String _symbol; 030 031 /** 032 * Holds the parent unit (a system unit). 033 */ 034 private final Unit<?> _parent; 035 036 /** 037 * Creates an alternate unit for the specified unit identified by the 038 * specified symbol. 039 * 040 * @param symbol the symbol for this alternate unit. 041 * @param parent the system unit from which this alternate unit is 042 * derived. 043 * @throws UnsupportedOperationException if the source is not 044 * a standard unit. 045 * @throws IllegalArgumentException if the specified symbol is 046 * associated to a different unit. 047 */ 048 AlternateUnit(String symbol, Unit<?> parent) { 049 if (!parent.isStandardUnit()) 050 throw new UnsupportedOperationException(this 051 + " is not a standard unit"); 052 _symbol = symbol; 053 _parent = parent; 054 // Checks if the symbol is associated to a different unit. 055 synchronized (Unit.SYMBOL_TO_UNIT) { 056 Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol); 057 if (unit == null) { 058 Unit.SYMBOL_TO_UNIT.put(symbol, this); 059 return; 060 } 061 if (unit instanceof AlternateUnit) { 062 AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit; 063 if (symbol.equals(existingUnit._symbol) 064 && _parent.equals(existingUnit._parent)) 065 return; // OK, same unit. 066 } 067 throw new IllegalArgumentException("Symbol " + symbol 068 + " is associated to a different unit"); 069 } 070 } 071 072 /** 073 * Returns the symbol for this alternate unit. 074 * 075 * @return this alternate unit symbol. 076 */ 077 public final String getSymbol() { 078 return _symbol; 079 } 080 081 /** 082 * Returns the parent unit from which this alternate unit is derived 083 * (a system unit itself). 084 * 085 * @return the parent of the alternate unit. 086 */ 087 @SuppressWarnings("unchecked") 088 public final Unit<? super Q> getParent() { 089 return (Unit<? super Q>) _parent; 090 } 091 092 @Override 093 public final Unit<? super Q> getStandardUnit() { 094 return this; 095 } 096 097 @Override 098 public final UnitConverter toStandardUnit() { 099 return UnitConverter.IDENTITY; 100 } 101 102 /** 103 * Indicates if this alternate unit is considered equals to the specified 104 * object (both are alternate units with equal symbol, equal base units 105 * and equal converter to base units). 106 * 107 * @param that the object to compare for equality. 108 * @return <code>true</code> if <code>this</code> and <code>that</code> 109 * are considered equals; <code>false</code>otherwise. 110 */ 111 public boolean equals(Object that) { 112 if (this == that) 113 return true; 114 if (!(that instanceof AlternateUnit)) 115 return false; 116 AlternateUnit<?> thatUnit = (AlternateUnit<?>) that; 117 return this._symbol.equals(thatUnit._symbol); // Symbols are unique. 118 } 119 120 // Implements abstract method. 121 public int hashCode() { 122 return _symbol.hashCode(); 123 } 124 125 private static final long serialVersionUID = 1L; 126}