001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/units/Prefix.java $
002    /*
003     * Map and oceanographical data visualisation
004     * Copyright (C) 1998 University Corporation for Atmospheric Research (Unidata)
005     *               1998 Bill Hibbard & al. (VisAD)
006     *               1999 P�ches et Oc�ans Canada
007     *               2000 Institut de Recherche pour le D�veloppement
008     *
009     *
010     *    This library is free software; you can redistribute it and/or
011     *    modify it under the terms of the GNU Library General Public
012     *    License as published by the Free Software Foundation; either
013     *    version 2 of the License, or (at your option) any later version.
014     *
015     *    This library is distributed in the hope that it will be useful,
016     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
017     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018     *    Library General Public License for more details (http://www.gnu.org/).
019     *
020     *
021     * Contacts:
022     *     FRANCE: Surveillance de l'Environnement Assist�e par Satellite
023     *             Institut de Recherche pour le D�veloppement / US-Espace
024     *             mailto:seasnet@teledetection.fr
025     *
026     *     CANADA: Observatoire du Saint-Laurent
027     *             Institut Maurice-Lamontagne
028     *             mailto:osl@osl.gc.ca
029     *
030     *
031     *    This package is inspired from the units package of VisAD.
032     *    Unidata and Visad's work is fully acknowledged here.
033     *
034     *                   THIS IS A TEMPORARY CLASS
035     *
036     *    This is a placeholder for future <code>Unit</code> class.
037     *    This skeleton will be removed when the real classes from
038     *    JSR-108: Units specification will be publicly available.
039     */
040    package org.deegree.model.csct.units;
041    
042    // Entr�s/sorties
043    import java.io.Serializable;
044    
045    import org.deegree.model.csct.resources.WeakHashSet;
046    
047    /**
048     * Repr�sentation d'un pr�fix du syst�me m�trique. Un objet <code>Prefix</code>
049     * peut par exemple repr�senter des "centi" (symbole "c") comme dans "centim�tres" (symbole "cm").
050     * La description du paquet <code>javax.units</code> donne une liste des pr�fix standards du
051     * syst�me SI.
052     *
053     * <p><em>Note: this class has a natural ordering that is inconsistent with equals.</em>
054     * La m�thode {@link #compareTo} ne compare que le champ {@link #amount}, tandis que la m�thode
055     * {@link #equals} compare tous les champs ({@link #name}, {@link #symbol} et {@link #amount}).</p>
056     *
057     * @version 1.0
058     * @author Martin Desruisseaux
059     */
060    /*public*/final class Prefix implements Comparable, Serializable {
061        /**
062         * Banque des objets qui ont �t� pr�c�demment cr��s et
063         * enregistr�s par un appel � la m�thode {@link #intern}.
064         */
065        static final WeakHashSet pool = new WeakHashSet();
066    
067        /**
068         * Nom neutre du pr�fix. Le syst�me SI d�finit plusieurs noms de pr�fix, parmi lesquels on trouve
069         * "milli", "centi" et "kilo". Certaines unit�s (notamment des unit�s du type )
070         * pourront combiner leurs noms avec un nom de pr�fix. Par exemple le pr�fix "centi" (symbole "c")
071         * pourra �tre combin� avec les unit�s "m�tres" (symbole "m") pour former les "centim�tres" (symbole
072         * "cm"). La cha�ne <code>name</code> peut �tre vide, mais ne sera jamais nulle. Notez enfin que
073         * <code>name</code> est "language-neutral". Pour obtenir un nom dans la langue de l'utilisateur,
074         * utilisez la m�thode {@link #getLocalizedName}.
075         */
076        public final String name;
077    
078        /**
079         * Symbole du pr�fix. La plupart des symboles de pr�fix n'ont qu'une seule lettre. Il s'agit
080         * la plupart du temps de la premi�re lettre de <code>name</code>, parfois en majuscule. Les
081         * majuscules et minuscules sont significatifs et tr�s importants. Par exemple le symbole "m"
082         * est pour "milli" tandis que le symbole "M" est pour "mega".
083         */
084        public final String symbol;
085    
086        /**
087         * Quantit� repr�sent� par ce pr�fix. Pour les pr�fix SI, cette quantit� est toujours une puissance de 10.
088         * Par exemple pour les "kilo" (symbole 'k'), la quantit� <code>amount</code> est 1000. Cette quantit� ne
089         * sera jamais <code>NaN</code> ni infinie.
090         */
091        public final double amount;
092    
093        /**
094         * Construit un pr�fix temporaire. Ce constructeur ne sert qu'� effectuer
095         * des recherches dans une liste de pr�fix par {@link PrefixSet}.
096         */
097        Prefix( final double amount ) {
098            this.name = "";
099            this.symbol = "";
100            this.amount = amount;
101        }
102    
103        /**
104         * Construit un nouveau pr�fix.
105         *
106         * @param name    Nom du pr�fix (par exemple "centi" comme dans "centim�tres").
107         * @param symbol  Symbole du pr�fix (par exemple "c" pour "centim�tres").
108         * @param amount  Quantit� repr�sent� par ce pr�fix (par exemple 0.01 pour "c").
109         */
110        private Prefix( final String name, final String symbol, final double amount ) {
111            this.name = name.trim();
112            this.symbol = symbol.trim();
113            this.amount = amount;
114            if ( !( amount > 0 ) || Double.isInfinite( amount ) )
115                throw new IllegalArgumentException();
116        }
117    
118        /**
119         * Construit un nouveau pr�fix.
120         *
121         * @param name    Nom du pr�fix (par exemple "centi" comme dans "centim�tres").
122         * @param symbol  Symbole du pr�fix (par exemple "c" pour "centim�tres").
123         * @param amount  Quantit� repr�sent� par ce pr�fix (par exemple 0.01 pour "c").
124         */
125        public static Prefix getPrefix( final String name, final String symbol, final double amount ) {
126            return new Prefix( name, symbol, amount ).intern();
127        }
128    
129        /**
130         * Retourne le nom du pr�fix dans la langue de l'utilisateur.
131         * Par exemple le pr�fix "deci" est �crit "d�ci" en fran�ais.
132         */
133        public String getLocalizedName() {
134            return org.deegree.model.csct.units.resources.Prefix.localize( name );
135        }
136    
137        /**
138         * Retourne le symbole du pr�fix. Cette m�thode retourne
139         * syst�matiquement le champ {@link #symbol}.
140         */
141        public String toString() {
142            return symbol;
143        }
144    
145        /**
146         * Compare deux pr�fix. Cette m�thode compare les quantit�s {@link #amount} de fa�on � permettre un classement
147         * des pr�fix en ordre croissant de quantit�. Contrairement � la m�thode {@link #equals}, <code>compareTo</code>
148         * ne compare pas les noms et symboles des pr�fix. Ainsi, deux pr�fix repr�sentant la m�me quantit� mais avec
149         * des symboles diff�rents seront consid�r�s �gaux par <code>compareTo</code>.
150         */
151        public int compareTo( final Object object ) {
152            final Prefix that = (Prefix) object;
153            if ( this.amount > that.amount )
154                return +1;
155            if ( this.amount < that.amount )
156                return -1;
157            return 0;
158        }
159    
160        /**
161         * Indique si ce pr�fix est identique � l'objet sp�cifi�.
162         * Cette m�thode retourne <code>true</code> si <code>object</code> est aussi un
163         * objet <code>Prefix</code> et si les deux pr�fix ont les m�mes nom et symbole
164         * et repr�sentent la m�me quantit� {@link #amount}.
165         */
166        public boolean equals( final Object object ) {
167            if ( object == this )
168                return true; // slight optimisation
169            if ( object instanceof Prefix ) {
170                final Prefix prefix = (Prefix) object;
171                return Double.doubleToLongBits( amount ) == Double.doubleToLongBits( prefix.amount )
172                       && symbol.equals( prefix.symbol ) && name.equals( prefix.name );
173            }
174            return false;
175        }
176    
177        /**
178         * Retourne un code repr�sentant ce pr�fix.
179         */
180        public int hashCode() {
181            final long code = Double.doubleToLongBits( amount );
182            return (int) code ^ (int) ( code >>> 32 );
183        }
184    
185        /**
186         * Retourne un exemplaire unique de ce pr�fix. Une banque de pr�fix, initialement
187         * vide, est maintenue de fa�on interne par la classe <code>Prefix</code>. Lorsque
188         * la m�thode <code>intern</code> est appel�e, elle recherchera un pr�fix �gale �
189         * <code>this</code> au sens de la m�thode {@link #equals}. Si un tel pr�fix est
190         * trouv�, il sera retourn�. Sinon, le pr�fix <code>this</code> sera ajout� � la
191         * banque de donn�es en utilisant une r�f�rence faible et cette m�thode retournera
192         * <code>this</code>.
193         * <br><br>
194         * De cette m�thode il s'ensuit que pour deux pr�fix <var>u</var> et <var>v</var>,
195         * la condition <code>u.intern()==v.intern()</code> sera vrai si et seulement si
196         * <code>u.equals(v)</code> est vrai.
197         */
198        private final Prefix intern() {
199            return (Prefix) pool.intern( this );
200        }
201    
202        /**
203         * Apr�s la lecture d'une unit�, v�rifie si ce pr�fix
204         * appara�t d�j� dans la banque des pr�fix. Si oui,
205         * l'exemplaire de la banque sera retourn� plut�t
206         * que de garder inutilement le pr�fix courant comme copie.
207         */
208        private Object readResolve() {
209            return intern();
210        }
211    }