All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.units.UnitDBImpl Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

There is a newer version: 4.3.22
Show newest version
// $Id: UnitDBImpl.java 64 2006-07-12 22:30:50Z edavis $
/*
 * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
 *
 * Portions of this software were developed by the Unidata Program at the
 * University Corporation for Atmospheric Research.
 *
 * Access and use of this software shall impose the following obligations
 * and understandings on the user. The user is granted the right, without
 * any fee or cost, to use, copy, modify, alter, enhance and distribute
 * this software, and any derivative works thereof, and its supporting
 * documentation for any purpose whatsoever, provided that this entire
 * notice appears in all copies of the software, derivative works and
 * supporting documentation.  Further, UCAR requests that the user credit
 * UCAR/Unidata in any publications that result from the use of this
 * software or in any product that includes this software. The names UCAR
 * and/or Unidata, however, may not be used in any advertising or publicity
 * to endorse or promote any products or commercial entity unless specific
 * written permission is obtained from UCAR/Unidata. The user also
 * understands that UCAR/Unidata is not obligated to provide the user with
 * any support, consulting, training or assistance of any kind with regard
 * to the use, operation and performance of this software nor to provide
 * the user with any updates, revisions, new versions or "bug fixes."
 *
 * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
 */
package ucar.units;

import java.io.Serializable;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * Provides most of a concrete implementation of a database of units.
 * 
 * @author Steven R. Emmerson
 * @version $Id: UnitDBImpl.java 64 2006-07-12 22:30:50Z edavis $
 */
public class UnitDBImpl implements UnitDB, Serializable {
	private static final long		serialVersionUID	= 1L;

	/**
	 * The set of units.
	 * 
	 * @serial
	 */
	private final Set			unitSet;

	/**
	 * The name-to-unit map.
	 * 
	 * @serial
	 */
	private final Map	nameMap;

	/**
	 * The symbol-to-unit map.
	 * 
	 * @serial
	 */
	private final Map	symbolMap;

	/**
	 * Constructs from the expected number of names and symbols. The sizes will
	 * be used to construct the initial database but will not limit its growth.
	 * 
	 * @param nameCount
	 *            The expected number of names (including plurals and aliases).
	 * @param symbolCount
	 *            The expected number of symbols.
	 */
	protected UnitDBImpl(final int nameCount, final int symbolCount) {
		unitSet = new TreeSet(new Comparator() {
			public int compare(final Unit obj1, final Unit obj2) {
				return (obj1).getName().compareTo((obj2).getName());
			}
		});
		nameMap = new Hashtable(nameCount + 1);
		symbolMap = new Hashtable(symbolCount + 1);
	}

	/**
	 * Adds all the entries in another UnitDBImpl to this database.
	 * 
	 * @param that
	 *            The other UnitDBImpl.
	 * @throws UnitExistsException
	 *             Attempt to redefine an existing entry.
	 */
	public void add(final UnitDBImpl that) throws UnitExistsException {
		unitSet.addAll(that.unitSet);
		nameMap.putAll(that.nameMap);
		symbolMap.putAll(that.symbolMap);
	}

	/**
	 * Return the number of names in this database
	 * 
	 * @return The total number of names, plurals, and aliases.
	 */
	public int nameCount() {
		return nameMap.size();
	}

	/**
	 * Return the number of symbols in this database.
	 * 
	 * @return The number of symbols in this database.
	 */
	public int symbolCount() {
		return symbolMap.size();
	}

	/**
	 * Adds a unit to the database.
	 * 
	 * @param unit
	 *            The unit to be added.
	 * @throws UnitExistsException
	 *             Another unit with the same name or symbol already exists in
	 *             the database.
	 * @throws NameException
	 *             Bad unit name.
	 */
	public void addUnit(final Unit unit) throws UnitExistsException,
			NameException {
		if (unit.getName() == null) {
			throw new NameException("Unit name can't be null");
		}
		addByName(unit.getName(), unit);
		addByName(unit.getPlural(), unit);
		addBySymbol(unit.getSymbol(), unit);
		unitSet.add(unit);
	}

	/**
	 * Adds an alias for a unit already in the database.
	 * 
	 * @param alias
	 *            An alias for the unit.
	 * @param name
	 *            The name of the unit already in the database.
	 * @throws UnitExistsException
	 *             Another unit with the same name or symbol already exists in
	 *             the database.
	 * @throws NoSuchUnitException
	 *             The unit isn't in the database.
	 */
	public final void addAlias(final String alias, final String name)
			throws NoSuchUnitException, UnitExistsException {
		addAlias(alias, name, null);
	}

	/**
	 * Adds an alias for a unit already in the database.
	 * 
	 * @param alias
	 *            An alias for the unit.
	 * @param name
	 *            The name of the unit already in the database.
	 * @param symbol
	 *            The symbol for the unit.
	 * @throws UnitExistsException
	 *             Another unit with the same name or symbol already exists in
	 *             the database.
	 * @throws NoSuchUnitException
	 *             The unit isn't in the database.
	 */
	public final void addAlias(final String alias, final String name,
			final String symbol) throws NoSuchUnitException,
			UnitExistsException {
		addAlias(alias, name, symbol, null);
	}

