summaryrefslogtreecommitdiff
path: root/icu4j/main/core/src/main/java/com/ibm/icu/text/PersonNameFormatter.java
blob: be7e4206580a4e32ac1cadf79b14dc405cd415ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
// © 2022 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.text;

import java.util.Locale;

import com.ibm.icu.impl.personname.PersonNameFormatterImpl;

/**
 * A class for formatting names of people.  Takes raw name data for a person and renders it into a string according to
 * the caller's specifications, taking into account how people's names are rendered in the caller's locale.
 *
 * The Length, Usage, and Formality options can be used to get a wide variety of results.  In English, they would
 * produce results along these lines:
 * <table border="1">
 *     <tr>
 *         <th rowspan="2">
 *         </th>
 *         <th colspan="2">
 *             REFERRING
 *         </th>
 *         <th colspan="2">
 *             ADDRESSING
 *         </th>
 *         <th colspan="2">
 *             MONOGRAM
 *         </th>
 *     </tr>
 *     <tr>
 *         <th>FORMAL</th>
 *         <th>INFORMAL</th>
 *         <th>FORMAL</th>
 *         <th>INFORMAL</th>
 *         <th>FORMAL</th>
 *         <th>INFORMAL</th>
 *     </tr>
 *     <tr>
 *         <th>LONG</th>
 *         <td>James Earl Carter Jr.</td>
 *         <td>Jimmy Carter</td>
 *         <td>Mr. Carter</td>
 *         <td>Jimmy</td>
 *         <td>JEC</td>
 *         <td>JC</td>
 *     </tr>
 *     <tr>
 *         <th>MEDIUM</th>
 *         <td>James E. Carter Jr.</td>
 *         <td>Jimmy Carter</td>
 *         <td>Mr. Carter</td>
 *         <td>Jimmy</td>
 *         <td>C</td>
 *         <td>J</td>
 *     </tr>
 *     <tr>
 *         <th>SHORT</th>
 *         <td>J. E. Carter</td>
 *         <td>Jimmy Carter</td>
 *         <td>Mr. Carter</td>
 *         <td>Jimmy</td>
 *         <td>C</td>
 *         <td>J</td>
 *     </tr>
 * </table>
 *
 * @stable ICU 73
 */
public class PersonNameFormatter {
    //==============================================================================
    // Parameters that control formatting behavior

    /**
     * Specifies the desired length of the formatted name.
     * @stable ICU 73
     */
    public enum Length {
        /**
         * The longest name length.  Generally uses most of the fields in the name object.
         * @stable ICU 73
         */
        LONG,

        /**
         * The most typical name length.  Generally includes the given name and surname, but generally
         * not most of the other fields.
         * @stable ICU 73
         */
        MEDIUM,

        /**
         * A shortened name.  Skips most fields and may abbreviate some name fields to just their initials.
         * When Formality is INFORMAL, may only include one field.
         * @stable ICU 73
         */
        SHORT,

        /**
         * The default name length for the locale.  For most locales, this is the same as MEDIUM.
         * @draft ICU 74
         */
        DEFAULT
    }

    /**
     * Specifies the intended usage of the formatted name.
     * @stable ICU 73
     */
    public enum Usage {
        /**
         * Used for when the name is going to be used to address the user directly: "Turn left here, John."
         * @stable ICU 73
         */
        ADDRESSING,

        /**
         * Used in general cases, when the name is used to refer to somebody else.
         * @stable ICU 73
         */
        REFERRING,

        /**
         * Used to generate monograms, short 1 to 3-character versions of the name suitable for use in things
         * like chat avatars.  In English, this is usually the person's initials, but this isn't true in all
         * languages.  When the caller specifies Usage.MONOGRAM, the Length parameter can be used to get different
         * lengths of monograms: Length.SHORT is generally a single letter; Length.LONG may be as many as three or four.
         * @stable ICU 73
         */
        MONOGRAM
    }

    /**
     * Specifies the intended formality of the formatted name.
     * @stable ICU 73
     */
    public enum Formality {
        /**
         * The more formal version of the name.
         * @stable ICU 73
         */
        FORMAL,

        /**
         * The more informal version of the name.  In English, this might omit fields or use the "informal" variant
         * of the given name.
         * @stable ICU 73
         */
        INFORMAL,

        /**
         * The default formality for the locale.  For most locales, this is the same as FORMAL, but for English,
         * this is the same as INFORMAL.
         * @draft ICU 74
         */
        DEFAULT
    }

    /**
     * An enum indicating the desired display order for a formatted name.
     * @stable ICU 73
     */
    public enum DisplayOrder {
        /**
         * The default display order; used to indicate normal formatting.
         * @stable ICU 73
         */
        DEFAULT,

        /**
         * Used to indicate a display order suitable for use in a sorted list:
         * For English, this would put the surnames first, with a comma between them and the rest
         * of the name: "Smith, John".
         * @stable ICU 73
         */
        SORTING,

        /**
         * Forces the formatter to format the name in given-first order.  If the name itself specifies
         * a display order, this overrides it.
         * @draft ICU 74
         */
        FORCE_GIVEN_FIRST,

        /**
         * Forces the formatter to format the name in surname-first order.  If the name itself specifies
         * a display order, this overrides it.
         * @draft ICU 74
         */
        FORCE_SURNAME_FIRST,
    }

