1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5 ********************************************************************************
6 * Copyright (C) 2003-2016, Google, International Business Machines Corporation
7 * and others. All Rights Reserved.
8 ********************************************************************************
9*/
10package android.icu.util;
11
12import java.util.Arrays;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Locale;
16import java.util.Map;
17import java.util.MissingResourceException;
18
19import android.icu.impl.ICUCache;
20import android.icu.impl.ICUData;
21import android.icu.impl.ICUResourceBundle;
22import android.icu.impl.SimpleCache;
23
24/**
25 * Provide information about gender in locales based on data in CLDR. Currently supplies gender of lists.
26 * @author markdavis
27 * @deprecated This API is ICU internal only.
28 * @hide Only a subset of ICU is exposed in Android
29 * @hide draft / provisional / internal are hidden on Android
30 */
31@Deprecated
32public class GenderInfo {
33
34    private final ListGenderStyle style; // set based on locale
35
36    /**
37     * Gender: OTHER means either the information is unavailable, or the person has declined to state MALE or FEMALE.
38     * @deprecated This API is ICU internal only.
39     * @hide draft / provisional / internal are hidden on Android
40     */
41    @Deprecated
42    public enum Gender {
43        /**
44         * @deprecated This API is ICU internal only.
45         * @hide draft / provisional / internal are hidden on Android
46         */
47        @Deprecated
48        MALE,
49        /**
50         * @deprecated This API is ICU internal only.
51         * @hide draft / provisional / internal are hidden on Android
52         */
53        @Deprecated
54        FEMALE,
55        /**
56         * @deprecated This API is ICU internal only.
57         * @hide draft / provisional / internal are hidden on Android
58         */
59        @Deprecated
60        OTHER
61    }
62
63    /**
64     * Create GenderInfo from a ULocale.
65     * @param uLocale desired locale
66     * @deprecated This API is ICU internal only.
67     * @hide draft / provisional / internal are hidden on Android
68     */
69    @Deprecated
70    public static GenderInfo getInstance(ULocale uLocale) {
71        return genderInfoCache.get(uLocale);
72    }
73
74    /**
75     * Create GenderInfo from a Locale.
76     * @param locale desired locale
77     * @deprecated This API is ICU internal only.
78     * @hide draft / provisional / internal are hidden on Android
79     */
80    @Deprecated
81    public static GenderInfo getInstance(Locale locale) {
82        return getInstance(ULocale.forLocale(locale));
83    }
84
85    /**
86     * Enum only meant for use in CLDR and in testing. Indicates the category for the locale.
87     * This only affects gender for lists more than one. For lists of 1 item, the gender
88     * of the list always equals the gender of that sole item.
89     * @deprecated This API is ICU internal only.
90     * @hide draft / provisional / internal are hidden on Android
91     */
92    @Deprecated
93    public enum ListGenderStyle {
94        /**
95         * For an empty list, returns OTHER;
96         * For a single item, returns its gender;
97         * Otherwise always OTHER.
98         * @deprecated This API is ICU internal only.
99         * @hide draft / provisional / internal are hidden on Android
100         */
101        @Deprecated
102        NEUTRAL,
103        /**
104         * For an empty list, returns OTHER;
105         * For a single item, returns its gender;
106         * Otherwise gender(all male) = male, gender(all female) = female, otherwise gender(list) = other.
107         * So any 'other' value makes the overall gender be 'other'.
108         * @deprecated This API is ICU internal only.
109         * @hide draft / provisional / internal are hidden on Android
110         */
111        @Deprecated
112        MIXED_NEUTRAL,
113        /**
114         * For an empty list, returns OTHER;
115         * For a single item, returns its gender;
116         * Otherwise, gender(all female) = female, otherwise gender(list) = male.
117         * So for more than one item, any 'other' value makes the overall gender be 'male'.
118         * @deprecated This API is ICU internal only.
119         * @hide draft / provisional / internal are hidden on Android
120         */
121        @Deprecated
122        MALE_TAINTS;
123
124        private static Map<String, ListGenderStyle> fromNameMap =
125            new HashMap<String, ListGenderStyle>(3);
126
127        static {
128            fromNameMap.put("neutral", NEUTRAL);
129            fromNameMap.put("maleTaints", MALE_TAINTS);
130            fromNameMap.put("mixedNeutral", MIXED_NEUTRAL);
131        }
132
133        /**
134         * @deprecated This API is ICU internal only.
135         * @hide draft / provisional / internal are hidden on Android
136         */
137        @Deprecated
138        public static ListGenderStyle fromName(String name) {
139            ListGenderStyle result = fromNameMap.get(name);
140            if (result == null) {
141                throw new IllegalArgumentException("Unknown gender style name: " + name);
142            }
143            return result;
144        }
145    }
146
147    /**
148     * Get the gender of a list, based on locale usage.
149     * @param genders a list of genders.
150     * @return the gender of the list.
151     * @deprecated This API is ICU internal only.
152     * @hide draft / provisional / internal are hidden on Android
153     */
154    @Deprecated
155    public Gender getListGender(Gender... genders) {
156        return getListGender(Arrays.asList(genders));
157    }
158
159    /**
160     * Get the gender of a list, based on locale usage.
161     * @param genders a list of genders.
162     * @return the gender of the list.
163     * @deprecated This API is ICU internal only.
164     * @hide draft / provisional / internal are hidden on Android
165     */
166    @Deprecated
167    public Gender getListGender(List<Gender> genders) {
168        if (genders.size() == 0) {
169            return Gender.OTHER; // degenerate case
170        }
171        if (genders.size() == 1) {
172            return genders.get(0); // degenerate case
173        }
174        switch(style) {
175        case NEUTRAL:
176            return Gender.OTHER;
177        case MIXED_NEUTRAL:
178            boolean hasFemale = false;
179            boolean hasMale = false;
180            for (Gender gender : genders) {
181                switch (gender) {
182                case FEMALE:
183                    if (hasMale) {
184                        return Gender.OTHER;
185                    }
186                    hasFemale = true;
187                    break;
188                case MALE:
189                    if (hasFemale) {
190                        return Gender.OTHER;
191                    }
192                    hasMale = true;
193                    break;
194                case OTHER:
195                    return Gender.OTHER;
196                }
197            }
198            return hasMale ? Gender.MALE : Gender.FEMALE;
199            // Note: any OTHER would have caused a return in the loop, which always happens.
200        case MALE_TAINTS:
201            for (Gender gender : genders) {
202                if (gender != Gender.FEMALE) {
203                    return Gender.MALE;
204                }
205            }
206            return Gender.FEMALE;
207        default:
208            return Gender.OTHER;
209        }
210    }
211
212    /**
213     * Only for testing and use with CLDR.
214     * @param genderStyle gender style
215     * @deprecated This API is ICU internal only.
216     * @hide draft / provisional / internal are hidden on Android
217     */
218    @Deprecated
219    public GenderInfo(ListGenderStyle genderStyle) {
220        style = genderStyle;
221    }
222
223    private static GenderInfo neutral = new GenderInfo(ListGenderStyle.NEUTRAL);
224
225    private static class Cache {
226        private final ICUCache<ULocale, GenderInfo> cache =
227            new SimpleCache<ULocale, GenderInfo>();
228
229        public GenderInfo get(ULocale locale) {
230            GenderInfo result = cache.get(locale);
231            if (result == null) {
232                result = load(locale);
233                if (result == null) {
234                    ULocale fallback = locale.getFallback();
235
236                    // We call get() recursively so that we can leverage the cache
237                    // for all fallback locales too. If we get to the root locale,
238                    // and find no resource assume that list gender style is NEUTRAL.
239                    result = fallback == null ? neutral : get(fallback);
240                }
241                cache.put(locale, result);
242            }
243            return result;
244        }
245
246        private static GenderInfo load(ULocale ulocale) {
247            UResourceBundle rb = UResourceBundle.getBundleInstance(
248                    ICUData.ICU_BASE_NAME,
249                    "genderList",
250                    ICUResourceBundle.ICU_DATA_CLASS_LOADER, true);
251            UResourceBundle genderList = rb.get("genderList");
252            try {
253                return new GenderInfo(
254                        ListGenderStyle.fromName(genderList.getString(ulocale.toString())));
255            } catch (MissingResourceException mre) {
256                return null;
257            }
258        }
259    }
260
261    private static Cache genderInfoCache = new Cache();
262}
263