1/*
2 *******************************************************************************
3 * Copyright (C) 2004-2015, Google Inc, International Business Machines        *
4 * Corporation and others. All Rights Reserved.                                *
5 *******************************************************************************
6 */
7package com.ibm.icu.util;
8
9import java.io.Externalizable;
10import java.io.IOException;
11import java.io.ObjectInput;
12import java.io.ObjectOutput;
13import java.io.ObjectStreamException;
14import java.io.Serializable;
15import java.util.Collections;
16import java.util.Enumeration;
17import java.util.HashMap;
18import java.util.HashSet;
19import java.util.Map;
20import java.util.MissingResourceException;
21import java.util.Set;
22
23import com.ibm.icu.impl.ICUResourceBundle;
24import com.ibm.icu.impl.Pair;
25import com.ibm.icu.text.UnicodeSet;
26
27/**
28 * A unit such as length, mass, volume, currency, etc.  A unit is
29 * coupled with a numeric amount to produce a Measure. MeasureUnit objects are immutable.
30 * All subclasses must guarantee that. (However, subclassing is discouraged.)
31
32 *
33 * @see com.ibm.icu.util.Measure
34 * @author Alan Liu
35 * @stable ICU 3.0
36 */
37public class MeasureUnit implements Serializable {
38    private static final long serialVersionUID = -1839973855554750484L;
39
40    // Used to pre-fill the cache. These same constants appear in MeasureFormat too.
41    private static final String[] unitKeys = new String[]{"units", "unitsShort", "unitsNarrow"};
42
43    private static final Map<String, Map<String,MeasureUnit>> cache
44    = new HashMap<String, Map<String,MeasureUnit>>();
45
46    /**
47     * @internal
48     * @deprecated This API is ICU internal only.
49     */
50    @Deprecated
51    protected final String type;
52
53    /**
54     * @internal
55     * @deprecated This API is ICU internal only.
56     */
57    @Deprecated
58    protected final String subType;
59
60    /**
61     * @internal
62     * @deprecated This API is ICU internal only.
63     */
64    @Deprecated
65    protected MeasureUnit(String type, String subType) {
66        this.type = type;
67        this.subType = subType;
68    }
69
70    /**
71     * Get the type, such as "length"
72     *
73     * @stable ICU 53
74     */
75    public String getType() {
76        return type;
77    }
78
79
80    /**
81     * Get the subType, such as “foot”.
82     *
83     * @stable ICU 53
84     */
85    public String getSubtype() {
86        return subType;
87    }
88
89
90
91    /**
92     * {@inheritDoc}
93     *
94     * @stable ICU 53
95     */
96    @Override
97    public int hashCode() {
98        return 31 * type.hashCode() + subType.hashCode();
99    }
100
101    /**
102     * {@inheritDoc}
103     *
104     * @stable ICU 53
105     */
106    @Override
107    public boolean equals(Object rhs) {
108        if (rhs == this) {
109            return true;
110        }
111        if (!(rhs instanceof MeasureUnit)) {
112            return false;
113        }
114        MeasureUnit c = (MeasureUnit) rhs;
115        return type.equals(c.type) && subType.equals(c.subType);
116    }
117
118    /**
119     * {@inheritDoc}
120     *
121     * @stable ICU 53
122     */
123    @Override
124    public String toString() {
125        return type + "-" + subType;
126    }
127
128    /**
129     * Get all of the available units' types. Returned set is unmodifiable.
130     *
131     * @stable ICU 53
132     */
133    public synchronized static Set<String> getAvailableTypes() {
134        return Collections.unmodifiableSet(cache.keySet());
135    }
136
137    /**
138     * For the given type, return the available units.
139     * @param type the type
140     * @return the available units for type. Returned set is unmodifiable.
141     * @stable ICU 53
142     */
143    public synchronized static Set<MeasureUnit> getAvailable(String type) {
144        Map<String, MeasureUnit> units = cache.get(type);
145        // Train users not to modify returned set from the start giving us more
146        // flexibility for implementation.
147        return units == null ? Collections.<MeasureUnit>emptySet()
148                : Collections.unmodifiableSet(new HashSet<MeasureUnit>(units.values()));
149    }
150
151    /**
152     * Get all of the available units. Returned set is unmodifiable.
153     *
154     * @stable ICU 53
155     */
156    public synchronized static Set<MeasureUnit> getAvailable() {
157        Set<MeasureUnit> result = new HashSet<MeasureUnit>();
158        for (String type : new HashSet<String>(MeasureUnit.getAvailableTypes())) {
159            for (MeasureUnit unit : MeasureUnit.getAvailable(type)) {
160                result.add(unit);
161            }
162        }
163        // Train users not to modify returned set from the start giving us more
164        // flexibility for implementation.
165        return Collections.unmodifiableSet(result);
166    }
167
168    /**
169     * Create a MeasureUnit instance (creates a singleton instance).
170     * <p>
171     * Normally this method should not be used, since there will be no formatting data
172     * available for it, and it may not be returned by getAvailable().
173     * However, for special purposes (such as CLDR tooling), it is available.
174     *
175     * @internal
176     * @deprecated This API is ICU internal only.
177     */
178    @Deprecated
179    public static MeasureUnit internalGetInstance(String type, String subType) {
180        if (type == null || subType == null) {
181            throw new NullPointerException("Type and subType must be non-null");
182        }
183        if (!"currency".equals(type)) {
184            if (!ASCII.containsAll(type) || !ASCII_HYPHEN_DIGITS.containsAll(subType)) {
185                throw new IllegalArgumentException("The type or subType are invalid.");
186            }
187        }
188        Factory factory;
189        if ("currency".equals(type)) {
190            factory = CURRENCY_FACTORY;
191        } else if ("duration".equals(type)) {
192            factory = TIMEUNIT_FACTORY;
193        } else {
194            factory = UNIT_FACTORY;
195        }
196        return MeasureUnit.addUnit(type, subType, factory);
197    }
198
199    /**
200     * For ICU use only.
201     * @internal
202     * @deprecated This API is ICU internal only.
203     */
204    @Deprecated
205    public static MeasureUnit resolveUnitPerUnit(MeasureUnit unit, MeasureUnit perUnit) {
206        return unitPerUnitToSingleUnit.get(Pair.of(unit, perUnit));
207    }
208
209    static final UnicodeSet ASCII = new UnicodeSet('a', 'z').freeze();
210    static final UnicodeSet ASCII_HYPHEN_DIGITS = new UnicodeSet('-', '-', '0', '9', 'a', 'z').freeze();
211
212    /**
213     * @internal
214     * @deprecated This API is ICU internal only.
215     */
216    @Deprecated
217    protected interface Factory {
218        /**
219         * @internal
220         * @deprecated This API is ICU internal only.
221         */
222        @Deprecated
223        MeasureUnit create(String type, String subType);
224    }
225
226    private static Factory UNIT_FACTORY = new Factory() {
227        public MeasureUnit create(String type, String subType) {
228            return new MeasureUnit(type, subType);
229        }
230    };
231
232    static Factory CURRENCY_FACTORY = new Factory() {
233        public MeasureUnit create(String unusedType, String subType) {
234            return new Currency(subType);
235        }
236    };
237
238    static Factory TIMEUNIT_FACTORY = new Factory() {
239        public MeasureUnit create(String type, String subType) {
240           return new TimeUnit(type, subType);
241        }
242    };
243
244    static {
245        // load all of the units for English, since we know that that is a superset.
246        /**
247         *     units{
248         *            duration{
249         *                day{
250         *                    one{"{0} ден"}
251         *                    other{"{0} дена"}
252         *                }
253         */
254        ICUResourceBundle resource = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "en");
255        for (String key : unitKeys) {
256            try {
257                ICUResourceBundle unitsTypeRes = resource.getWithFallback(key);
258                int size = unitsTypeRes.getSize();
259                for ( int index = 0; index < size; ++index) {
260                    UResourceBundle unitsRes = unitsTypeRes.get(index);
261                    String type = unitsRes.getKey();
262                    if (type.equals("compound")) {
263                        continue; // special type, does not have any unit plurals
264                    }
265                    int unitsSize = unitsRes.getSize();
266                    for ( int index2 = 0; index2 < unitsSize; ++index2) {
267                        ICUResourceBundle unitNameRes = (ICUResourceBundle)unitsRes.get(index2);
268                        if (unitNameRes.get("other") != null) {
269                            internalGetInstance(type, unitNameRes.getKey());
270                        }
271                    }
272                }
273            } catch ( MissingResourceException e ) {
274                continue;
275            }
276        }
277        // preallocate currencies
278        try {
279            UResourceBundle bundle = UResourceBundle.getBundleInstance(
280                    ICUResourceBundle.ICU_BASE_NAME,
281                    "currencyNumericCodes",
282                    ICUResourceBundle.ICU_DATA_CLASS_LOADER);
283            UResourceBundle codeMap = bundle.get("codeMap");
284            for (Enumeration<String> it = codeMap.getKeys(); it.hasMoreElements();) {
285                MeasureUnit.internalGetInstance("currency", it.nextElement());
286            }
287        } catch (MissingResourceException e) {
288            // fall through
289        }
290    }
291
292    // Must only be called at static initialization, or inside synchronized block.
293    /**
294     * @internal
295     * @deprecated This API is ICU internal only.
296     */
297    @Deprecated
298    protected synchronized static MeasureUnit addUnit(String type, String unitName, Factory factory) {
299        Map<String, MeasureUnit> tmp = cache.get(type);
300        if (tmp == null) {
301            cache.put(type, tmp = new HashMap<String, MeasureUnit>());
302        } else {
303            // "intern" the type by setting to first item's type.
304            type = tmp.entrySet().iterator().next().getValue().type;
305        }
306        MeasureUnit unit = tmp.get(unitName);
307        if (unit == null) {
308            tmp.put(unitName, unit = factory.create(type, unitName));
309        }
310        return unit;
311    }
312
313
314    /*
315     * Useful constants. Not necessarily complete: see {@link #getAvailable()}.
316     */
317
318// All code between the "Start generated MeasureUnit constants" comment and
319// the "End generated MeasureUnit constants" comment is auto generated code
320// and must not be edited manually. For instructions on how to correctly
321// update this code, refer to:
322// http://site.icu-project.org/design/formatting/measureformat/updating-measure-unit
323//
324    // Start generated MeasureUnit constants
325
326    /**
327     * Constant for unit of acceleration: g-force
328     * @stable ICU 53
329     */
330    public static final MeasureUnit G_FORCE = MeasureUnit.internalGetInstance("acceleration", "g-force");
331
332    /**
333     * Constant for unit of acceleration: meter-per-second-squared
334     * @stable ICU 54
335     */
336    public static final MeasureUnit METER_PER_SECOND_SQUARED = MeasureUnit.internalGetInstance("acceleration", "meter-per-second-squared");
337
338    /**
339     * Constant for unit of angle: arc-minute
340     * @stable ICU 53
341     */
342    public static final MeasureUnit ARC_MINUTE = MeasureUnit.internalGetInstance("angle", "arc-minute");
343
344    /**
345     * Constant for unit of angle: arc-second
346     * @stable ICU 53
347     */
348    public static final MeasureUnit ARC_SECOND = MeasureUnit.internalGetInstance("angle", "arc-second");
349
350    /**
351     * Constant for unit of angle: degree
352     * @stable ICU 53
353     */
354    public static final MeasureUnit DEGREE = MeasureUnit.internalGetInstance("angle", "degree");
355
356    /**
357     * Constant for unit of angle: radian
358     * @stable ICU 54
359     */
360    public static final MeasureUnit RADIAN = MeasureUnit.internalGetInstance("angle", "radian");
361
362    /**
363     * Constant for unit of angle: revolution
364     * @draft ICU 56
365     * @provisional This API might change or be removed in a future release.
366     */
367    public static final MeasureUnit REVOLUTION_ANGLE = MeasureUnit.internalGetInstance("angle", "revolution");
368
369    /**
370     * Constant for unit of area: acre
371     * @stable ICU 53
372     */
373    public static final MeasureUnit ACRE = MeasureUnit.internalGetInstance("area", "acre");
374
375    /**
376     * Constant for unit of area: hectare
377     * @stable ICU 53
378     */
379    public static final MeasureUnit HECTARE = MeasureUnit.internalGetInstance("area", "hectare");
380
381    /**
382     * Constant for unit of area: square-centimeter
383     * @stable ICU 54
384     */
385    public static final MeasureUnit SQUARE_CENTIMETER = MeasureUnit.internalGetInstance("area", "square-centimeter");
386
387    /**
388     * Constant for unit of area: square-foot
389     * @stable ICU 53
390     */
391    public static final MeasureUnit SQUARE_FOOT = MeasureUnit.internalGetInstance("area", "square-foot");
392
393    /**
394     * Constant for unit of area: square-inch
395     * @stable ICU 54
396     */
397    public static final MeasureUnit SQUARE_INCH = MeasureUnit.internalGetInstance("area", "square-inch");
398
399    /**
400     * Constant for unit of area: square-kilometer
401     * @stable ICU 53
402     */
403    public static final MeasureUnit SQUARE_KILOMETER = MeasureUnit.internalGetInstance("area", "square-kilometer");
404
405    /**
406     * Constant for unit of area: square-meter
407     * @stable ICU 53
408     */
409    public static final MeasureUnit SQUARE_METER = MeasureUnit.internalGetInstance("area", "square-meter");
410
411    /**
412     * Constant for unit of area: square-mile
413     * @stable ICU 53
414     */
415    public static final MeasureUnit SQUARE_MILE = MeasureUnit.internalGetInstance("area", "square-mile");
416
417    /**
418     * Constant for unit of area: square-yard
419     * @stable ICU 54
420     */
421    public static final MeasureUnit SQUARE_YARD = MeasureUnit.internalGetInstance("area", "square-yard");
422
423    /**
424     * Constant for unit of consumption: liter-per-100kilometers
425     * @draft ICU 56
426     * @provisional This API might change or be removed in a future release.
427     */
428    public static final MeasureUnit LITER_PER_100KILOMETERS = MeasureUnit.internalGetInstance("consumption", "liter-per-100kilometers");
429
430    /**
431     * Constant for unit of consumption: liter-per-kilometer
432     * @stable ICU 54
433     */
434    public static final MeasureUnit LITER_PER_KILOMETER = MeasureUnit.internalGetInstance("consumption", "liter-per-kilometer");
435
436    /**
437     * Constant for unit of consumption: mile-per-gallon
438     * @stable ICU 54
439     */
440    public static final MeasureUnit MILE_PER_GALLON = MeasureUnit.internalGetInstance("consumption", "mile-per-gallon");
441
442    /**
443     * Constant for unit of digital: bit
444     * @stable ICU 54
445     */
446    public static final MeasureUnit BIT = MeasureUnit.internalGetInstance("digital", "bit");
447
448    /**
449     * Constant for unit of digital: byte
450     * @stable ICU 54
451     */
452    public static final MeasureUnit BYTE = MeasureUnit.internalGetInstance("digital", "byte");
453
454    /**
455     * Constant for unit of digital: gigabit
456     * @stable ICU 54
457     */
458    public static final MeasureUnit GIGABIT = MeasureUnit.internalGetInstance("digital", "gigabit");
459
460    /**
461     * Constant for unit of digital: gigabyte
462     * @stable ICU 54
463     */
464    public static final MeasureUnit GIGABYTE = MeasureUnit.internalGetInstance("digital", "gigabyte");
465
466    /**
467     * Constant for unit of digital: kilobit
468     * @stable ICU 54
469     */
470    public static final MeasureUnit KILOBIT = MeasureUnit.internalGetInstance("digital", "kilobit");
471
472    /**
473     * Constant for unit of digital: kilobyte
474     * @stable ICU 54
475     */
476    public static final MeasureUnit KILOBYTE = MeasureUnit.internalGetInstance("digital", "kilobyte");
477
478    /**
479     * Constant for unit of digital: megabit
480     * @stable ICU 54
481     */
482    public static final MeasureUnit MEGABIT = MeasureUnit.internalGetInstance("digital", "megabit");
483
484    /**
485     * Constant for unit of digital: megabyte
486     * @stable ICU 54
487     */
488    public static final MeasureUnit MEGABYTE = MeasureUnit.internalGetInstance("digital", "megabyte");
489
490    /**
491     * Constant for unit of digital: terabit
492     * @stable ICU 54
493     */
494    public static final MeasureUnit TERABIT = MeasureUnit.internalGetInstance("digital", "terabit");
495
496    /**
497     * Constant for unit of digital: terabyte
498     * @stable ICU 54
499     */
500    public static final MeasureUnit TERABYTE = MeasureUnit.internalGetInstance("digital", "terabyte");
501
502    /**
503     * Constant for unit of duration: century
504     * @draft ICU 56
505     * @provisional This API might change or be removed in a future release.
506     */
507    public static final MeasureUnit CENTURY = MeasureUnit.internalGetInstance("duration", "century");
508
509    /**
510     * Constant for unit of duration: day
511     * @stable ICU 4.0
512     */
513    public static final TimeUnit DAY = (TimeUnit) MeasureUnit.internalGetInstance("duration", "day");
514
515    /**
516     * Constant for unit of duration: hour
517     * @stable ICU 4.0
518     */
519    public static final TimeUnit HOUR = (TimeUnit) MeasureUnit.internalGetInstance("duration", "hour");
520
521    /**
522     * Constant for unit of duration: microsecond
523     * @stable ICU 54
524     */
525    public static final MeasureUnit MICROSECOND = MeasureUnit.internalGetInstance("duration", "microsecond");
526
527    /**
528     * Constant for unit of duration: millisecond
529     * @stable ICU 53
530     */
531    public static final MeasureUnit MILLISECOND = MeasureUnit.internalGetInstance("duration", "millisecond");
532
533    /**
534     * Constant for unit of duration: minute
535     * @stable ICU 4.0
536     */
537    public static final TimeUnit MINUTE = (TimeUnit) MeasureUnit.internalGetInstance("duration", "minute");
538
539    /**
540     * Constant for unit of duration: month
541     * @stable ICU 4.0
542     */
543    public static final TimeUnit MONTH = (TimeUnit) MeasureUnit.internalGetInstance("duration", "month");
544
545    /**
546     * Constant for unit of duration: nanosecond
547     * @stable ICU 54
548     */
549    public static final MeasureUnit NANOSECOND = MeasureUnit.internalGetInstance("duration", "nanosecond");
550
551    /**
552     * Constant for unit of duration: second
553     * @stable ICU 4.0
554     */
555    public static final TimeUnit SECOND = (TimeUnit) MeasureUnit.internalGetInstance("duration", "second");
556
557    /**
558     * Constant for unit of duration: week
559     * @stable ICU 4.0
560     */
561    public static final TimeUnit WEEK = (TimeUnit) MeasureUnit.internalGetInstance("duration", "week");
562
563    /**
564     * Constant for unit of duration: year
565     * @stable ICU 4.0
566     */
567    public static final TimeUnit YEAR = (TimeUnit) MeasureUnit.internalGetInstance("duration", "year");
568
569    /**
570     * Constant for unit of electric: ampere
571     * @stable ICU 54
572     */
573    public static final MeasureUnit AMPERE = MeasureUnit.internalGetInstance("electric", "ampere");
574
575    /**
576     * Constant for unit of electric: milliampere
577     * @stable ICU 54
578     */
579    public static final MeasureUnit MILLIAMPERE = MeasureUnit.internalGetInstance("electric", "milliampere");
580
581    /**
582     * Constant for unit of electric: ohm
583     * @stable ICU 54
584     */
585    public static final MeasureUnit OHM = MeasureUnit.internalGetInstance("electric", "ohm");
586
587    /**
588     * Constant for unit of electric: volt
589     * @stable ICU 54
590     */
591    public static final MeasureUnit VOLT = MeasureUnit.internalGetInstance("electric", "volt");
592
593    /**
594     * Constant for unit of energy: calorie
595     * @stable ICU 54
596     */
597    public static final MeasureUnit CALORIE = MeasureUnit.internalGetInstance("energy", "calorie");
598
599    /**
600     * Constant for unit of energy: foodcalorie
601     * @stable ICU 54
602     */
603    public static final MeasureUnit FOODCALORIE = MeasureUnit.internalGetInstance("energy", "foodcalorie");
604
605    /**
606     * Constant for unit of energy: joule
607     * @stable ICU 54
608     */
609    public static final MeasureUnit JOULE = MeasureUnit.internalGetInstance("energy", "joule");
610
611    /**
612     * Constant for unit of energy: kilocalorie
613     * @stable ICU 54
614     */
615    public static final MeasureUnit KILOCALORIE = MeasureUnit.internalGetInstance("energy", "kilocalorie");
616
617    /**
618     * Constant for unit of energy: kilojoule
619     * @stable ICU 54
620     */
621    public static final MeasureUnit KILOJOULE = MeasureUnit.internalGetInstance("energy", "kilojoule");
622
623    /**
624     * Constant for unit of energy: kilowatt-hour
625     * @stable ICU 54
626     */
627    public static final MeasureUnit KILOWATT_HOUR = MeasureUnit.internalGetInstance("energy", "kilowatt-hour");
628
629    /**
630     * Constant for unit of frequency: gigahertz
631     * @stable ICU 54
632     */
633    public static final MeasureUnit GIGAHERTZ = MeasureUnit.internalGetInstance("frequency", "gigahertz");
634
635    /**
636     * Constant for unit of frequency: hertz
637     * @stable ICU 54
638     */
639    public static final MeasureUnit HERTZ = MeasureUnit.internalGetInstance("frequency", "hertz");
640
641    /**
642     * Constant for unit of frequency: kilohertz
643     * @stable ICU 54
644     */
645    public static final MeasureUnit KILOHERTZ = MeasureUnit.internalGetInstance("frequency", "kilohertz");
646
647    /**
648     * Constant for unit of frequency: megahertz
649     * @stable ICU 54
650     */
651    public static final MeasureUnit MEGAHERTZ = MeasureUnit.internalGetInstance("frequency", "megahertz");
652
653    /**
654     * Constant for unit of length: astronomical-unit
655     * @stable ICU 54
656     */
657    public static final MeasureUnit ASTRONOMICAL_UNIT = MeasureUnit.internalGetInstance("length", "astronomical-unit");
658
659    /**
660     * Constant for unit of length: centimeter
661     * @stable ICU 53
662     */
663    public static final MeasureUnit CENTIMETER = MeasureUnit.internalGetInstance("length", "centimeter");
664
665    /**
666     * Constant for unit of length: decimeter
667     * @stable ICU 54
668     */
669    public static final MeasureUnit DECIMETER = MeasureUnit.internalGetInstance("length", "decimeter");
670
671    /**
672     * Constant for unit of length: fathom
673     * @stable ICU 54
674     */
675    public static final MeasureUnit FATHOM = MeasureUnit.internalGetInstance("length", "fathom");
676
677    /**
678     * Constant for unit of length: foot
679     * @stable ICU 53
680     */
681    public static final MeasureUnit FOOT = MeasureUnit.internalGetInstance("length", "foot");
682
683    /**
684     * Constant for unit of length: furlong
685     * @stable ICU 54
686     */
687    public static final MeasureUnit FURLONG = MeasureUnit.internalGetInstance("length", "furlong");
688
689    /**
690     * Constant for unit of length: inch
691     * @stable ICU 53
692     */
693    public static final MeasureUnit INCH = MeasureUnit.internalGetInstance("length", "inch");
694
695    /**
696     * Constant for unit of length: kilometer
697     * @stable ICU 53
698     */
699    public static final MeasureUnit KILOMETER = MeasureUnit.internalGetInstance("length", "kilometer");
700
701    /**
702     * Constant for unit of length: light-year
703     * @stable ICU 53
704     */
705    public static final MeasureUnit LIGHT_YEAR = MeasureUnit.internalGetInstance("length", "light-year");
706
707    /**
708     * Constant for unit of length: meter
709     * @stable ICU 53
710     */
711    public static final MeasureUnit METER = MeasureUnit.internalGetInstance("length", "meter");
712
713    /**
714     * Constant for unit of length: micrometer
715     * @stable ICU 54
716     */
717    public static final MeasureUnit MICROMETER = MeasureUnit.internalGetInstance("length", "micrometer");
718
719    /**
720     * Constant for unit of length: mile
721     * @stable ICU 53
722     */
723    public static final MeasureUnit MILE = MeasureUnit.internalGetInstance("length", "mile");
724
725    /**
726     * Constant for unit of length: mile-scandinavian
727     * @draft ICU 56
728     * @provisional This API might change or be removed in a future release.
729     */
730    public static final MeasureUnit MILE_SCANDINAVIAN = MeasureUnit.internalGetInstance("length", "mile-scandinavian");
731
732    /**
733     * Constant for unit of length: millimeter
734     * @stable ICU 53
735     */
736    public static final MeasureUnit MILLIMETER = MeasureUnit.internalGetInstance("length", "millimeter");
737
738    /**
739     * Constant for unit of length: nanometer
740     * @stable ICU 54
741     */
742    public static final MeasureUnit NANOMETER = MeasureUnit.internalGetInstance("length", "nanometer");
743
744    /**
745     * Constant for unit of length: nautical-mile
746     * @stable ICU 54
747     */
748    public static final MeasureUnit NAUTICAL_MILE = MeasureUnit.internalGetInstance("length", "nautical-mile");
749
750    /**
751     * Constant for unit of length: parsec
752     * @stable ICU 54
753     */
754    public static final MeasureUnit PARSEC = MeasureUnit.internalGetInstance("length", "parsec");
755
756    /**
757     * Constant for unit of length: picometer
758     * @stable ICU 53
759     */
760    public static final MeasureUnit PICOMETER = MeasureUnit.internalGetInstance("length", "picometer");
761
762    /**
763     * Constant for unit of length: yard
764     * @stable ICU 53
765     */
766    public static final MeasureUnit YARD = MeasureUnit.internalGetInstance("length", "yard");
767
768    /**
769     * Constant for unit of light: lux
770     * @stable ICU 54
771     */
772    public static final MeasureUnit LUX = MeasureUnit.internalGetInstance("light", "lux");
773
774    /**
775     * Constant for unit of mass: carat
776     * @stable ICU 54
777     */
778    public static final MeasureUnit CARAT = MeasureUnit.internalGetInstance("mass", "carat");
779
780    /**
781     * Constant for unit of mass: gram
782     * @stable ICU 53
783     */
784    public static final MeasureUnit GRAM = MeasureUnit.internalGetInstance("mass", "gram");
785
786    /**
787     * Constant for unit of mass: kilogram
788     * @stable ICU 53
789     */
790    public static final MeasureUnit KILOGRAM = MeasureUnit.internalGetInstance("mass", "kilogram");
791
792    /**
793     * Constant for unit of mass: metric-ton
794     * @stable ICU 54
795     */
796    public static final MeasureUnit METRIC_TON = MeasureUnit.internalGetInstance("mass", "metric-ton");
797
798    /**
799     * Constant for unit of mass: microgram
800     * @stable ICU 54
801     */
802    public static final MeasureUnit MICROGRAM = MeasureUnit.internalGetInstance("mass", "microgram");
803
804    /**
805     * Constant for unit of mass: milligram
806     * @stable ICU 54
807     */
808    public static final MeasureUnit MILLIGRAM = MeasureUnit.internalGetInstance("mass", "milligram");
809
810    /**
811     * Constant for unit of mass: ounce
812     * @stable ICU 53
813     */
814    public static final MeasureUnit OUNCE = MeasureUnit.internalGetInstance("mass", "ounce");
815
816    /**
817     * Constant for unit of mass: ounce-troy
818     * @stable ICU 54
819     */
820    public static final MeasureUnit OUNCE_TROY = MeasureUnit.internalGetInstance("mass", "ounce-troy");
821
822    /**
823     * Constant for unit of mass: pound
824     * @stable ICU 53
825     */
826    public static final MeasureUnit POUND = MeasureUnit.internalGetInstance("mass", "pound");
827
828    /**
829     * Constant for unit of mass: stone
830     * @stable ICU 54
831     */
832    public static final MeasureUnit STONE = MeasureUnit.internalGetInstance("mass", "stone");
833
834    /**
835     * Constant for unit of mass: ton
836     * @stable ICU 54
837     */
838    public static final MeasureUnit TON = MeasureUnit.internalGetInstance("mass", "ton");
839
840    /**
841     * Constant for unit of power: gigawatt
842     * @stable ICU 54
843     */
844    public static final MeasureUnit GIGAWATT = MeasureUnit.internalGetInstance("power", "gigawatt");
845
846    /**
847     * Constant for unit of power: horsepower
848     * @stable ICU 53
849     */
850    public static final MeasureUnit HORSEPOWER = MeasureUnit.internalGetInstance("power", "horsepower");
851
852    /**
853     * Constant for unit of power: kilowatt
854     * @stable ICU 53
855     */
856    public static final MeasureUnit KILOWATT = MeasureUnit.internalGetInstance("power", "kilowatt");
857
858    /**
859     * Constant for unit of power: megawatt
860     * @stable ICU 54
861     */
862    public static final MeasureUnit MEGAWATT = MeasureUnit.internalGetInstance("power", "megawatt");
863
864    /**
865     * Constant for unit of power: milliwatt
866     * @stable ICU 54
867     */
868    public static final MeasureUnit MILLIWATT = MeasureUnit.internalGetInstance("power", "milliwatt");
869
870    /**
871     * Constant for unit of power: watt
872     * @stable ICU 53
873     */
874    public static final MeasureUnit WATT = MeasureUnit.internalGetInstance("power", "watt");
875
876    /**
877     * Constant for unit of pressure: hectopascal
878     * @stable ICU 53
879     */
880    public static final MeasureUnit HECTOPASCAL = MeasureUnit.internalGetInstance("pressure", "hectopascal");
881
882    /**
883     * Constant for unit of pressure: inch-hg
884     * @stable ICU 53
885     */
886    public static final MeasureUnit INCH_HG = MeasureUnit.internalGetInstance("pressure", "inch-hg");
887
888    /**
889     * Constant for unit of pressure: millibar
890     * @stable ICU 53
891     */
892    public static final MeasureUnit MILLIBAR = MeasureUnit.internalGetInstance("pressure", "millibar");
893
894    /**
895     * Constant for unit of pressure: millimeter-of-mercury
896     * @stable ICU 54
897     */
898    public static final MeasureUnit MILLIMETER_OF_MERCURY = MeasureUnit.internalGetInstance("pressure", "millimeter-of-mercury");
899
900    /**
901     * Constant for unit of pressure: pound-per-square-inch
902     * @stable ICU 54
903     */
904    public static final MeasureUnit POUND_PER_SQUARE_INCH = MeasureUnit.internalGetInstance("pressure", "pound-per-square-inch");
905
906    /**
907     * Constant for unit of proportion: karat
908     * @stable ICU 54
909     */
910    public static final MeasureUnit KARAT = MeasureUnit.internalGetInstance("proportion", "karat");
911
912    /**
913     * Constant for unit of speed: kilometer-per-hour
914     * @stable ICU 53
915     */
916    public static final MeasureUnit KILOMETER_PER_HOUR = MeasureUnit.internalGetInstance("speed", "kilometer-per-hour");
917
918    /**
919     * Constant for unit of speed: knot
920     * @draft ICU 56
921     * @provisional This API might change or be removed in a future release.
922     */
923    public static final MeasureUnit KNOT = MeasureUnit.internalGetInstance("speed", "knot");
924
925    /**
926     * Constant for unit of speed: meter-per-second
927     * @stable ICU 53
928     */
929    public static final MeasureUnit METER_PER_SECOND = MeasureUnit.internalGetInstance("speed", "meter-per-second");
930
931    /**
932     * Constant for unit of speed: mile-per-hour
933     * @stable ICU 53
934     */
935    public static final MeasureUnit MILE_PER_HOUR = MeasureUnit.internalGetInstance("speed", "mile-per-hour");
936
937    /**
938     * Constant for unit of temperature: celsius
939     * @stable ICU 53
940     */
941    public static final MeasureUnit CELSIUS = MeasureUnit.internalGetInstance("temperature", "celsius");
942
943    /**
944     * Constant for unit of temperature: fahrenheit
945     * @stable ICU 53
946     */
947    public static final MeasureUnit FAHRENHEIT = MeasureUnit.internalGetInstance("temperature", "fahrenheit");
948
949    /**
950     * Constant for unit of temperature: generic
951     * @draft ICU 56
952     * @provisional This API might change or be removed in a future release.
953     */
954    public static final MeasureUnit GENERIC_TEMPERATURE = MeasureUnit.internalGetInstance("temperature", "generic");
955
956    /**
957     * Constant for unit of temperature: kelvin
958     * @stable ICU 54
959     */
960    public static final MeasureUnit KELVIN = MeasureUnit.internalGetInstance("temperature", "kelvin");
961
962    /**
963     * Constant for unit of volume: acre-foot
964     * @stable ICU 54
965     */
966    public static final MeasureUnit ACRE_FOOT = MeasureUnit.internalGetInstance("volume", "acre-foot");
967
968    /**
969     * Constant for unit of volume: bushel
970     * @stable ICU 54
971     */
972    public static final MeasureUnit BUSHEL = MeasureUnit.internalGetInstance("volume", "bushel");
973
974    /**
975     * Constant for unit of volume: centiliter
976     * @stable ICU 54
977     */
978    public static final MeasureUnit CENTILITER = MeasureUnit.internalGetInstance("volume", "centiliter");
979
980    /**
981     * Constant for unit of volume: cubic-centimeter
982     * @stable ICU 54
983     */
984    public static final MeasureUnit CUBIC_CENTIMETER = MeasureUnit.internalGetInstance("volume", "cubic-centimeter");
985
986    /**
987     * Constant for unit of volume: cubic-foot
988     * @stable ICU 54
989     */
990    public static final MeasureUnit CUBIC_FOOT = MeasureUnit.internalGetInstance("volume", "cubic-foot");
991
992    /**
993     * Constant for unit of volume: cubic-inch
994     * @stable ICU 54
995     */
996    public static final MeasureUnit CUBIC_INCH = MeasureUnit.internalGetInstance("volume", "cubic-inch");
997
998    /**
999     * Constant for unit of volume: cubic-kilometer
1000     * @stable ICU 53
1001     */
1002    public static final MeasureUnit CUBIC_KILOMETER = MeasureUnit.internalGetInstance("volume", "cubic-kilometer");
1003
1004    /**
1005     * Constant for unit of volume: cubic-meter
1006     * @stable ICU 54
1007     */
1008    public static final MeasureUnit CUBIC_METER = MeasureUnit.internalGetInstance("volume", "cubic-meter");
1009
1010    /**
1011     * Constant for unit of volume: cubic-mile
1012     * @stable ICU 53
1013     */
1014    public static final MeasureUnit CUBIC_MILE = MeasureUnit.internalGetInstance("volume", "cubic-mile");
1015
1016    /**
1017     * Constant for unit of volume: cubic-yard
1018     * @stable ICU 54
1019     */
1020    public static final MeasureUnit CUBIC_YARD = MeasureUnit.internalGetInstance("volume", "cubic-yard");
1021
1022    /**
1023     * Constant for unit of volume: cup
1024     * @stable ICU 54
1025     */
1026    public static final MeasureUnit CUP = MeasureUnit.internalGetInstance("volume", "cup");
1027
1028    /**
1029     * Constant for unit of volume: cup-metric
1030     * @draft ICU 56
1031     * @provisional This API might change or be removed in a future release.
1032     */
1033    public static final MeasureUnit CUP_METRIC = MeasureUnit.internalGetInstance("volume", "cup-metric");
1034
1035    /**
1036     * Constant for unit of volume: deciliter
1037     * @stable ICU 54
1038     */
1039    public static final MeasureUnit DECILITER = MeasureUnit.internalGetInstance("volume", "deciliter");
1040
1041    /**
1042     * Constant for unit of volume: fluid-ounce
1043     * @stable ICU 54
1044     */
1045    public static final MeasureUnit FLUID_OUNCE = MeasureUnit.internalGetInstance("volume", "fluid-ounce");
1046
1047    /**
1048     * Constant for unit of volume: gallon
1049     * @stable ICU 54
1050     */
1051    public static final MeasureUnit GALLON = MeasureUnit.internalGetInstance("volume", "gallon");
1052
1053    /**
1054     * Constant for unit of volume: hectoliter
1055     * @stable ICU 54
1056     */
1057    public static final MeasureUnit HECTOLITER = MeasureUnit.internalGetInstance("volume", "hectoliter");
1058
1059    /**
1060     * Constant for unit of volume: liter
1061     * @stable ICU 53
1062     */
1063    public static final MeasureUnit LITER = MeasureUnit.internalGetInstance("volume", "liter");
1064
1065    /**
1066     * Constant for unit of volume: megaliter
1067     * @stable ICU 54
1068     */
1069    public static final MeasureUnit MEGALITER = MeasureUnit.internalGetInstance("volume", "megaliter");
1070
1071    /**
1072     * Constant for unit of volume: milliliter
1073     * @stable ICU 54
1074     */
1075    public static final MeasureUnit MILLILITER = MeasureUnit.internalGetInstance("volume", "milliliter");
1076
1077    /**
1078     * Constant for unit of volume: pint
1079     * @stable ICU 54
1080     */
1081    public static final MeasureUnit PINT = MeasureUnit.internalGetInstance("volume", "pint");
1082
1083    /**
1084     * Constant for unit of volume: pint-metric
1085     * @draft ICU 56
1086     * @provisional This API might change or be removed in a future release.
1087     */
1088    public static final MeasureUnit PINT_METRIC = MeasureUnit.internalGetInstance("volume", "pint-metric");
1089
1090    /**
1091     * Constant for unit of volume: quart
1092     * @stable ICU 54
1093     */
1094    public static final MeasureUnit QUART = MeasureUnit.internalGetInstance("volume", "quart");
1095
1096    /**
1097     * Constant for unit of volume: tablespoon
1098     * @stable ICU 54
1099     */
1100    public static final MeasureUnit TABLESPOON = MeasureUnit.internalGetInstance("volume", "tablespoon");
1101
1102    /**
1103     * Constant for unit of volume: teaspoon
1104     * @stable ICU 54
1105     */
1106    public static final MeasureUnit TEASPOON = MeasureUnit.internalGetInstance("volume", "teaspoon");
1107
1108    private static HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>unitPerUnitToSingleUnit =
1109            new HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>();
1110
1111    static {
1112        unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.KILOMETER, MeasureUnit.HOUR), MeasureUnit.KILOMETER_PER_HOUR);
1113        unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.GALLON), MeasureUnit.MILE_PER_GALLON);
1114        unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.HOUR), MeasureUnit.MILE_PER_HOUR);
1115        unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.METER, MeasureUnit.SECOND), MeasureUnit.METER_PER_SECOND);
1116        unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.LITER, MeasureUnit.KILOMETER), MeasureUnit.LITER_PER_KILOMETER);
1117        unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.POUND, MeasureUnit.SQUARE_INCH), MeasureUnit.POUND_PER_SQUARE_INCH);
1118    }
1119
1120    // End generated MeasureUnit constants
1121    /* Private */
1122
1123    private Object writeReplace() throws ObjectStreamException {
1124        return new MeasureUnitProxy(type, subType);
1125    }
1126
1127    static final class MeasureUnitProxy implements Externalizable {
1128        private static final long serialVersionUID = -3910681415330989598L;
1129
1130        private String type;
1131        private String subType;
1132
1133        public MeasureUnitProxy(String type, String subType) {
1134            this.type = type;
1135            this.subType = subType;
1136        }
1137
1138        // Must have public constructor, to enable Externalizable
1139        public MeasureUnitProxy() {
1140        }
1141
1142        public void writeExternal(ObjectOutput out) throws IOException {
1143            out.writeByte(0); // version
1144            out.writeUTF(type);
1145            out.writeUTF(subType);
1146            out.writeShort(0); // allow for more data.
1147        }
1148
1149        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
1150            /* byte version = */ in.readByte(); // version
1151            type = in.readUTF();
1152            subType = in.readUTF();
1153            // allow for more data from future version
1154            int extra = in.readShort();
1155            if (extra > 0) {
1156                byte[] extraBytes = new byte[extra];
1157                in.read(extraBytes, 0, extra);
1158            }
1159        }
1160
1161        private Object readResolve() throws ObjectStreamException {
1162            return MeasureUnit.internalGetInstance(type, subType);
1163        }
1164    }
1165}
1166