    private final PersonNameFormatterImpl impl;

    //==============================================================================
    // Builder for PersonNameFormatter

    /**
     * A utility class that can be used to construct a PersonNameFormatter.
     * Use PersonNameFormatter.builder() to get a new instance.
     * @stable ICU 73
     */
    public static class Builder {
        /**
         * Sets the locale for the formatter to be constructed.
         * @param locale The new formatter locale.  May not be null.
         * @return This builder.
         * @stable ICU 73
         */
        public Builder setLocale(Locale locale) {
            if (locale != null) {
                this.locale = locale;
            }
            return this;
        }

        /**
         * Sets the name length for the formatter to be constructed.
         * @param length The new name length.
         * @return This builder.
         * @stable ICU 73
         */
        public Builder setLength(Length length) {
            this.length = length;
            return this;
        }

        /**
         * Sets the name usage for the formatter to be constructed.
         * @param usage The new name length.
         * @return This builder.
         * @stable ICU 73
         */
        public Builder setUsage(Usage usage) {
            this.usage = usage;
            return this;
        }

        /**
         * Sets the name formality for the formatter to be constructed.
         * @param formality The new name length.
         * @return This builder.
         * @stable ICU 73
         */
        public Builder setFormality(Formality formality) {
            this.formality = formality;
            return this;
        }

        /**
         * Specifies the desired display order for the formatted names.  This can be either SORTING,
         * which requests that names be formatted in a manner suitable for inclusion in a sorted list
         * (e.g., in English, "Smith, John"), or DEFAULT, which gives the standard field order suitable
         * for most contexts (e.g., in English, "John Smith").
         * @param order The desired display order for formatted names.
         * @return This builder.
         * @stable ICU 73
         */
        public Builder setDisplayOrder(DisplayOrder order) {
            this.displayOrder = order;
            return this;
        }

        /**
         * Requests that the surname in the formatted result be rendered in ALL CAPS.  This is often done with
         * Japanese names to highlight which name is the surname.
         * @param allCaps If true, the surname in the formatted result will be rendered in ALL CAPS.
         * @return This builder.
         * @stable ICU 73
         */
        public Builder setSurnameAllCaps(boolean allCaps) {
            this.surnameAllCaps = allCaps;
            return this;
        }

        /**
         * Returns a new PersonNameFormatter with the values that were passed to this builder.
         * This method doesn't freeze or delete the builder; you can call build() more than once
         * (presumably after calling the other methods to change the parameter) to create more
         * than one PersonNameFormatter; you don't need a new Builder for each PersonNameFormatter.
         * @return A new PersonNameFormatter.
         * @stable ICU 73
         */
        public PersonNameFormatter build() {
            return new PersonNameFormatter(locale, length, usage, formality, displayOrder, surnameAllCaps);
        }

        private Builder() {
       }

        private Locale locale = Locale.getDefault();
        private Length length = Length.DEFAULT;
        private Usage usage = Usage.REFERRING;
        private Formality formality = Formality.DEFAULT;
        private DisplayOrder displayOrder = DisplayOrder.DEFAULT;
        private boolean surnameAllCaps = false;
    }

    //==============================================================================
    // Public API on PersonNameFormatter

    /**
     * Returns a Builder object that can be used to construct a new PersonNameFormatter.
     * @return A new Builder.
     * @stable ICU 73
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Returns a Builder object whose fields match those used to construct this formatter,
     * allowing a new formatter to be created based on this one.
     * @return A new Builder that can be used to create a new formatter based on this formatter.
     * @stable ICU 73
     */
    public Builder toBuilder() {
        Builder builder = builder();
        builder.setLocale(impl.getLocale());
        builder.setLength(impl.getLength());
        builder.setUsage(impl.getUsage());
        builder.setFormality(impl.getFormality());
        builder.setDisplayOrder(impl.getDisplayOrder());
        builder.setSurnameAllCaps(impl.getSurnameAllCaps());
        return builder;
    }

    /**
     * Formats a name.
     * @param name A PersonName object that supplies individual field values (optionally, with modifiers applied)
     *             to the formatter for formatting.
     * @return The name, formatted according to the locale and other parameters passed to the formatter's constructor.
     * @stable ICU 73
     */
    public String formatToString(PersonName name) {
        // TODO: Add a format() method that returns a FormattedPersonName object that descends from FormattedValue.
        return impl.formatToString(name);
    }

    //==============================================================================
    // Internal implementation
    private PersonNameFormatter(Locale locale, Length length, Usage usage, Formality formality, DisplayOrder displayOrder, boolean surnameAllCaps) {
        this.impl = new PersonNameFormatterImpl(locale, length, usage, formality, displayOrder, surnameAllCaps);
    }

    /**
     * @internal For unit testing only!
     * @deprecated This API is for unit testing only.
     */
    @Deprecated
    public PersonNameFormatter(Locale locale, String[] gnFirstPatterns, String[] snFirstPatterns, String[] gnFirstLocales, String[] snFirstLocales) {
        this.impl = new PersonNameFormatterImpl(locale, gnFirstPatterns, snFirstPatterns, gnFirstLocales, snFirstLocales);
    }

    /**
     * @internal For debugging only!
     * @deprecated This API is for debugging only.
     */
    @Override
    @Deprecated
    public String toString() {
        return impl.toString();
    }
}