package dods.clients.importwizard.TMAP.convert; /** * An abstract class for conversions between <tt>double</tt> and * <tt>String</tt> along an axis. The axis will have * a range of acceptable values. This package is designed * to be hooked up with TextInputFields for region specification * on database servers. * * @version 0.1, Sep 03, 1997 * @author Jonathan Callahan * * This class may change substantially when ported to JDK 1.1 which * contains a java.text.Format class. In the future, Convert and its * subclasses may extend that class. * * This software was developed by the Thermal Modeling and Analysis * Project(TMAP) of the National Oceanographic and Atmospheric * Administration's (NOAA) Pacific Marine Environmental Lab(PMEL), * hereafter referred to as NOAA/PMEL/TMAP. * * 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, the user * agrees to credit NOAA/PMEL/TMAP in any publications that result from * the use of this software or in any product that includes this * software. The names TMAP, NOAA and/or PMEL, 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 NOAA/PMEL/TMAP. The user also understands that NOAA/PMEL/TMAP * 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 NOAA/PMEL/TMAP "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 NOAA/PMEL/TMAP 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 TORTUOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ public abstract class Convert { protected static final int LO = 0; protected static final int HI = 1; /** * The output style as defined by individual Convert objects. */ protected int outputStyle = 0; /** * The range within which a value is acceptable. * <p> * This can be used if you have a region of interest and you * wish to do bounds checking at the level of the input before * passing to value to any other routines. */ protected double [] range = {-1.0, 1.0}; /** * The base units in which all <tt>double</tt> values will be expressed. * */ protected String units = new String(""); /** * The strings recognized as valid units. (always lower case) * Standard units are specified in individual subclasses. */ protected String recognizedUnits[]; /** * Creates a <B>Convert</B> object. * */ public Convert() { } /** * Returns a String describing the base units. For example: * <tt>m, km, ft, sec, msec, deg E, etc.</tt> * */ public String getUnits() { return units; } /** * Sets the valid range for the <b>Convert</b> object. * range[LO] < range[HI] regardless of the order in which * they are passed in. * * @param lo the lowest acceptable value. * @param hi the highest acceptable value. */ public void setRange(double lo, double hi) throws IllegalArgumentException { if (hi < lo) { System.out.println("Convert:setRange(" + lo + "," + hi + ") -- swapping lo and hi limits"); range[LO] = hi; range[HI] = lo; } range[LO] = lo; range[HI] = hi; } /** * Returns the LO [0] or HI [1] value from the range of acceptable values. * * @param index the LO [0] or HI [1] index. * @return the requested value. * */ public double getRange(int index) { return range[index]; } /** * Returns the LO [0] and HI [1] values of the range * as an array of doubles. * * @return the lo and hi valus of the range. */ public double [] getRange() { double [] return_vals = {range[LO], range[HI]}; return return_vals; } /** * Sets the String describing the base units. For example: * <tt>m, km, ft, sec, msec, deg E, etc.</tt> * Standard units are specified in individual subclasses. * * @param u the string describing the base units. * @exception IllegalArgumentException the unit string is not recognized. */ public void setUnits(String u) throws IllegalArgumentException { units = new String(unitTest(u)); } /** * Converts a <tt>double<tt> value to a <tt>String<tt>. * * This is the <code>abstract</code> method which makes this class abstract. * * @param string the string to be converted. */ public abstract double toDouble(String s) throws IllegalArgumentException; /** * Prints out the internal properties. * * @return String the internal properties of this converter. */ public String toString() { StringBuffer sbuf = new StringBuffer(""); sbuf.append("Convert:range = [" + range[LO] + ", " + range[HI] + "]"); return sbuf.toString(); } /** * Converts a <tt>String<tt> value to a <tt>double<tt>. * * This is the <code>abstract</code> method which makes this class abstract. * * @param val the string to be converted. */ public abstract String toString(double val) throws IllegalArgumentException; /** * Returns the nearest value within the range. * * @param <TT>val</TT> The value passed in. * @return the nearest value within the range. */ public double getNearestValue(double val) { try { return rangeTest(val); } catch (IllegalArgumentException e) { if ( val < range[LO] ) { val = range[LO]; } else { val = range[HI]; } System.out.println("Convert:getNearestValue(" + val + "): " + e + ", returning " + val); return val; } } /** * Returns the nearest value within the range. * If the value is completely outside the range, the lo_hi * parameter is used to determine which end of the range * to return. * * @param <TT>val</TT> The value passed in. * @param lo_hi which end of the range to return. * @return the nearest value within the range. */ public double getNearestValue(double val, int lo_hi) { try { return rangeTest(val); } catch (IllegalArgumentException e) { System.out.println("Convert:getNearestValue(" + val + "," + lo_hi + "): " + e + ", returning " + range[lo_hi]); return range[lo_hi]; } } /** * Returns the intersection of the incoming range within the * internal range. An error is returned if there is no intersection. * * @param <TT>val_lo</TT> The lo value of the range to be tested. * @param <TT>val_hi</TT> The hi value of the range to be tested. * @return the nearest value within the range. * @exception IllegalArgumentException <TT>range</TT> is outside * the internally defined range. */ public double [] intersectRange(double val_lo, double val_hi) throws IllegalArgumentException { double [] return_vals = {range[LO], range[HI]}; double [] vals = {val_lo, val_hi}; if ( val_hi < val_lo ) { vals[LO] = val_hi; vals[HI] = val_lo; } if ( vals[LO] > range[HI] ) { throw new IllegalArgumentException("incoming range [" + val_lo + ", " + val_hi + "] does not intersect range[" + range[LO] + "," + range[HI] + "]."); } else if ( vals[LO] > range[LO] ) { return_vals[LO] = vals[LO]; } else { return_vals[LO] = range[LO]; } if ( vals[HI] < range[LO] ) { throw new IllegalArgumentException("incoming range [" + val_lo + ", " + val_hi + "] does not intersect range[" + range[LO] + "," + range[HI] + "]."); } else if ( vals[HI] < range[HI] ) { return_vals[HI] = vals[HI]; } else { return_vals[HI] = range[HI]; } return return_vals; } /* * Tests a value against the range. * * @param <tt>val</tt> * @return The value passed in. * @exception IllegalArgumentException <TT>val</TT> is * outisde the specified range. */ protected double rangeTest(double val) throws IllegalArgumentException { if ( val < range[LO] || val > range[HI] ) { throw new IllegalArgumentException("value [" + val + "] outside of range[" + range[LO] + "," + range[HI] + "]."); } return val; } /* * Test the String describing the base units against the * <tt>recognizedUnits</tt> array. * * @param u the string describing the base units. * @exception IllegalArgumentException the unit string is not recognized. */ protected String unitTest(String u) throws IllegalArgumentException { String s = new String(u); // so we don't corrupt u s = s.trim(); s = s.toLowerCase(); for (int i=1; i<recognizedUnits.length; i++) { if ( s.equalsIgnoreCase(recognizedUnits[i]) ) { return s; } } throw new IllegalArgumentException("Unit \"" + s + "\" not recognized."); } }