1 /*
2  *******************************************************************************
3  * Copyright (C) 2004-2015, Google Inc, International Business Machines        *
4  * Corporation and others. All Rights Reserved.                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.util;
8 
9 import java.io.Externalizable;
10 import java.io.IOException;
11 import java.io.ObjectInput;
12 import java.io.ObjectOutput;
13 import java.io.ObjectStreamException;
14 import java.io.Serializable;
15 import java.util.Collections;
16 import java.util.Enumeration;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.Map;
20 import java.util.MissingResourceException;
21 import java.util.Set;
22 
23 import com.ibm.icu.impl.ICUResourceBundle;
24 import com.ibm.icu.impl.Pair;
25 import 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  */
37 public 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
MeasureUnit(String type, String subType)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      */
getType()75     public String getType() {
76         return type;
77     }
78 
79 
80     /**
81      * Get the subType, such as “foot”.
82      *
83      * @stable ICU 53
84      */
getSubtype()85     public String getSubtype() {
86         return subType;
87     }
88 
89 
90 
91     /**
92      * {@inheritDoc}
93      *
94      * @stable ICU 53
95      */
96     @Override
hashCode()97     public int hashCode() {
98         return 31 * type.hashCode() + subType.hashCode();
99     }
100 
101     /**
102      * {@inheritDoc}
103      *
104      * @stable ICU 53
105      */
106     @Override
equals(Object rhs)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
toString()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      */
getAvailableTypes()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      */
getAvailable(String type)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      */
getAvailable()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
internalGetInstance(String type, String subType)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.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
resolveUnitPerUnit(MeasureUnit unit, MeasureUnit perUnit)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 = new UnicodeSet('-', '-', '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
create(String type, String subType)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) {
internalGetInstance(type, unitNameRes.getKey())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
addUnit(String type, String unitName, Factory factory)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      * @draft ICU 54
335      * @provisional This API might change or be removed in a future release.
336      */
337     public static final MeasureUnit METER_PER_SECOND_SQUARED = MeasureUnit.internalGetInstance("acceleration", "meter-per-second-squared");
338 
339     /**
340      * Constant for unit of angle: arc-minute
341      * @stable ICU 53
342      */
343     public static final MeasureUnit ARC_MINUTE = MeasureUnit.internalGetInstance("angle", "arc-minute");
344 
345     /**
346      * Constant for unit of angle: arc-second
347      * @stable ICU 53
348      */
349     public static final MeasureUnit ARC_SECOND = MeasureUnit.internalGetInstance("angle", "arc-second");
350 
351     /**
352      * Constant for unit of angle: degree
353      * @stable ICU 53
354      */
355     public static final MeasureUnit DEGREE = MeasureUnit.internalGetInstance("angle", "degree");
356 
357     /**
358      * Constant for unit of angle: radian
359      * @draft ICU 54
360      * @provisional This API might change or be removed in a future release.
361      */
362     public static final MeasureUnit RADIAN = MeasureUnit.internalGetInstance("angle", "radian");
363 
364     /**
365      * Constant for unit of area: acre
366      * @stable ICU 53
367      */
368     public static final MeasureUnit ACRE = MeasureUnit.internalGetInstance("area", "acre");
369 
370     /**
371      * Constant for unit of area: hectare
372      * @stable ICU 53
373      */
374     public static final MeasureUnit HECTARE = MeasureUnit.internalGetInstance("area", "hectare");
375 
376     /**
377      * Constant for unit of area: square-centimeter
378      * @draft ICU 54
379      * @provisional This API might change or be removed in a future release.
380      */
381     public static final MeasureUnit SQUARE_CENTIMETER = MeasureUnit.internalGetInstance("area", "square-centimeter");
382 
383     /**
384      * Constant for unit of area: square-foot
385      * @stable ICU 53
386      */
387     public static final MeasureUnit SQUARE_FOOT = MeasureUnit.internalGetInstance("area", "square-foot");
388 
389     /**
390      * Constant for unit of area: square-inch
391      * @draft ICU 54
392      * @provisional This API might change or be removed in a future release.
393      */
394     public static final MeasureUnit SQUARE_INCH = MeasureUnit.internalGetInstance("area", "square-inch");
395 
396     /**
397      * Constant for unit of area: square-kilometer
398      * @stable ICU 53
399      */
400     public static final MeasureUnit SQUARE_KILOMETER = MeasureUnit.internalGetInstance("area", "square-kilometer");
401 
402     /**
403      * Constant for unit of area: square-meter
404      * @stable ICU 53
405      */
406     public static final MeasureUnit SQUARE_METER = MeasureUnit.internalGetInstance("area", "square-meter");
407 
408     /**
409      * Constant for unit of area: square-mile
410      * @stable ICU 53
411      */
412     public static final MeasureUnit SQUARE_MILE = MeasureUnit.internalGetInstance("area", "square-mile");
413 
414     /**
415      * Constant for unit of area: square-yard
416      * @draft ICU 54
417      * @provisional This API might change or be removed in a future release.
418      */
419     public static final MeasureUnit SQUARE_YARD = MeasureUnit.internalGetInstance("area", "square-yard");
420 
421     /**
422      * Constant for unit of consumption: liter-per-kilometer
423      * @draft ICU 54
424      * @provisional This API might change or be removed in a future release.
425      */
426     public static final MeasureUnit LITER_PER_KILOMETER = MeasureUnit.internalGetInstance("consumption", "liter-per-kilometer");
427 
428     /**
429      * Constant for unit of consumption: mile-per-gallon
430      * @draft ICU 54
431      * @provisional This API might change or be removed in a future release.
432      */
433     public static final MeasureUnit MILE_PER_GALLON = MeasureUnit.internalGetInstance("consumption", "mile-per-gallon");
434 
435     /**
436      * Constant for unit of digital: bit
437      * @draft ICU 54
438      * @provisional This API might change or be removed in a future release.
439      */
440     public static final MeasureUnit BIT = MeasureUnit.internalGetInstance("digital", "bit");
441 
442     /**
443      * Constant for unit of digital: byte
444      * @draft ICU 54
445      * @provisional This API might change or be removed in a future release.
446      */
447     public static final MeasureUnit BYTE = MeasureUnit.internalGetInstance("digital", "byte");
448 
449     /**
450      * Constant for unit of digital: gigabit
451      * @draft ICU 54
452      * @provisional This API might change or be removed in a future release.
453      */
454     public static final MeasureUnit GIGABIT = MeasureUnit.internalGetInstance("digital", "gigabit");
455 
456     /**
457      * Constant for unit of digital: gigabyte
458      * @draft ICU 54
459      * @provisional This API might change or be removed in a future release.
460      */
461     public static final MeasureUnit GIGABYTE = MeasureUnit.internalGetInstance("digital", "gigabyte");
462 
463     /**
464      * Constant for unit of digital: kilobit
465      * @draft ICU 54
466      * @provisional This API might change or be removed in a future release.
467      */
468     public static final MeasureUnit KILOBIT = MeasureUnit.internalGetInstance("digital", "kilobit");
469 
470     /**
471      * Constant for unit of digital: kilobyte
472      * @draft ICU 54
473      * @provisional This API might change or be removed in a future release.
474      */
475     public static final MeasureUnit KILOBYTE = MeasureUnit.internalGetInstance("digital", "kilobyte");
476 
477     /**
478      * Constant for unit of digital: megabit
479      * @draft ICU 54
480      * @provisional This API might change or be removed in a future release.
481      */
482     public static final MeasureUnit MEGABIT = MeasureUnit.internalGetInstance("digital", "megabit");
483 
484     /**
485      * Constant for unit of digital: megabyte
486      * @draft ICU 54
487      * @provisional This API might change or be removed in a future release.
488      */
489     public static final MeasureUnit MEGABYTE = MeasureUnit.internalGetInstance("digital", "megabyte");
490 
491     /**
492      * Constant for unit of digital: terabit
493      * @draft ICU 54
494      * @provisional This API might change or be removed in a future release.
495      */
496     public static final MeasureUnit TERABIT = MeasureUnit.internalGetInstance("digital", "terabit");
497 
498     /**
499      * Constant for unit of digital: terabyte
500      * @draft ICU 54
501      * @provisional This API might change or be removed in a future release.
502      */
503     public static final MeasureUnit TERABYTE = MeasureUnit.internalGetInstance("digital", "terabyte");
504 
505     /**
506      * Constant for unit of duration: day
507      * @stable ICU 4.0
508      */
509     public static final TimeUnit DAY = (TimeUnit) MeasureUnit.internalGetInstance("duration", "day");
510 
511     /**
512      * Constant for unit of duration: hour
513      * @stable ICU 4.0
514      */
515     public static final TimeUnit HOUR = (TimeUnit) MeasureUnit.internalGetInstance("duration", "hour");
516 
517     /**
518      * Constant for unit of duration: microsecond
519      * @draft ICU 54
520      * @provisional This API might change or be removed in a future release.
521      */
522     public static final MeasureUnit MICROSECOND = MeasureUnit.internalGetInstance("duration", "microsecond");
523 
524     /**
525      * Constant for unit of duration: millisecond
526      * @stable ICU 53
527      */
528     public static final MeasureUnit MILLISECOND = MeasureUnit.internalGetInstance("duration", "millisecond");
529 
530     /**
531      * Constant for unit of duration: minute
532      * @stable ICU 4.0
533      */
534     public static final TimeUnit MINUTE = (TimeUnit) MeasureUnit.internalGetInstance("duration", "minute");
535 
536     /**
537      * Constant for unit of duration: month
538      *
539      * @stable ICU 4.0
540      */
541     public static final TimeUnit MONTH = (TimeUnit) MeasureUnit.internalGetInstance("duration", "month");
542 
543     /**
544      * Constant for unit of duration: nanosecond
545      * @draft ICU 54
546      * @provisional This API might change or be removed in a future release.
547      */
548     public static final MeasureUnit NANOSECOND = MeasureUnit.internalGetInstance("duration", "nanosecond");
549 
550     /**
551      * Constant for unit of duration: second
552      * @stable ICU 4.0
553      */
554     public static final TimeUnit SECOND = (TimeUnit) MeasureUnit.internalGetInstance("duration", "second");
555 
556     /**
557      * Constant for unit of duration: week
558      * @stable ICU 4.0
559      */
560     public static final TimeUnit WEEK = (TimeUnit) MeasureUnit.internalGetInstance("duration", "week");
561 
562     /**
563      * Constant for unit of duration: year
564      * @stable ICU 4.0
565      */
566     public static final TimeUnit YEAR = (TimeUnit) MeasureUnit.internalGetInstance("duration", "year");
567 
568     /**
569      * Constant for unit of electric: ampere
570      * @draft ICU 54
571      * @provisional This API might change or be removed in a future release.
572      */
573     public static final MeasureUnit AMPERE = MeasureUnit.internalGetInstance("electric", "ampere");
574 
575     /**
576      * Constant for unit of electric: milliampere
577      * @draft ICU 54
578      * @provisional This API might change or be removed in a future release.
579      */
580     public static final MeasureUnit MILLIAMPERE = MeasureUnit.internalGetInstance("electric", "milliampere");
581 
582     /**
583      * Constant for unit of electric: ohm
584      * @draft ICU 54
585      * @provisional This API might change or be removed in a future release.
586      */
587     public static final MeasureUnit OHM = MeasureUnit.internalGetInstance("electric", "ohm");
588 
589     /**
590      * Constant for unit of electric: volt
591      * @draft ICU 54
592      * @provisional This API might change or be removed in a future release.
593      */
594     public static final MeasureUnit VOLT = MeasureUnit.internalGetInstance("electric", "volt");
595 
596     /**
597      * Constant for unit of energy: calorie
598      * @draft ICU 54
599      * @provisional This API might change or be removed in a future release.
600      */
601     public static final MeasureUnit CALORIE = MeasureUnit.internalGetInstance("energy", "calorie");
602 
603     /**
604      * Constant for unit of energy: foodcalorie
605      * @draft ICU 54
606      * @provisional This API might change or be removed in a future release.
607      */
608     public static final MeasureUnit FOODCALORIE = MeasureUnit.internalGetInstance("energy", "foodcalorie");
609 
610     /**
611      * Constant for unit of energy: joule
612      * @draft ICU 54
613      * @provisional This API might change or be removed in a future release.
614      */
615     public static final MeasureUnit JOULE = MeasureUnit.internalGetInstance("energy", "joule");
616 
617     /**
618      * Constant for unit of energy: kilocalorie
619      * @draft ICU 54
620      * @provisional This API might change or be removed in a future release.
621      */
622     public static final MeasureUnit KILOCALORIE = MeasureUnit.internalGetInstance("energy", "kilocalorie");
623 
624     /**
625      * Constant for unit of energy: kilojoule
626      * @draft ICU 54
627      * @provisional This API might change or be removed in a future release.
628      */
629     public static final MeasureUnit KILOJOULE = MeasureUnit.internalGetInstance("energy", "kilojoule");
630 
631     /**
632      * Constant for unit of energy: kilowatt-hour
633      * @draft ICU 54
634      * @provisional This API might change or be removed in a future release.
635      */
636     public static final MeasureUnit KILOWATT_HOUR = MeasureUnit.internalGetInstance("energy", "kilowatt-hour");
637 
638     /**
639      * Constant for unit of frequency: gigahertz
640      * @draft ICU 54
641      * @provisional This API might change or be removed in a future release.
642      */
643     public static final MeasureUnit GIGAHERTZ = MeasureUnit.internalGetInstance("frequency", "gigahertz");
644 
645     /**
646      * Constant for unit of frequency: hertz
647      * @draft ICU 54
648      * @provisional This API might change or be removed in a future release.
649      */
650     public static final MeasureUnit HERTZ = MeasureUnit.internalGetInstance("frequency", "hertz");
651 
652     /**
653      * Constant for unit of frequency: kilohertz
654      * @draft ICU 54
655      * @provisional This API might change or be removed in a future release.
656      */
657     public static final MeasureUnit KILOHERTZ = MeasureUnit.internalGetInstance("frequency", "kilohertz");
658 
659     /**
660      * Constant for unit of frequency: megahertz
661      * @draft ICU 54
662      * @provisional This API might change or be removed in a future release.
663      */
664     public static final MeasureUnit MEGAHERTZ = MeasureUnit.internalGetInstance("frequency", "megahertz");
665 
666     /**
667      * Constant for unit of length: astronomical-unit
668      * @draft ICU 54
669      * @provisional This API might change or be removed in a future release.
670      */
671     public static final MeasureUnit ASTRONOMICAL_UNIT = MeasureUnit.internalGetInstance("length", "astronomical-unit");
672 
673     /**
674      * Constant for unit of length: centimeter
675      * @stable ICU 53
676      */
677     public static final MeasureUnit CENTIMETER = MeasureUnit.internalGetInstance("length", "centimeter");
678 
679     /**
680      * Constant for unit of length: decimeter
681      * @draft ICU 54
682      * @provisional This API might change or be removed in a future release.
683      */
684     public static final MeasureUnit DECIMETER = MeasureUnit.internalGetInstance("length", "decimeter");
685 
686     /**
687      * Constant for unit of length: fathom
688      * @draft ICU 54
689      * @provisional This API might change or be removed in a future release.
690      */
691     public static final MeasureUnit FATHOM = MeasureUnit.internalGetInstance("length", "fathom");
692 
693     /**
694      * Constant for unit of length: foot
695      * @stable ICU 53
696      */
697     public static final MeasureUnit FOOT = MeasureUnit.internalGetInstance("length", "foot");
698 
699     /**
700      * Constant for unit of length: furlong
701      * @draft ICU 54
702      * @provisional This API might change or be removed in a future release.
703      */
704     public static final MeasureUnit FURLONG = MeasureUnit.internalGetInstance("length", "furlong");
705 
706     /**
707      * Constant for unit of length: inch
708      * @stable ICU 53
709      */
710     public static final MeasureUnit INCH = MeasureUnit.internalGetInstance("length", "inch");
711 
712     /**
713      * Constant for unit of length: kilometer
714      * @stable ICU 53
715      */
716     public static final MeasureUnit KILOMETER = MeasureUnit.internalGetInstance("length", "kilometer");
717 
718     /**
719      * Constant for unit of length: light-year
720      * @stable ICU 53
721      */
722     public static final MeasureUnit LIGHT_YEAR = MeasureUnit.internalGetInstance("length", "light-year");
723 
724     /**
725      * Constant for unit of length: meter
726      * @stable ICU 53
727      */
728     public static final MeasureUnit METER = MeasureUnit.internalGetInstance("length", "meter");
729 
730     /**
731      * Constant for unit of length: micrometer
732      * @draft ICU 54
733      * @provisional This API might change or be removed in a future release.
734      */
735     public static final MeasureUnit MICROMETER = MeasureUnit.internalGetInstance("length", "micrometer");
736 
737     /**
738      * Constant for unit of length: mile
739      * @stable ICU 53
740      */
741     public static final MeasureUnit MILE = MeasureUnit.internalGetInstance("length", "mile");
742 
743     /**
744      * Constant for unit of length: millimeter
745      * @stable ICU 53
746      */
747     public static final MeasureUnit MILLIMETER = MeasureUnit.internalGetInstance("length", "millimeter");
748 
749     /**
750      * Constant for unit of length: nanometer
751      * @draft ICU 54
752      * @provisional This API might change or be removed in a future release.
753      */
754     public static final MeasureUnit NANOMETER = MeasureUnit.internalGetInstance("length", "nanometer");
755 
756     /**
757      * Constant for unit of length: nautical-mile
758      * @draft ICU 54
759      * @provisional This API might change or be removed in a future release.
760      */
761     public static final MeasureUnit NAUTICAL_MILE = MeasureUnit.internalGetInstance("length", "nautical-mile");
762 
763     /**
764      * Constant for unit of length: parsec
765      * @draft ICU 54
766      * @provisional This API might change or be removed in a future release.
767      */
768     public static final MeasureUnit PARSEC = MeasureUnit.internalGetInstance("length", "parsec");
769 
770     /**
771      * Constant for unit of length: picometer
772      * @stable ICU 53
773      */
774     public static final MeasureUnit PICOMETER = MeasureUnit.internalGetInstance("length", "picometer");
775 
776     /**
777      * Constant for unit of length: yard
778      * @stable ICU 53
779      */
780     public static final MeasureUnit YARD = MeasureUnit.internalGetInstance("length", "yard");
781 
782     /**
783      * Constant for unit of light: lux
784      * @draft ICU 54
785      * @provisional This API might change or be removed in a future release.
786      */
787     public static final MeasureUnit LUX = MeasureUnit.internalGetInstance("light", "lux");
788 
789     /**
790      * Constant for unit of mass: carat
791      * @draft ICU 54
792      * @provisional This API might change or be removed in a future release.
793      */
794     public static final MeasureUnit CARAT = MeasureUnit.internalGetInstance("mass", "carat");
795 
796     /**
797      * Constant for unit of mass: gram
798      * @stable ICU 53
799      */
800     public static final MeasureUnit GRAM = MeasureUnit.internalGetInstance("mass", "gram");
801 
802     /**
803      * Constant for unit of mass: kilogram
804      * @stable ICU 53
805      */
806     public static final MeasureUnit KILOGRAM = MeasureUnit.internalGetInstance("mass", "kilogram");
807 
808     /**
809      * Constant for unit of mass: metric-ton
810      * @draft ICU 54
811      * @provisional This API might change or be removed in a future release.
812      */
813     public static final MeasureUnit METRIC_TON = MeasureUnit.internalGetInstance("mass", "metric-ton");
814 
815     /**
816      * Constant for unit of mass: microgram
817      * @draft ICU 54
818      * @provisional This API might change or be removed in a future release.
819      */
820     public static final MeasureUnit MICROGRAM = MeasureUnit.internalGetInstance("mass", "microgram");
821 
822     /**
823      * Constant for unit of mass: milligram
824      * @draft ICU 54
825      * @provisional This API might change or be removed in a future release.
826      */
827     public static final MeasureUnit MILLIGRAM = MeasureUnit.internalGetInstance("mass", "milligram");
828 
829     /**
830      * Constant for unit of mass: ounce
831      * @stable ICU 53
832      */
833     public static final MeasureUnit OUNCE = MeasureUnit.internalGetInstance("mass", "ounce");
834 
835     /**
836      * Constant for unit of mass: ounce-troy
837      * @draft ICU 54
838      * @provisional This API might change or be removed in a future release.
839      */
840     public static final MeasureUnit OUNCE_TROY = MeasureUnit.internalGetInstance("mass", "ounce-troy");
841 
842     /**
843      * Constant for unit of mass: pound
844      * @stable ICU 53
845      */
846     public static final MeasureUnit POUND = MeasureUnit.internalGetInstance("mass", "pound");
847 
848     /**
849      * Constant for unit of mass: stone
850      * @draft ICU 54
851      * @provisional This API might change or be removed in a future release.
852      */
853     public static final MeasureUnit STONE = MeasureUnit.internalGetInstance("mass", "stone");
854 
855     /**
856      * Constant for unit of mass: ton
857      * @draft ICU 54
858      * @provisional This API might change or be removed in a future release.
859      */
860     public static final MeasureUnit TON = MeasureUnit.internalGetInstance("mass", "ton");
861 
862     /**
863      * Constant for unit of power: gigawatt
864      * @draft ICU 54
865      * @provisional This API might change or be removed in a future release.
866      */
867     public static final MeasureUnit GIGAWATT = MeasureUnit.internalGetInstance("power", "gigawatt");
868 
869     /**
870      * Constant for unit of power: horsepower
871      * @stable ICU 53
872      */
873     public static final MeasureUnit HORSEPOWER = MeasureUnit.internalGetInstance("power", "horsepower");
874 
875     /**
876      * Constant for unit of power: kilowatt
877      * @stable ICU 53
878      */
879     public static final MeasureUnit KILOWATT = MeasureUnit.internalGetInstance("power", "kilowatt");
880 
881     /**
882      * Constant for unit of power: megawatt
883      * @draft ICU 54
884      * @provisional This API might change or be removed in a future release.
885      */
886     public static final MeasureUnit MEGAWATT = MeasureUnit.internalGetInstance("power", "megawatt");
887 
888     /**
889      * Constant for unit of power: milliwatt
890      * @draft ICU 54
891      * @provisional This API might change or be removed in a future release.
892      */
893     public static final MeasureUnit MILLIWATT = MeasureUnit.internalGetInstance("power", "milliwatt");
894 
895     /**
896      * Constant for unit of power: watt
897      * @stable ICU 53
898      */
899     public static final MeasureUnit WATT = MeasureUnit.internalGetInstance("power", "watt");
900 
901     /**
902      * Constant for unit of pressure: hectopascal
903      * @stable ICU 53
904      */
905     public static final MeasureUnit HECTOPASCAL = MeasureUnit.internalGetInstance("pressure", "hectopascal");
906 
907     /**
908      * Constant for unit of pressure: inch-hg
909      * @stable ICU 53
910      */
911     public static final MeasureUnit INCH_HG = MeasureUnit.internalGetInstance("pressure", "inch-hg");
912 
913     /**
914      * Constant for unit of pressure: millibar
915      * @stable ICU 53
916      */
917     public static final MeasureUnit MILLIBAR = MeasureUnit.internalGetInstance("pressure", "millibar");
918 
919     /**
920      * Constant for unit of pressure: millimeter-of-mercury
921      * @draft ICU 54
922      * @provisional This API might change or be removed in a future release.
923      */
924     public static final MeasureUnit MILLIMETER_OF_MERCURY = MeasureUnit.internalGetInstance("pressure", "millimeter-of-mercury");
925 
926     /**
927      * Constant for unit of pressure: pound-per-square-inch
928      * @draft ICU 54
929      * @provisional This API might change or be removed in a future release.
930      */
931     public static final MeasureUnit POUND_PER_SQUARE_INCH = MeasureUnit.internalGetInstance("pressure", "pound-per-square-inch");
932 
933     /**
934      * Constant for unit of proportion: karat
935      * @draft ICU 54
936      * @provisional This API might change or be removed in a future release.
937      */
938     public static final MeasureUnit KARAT = MeasureUnit.internalGetInstance("proportion", "karat");
939 
940     /**
941      * Constant for unit of speed: kilometer-per-hour
942      * @stable ICU 53
943      */
944     public static final MeasureUnit KILOMETER_PER_HOUR = MeasureUnit.internalGetInstance("speed", "kilometer-per-hour");
945 
946     /**
947      * Constant for unit of speed: meter-per-second
948      * @stable ICU 53
949      */
950     public static final MeasureUnit METER_PER_SECOND = MeasureUnit.internalGetInstance("speed", "meter-per-second");
951 
952     /**
953      * Constant for unit of speed: mile-per-hour
954      * @stable ICU 53
955      */
956     public static final MeasureUnit MILE_PER_HOUR = MeasureUnit.internalGetInstance("speed", "mile-per-hour");
957 
958     /**
959      * Constant for unit of temperature: celsius
960      * @stable ICU 53
961      */
962     public static final MeasureUnit CELSIUS = MeasureUnit.internalGetInstance("temperature", "celsius");
963 
964     /**
965      * Constant for unit of temperature: fahrenheit
966      * @stable ICU 53
967      */
968     public static final MeasureUnit FAHRENHEIT = MeasureUnit.internalGetInstance("temperature", "fahrenheit");
969 
970     /**
971      * Constant for unit of temperature: kelvin
972      * @draft ICU 54
973      * @provisional This API might change or be removed in a future release.
974      */
975     public static final MeasureUnit KELVIN = MeasureUnit.internalGetInstance("temperature", "kelvin");
976 
977     /**
978      * Constant for unit of volume: acre-foot
979      * @draft ICU 54
980      * @provisional This API might change or be removed in a future release.
981      */
982     public static final MeasureUnit ACRE_FOOT = MeasureUnit.internalGetInstance("volume", "acre-foot");
983 
984     /**
985      * Constant for unit of volume: bushel
986      * @draft ICU 54
987      * @provisional This API might change or be removed in a future release.
988      */
989     public static final MeasureUnit BUSHEL = MeasureUnit.internalGetInstance("volume", "bushel");
990 
991     /**
992      * Constant for unit of volume: centiliter
993      * @draft ICU 54
994      * @provisional This API might change or be removed in a future release.
995      */
996     public static final MeasureUnit CENTILITER = MeasureUnit.internalGetInstance("volume", "centiliter");
997 
998     /**
999      * Constant for unit of volume: cubic-centimeter
1000      * @draft ICU 54
1001      * @provisional This API might change or be removed in a future release.
1002      */
1003     public static final MeasureUnit CUBIC_CENTIMETER = MeasureUnit.internalGetInstance("volume", "cubic-centimeter");
1004 
1005     /**
1006      * Constant for unit of volume: cubic-foot
1007      * @draft ICU 54
1008      * @provisional This API might change or be removed in a future release.
1009      */
1010     public static final MeasureUnit CUBIC_FOOT = MeasureUnit.internalGetInstance("volume", "cubic-foot");
1011 
1012     /**
1013      * Constant for unit of volume: cubic-inch
1014      * @draft ICU 54
1015      * @provisional This API might change or be removed in a future release.
1016      */
1017     public static final MeasureUnit CUBIC_INCH = MeasureUnit.internalGetInstance("volume", "cubic-inch");
1018 
1019     /**
1020      * Constant for unit of volume: cubic-kilometer
1021      * @stable ICU 53
1022      */
1023     public static final MeasureUnit CUBIC_KILOMETER = MeasureUnit.internalGetInstance("volume", "cubic-kilometer");
1024 
1025     /**
1026      * Constant for unit of volume: cubic-meter
1027      * @draft ICU 54
1028      * @provisional This API might change or be removed in a future release.
1029      */
1030     public static final MeasureUnit CUBIC_METER = MeasureUnit.internalGetInstance("volume", "cubic-meter");
1031 
1032     /**
1033      * Constant for unit of volume: cubic-mile
1034      * @stable ICU 53
1035      */
1036     public static final MeasureUnit CUBIC_MILE = MeasureUnit.internalGetInstance("volume", "cubic-mile");
1037 
1038     /**
1039      * Constant for unit of volume: cubic-yard
1040      * @draft ICU 54
1041      * @provisional This API might change or be removed in a future release.
1042      */
1043     public static final MeasureUnit CUBIC_YARD = MeasureUnit.internalGetInstance("volume", "cubic-yard");
1044 
1045     /**
1046      * Constant for unit of volume: cup
1047      * @draft ICU 54
1048      * @provisional This API might change or be removed in a future release.
1049      */
1050     public static final MeasureUnit CUP = MeasureUnit.internalGetInstance("volume", "cup");
1051 
1052     /**
1053      * Constant for unit of volume: deciliter
1054      * @draft ICU 54
1055      * @provisional This API might change or be removed in a future release.
1056      */
1057     public static final MeasureUnit DECILITER = MeasureUnit.internalGetInstance("volume", "deciliter");
1058 
1059     /**
1060      * Constant for unit of volume: fluid-ounce
1061      * @draft ICU 54
1062      * @provisional This API might change or be removed in a future release.
1063      */
1064     public static final MeasureUnit FLUID_OUNCE = MeasureUnit.internalGetInstance("volume", "fluid-ounce");
1065 
1066     /**
1067      * Constant for unit of volume: gallon
1068      * @draft ICU 54
1069      * @provisional This API might change or be removed in a future release.
1070      */
1071     public static final MeasureUnit GALLON = MeasureUnit.internalGetInstance("volume", "gallon");
1072 
1073     /**
1074      * Constant for unit of volume: hectoliter
1075      * @draft ICU 54
1076      * @provisional This API might change or be removed in a future release.
1077      */
1078     public static final MeasureUnit HECTOLITER = MeasureUnit.internalGetInstance("volume", "hectoliter");
1079 
1080     /**
1081      * Constant for unit of volume: liter
1082      * @stable ICU 53
1083      */
1084     public static final MeasureUnit LITER = MeasureUnit.internalGetInstance("volume", "liter");
1085 
1086     /**
1087      * Constant for unit of volume: megaliter
1088      * @draft ICU 54
1089      * @provisional This API might change or be removed in a future release.
1090      */
1091     public static final MeasureUnit MEGALITER = MeasureUnit.internalGetInstance("volume", "megaliter");
1092 
1093     /**
1094      * Constant for unit of volume: milliliter
1095      * @draft ICU 54
1096      * @provisional This API might change or be removed in a future release.
1097      */
1098     public static final MeasureUnit MILLILITER = MeasureUnit.internalGetInstance("volume", "milliliter");
1099 
1100     /**
1101      * Constant for unit of volume: pint
1102      * @draft ICU 54
1103      * @provisional This API might change or be removed in a future release.
1104      */
1105     public static final MeasureUnit PINT = MeasureUnit.internalGetInstance("volume", "pint");
1106 
1107     /**
1108      * Constant for unit of volume: quart
1109      * @draft ICU 54
1110      * @provisional This API might change or be removed in a future release.
1111      */
1112     public static final MeasureUnit QUART = MeasureUnit.internalGetInstance("volume", "quart");
1113 
1114     /**
1115      * Constant for unit of volume: tablespoon
1116      * @draft ICU 54
1117      * @provisional This API might change or be removed in a future release.
1118      */
1119     public static final MeasureUnit TABLESPOON = MeasureUnit.internalGetInstance("volume", "tablespoon");
1120 
1121     /**
1122      * Constant for unit of volume: teaspoon
1123      * @draft ICU 54
1124      * @provisional This API might change or be removed in a future release.
1125      */
1126     public static final MeasureUnit TEASPOON = MeasureUnit.internalGetInstance("volume", "teaspoon");
1127 
1128     private static HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>unitPerUnitToSingleUnit =
1129             new HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>();
1130 
1131     static {
of(MeasureUnit.KILOMETER, MeasureUnit.HOUR)1132         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.KILOMETER, MeasureUnit.HOUR), MeasureUnit.KILOMETER_PER_HOUR);
of(MeasureUnit.MILE, MeasureUnit.GALLON)1133         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.GALLON), MeasureUnit.MILE_PER_GALLON);
of(MeasureUnit.MILE, MeasureUnit.HOUR)1134         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.HOUR), MeasureUnit.MILE_PER_HOUR);
of(MeasureUnit.METER, MeasureUnit.SECOND)1135         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.METER, MeasureUnit.SECOND), MeasureUnit.METER_PER_SECOND);
of(MeasureUnit.LITER, MeasureUnit.KILOMETER)1136         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.LITER, MeasureUnit.KILOMETER), MeasureUnit.LITER_PER_KILOMETER);
of(MeasureUnit.POUND, MeasureUnit.SQUARE_INCH)1137         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.POUND, MeasureUnit.SQUARE_INCH), MeasureUnit.POUND_PER_SQUARE_INCH);
1138     }
1139 
1140     // End generated MeasureUnit constants
1141     /* Private */
1142 
writeReplace()1143     private Object writeReplace() throws ObjectStreamException {
1144         return new MeasureUnitProxy(type, subType);
1145     }
1146 
1147     static final class MeasureUnitProxy implements Externalizable {
1148         private static final long serialVersionUID = -3910681415330989598L;
1149 
1150         private String type;
1151         private String subType;
1152 
MeasureUnitProxy(String type, String subType)1153         public MeasureUnitProxy(String type, String subType) {
1154             this.type = type;
1155             this.subType = subType;
1156         }
1157 
1158         // Must have public constructor, to enable Externalizable
MeasureUnitProxy()1159         public MeasureUnitProxy() {
1160         }
1161 
writeExternal(ObjectOutput out)1162         public void writeExternal(ObjectOutput out) throws IOException {
1163             out.writeByte(0); // version
1164             out.writeUTF(type);
1165             out.writeUTF(subType);
1166             out.writeShort(0); // allow for more data.
1167         }
1168 
readExternal(ObjectInput in)1169         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
1170             /* byte version = */ in.readByte(); // version
1171             type = in.readUTF();
1172             subType = in.readUTF();
1173             // allow for more data from future version
1174             int extra = in.readShort();
1175             if (extra > 0) {
1176                 byte[] extraBytes = new byte[extra];
1177                 in.read(extraBytes, 0, extra);
1178             }
1179         }
1180 
readResolve()1181         private Object readResolve() throws ObjectStreamException {
1182             return MeasureUnit.internalGetInstance(type, subType);
1183         }
1184     }
1185 }
1186