/* * Units - Temporary implementation for Geotools 2 * Copyright (C) 1998 University Corporation for Atmospheric Research (Unidata) * 1998 Bill Hibbard & al. (VisAD) * 1999 Pêches et Océans Canada * 2000 Institut de Recherche pour le Développement * 2002 Centre for Computational Geography * * * 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 (http://www.gnu.org/). * * * This package is inspired from the units package of VisAD. * Unidata and Visad's work is fully acknowledged here. * * THIS IS A TEMPORARY CLASS * * This is a placeholder for future Unit class. * This skeleton will be removed when the real classes from * JSR-108: Units specification will be publicly available. */ package org.geotools.units; // Entrés/sorties import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamException; import java.io.Serializable; import java.util.Iterator; import javax.units.NonSI; import javax.units.SI; import org.geotools.resources.i18n.ErrorKeys; import org.geotools.resources.i18n.Errors; import org.geotools.resources.units.Quantities; import org.geotools.resources.units.Units; import org.geotools.util.WeakHashSet; /** * Placeholder for future Unit class. This * skeleton will be removed when the real classes (from * JSR-108: * Units specification) will be publicly available. *

* IMPORTANT: future version will NOT be compatible * will this one. Remind, this is a temporary class! * * @source $URL$ * @version $Id$ * @author Steven R. Emmerson * @author Bill Hibbard * @author Martin Desruisseaux * * @deprecated Replaced by the {@link javax.units.Unit} framework. */ public abstract class Unit implements Serializable { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = 8745958719541785628L; /** * Banque des objets qui ont été précédemment créés et * enregistrés par un appel à la méthode {@link #intern}. */ private static final WeakHashSet pool=Prefix.pool; // Must be first! /** * Convenience constant for dimensionless unit. */ public static final Unit DIMENSIONLESS = DerivedUnit.DIMENSIONLESS; /** * Convenience constant for base unit of angle. * Not a SI unit, but provides here for convenience. * * @deprecated Replaced by {@link SI#RADIAN}. */ public static final Unit RADIAN = get("rad"); /** * Convenience constant for unit of angle. * Not a SI unit, but provides here for convenience. * * @deprecated Replaced by {@link NonSI#DEGREE_ANGLE}. */ public static final Unit DEGREE = get("\u00b0"); /** * Convenience constant for base unit of length. * * @deprecated Replaced by {@link SI#METER}. */ public static final Unit METRE = get("m"); /** * Convenience constant for derived unit of length. * * @deprecated Replaced by SI.KILO({@linkplain SI#METER}). */ public static final Unit KILOMETRE = METRE.scale(1000); /** * Convenience constant for base unit of time. * * @deprecated Replaced by {@link SI#SECOND}. */ public static final Unit SECOND = get("s"); /** * Convenience constant for unit of time. * Not a SI unit, but provides here for convenience. * * @deprecated Replaced by SI.MILLI({@linkplain SI#SECOND}). */ public static final Unit MILLISECOND = get("ms"); /** * Convenience constant for unit of time. * Not a SI unit, but provides here for convenience. * * @deprecated Replaced by {@link NonSI#DAY}. */ public static final Unit DAY = get("d"); /** * Convenience constant for base unit of mass. * * @deprecated Replaced by {@link SI#KILOGRAM}. */ public static final Unit KILOGRAM = get("kg"); /** * Unit of arc-second. Used by the EPSG database. * * @deprecated Replaced by {@link NonSI#SECOND_ANGLE}. */ public static final Unit ARC_SECOND = DEGREE.scale(1.0/3600); /** * Convenience constant for "Degrees Minutes Secondes" unit. * For example, this "unit" convert 12.5° into 123000 (i.e. * the concatenation of 12°30'00"). In a strict sence, this * is a formatting issue rather than an unit transformation * issue. Such transformation would be better handle by the * {@link org.geotools.measure.AngleFormat} class. However, this * "unit" appears really often in the EPSG database, and we * need it for interoperability with legacy libraries. */ public static final Unit DMS = (Unit) new DMSUnit(1).intern(); /** * Convenience constant for "Degrees dot Minutes Secondes" unit. * For example, this "unit" convert 12.5° into 12.3 (i.e. * the concatenation of 12°30'00"). In a strict sence, this * is a formatting issue rather than an unit transformation * issue. Such transformation would be better handle by the * {@link org.geotools.measure.AngleFormat} class. However, this * "unit" appears really often in the EPSG database, and we * need it for interoperability with legacy libraries. */ public static final Unit SEXAGESIMAL_DEGREE = (Unit) new DMSUnit(10000).intern(); /** * Returns this unit as a javax.units object. */ public final javax.units.Unit toJSR108() { if (equals(RADIAN )) return SI.RADIAN; if (equals(DEGREE )) return NonSI.DEGREE_ANGLE; if (equals(METRE )) return SI.METER; if (equals(KILOMETRE )) return SI.KILO(SI.METER); if (equals(SECOND )) return SI.SECOND; if (equals(MILLISECOND)) return SI.MILLI(SI.SECOND); if (equals(DAY )) return NonSI.DAY; if (equals(KILOGRAM )) return SI.KILO(SI.KILOGRAM); if (equals(ARC_SECOND )) return NonSI.SECOND_ANGLE; throw new UnsupportedOperationException(toString()); } /** * Symbole des unités de cet objet Unit (par exemple "kg"). * Ce champs sera initialisé lors de la construction de chaque objet * Unit et ne sera jamais nul. Ce symbole peut commencer * par un des préfix énumérés dans le champ prefix. C'est * le cas par exemple des symboles "kg" (kilogramme) et "km" (kilomètre). */ /*public*/ final String symbol; /** * Ensemble des préfix qui peuvent être combinés avec le symbole de l'unité. * Cet ensemble peut contenir par exemple les préfix "milli" (m), "centi" (c) et * "kilo" (k) qui, combinés avec les mètres (m), donneront les millimètres (mm), * centimètres (cm) ou kilomètre (km). Ce champ intervient lors des appels à la * méthode {@link #scale}. Il peut être nul si aucun préfix n'est autorisé pour * le symbole. */ /*public*/ final PrefixSet prefix; /** * Construit une unité qui aura le symbole spécifié. * @param symbol Symbole de ces unités (ne doit pas être nul). * @param prefix Ensemble des préfix utilisables avec {@link #symbol}, * ou null s'il n'y en a aucun. Cet ensemble sera * affecté au champ {@link #prefix} et interviendra lors des * appels à la méthode {@link #scale}. * @throws NullPointerException Si symbol est nul. */ /*protected*/ Unit(final String symbol, final PrefixSet prefix) throws NullPointerException { this.symbol=symbol.trim(); this.prefix=prefix; } /** * Retourne les unités qui correspondent au symbole spécifié. Si plus d'une * unité correspond au symbole spécifié, une unité arbitraire sera choisie. * Si aucune unité n'a été trouvée, alors cette méthode retourne null. * * @param symbol Symbole des unités recherchées. Cet argument ne doit pas être nul. * @return Les unités demandées. */ public static Unit get(final String symbol) { Object unit=null; Unit[] units=null; for (int i=0; i<3; i++) { switch (i) { case 2: units=getDefaultUnits(); // fallthrough case 1: unit=UnitFormat.DEFAULT.parse(symbol); break; case 0: unit=getCached(symbol); break; } if (unit instanceof Unit) { return (Unit) unit; } } return null; } /** * Retourne l'ensemble des unités prédéfinies par défaut. Les unités seront * retournées sans ordre particulier. Si les unités par défaut n'ont pas pu * être obtenues, cette méthode retourne null. */ private static Unit[] getDefaultUnits() { final InputStream in=Unit.class.getClassLoader().getResourceAsStream(UnitSet.PATHNAME); if (in!=null) try { final ObjectInputStream oin=new ObjectInputStream(in); final Unit[] units=(Unit[]) oin.readObject(); oin.close(); /* * Appelle 'intern()' simplement par précaution. * En principe, ce n'est pas nécessaire. */ for (int i=0; ithis, mais ne sera jamais null. */ public abstract Unit rename(final String symbol, final PrefixSet prefix); /** * Retourne le nom de l'unité dans la langue de l'utilisateur. * Par exemple le symbole "m" sera traduit par "mètre" dans la * langue française. Si aucun nom n'est disponible pour l'unité * courante, retourne simplement son symbole. */ public String getLocalizedName() { return Units.localize(symbol); } /** * Retourne la quantité que représente cette unité. Les quantités sont des chaînes de * caractères qui décrivent le paramètre physique mesuré, comme "mass" ou "speed". Si * aucune quantité n'est définie pour cette unité, retourne null. */ public abstract String getQuantityName(); /** * Retourne la quantité que représente cette unité dans la langue de l'utilisateur. * Les quantités sont des chaînes de caractères qui décrivent le paramètre physique * mesuré, comme "masse" ou "vitesse". Si aucune quantité n'est définie pour cette * unité, retourne null. */ public String getLocalizedQuantityName() { return Quantities.localize(getQuantityName()); } /** * Élève ces unités à une puissance entière. Notez que ce ne sont pas toutes les * unités qui peuvent être élevées à une puissance. Par exemple les unités de * température en degrés Celcius (°C), en Fahrenheit (°F) et la densité sigma-T * ne peuvent pas être élevées à une puissance autre que 0 et 1. * * * L'implémentation par défaut retourne une unité sans dimension ou this * selon que power ait la valeur 0 ou 1 respectivement, et lance une exception * dans tous les autres cas. * * @param power La puissance à laquelle élever cette unité. * @return Les unités résultant de l'élévation des unités * this à la puissance power. * @throws UnitException Si ces unités ne peuvent être * élevées à une puissance autre que 0 et 1. * * @see #multiply * @see #divide * @see #scale * @see #shift */ public Unit pow(final int power) throws UnitException { switch (power) { case 0: return DerivedUnit.DIMENSIONLESS; case 1: return this; default: throw new UnitException(Errors.format( ErrorKeys.BAD_UNIT_POWER_$2, new Integer(power), this), this, null); } } /** * Élève ces unités à une puissance fractionnaire. Cette méthode est utile entre * autre pour prendre la racine carrée d'un nombre, ce qui revient à l'élever à la * puissance ½. L'implémentation par défaut appele la méthode {@link #pow(int)} * pour les puissances entières, et lance une exception dans tous les autres cas. * * @param power La puissance à laquelle élever cette unité. * @return Les unités résultant de l'élévation des unités * this à la puissance power. * @throws UnitException Si ces unités ne peuvent être * élevées à une puissance autre que 0 et 1. */ public Unit pow(final double power) throws UnitException { final int integer=(int) power; if (integer==power) { return pow(integer); } throw new UnitException(Errors.format( ErrorKeys.BAD_UNIT_POWER_$2, new Double(power), this), this, null); } /** * Multiplie cette unité par une autre unité. * L'implémentation par défaut retourne this si that est * égal à une unité sans dimension, et lance une exception dams tous les autres cas. * * @param that L'unité par laquelle multiplier cette unité. * @return Le produit de this par that. * @throws UnitException Si les unités this * that ne peuvent pas être multipliées. * * @see #pow * @see #divide * @see #scale * @see #shift */ public Unit multiply(final Unit that) throws UnitException { if (DerivedUnit.DIMENSIONLESS.equals(that)) { return this; } throw illegalUnitOperationException(that); } /** Overrided by {@link SimpleUnit}.*/ Unit inverseMultiply(BaseUnit that) throws UnitException {throw that.illegalUnitOperationException(this);} /** Overrided by {@link SimpleUnit}.*/ Unit inverseMultiply(DerivedUnit that) throws UnitException {throw that.illegalUnitOperationException(this);} /** Overrided by {@link SimpleUnit}.*/ Unit inverseMultiply(ScaledUnit that) throws UnitException {throw that.illegalUnitOperationException(this);} /** * Divise cette unité par une autre unité. * L'implémentation par défaut retourne this si that est * égal à une unité sans dimension, et lance une exception dams tous les autres cas. * * @param that L'unité par laquelle diviser cette unité. * @return Le quotient de this par that. * @throws UnitException Si les unités this * that ne peuvent pas être divisées. * * @see #pow * @see #multiply * @see #scale * @see #shift */ public Unit divide(final Unit that) throws UnitException { if (DerivedUnit.DIMENSIONLESS.equals(that)) { return this; } throw illegalUnitOperationException(that); } /** Overrided by {@link SimpleUnit}.*/ Unit inverseDivide(BaseUnit that) throws UnitException {throw that.illegalUnitOperationException(this);} /** Overrided by {@link SimpleUnit}.*/ Unit inverseDivide(DerivedUnit that) throws UnitException {throw that.illegalUnitOperationException(this);} /** Overrided by {@link SimpleUnit}.*/ Unit inverseDivide(ScaledUnit that) throws UnitException {throw that.illegalUnitOperationException(this);} /** * Crée une nouvelle unité proportionnelle à cette unité. Par exemple * pour convertir en kilomètres des mesures exprimées en mètres, il * faut les diviser par 1000. On peut exprimer cette relation par le * code Unit KILOMETRE=METRE.scale(1000). * * @param amount Facteur par lequel il faudra diviser les valeurs * exprimées selon ces unités pour obtenir des valeurs * exprimées selon les nouvelles unités. * @return Les nouvelles unités. * * @see #pow * @see #multiply * @see #divide * @see #shift */ public abstract Unit scale(double amount); /** * Crée une nouvelle unité décalée par rapport à cette unité. Par exemple * pour convertir des degrés Kelvin en degrés Celsius, il faut soustraire * 273.15 aux degrés Kelvin. On peut exprimer cette relation par le code * Unit CELCIUS=KELVIN.shift(273.15). * * @param offset Constante à soustraire aux valeurs exprimées selon ces * unités pour obtenir des valeurs exprimées selon les nouvelles * unités. * @return Les nouvelles unités. * * @see #pow * @see #multiply * @see #divide * @see #scale */ public abstract Unit shift(double offset); /** * Indique si les unités this et that sont compatibles. * Si elles le sont, alors les méthodes convert ne lanceront jamais * d'exception pour ces unités. Toutes les classes du paquet org.geotools.units * garantissent que this.canConvert(that) donnera toujours le même * résultat que that.canConvert(this). Si vous écrivez vos propres * classes dérivées de Unit, vous devrez vous assurer que cette * condition reste respectée. Mais évitez d'appeller that.canConvert(this) * à l'intérieur de cette méthode sous peine de tomber dans une boucle sans fin. * * @param that Autre unités avec laquelle on veut * vérifier si ces unités sont compatibles. * @return true Si l'on garantie que les méthodes * convert ne lanceront pas d'exceptions. */ public abstract boolean canConvert(Unit that); /**SimpleUnit*/ boolean canConvert(BaseUnit that) {return canConvert((Unit) that);} /**SimpleUnit*/ boolean canConvert(DerivedUnit that) {return canConvert((Unit) that);} /** * Effectue la conversion d'une mesure exprimée selon d'autres unités. Par * exemple METRE.convert(1, FOOT) retournera 0.3048. * * @param value La valeur exprimée selon les autres unités (fromUnit). * @param fromUnit Les autres unités. * @return La valeur convertie selon ces unités (this). * @throws UnitException Si les unités ne sont pas compatibles. */ public abstract double convert(double value, Unit fromUnit) throws UnitException; /**SimpleUnit*/ double convert(double value, BaseUnit fromUnit) throws UnitException {return convert(value, (Unit) fromUnit);} /**SimpleUnit*/ double convert(double value, DerivedUnit fromUnit) throws UnitException {return convert(value, (Unit) fromUnit);} /** * Effectue sur-place la conversion de mesures exprimées selon d'autres * unités. Les valeurs converties remplaceront les anciennes valeurs. * * @param values En entré, les valeurs exprimées selon les autres unités * (fromUnit). En sortie, les valeurs exprimées selon ces * unités (this). * @param fromUnit Les autres unités. * @throws UnitException Si les unités ne sont pas compatibles. Dans ce * cas, aucun élément de values n'aura été modifié. */ public abstract void convert(double[] values, Unit fromUnit) throws UnitException; /**SimpleUnit*/ void convert(double[] values, BaseUnit fromUnit) throws UnitException {convert(values, (Unit) fromUnit);} /**SimpleUnit*/ void convert(double[] values, DerivedUnit fromUnit) throws UnitException {convert(values, (Unit) fromUnit);} /** * Effectue sur-place la conversion de mesures exprimées selon d'autres * unités. Les valeurs converties remplaceront les anciennes valeurs. * * @param values En entré, les valeurs exprimées selon les autres * unités (fromUnit). En sortie, les valeurs exprimées * selon ces unités (this). * @param fromUnit Les autres unités. * @throws UnitException Si les unités ne sont pas compatibles. Dans ce * cas, aucun élément de values n'aura été modifié. */ public abstract void convert(float[] values, Unit fromUnit) throws UnitException; /**SimpleUnit*/ void convert(float[] values, BaseUnit fromUnit) throws UnitException {convert(values, (Unit) fromUnit);} /**SimpleUnit*/ void convert(float[] values, DerivedUnit fromUnit) throws UnitException {convert(values, (Unit) fromUnit);} /** * Retourne un objet qui saura convertir selon ces unités les valeurs exprimées * selon d'autres unités. Cette méthode est avantageuse si on prévoie faîre * plusieurs conversions, car la transformation à utiliser est déterminée une * fois pour toute. * * @param fromUnit Unités à partir de lesquel faire les conversions. * @return Une transformation des unités fromUnit * vers les unités this. Cette méthode ne * retourne jamais null. * @throws UnitException Si les unités ne sont pas compatibles. */ public abstract UnitTransform getTransform(Unit fromUnit) throws UnitException; /**SimpleUnit*/ UnitTransform getTransform(BaseUnit fromUnit) throws UnitException {return getTransform((Unit) fromUnit);} /**SimpleUnit*/ UnitTransform getTransform(DerivedUnit fromUnit) throws UnitException {return getTransform((Unit) fromUnit);} /** * Convertit une mesure vers d'autre unités. Par exemple * METRE.inverseConvert(1, FOOT) retournera * 3.2808. Cette méthode est l'inverse de la méthode * {@link #convert(double,Unit)}. Bien que n'étant pas destinée à * être appellée directement, les classes dérivées devront quand * même la définir pour un fonctionnement correcte. * * @param value La valeur exprimée selon ces unités (this). * @param toUnit Les autres unités. * @return La valeur convertie selon les autres unités (toUnit). * @throws UnitException Si les unités ne sont pas compatibles. */ /*protected*/ abstract double inverseConvert(double value, Unit toUnit) throws UnitException; /**SimpleUnit*/ double inverseConvert(double value, BaseUnit toUnit) throws UnitException {return inverseConvert(value, (Unit) toUnit);} /**SimpleUnit*/ double inverseConvert(double value, DerivedUnit toUnit) throws UnitException {return inverseConvert(value, (Unit) toUnit);} /** * Effectue sur-place la conversion de mesures vers d'autres unités. * Les valeurs converties remplaceront les anciennes valeurs. Cette * méthode est l'inverse de la méthode {@link #convert(double[],Unit)}. * Bien que n'étant pas destinée à être appellée directement, les classes * dérivées devront quand même la définir pour un fonctionnement correcte. * * @param values En entré, les valeur exprimées selon ces unités * (this). En sortie, les valeurs exprimées * selon les autres unités (toUnit). * @param toUnit Les autres unités. * @throws UnitException Si les unités ne sont pas compatibles. Dans ce * cas, aucun élément de values n'aura été modifié. */ /*protected*/ abstract void inverseConvert(double[] values, Unit toUnit) throws UnitException; /**SimpleUnit*/ void inverseConvert(double[] values, BaseUnit toUnit) throws UnitException {inverseConvert(values, (Unit) toUnit);} /**SimpleUnit*/ void inverseConvert(double[] values, DerivedUnit toUnit) throws UnitException {inverseConvert(values, (Unit) toUnit);} /** * Effectue sur-place la conversion de mesures vers d'autres unités. * Les valeurs converties remplaceront les anciennes valeurs. Cette * méthode est l'inverse de la méthode {@link #convert(float[],Unit)}. * Bien que n'étant pas destinée à être appellée directement, les classes * dérivées devront quand même la définir pour un fonctionnement correcte. * * @param values En entré, les valeur exprimées selon ces unités * (this). En sortie, les valeurs exprimées * selon les autres unités (toUnit). * @param toUnit Les autres unités. * @throws UnitException Si les unités ne sont pas compatibles. Dans ce * cas, aucun élément de values n'aura été modifié. */ /*protected*/ abstract void inverseConvert(float[] values, Unit toUnit) throws UnitException; /**SimpleUnit*/ void inverseConvert(float[] values, BaseUnit toUnit) throws UnitException {inverseConvert(values, (Unit) toUnit);} /**SimpleUnit*/ void inverseConvert(float[] values, DerivedUnit toUnit) throws UnitException {inverseConvert(values, (Unit) toUnit);} /** * Retourne un objet qui saura convertir selon d'autres unités les * valeurs exprimées selon ces unités. Cette méthode est l'inverse * de {@link #getTransform}. * * @param toUnit Unités vers lesquel faire les conversions. * @return Une transformation des unités this * vers les unités toUnit. Cette méthode * ne retourne jamais null. * @throws UnitException Si les unités ne sont pas compatibles. */ /*protected*/ abstract UnitTransform getInverseTransform(Unit toUnit) throws UnitException; /**SimpleUnit*/ UnitTransform getInverseTransform(BaseUnit toUnit) throws UnitException {return getInverseTransform((Unit) toUnit);} /**SimpleUnit*/ UnitTransform getInverseTransform(DerivedUnit toUnit) throws UnitException {return getInverseTransform((Unit) toUnit);} /** * Retourne une exception à lancer lorsque * l'opération demandée n'est pas permise. */ final UnitException illegalUnitOperationException(Unit that) { return new UnitException(Errors.format( ErrorKeys.BAD_UNIT_OPERATION_$2, this, that), this, that); } /** * Retourne une exception à lancer lorsque * les unités ne sont pas compatibles. */ final UnitException incompatibleUnitsException(Unit that) { return new UnitException(Errors.format( ErrorKeys.NON_CONVERTIBLE_UNITS_$2, this, that), this, that); } /** * Après la lecture binaire, vérifie si les * unitées lues existaient déjà en mémoire. */ final Object readResolve() throws ObjectStreamException { return intern(); } /** * Retourne un exemplaire unique de cette unité. Une banque d'unités, initialement * vide, est maintenue de façon interne par la classe Unit. Lorsque la * méthode intern est appelée, elle recherchera des unités égales à * this au sens de la méthode {@link #equals}. Si de telles unités * sont trouvées, elles seront retournées. Sinon, les unités this * seront ajoutées à la banque de données en utilisant une référence faible * et cette méthode retournera this. *

* De cette méthode il s'ensuit que pour deux unités u et v, * la condition u.intern()==v.intern() sera vrai si et seulement si * u.equals(v) est vrai. */ /*protected*/ final Unit intern() { return (Unit) pool.canonicalize(this); } /** * Retourne un exemplaire unique de cette unité, quel que soit son symbole. Une banque d'unités, * initialement vide, est maintenue de façon interne par la classe Unit. Lorsque la * méthode internIgnoreSymbol est appelée, elle recherchera des unités égales à * this au sens de la méthode {@link #equalsIgnoreSymbol}. Si de telles unités * sont trouvées, elles seront retournées. Sinon, les unités this seront ajoutées * à la banque de données en utilisant une référence faible et cette méthode retournera this. *

* De cette méthode il s'ensuit que pour deux unités u et v, * la condition u.internIgnoreSymbol()==v.internIgnoreSymbol() sera * généralement vrai si u.equalsIgnoreSymbol(v) est vrai. Toutefois, * si la banque de données contient plusieurs unités identiques en tout sauf leurs * symboles, alors il n'y a aucune garantie de quelle unité sera choisie par cette * méthode. */ /*protected*/ final Unit internIgnoreSymbol() { synchronized (pool) { final Object canonical = pool.get(new Unamed()); if (canonical instanceof Unit) { return (Unit) canonical; } pool.add(this); return this; } } /** * Indique si deux unités sont égales et utilisent le même symbole. */ public boolean equals(final Object unit) { if (unit!=null) { if (unit instanceof Unamed) { return unit.equals(this); } if (getClass().equals(unit.getClass())) { final Unit cast = (Unit) unit; if (symbol.equals(cast.symbol)) { if (equalsIgnoreSymbol(cast)) { if (prefix==cast.prefix) return true; if (prefix==null) return false; return prefix.equals(cast.prefix); } } } } return false; } /** * Indique si deux unités sont égales, en ignorant leurs symboles. Le * champs {@link #symbol} de chacune des deux unités ne sera pas pris * en compte. */ /*public*/ abstract boolean equalsIgnoreSymbol(Unit unit); /** * Retourne un code propre à cette unité. Le calcul de * ce code ne devrait pas prendre en compte le symbole * de l'unité. */ public abstract int hashCode(); /** * Retourne les symboles de ces unités, par exemple "m/s". * S'il existe un symbole particulier pour la langue de * l'utilisateur, ce symbole sera retourné. */ public String toString() { return symbol; } /** * Enveloppe des unités qui seront comparées sans tenir compte des symboles. * Cette classe est utilisée par {@link #internIgnoreSymbol} afin de puiser * dans la banque d'unités {@link #pool} n'importe quel unité de dimensions * appropriées, quel que soit son symbole. * * @version 1.0 * @author Martin Desruisseaux */ private final class Unamed { /** * Renvoie le code des * unités enveloppées. */ public int hashCode() { return Unit.this.hashCode(); } /** * Vérifie si les unités enveloppées sont * égales aux unités spécifiées, sans tenir * compte de leurs symboles respectifs. */ public boolean equals(final Object obj) { return (obj instanceof Unit) && equalsIgnoreSymbol((Unit) obj); } } }