//
// BaseQuantity.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad;

import java.io.Serializable;
import java.util.AbstractList;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;


/**
 * This class represents a base quantity (e.g. "length").
 *
 * This class is mutable but monotonic: new base quantities can be added but
 * not removed.
 */
public final class BaseQuantity
  implements	Serializable
{
  /**
   * The name/quantity map-view of the database.
   */
  private static final Map		nameDB = new TreeMap();

  /**
   * The alias/quantity map-view of the database.
   */
  private static final Map		aliasDB = new TreeMap();

  /**
   * The index/quantity map-view of the database.
   */
  private static final AbstractList	indexDB = new Vector(8);

  /**
   * The name of this base quantity.
   */
  private final String			name;

  /**
   * The index of this base quantity.
   */
  private final int			index;


  /*
   * Initialize the database with standard base quantities.
   */
  static
  {
    try
    {
      add("electric current",
	new String[] {SI.ampere.quantityName(), "current"});
      add("luminous intensity", SI.candela.quantityName());
      add("thermodynamic temperature",
	new String[] {SI.kelvin.quantityName(), "temperature"});
      add("mass", SI.kilogram.quantityName());
      add("length", SI.meter.quantityName());
      add("time", SI.second.quantityName());
      add("amount of substance", SI.mole.quantityName());
      add("plane angle", new String[] {SI.radian.quantityName(), "angle"});
      add("solid angle", SI.steradian.quantityName());
    }
    catch (VisADException e)
    {
      /*
       * With our godlike powers of observation, we know that this
       * VisADException can't occur -- so we ignore it.
       */
    }
  }


  /**
   * Construct a base quantity.  Private to ensure use of the get...()
   * methods.
   *
   * @param name	The name of the base qantity.
   */
  private BaseQuantity(String name, int index)
  {
    this.name = name;
    this.index = index;
  }


  /**
   * Add a base quantity to the database.
   *
   * @param name		The name of the base quantity.
   * @precondition		name isn't already in the database.
   * @exception VisADException	Attempt to redefine an existing base quantity.
   */
  public static synchronized BaseQuantity add(String name)
    throws VisADException
  {
    String	key = key(name);

    if (nameDB.containsKey(key))
      throw new VisADException("Attempt to redefine existing base quantity \"" +
	name + "\"");

    BaseQuantity	q = new BaseQuantity(name, indexDB.size());

    nameDB.put(key, q);
    indexDB.add(q);

    return q;
  }


  /**
   * Add a base quantity with an alias to the database.
   *
   * @param name		The name of the base quantity being added to
   *				the database (e.g. "plane angle", "foobility").
   * @param alias		An alias for the base quantity (e.g. "angle").
   * @precondition              Neither name nor alias
   *				is in the database.
   * @return			A reference to the new base quantity in the
   *				database.
   * @exception VisADException  Attempt to redefine an existing base quantity
   *				or alias.  If thrown, then the database is
   *				unmodified.
   */
  public static synchronized BaseQuantity add(String name, String alias)
    throws VisADException
  {
    return add(name, new String[] {alias});
  }


  /**
   * Add a base quantity with aliases to the database.
   *
   * @param name		The name of the base quantity being added to
   *				the database (e.g. "plane angle", "foobility").
   * @param aliases		Aliases for the base quantity (e.g. "angle").
   * @precondition		Neither name nor any name in
   *				aliases is in the database.
   * @postcondition		size() will return one greater
   *				than on entry.
   * @return			A reference to the new base quantity in the
   *				database.
   * @exception VisADException	Attempt to redefine an existing base quantity
   *				or alias.  If thrown, then the database is
   *				unmodified.
   */
  public static synchronized BaseQuantity add(String name, String[] aliases)
    throws VisADException
  {
    for (int i = 0; i < aliases.length; ++i)
    {
      if (aliasDB.containsKey(key(aliases[i])))
	throw new VisADException(
	  "Attempt to redefine existing base quantity alias \"" +
	  aliases[i] + "\"");
    }

    BaseQuantity	q = add(name);

    for (int i = 0; i < aliases.length; ++i)
      aliasDB.put(key(aliases[i]), q);

    return q;
  }


  /**
   * Convert the given name into a database key.
   *
   * @param name		The name or alias of the base quantity.
   * @return			The database key.
   */
  private static String key(String name)
  {
    return name.toLowerCase();
  }


  /**
   * Return the number of base qantities in the database.
   *
   * @return			The current number of base quantities in the
   *				database.  This number is strictly monotonic:
   *				it will increase by one each time a new base
   *				quantity is added to the database.
   */
  public static synchronized int size()
  {
    return indexDB.size();
  }


  /**
   * Return the name of this base quantity.
   *
   * @return			The name of this base quantity.
   */
  public String getName()
  {
    return name;
  }


  /**
   * Return the index of this base quantity.
   *
   * @return			The index of this base quantity.
   */
  public int getIndex()
  {
    return index;
  }


  /**
   * Retrieve a base quantity from the database based on a
   * match of the name.
   *
   * @param name		The name of the base quantity to be retrieved.
   * @return			The base quantity in the database corresponding
   *				to name or null if
   *				no such quantity exists.
   */
  public static synchronized BaseQuantity getByName(String name)
  {
    return (BaseQuantity)nameDB.get(key(name));
  }


  /**
   * Retrieve a base quantity from the database based on a
   * match of an alias.
   *
   * @param name		An alias of the base quantity to be retrieved.
   * @return			The base quantity in the database corresponding
   *				to name or null if
   *				no such quantity exists.
   */
  public static synchronized BaseQuantity getByAlias(String name)
  {
    return (BaseQuantity)aliasDB.get(key(name));
  }


  /**
   * Retrieve a base quantity from the database based on a
   * match of either the name or an alias.  Try the name first.
   *
   * @param name		The name or an alias of the base quantity to
   *				be retrieved.
   * @return			The base quantity in the database corresponding
   *				to name or null if
   *				no such quantity exists.
   */
  public static synchronized BaseQuantity get(String name)
  {
    BaseQuantity	q = getByName(name);

    return q != null ? q : getByAlias(name);
  }


  /**
   * Retrieve the base quantity associated with a given index.
   *
   * @param i			The origin-0 index of the base quantity.
   * @precondition		i >= 0 && i < size().
   * @return			The base quantity at index i.
   */
  public static BaseQuantity get(int i)
  {
    return (BaseQuantity)indexDB.get(i);
  }
}

 

Ads help maintain this website.