001/*
002 * Units of Measurement Reference Implementation
003 * Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil, V2COM.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package tec.units.ri.unit;
031
032import java.util.Map;
033import javax.measure.Dimension;
034import javax.measure.Quantity;
035import javax.measure.UnitConverter;
036import tec.units.ri.AbstractConverter;
037import tec.units.ri.AbstractUnit;
038import tec.units.ri.quantity.QuantityDimension;
039
040/**
041 * <p>
042 * This class represents the building blocks on top of which all others physical units are created. Base units are always unscaled SI units.
043 * </p>
044 * 
045 * <p>
046 * When using the standard model, all seven SI base units are dimensionally independent.
047 * </p>
048 *
049 * @see <a href="http://en.wikipedia.org/wiki/SI_base_unit"> Wikipedia: SI base unit</a>
050 *
051 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
052 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
053 * @version 1.0, Oct 17, 2016
054 */
055public final class BaseUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> {
056
057  /**
058         * 
059         */
060  // private static final long serialVersionUID = 1721629233768215930L;
061
062  /**
063   * Holds the symbol.
064   */
065  private final String symbol;
066  /**
067   * Holds the base unit dimension.
068   */
069  private final Dimension dimension;
070
071  /**
072   * Creates a base unit having the specified symbol and dimension.
073   *
074   * @param symbol
075   *          the symbol of this base unit.
076   */
077  public BaseUnit(String symbol, Dimension dimension) {
078    this.symbol = symbol;
079    if (dimension == null) {
080      dimension = QuantityDimension.parse(' '); // XXX try pass
081      // char here
082    }
083    this.dimension = dimension;
084  }
085
086  /**
087   * Creates a base unit having the specified symbol and dimension.
088   *
089   * @param symbol
090   *          the symbol of this base unit.
091   */
092  public BaseUnit(String symbol) {
093    this.symbol = symbol;
094    this.dimension = QuantityDimension.NONE;
095  }
096
097  /**
098   * Creates a base unit having the specified symbol and name.
099   *
100   * @param symbol
101   *          the symbol of this base unit.
102   * @param name
103   *          the name of this base unit.
104   * @throws IllegalArgumentException
105   *           if the specified symbol is associated to a different unit.
106   */
107  public BaseUnit(String symbol, String name) {
108    this(symbol);
109    this.name = name;
110    // Checks if the symbol is associated to a different unit. TODO verify
111    // if we want these checks
112    /*
113     * synchronized (AbstractUnit.SYMBOL_TO_UNIT) { Unit<?> unit =
114     * AbstractUnit.SYMBOL_TO_UNIT.get(symbol); if (unit == null) {
115     * AbstractUnit.SYMBOL_TO_UNIT.put(symbol, this); return; } if (!(unit
116     * instanceof BaseUnit<?>)) throw new IllegalArgumentException("Symbol "
117     * + symbol + " is associated to a different unit"); }
118     */
119  }
120
121  @Override
122  public String getSymbol() {
123    return symbol;
124  }
125
126  @Override
127  public AbstractUnit<Q> toSystemUnit() {
128    return this;
129  }
130
131  @Override
132  public UnitConverter getSystemConverter() {
133    return AbstractConverter.IDENTITY;
134  }
135
136  @Override
137  public Dimension getDimension() {
138    return dimension;
139  }
140
141  @Override
142  public final boolean equals(Object that) {
143    if (this == that)
144      return true;
145    if (!(that instanceof BaseUnit))
146      return false;
147    BaseUnit<?> thatUnit = (BaseUnit<?>) that;
148    return this.symbol.equals(thatUnit.symbol) && this.dimension.equals(thatUnit.dimension);
149  }
150
151  @Override
152  public final int hashCode() {
153    return symbol.hashCode();
154  }
155
156  @Override
157  public Map<? extends AbstractUnit<Q>, Integer> getBaseUnits() {
158    return null;
159  }
160}