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 building blocks on top of which all others
016 *     units are created. Base units are typically dimensionally independent.
017 *     The actual unit dimension is determinated by the current 
018 *     {@link Dimension.Model model}. For example using the {@link 
019 *     Dimension.Model#STANDARD standard} model, {@link SI#CANDELA} 
020 *     has the dimension of {@link SI#WATT watt}:[code]
021 *     // Standard model.
022 *     BaseUnit<Length> METER = new BaseUnit<Length>("m");
023 *     BaseUnit<LuminousIntensity> CANDELA = new BaseUnit<LuminousIntensity>("cd");
024 *     System.out.println(METER.getDimension());
025 *     System.out.println(CANDELA.getDimension());
026 *     
027 *     > [L]
028 *     > [L]²·[M]/[T]³
029 *     [/code]</p>
030 * <p> This class represents the "standard base units" which includes SI base 
031 *     units and possibly others user-defined base units. It does not represent 
032 *     the base units of any specific {@link SystemOfUnits} (they would have 
033 *     be base units accross all possible systems otherwise).</p> 
034 *           
035 * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
036 * @version 3.1, April 22, 2006
037 * @see <a href="http://en.wikipedia.org/wiki/SI_base_unit">
038 *       Wikipedia: SI base unit</a>
039 */
040public class BaseUnit<Q extends Quantity> extends Unit<Q> {
041
042    /**
043     * Holds the symbol.
044     */
045    private final String _symbol;
046
047    /**
048     * Creates a base unit having the specified symbol. 
049     *
050     * @param symbol the symbol of this base unit.
051     * @throws IllegalArgumentException if the specified symbol is 
052     *         associated to a different unit.
053     */
054    public BaseUnit(String symbol) {
055        _symbol = symbol;
056        // Checks if the symbol is associated to a different unit.
057        synchronized (Unit.SYMBOL_TO_UNIT) {
058            Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
059            if (unit == null) {
060                Unit.SYMBOL_TO_UNIT.put(symbol, this);
061                return;
062            }
063            if (!(unit instanceof BaseUnit)) 
064               throw new IllegalArgumentException("Symbol " + symbol
065                    + " is associated to a different unit");
066        }
067    }
068
069    /**
070     * Returns the unique symbol for this base unit. 
071     *
072     * @return this base unit symbol.
073     */
074    public final String getSymbol() {
075        return _symbol;
076    }
077
078    /**
079     * Indicates if this base unit is considered equals to the specified 
080     * object (both are base units with equal symbol, standard dimension and 
081     * standard transform).
082     *
083     * @param  that the object to compare for equality.
084     * @return <code>true</code> if <code>this</code> and <code>that</code>
085     *         are considered equals; <code>false</code>otherwise. 
086     */
087    public boolean equals(Object that) {
088        if (this == that)
089            return true;
090        if (!(that instanceof BaseUnit))
091            return false;
092        BaseUnit<?> thatUnit = (BaseUnit<?>) that;
093        return this._symbol.equals(thatUnit._symbol); 
094    }
095        
096    @Override
097    public int hashCode() {
098        return _symbol.hashCode();
099    }
100
101    @Override
102    public Unit<? super Q> getStandardUnit() {
103        return this;
104    }
105
106    @Override
107    public UnitConverter toStandardUnit() {
108        return UnitConverter.IDENTITY;
109    }
110
111    private static final long serialVersionUID = 1L;
112}