	/**
	 * Adds a symbol for a unit already in the database.
	 * 
	 * @param symbol
	 *            The symbol for the unit.
	 * @param name
	 *            The name of the unit already in the database.
	 * @throws UnitExistsException
	 *             Another unit with the same name or symbol already exists in
	 *             the database.
	 * @throws NoSuchUnitException
	 *             The unit isn't in the database.
	 */
	public final void addSymbol(final String symbol, final String name)
			throws NoSuchUnitException, UnitExistsException {
		addAlias(null, name, symbol, null);
	}

	/**
	 * Adds an alias for a unit already in the database.
	 * 
	 * @param alias
	 *            The alias to be added to the database. May be null.
	 * @param name
	 *            The name of the unit to have an alias added to the database.
	 * @param symbol
	 *            The symbol to be added. May be null.
	 * @param plural
	 *            The plural form of the alias. If null
     *				, then regular
	 *            plural-forming rules are followed.
	 * @throws NoSuchUnitException
	 *             The unit is not in the database.
	 * @throws UnitExistsException
	 *             Another unit with the same alias is already in the database.
	 */
	public final void addAlias(final String alias, final String name,
			final String symbol, final String plural)
			throws NoSuchUnitException, UnitExistsException {
		addAlias(UnitID.newUnitID(alias, plural, symbol), name);
	}

	/**
	 * Adds an alias for a unit already in the database.
	 * 
	 * @param alias
	 *            The alias to be added to the database.
	 * @param name
	 *            The name of the unit to have an alias added to the database.
	 * @throws NoSuchUnitException
	 *             The unit is not in the database.
	 * @throws UnitExistsException
	 *             Another unit with the same alias is already in the database.
	 */
	public final void addAlias(final UnitID alias, final String name)
			throws NoSuchUnitException, UnitExistsException {
		final Unit unit = getByName(name);
		if (unit == null) {
			throw new NoSuchUnitException(name);
		}
		addByName(alias.getName(), unit);
		addByName(alias.getPlural(), unit);
		addBySymbol(alias.getSymbol(), unit);
	}

	/**
	 * Gets a unit by either name, plural, or symbol. Retrieving the unit by
	 * symbol is attempted before retrieving the unit by name because symbol
	 * comparisons are case sensitive and, hence, should be more robust.
	 * 
	 * @param id
	 *            The id to be matched.
	 * @return The unit whose name, plural, or symbol matches or
	 *         null if no such unit was found.
	 */
	public Unit get(final String id) {
		Unit unit = getBySymbol(id);
		if (unit == null) {
			unit = getByName(id);
		}
		return unit;
	}

	/**
	 * Gets a unit by name.
	 * 
	 * @param name
	 *            The name to be matched.
	 * @return The unit whose name, plural, or alias matches or
	 *         null if no such unit was found.
	 */
	public Unit getByName(final String name) {
		return nameMap.get(canonicalize(name));
	}

	/**
	 * Returns the canonical form of a unit name.
	 * 
	 * @param name
	 *            A unit name.
	 * @return The canonical form of the name.
	 */
	private static String canonicalize(final String name) {
		return name.toLowerCase().replace(' ', '_');
	}

	/**
	 * Gets a unit by symbol.
	 * 
	 * @param symbol
	 *            The symbol to be matched.
	 * @return The unit whose symbol matches or null
     *				 if no such unit was
	 *         found.
	 */
	public Unit getBySymbol(final String symbol) {
		return symbolMap.get(symbol);
	}

	/**
	 * Returns the string representation of this database.
	 * 
	 * @return The string representation of this database.
	 */
	@Override
	public String toString() {
		return unitSet.toString();
	}

	/**
	 * Gets an iterator over the units in the database.
	 * 
	 * @return An iterator over the units in the database. The iterator's
	 *         next() method returns objects of type
	 *         Unit.
	 */
	@SuppressWarnings("unchecked")
	public final Iterator getIterator() {
		return unitSet.iterator();
	}

	/**
	 * Adds a unit to the database by name.
	 * 
	 * @param name
	 *            The name of the unit. If null then the unit is
	 *            not added.
	 * @param newUnit
	 *            The unit to be added.
	 * @throws UnitExistsException
	 *             Attempt to redefine an existing unit.
	 */
	private final void addByName(final String name, final Unit newUnit)
			throws UnitExistsException {
		if (name != null) {
			addUnique(nameMap, canonicalize(name), newUnit);
		}
	}

	/**
	 * Adds a unit to the database by symbol.
	 * 
	 * @param symbol
	 *            The symbol for the unit. If null then the unit is
	 *            not added.
	 * @param newUnit
	 *            The unit to be added.
	 * @throws UnitExistsException
	 *             Attempt to redefine an existing unit.
	 */
	private final void addBySymbol(final String symbol, final Unit newUnit)
			throws UnitExistsException {
		if (symbol != null) {
			addUnique(symbolMap, symbol, newUnit);
		}
	}

	/**
	 * Adds a unique unit to a map..
	 * 
	 * @param map
	 *            The map to be added to.
	 * @param key
	 *            The key for the unit entry.
	 * @param newUnit
	 *            The unit to be added.
	 * @throws UnitExistsException
	 *             Attempt to redefine an existing unit.
	 */
	private static final void addUnique(final Map map,
			final String key, final Unit newUnit) throws UnitExistsException {
		final Unit oldUnit = map.put(key, newUnit);
		if (oldUnit != null && !oldUnit.equals(newUnit)) {
			throw new UnitExistsException(oldUnit, newUnit);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy