//
// QuantityDB.java
//

/*
 * Copyright 1998, University Corporation for Atmospheric Research
 * See file LICENSE for copying and redistribution conditions.
 *
 * $Id: QuantityDB.java,v 1.12 2002-09-20 18:15:29 steve Exp $
 */

package visad.data.netcdf;

import java.util.Iterator;
import java.util.NoSuchElementException;
import visad.Unit;
import visad.UnitException;
import visad.VisADException;
import visad.data.units.NoSuchUnitException;
import visad.data.units.ParseException;
import visad.data.units.Parser;

/**
 * Provides support for a database of quantities.
 *
 * @author Steven R. Emmerson
 */
public abstract class
QuantityDB
{
    /**
     * The empty quantity database.  This is useful if, for example, you do
     * not want the netCDF import package to map incoming netCDF variables to
     * canonical ones by, effectively, altering their names and units.  This
     * database cannot be altered.
     */
    public static final QuantityDB emptyDB;

    static {
	try {
	    emptyDB = 
		new QuantityDB() {
		    public Quantity get(String name) {
			return null;
		    }
		    public Quantity[] get(Unit unit) {
			return null;
		    }
		    public void add(String name, Quantity quantity) {
			throw new UnsupportedOperationException();
		    }
		    public Iterator quantityIterator() {
			return NilIterator.INSTANCE;
		    }
		    public Iterator nameIterator() {
			return NilIterator.INSTANCE;
		    }
		};
	}
	catch (Exception ex) {
	    throw new ExceptionInInitializerError();
	}
    }

    /**
     * Returns the quantity in the database whose name matches a
     * given name.
     *
     * @param name	The name of the quantity.
     * @return		The quantity in the loal database that matches
     *			name.  Note that
     *			RETURN_VALUE.getName().equals(name) can
     *			be false due to aliasing.
     */
    public abstract Quantity
    get(String name);


    /**
     * Returns all quantities in the database whose default unit is
     * convertible with a given unit.
     *
     * @param unit	The unit of the quantity.
     * @return		The quantities in the database whose unit is
     *			convertible with unit.
     */
    public abstract Quantity[]
    get(Unit unit);


    /**
     * Returns the quantity that matches the given name and unit.  If
     * necessary, it creates the quantity and adds it to the database.
     *
     * @param name		The name of the quantity.
     * @param unitSpec	The unit of the quantity.
     * @return			The quantity in the database that matches
     *				name and unit.  Note 
     *				that RETURN_VALUE.getName().equals(name)
     *				 can be false due to
     *				aliasing and RETURN_VALUE.
     *				getDefaultUnit().equals(unit) can be 
     *				false due to allowable unit
     *				conversion.
     * @throws ParseException	Couldn't decode unitSpec.
     * @throws NoSuchUnitException
     *				unitSpec not in unit database.
     * @throws UnitException	The quantity already exists with an 
     *				incompatible unit.
     * @throws VisADException	Couldn't create necessary VisAD object.
     */
    public synchronized Quantity
    get(String name, String unitSpec)
	throws ParseException, NoSuchUnitException, UnitException,
	    VisADException
    {
	Quantity	quantity = get(name);
	if (quantity == null)
	{
	    quantity = new Quantity(name, unitSpec);
	    add(quantity);
	}
	else
	{
	    Unit	quantityUnit = quantity.getDefaultUnit();
	    if (!Unit.canConvert(Parser.parse(unitSpec), quantityUnit))
		throw new UnitException(
		    "Quantity " + name + " already exists; its unit " +
		    quantity.getDefaultUnitString() +
		    " is inconvertible with " + unitSpec);
	}
	return quantity;
    }


    /**
     * Adds a given Quantity to the database under a given name.
     *
     * @param name		The name under which the quantity is to be
     *				added.  May be an alias.
     * @param quantity		The quantity to be added.
     * @throws VisADException	Couldn't create necessary VisAD object.
     */
    public abstract void
    add(String name, Quantity quantity)
	throws VisADException;

    /**
     * Adds a given Quantity to the database.
     *
     * @param quantity		The quantity to be added.  The quantity will
     *				be added under it own name.
     * @throws VisADException	Couldn't create necessary VisAD object.
     */
    
    public void add(Quantity quantity) throws VisADException
    {
    	add(quantity.getName(), quantity);
    }

    /**
     * Returns an iterator of the quantities in the database.
     */
    public abstract Iterator
    quantityIterator();


    /**
     * Returns an iterator of the names in the database.
     */
    public abstract Iterator
    nameIterator();

    /**
     * A nil {@link Iterator}.  Such an {@link Iterator} iterates over nothing.
     */
    static class NilIterator implements Iterator {

	static final NilIterator INSTANCE;

	static {
	    INSTANCE = new NilIterator();
	}

	private NilIterator() {
	}

	/**
	 * Indicates if another element exists.  This implementation always 
	 * returns false.
	 *
	 * @return                     false.
	 */
	public boolean hasNext() {
	    return false;
	}

	/**
	 * Returns the next element.  This implementation always throws a
	 * {@link NoSuchElementException}.
	 *
	 * @throws NoSuchElementException if this method is invoked.
	 */
	public Object next() {
	    throw new NoSuchElementException();
	}

	/**
	 * Removes the current element.  This implementation always throws an
	 * {@link UnsupportedOperationException}.
	 *
	 * @throws UnsupportedOperationException if this method is invoked.
	 */
	public void remove() {
	    throw new UnsupportedOperationException();
	}
    }
}

 

Ads help maintain this website.