From: Rich Gillam Date: Sun, 26 Feb 2023 00:06:28 +0000 (-0800) Subject: ICU-22287 Move PersonName/PersonNameFormatter API from Tech Preview to @draft X-Git-Tag: cldr/2023-03-13~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=797a01ee2baec8f97f747016092142cad58f241d;p=icu ICU-22287 Move PersonName/PersonNameFormatter API from Tech Preview to @draft --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/personname/PersonNameFormatterImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/personname/PersonNameFormatterImpl.java index 31f7c4b2fc3..6fb20620036 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/personname/PersonNameFormatterImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/personname/PersonNameFormatterImpl.java @@ -36,30 +36,26 @@ public class PersonNameFormatterImpl { private final PersonNameFormatter.Length length; private final PersonNameFormatter.Usage usage; private final PersonNameFormatter.Formality formality; - private final Set options; + private final PersonNameFormatter.DisplayOrder displayOrder; public PersonNameFormatterImpl(Locale locale, PersonNameFormatter.Length length, PersonNameFormatter.Usage usage, PersonNameFormatter.Formality formality, - Set options) { - // null for `options` is the same as the empty set - if (options == null) { - options = new HashSet<>(); - } - + PersonNameFormatter.DisplayOrder displayOrder, + boolean surnameAllCaps) { // save off our creation parameters (these are only used if we have to create a second formatter) this.length = length; this.usage = usage; this.formality = formality; - this.options = options; + this.displayOrder = displayOrder; + this.capitalizeSurname = surnameAllCaps; // load simple property values from the resource bundle (or the options set) ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale); this.locale = locale; this.initialPattern = rb.getStringWithFallback("personNames/initialPattern/initial"); this.initialSequencePattern = rb.getStringWithFallback("personNames/initialPattern/initialSequence"); - this.capitalizeSurname = options.contains(PersonNameFormatter.Options.SURNAME_ALLCAPS); this.foreignSpaceReplacement = rb.getStringWithFallback("personNames/foreignSpaceReplacement"); this.formatterLocaleUsesSpaces = !LOCALES_THAT_DONT_USE_SPACES.contains(locale.getLanguage()); @@ -67,8 +63,8 @@ public class PersonNameFormatterImpl { if (usage == PersonNameFormatter.Usage.MONOGRAM) { // we don't support SORTING in conjunction with MONOGRAM; if the caller passes in SORTING, remove it from // the options list - options.remove(PersonNameFormatter.Options.SORTING); - } else if (options.contains(PersonNameFormatter.Options.SORTING)) { + displayOrder = PersonNameFormatter.DisplayOrder.DEFAULT; + } else if (displayOrder == PersonNameFormatter.DisplayOrder.SORTING) { // we only support SORTING in conjunction with REFERRING; if the caller passes in ADDRESSING, treat it // the same as REFERRING usage = PersonNameFormatter.Usage.REFERRING; @@ -80,7 +76,7 @@ public class PersonNameFormatterImpl { final String RESOURCE_PATH_PREFIX = "personNames/namePattern/"; String resourceNameBody = length.toString().toLowerCase() + "-" + usage.toString().toLowerCase() + "-" + formality.toString().toLowerCase(); - if (!options.contains(PersonNameFormatter.Options.SORTING)) { + if (displayOrder == PersonNameFormatter.DisplayOrder.DEFAULT) { ICUResourceBundle gnFirstResource = rb.getWithFallback(RESOURCE_PATH_PREFIX + "givenFirst-" + resourceNameBody); ICUResourceBundle snFirstResource = rb.getWithFallback(RESOURCE_PATH_PREFIX + "surnameFirst-" + resourceNameBody); @@ -112,7 +108,7 @@ public class PersonNameFormatterImpl { length = PersonNameFormatter.Length.MEDIUM; usage = PersonNameFormatter.Usage.REFERRING; formality = PersonNameFormatter.Formality.FORMAL; - options = Collections.emptySet(); + displayOrder = PersonNameFormatter.DisplayOrder.DEFAULT; initialPattern = "{0}."; initialSequencePattern = "{0} {1}"; capitalizeSurname = false; @@ -134,7 +130,7 @@ public class PersonNameFormatterImpl { boolean nameLocaleUsesSpaces = !LOCALES_THAT_DONT_USE_SPACES.contains(nameLocale.getLanguage()); if (!formatterLocaleUsesSpaces && nameLocaleUsesSpaces) { PersonNameFormatterImpl nativeFormatter = new PersonNameFormatterImpl(nameLocale, this.length, - this.usage, this.formality, this.options); + this.usage, this.formality, this.displayOrder, this.capitalizeSurname); String result = nativeFormatter.formatToString(name); // BUT, if the name is actually written in the formatter locale's script, replace any spaces in the name @@ -164,7 +160,8 @@ public class PersonNameFormatterImpl { public PersonNameFormatter.Formality getFormality() { return formality; } - public Set getOptions() { return options; } + public PersonNameFormatter.DisplayOrder getDisplayOrder() { return displayOrder; } + public boolean getSurnameAllCaps() { return capitalizeSurname; } public String getInitialPattern() { return initialPattern; @@ -204,16 +201,10 @@ public class PersonNameFormatterImpl { */ private boolean nameIsGnFirst(PersonName name) { // the name can declare its order-- check that first (it overrides any locale-based calculation) - Set modifiers = new HashSet<>(); - String preferredOrder = name.getFieldValue(PersonName.NameField.PREFERRED_ORDER, modifiers); - if (preferredOrder != null) { - if (preferredOrder.equals("givenFirst")) { - return true; - } else if (preferredOrder.equals("surnameFirst")) { - return false; - } else { - throw new IllegalArgumentException("Illegal preferredOrder value " + preferredOrder); - } + if (name.getPreferredOrder() == PersonName.PreferredOrder.GIVEN_FIRST) { + return true; + } else if (name.getPreferredOrder() == PersonName.PreferredOrder.SURNAME_FIRST) { + return false; } String localeStr = getNameLocale(name).toString(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/PersonName.java b/icu4j/main/classes/core/src/com/ibm/icu/text/PersonName.java index d5443c3cff8..a725443c119 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/PersonName.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/PersonName.java @@ -13,95 +13,65 @@ import java.util.Set; * above. A concrete SimplePersonName object that does store the field values directly * is provided. * - * @internal ICU 72 technology preview + * @draft ICU 73 * @see SimplePersonName - * @deprecated This API is for technology preview only. */ -@Deprecated public interface PersonName { //============================================================================== // Identifiers used to request field values from the PersonName object /** * Identifiers for the name fields supported by the PersonName object. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated enum NameField { /** * Contains titles such as "Mr.", "Dr." (in English these typically * precede the name) - * @internal ICU 73 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated TITLE("title"), /** * The given name. May contain more than one token. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated GIVEN("given"), /** * Additional given names. (In English, this is usually the "middle name" and * may contain more than one word.) - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated GIVEN2("given2"), /** * The surname. In Spanish, this is the patronymic surname. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated SURNAME("surname"), /** * Additional surnames. This is only used in a few languages, such as Spanish, * where it is the matronymic surname. (In most languages, multiple surnames all * just go in the SURNAME field.) - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated SURNAME2("surname2"), /** * Generational qualifiers that in English generally follow the actual name, * such as "Jr." or "III". - * @internal ICU 73 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated GENERATION("generation"), /** * Professional qualifiers that in English generally follow the actual name, * such as "M.D." or "J.D.". - * @internal ICU 73 technology preview - * @deprecated This API is for technology preview only. - */ - @Deprecated - CREDENTIALS("credentials"), - - /** - * The preferred field order for the name. PersonName objects generally shouldn't provide - * this field, allowing the PersonNameFormatter to deduce the proper field order based on - * the locales of the name of the formatter. But this can be used to force a particular - * field order, generally in cases where the deduction logic in PersonNameFormatter would - * guess wrong. When used, the only valid values are "givenFirst" and "surnameFirst". - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated - PREFERRED_ORDER("preferredOrder"); + CREDENTIALS("credentials"); private final String name; @@ -111,10 +81,8 @@ public interface PersonName { /** * Returns the NameField's display name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated @Override public String toString() { return name; @@ -138,20 +106,16 @@ public interface PersonName { /** * Identifiers for the name field modifiers supported by the PersonName and PersonNameFormatter objects. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated enum FieldModifier { /** * Requests an "informal" variant of the field, generally a nickname of some type: * if "given" is "James", "given-informal" might be "Jimmy". Only applied to the "given" * field. If the PersonName object doesn't apply this modifier, PersonNameFormatter just * uses the unmodified version of "given". - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated INFORMAL("informal"), /** @@ -159,10 +123,8 @@ public interface PersonName { * "van den Hul", this requests just the prefixes ("van den"). Only applied to the "surname" * field. If the PersonName object doesn't apply this modifier, PersonNameFormatter * assumes there are no prefixes. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated PREFIX("prefix"), /** @@ -170,20 +132,16 @@ public interface PersonName { * "van den Hul", this requests just the main word ("Hul"). Only applied to the "surname" * field. If the implementing class doesn't apply this modifier, PersonNameFormatter * assumes the entire "surname" field is the "core". - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated CORE("core"), /** * Requests an initial for the specified field. PersonNameFormatter will do * this algorithmically, but a PersonName object can apply this modifier itself if it wants * different initial-generation logic (or stores the initial separately). - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated INITIAL("initial"), /** @@ -191,29 +149,23 @@ public interface PersonName { * (this usually differs from "initial" in that "initial" often adds a period and "monogram" * never does). PersonNameFormatter will do this algorithmically, but a PersonName object can * apply this modifier itself if it wants different monogram-generation logic. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated MONOGRAM("monogram"), /** * Requests the field value converted to ALL CAPS. PersonName objects * generally won't need to handle this modifier themselves. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated ALL_CAPS("allCaps"), /** * Requests the field value with the first grapheme of each word converted to titlecase. * A PersonName object might handle this modifier itself to capitalize words more * selectively. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated INITIAL_CAP("initialCap"); private final String name; @@ -224,10 +176,8 @@ public interface PersonName { /** * Returns the FieldModifier's display name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated @Override public String toString() { return name; @@ -235,10 +185,8 @@ public interface PersonName { /** * Returns the appropriate fieldModifier for its display name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public static FieldModifier forString(String name) { for (FieldModifier modifier : values()) { if (modifier.name.equals(name)) { @@ -249,6 +197,31 @@ public interface PersonName { } } + /** + * An enum to specify the preferred field order for the name. + * @defat ICU 73 + */ + enum PreferredOrder { + /** + * Indicates the name has no preferred field order, and that the formatter should deduce the + * proper field order based on the locales of the name and the formatter. + */ + DEFAULT, + + /** + * Indicates that the name should be formatted in given-first order, even when the formatter + * would normally guess that it should be formatted in surname-first order. + * @draft ICU 73 + */ + GIVEN_FIRST, + + /** + * Indicates that the name should be formatted in surname-first order, even when the formatter + * would normally guess that it should be formatted in given-first order. + */ + SURNAME_FIRST + } + //============================================================================== // Public API on PersonName /** @@ -256,12 +229,20 @@ public interface PersonName { * An implementing class is allowed to return null here to indicate the name's locale is unknown. * * @return The name's locale, or null if it's not known. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Locale getNameLocale(); + /** + * Returns the preferred field order for the name. PersonName objects should generally return DEFAULT, + * allowing the PersonNameFormatter to deduce the peoper field order based on the locales of the name + * and the formatter. But this can be used to force a particular field order, generally in cases + * where the deduction logic in PersonNameFormatter would guess wrong. + * @return The name's preferred field order. + * @draft ICU 73 + */ + public PreferredOrder getPreferredOrder(); + /** * Returns one field of the name, possibly in a modified form. * @@ -272,9 +253,7 @@ public interface PersonName { * DIDN'T handle. This parameter may not be null, and must either be mutable or empty. * @return The value of the requested field, optionally modified by some or all of the requested modifiers, or * null if the requested field isn't present in the name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public String getFieldValue(NameField identifier, Set modifiers); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/PersonNameFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/text/PersonNameFormatter.java index a45b7e2dccb..8cd0a5e1fc8 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/PersonNameFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/PersonNameFormatter.java @@ -65,69 +65,53 @@ import com.ibm.icu.impl.personname.PersonNameFormatterImpl; * * * - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ -@Deprecated public class PersonNameFormatter { //============================================================================== // Parameters that control formatting behavior /** * Specifies the desired length of the formatted name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public enum Length { /** * The longest name length. Generally uses most of the fields in the name object. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated LONG, /** * The most typical name length. Generally includes the given name and surname, but generally * not most of the other fields. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated 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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated SHORT } /** * Specifies the intended usage of the formatted name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public enum Usage { /** * Used for when the name is going to be used to address the user directly: "Turn left here, John." - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated ADDRESSING, /** * Used in general cases, when the name is used to refer to somebody else. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated REFERRING, /** @@ -135,63 +119,48 @@ public class PersonNameFormatter { * 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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated MONOGRAM } /** * Specifies the intended formality of the formatted name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public enum Formality { /** * The more formal version of the name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated FORMAL, /** * The more informal version of the name. In English, this might omit fields or use the "informal" variant * of the given name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated INFORMAL } /** - * Additional options to customize the behavior of the formatter. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * An enum indicating the desired display order for a formatted name. + * @draft ICU 73 */ - @Deprecated - public enum Options { + public enum DisplayOrder { /** - * Causes the formatter to generate results suitable for inclusion in a sorted list. For GN-first languages, - * this generally means moving the surname to the beginning of the string, with a comma between it and - * the rest of the name: e.g., "Carter, James E. Jr.". - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * The default display order; used to indicate normal formatting. + * @draft ICU 73 */ - @Deprecated - SORTING, + DEFAULT, /** - * 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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * 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". + * @draft ICU 73 */ - @Deprecated - SURNAME_ALLCAPS + SORTING } private final PersonNameFormatterImpl impl; @@ -202,19 +171,15 @@ public class PersonNameFormatter { /** * A utility class that can be used to construct a PersonNameFormatter. * Use PersonNameFormatter.builder() to get a new instance. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated 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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder setLocale(Locale locale) { if (locale != null) { this.locale = locale; @@ -226,10 +191,8 @@ public class PersonNameFormatter { * Sets the name length for the formatter to be constructed. * @param length The new name length. * @return This builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder setLength(Length length) { this.length = length; return this; @@ -239,10 +202,8 @@ public class PersonNameFormatter { * Sets the name usage for the formatter to be constructed. * @param usage The new name length. * @return This builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder setUsage(Usage usage) { this.usage = usage; return this; @@ -252,27 +213,36 @@ public class PersonNameFormatter { * Sets the name formality for the formatter to be constructed. * @param formality The new name length. * @return This builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder setFormality(Formality formality) { this.formality = formality; return this; } /** - * Sets the options set for the formatter to be constructed. The Set passed in - * here replaces the entire options set the builder already has (if one has - * already been set); this method doesn't modify the builder's options set. - * @param options The new options set. + * 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. + * @draft 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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated - public Builder setOptions(Set options) { - this.options = options; + public Builder setSurnameAllCaps(boolean allCaps) { + this.surnameAllCaps = allCaps; return this; } @@ -282,12 +252,10 @@ public class PersonNameFormatter { * (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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public PersonNameFormatter build() { - return new PersonNameFormatter(locale, length, usage, formality, options); + return new PersonNameFormatter(locale, length, usage, formality, displayOrder, surnameAllCaps); } private Builder() { @@ -297,7 +265,8 @@ public class PersonNameFormatter { private Length length = Length.MEDIUM; private Usage usage = Usage.REFERRING; private Formality formality = Formality.FORMAL; - private Set options = new HashSet<>(); + private DisplayOrder displayOrder = DisplayOrder.DEFAULT; + private boolean surnameAllCaps = false; } //============================================================================== @@ -306,10 +275,8 @@ public class PersonNameFormatter { /** * Returns a Builder object that can be used to construct a new PersonNameFormatter. * @return A new Builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public static Builder builder() { return new Builder(); } @@ -318,17 +285,16 @@ public class PersonNameFormatter { * 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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder toBuilder() { Builder builder = builder(); builder.setLocale(impl.getLocale()); builder.setLength(impl.getLength()); builder.setUsage(impl.getUsage()); builder.setFormality(impl.getFormality()); - builder.setOptions(impl.getOptions()); + builder.setDisplayOrder(impl.getDisplayOrder()); + builder.setSurnameAllCaps(impl.getSurnameAllCaps()); return builder; } @@ -337,10 +303,8 @@ public class PersonNameFormatter { * @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. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public String formatToString(PersonName name) { // TODO: Add a format() method that returns a FormattedPersonName object that descends from FormattedValue. return impl.formatToString(name); @@ -348,8 +312,8 @@ public class PersonNameFormatter { //============================================================================== // Internal implementation - private PersonNameFormatter(Locale locale, Length length, Usage usage, Formality formality, Set options) { - this.impl = new PersonNameFormatterImpl(locale, length, usage, formality, options); + private PersonNameFormatter(Locale locale, Length length, Usage usage, Formality formality, DisplayOrder displayOrder, boolean surnameAllCaps) { + this.impl = new PersonNameFormatterImpl(locale, length, usage, formality, displayOrder, surnameAllCaps); } /** diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/SimplePersonName.java b/icu4j/main/classes/core/src/com/ibm/icu/text/SimplePersonName.java index dba2fc010d8..f1139da8a93 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/SimplePersonName.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/SimplePersonName.java @@ -18,33 +18,38 @@ import java.util.TreeSet; * A caller can store both raw field values (such as "given") and modified field values (such as "given-informal") * in a SimplePersonName. But beyond storing and returning modified field values provided to it by the caller, * SimplePersonName relies on the PersonNameFormatter's default handling of field modifiers. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ -@Deprecated public class SimplePersonName implements PersonName { /** * A utility class for constructing a SimplePersonName. Use SimplePersonName.builder() * to get a new Builder instance. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public static class Builder { /** * Set the locale for the new name object. * @param locale The locale for the new name object. Can be null, which indicates the * name's locale is unknown. * @return This builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder setLocale(Locale locale) { this.locale = locale; return this; } + /** + * Set the preferred order for the new name object. + * @param preferredOrder The preferred order for the new name object. + * @return This builder. + * @draft ICU 73 + */ + public Builder setPreferredOrder(PreferredOrder preferredOrder) { + this.preferredOrder = preferredOrder; + return this; + } + /** * Sets the value for one field (with optional modifiers) in the new name object. * @param field A NameField object specifying the field to set. @@ -52,10 +57,8 @@ public class SimplePersonName implements PersonName { * to this field value. May be null, which is the same as the empty set. * @param value The value for this field. * @return This builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public Builder addField(NameField field, Collection modifiers, String value) { @@ -83,10 +86,8 @@ public class SimplePersonName implements PersonName { /** * Returns a SimplePersonName with the field values and name locale that were passed to this builder. * @return A SimplePersonName with the field values and name locale that were passed to this builder. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public SimplePersonName build() { // special-case code for the "surname" field -- if it isn't specified, but "surname-prefix" and // "surname-core" both are, let "surname" be the other two fields joined with a space @@ -98,25 +99,25 @@ public class SimplePersonName implements PersonName { } } - return new SimplePersonName(locale, fieldValues); + return new SimplePersonName(locale, preferredOrder, fieldValues); } private Builder() { locale = null; + preferredOrder = PreferredOrder.DEFAULT; fieldValues = new HashMap<>(); } private Locale locale; + private PreferredOrder preferredOrder; private Map fieldValues; } /** * Returns a Builder object that can be used to construct a new SimplePersonName object. * @return A Builder object that can be used to construct a new SimplePersonName object. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ - @Deprecated public static Builder builder() { return new Builder(); } @@ -124,23 +125,32 @@ public class SimplePersonName implements PersonName { /** * Internal constructor used by the Builder object. */ - private SimplePersonName(Locale nameLocale, Map fieldValues) { + private SimplePersonName(Locale nameLocale, PreferredOrder preferredOrder, Map fieldValues) { this.nameLocale = nameLocale; + this.preferredOrder = preferredOrder; this.fieldValues = new HashMap<>(fieldValues); } /** * Returns the locale of the name-- that is, the language or country of origin for the person being named. * @return The name's locale, or null if it's unknown. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ @Override - @Deprecated public Locale getNameLocale() { return nameLocale; } + /** + * Returns the preferred field order for the name. This will be DEFAULT, unless the caller sets it to something + * else using the builder. + * @return The name's preferred field order. + * @draft ICU 73 + * @return + */ + @Override + public PreferredOrder getPreferredOrder() { return preferredOrder; } + /** * Returns one field of the name, possibly in a modified form. This class can store modified versions of fields, * provided at construction time, and this function will return them. Otherwise, it ignores modifiers and @@ -152,11 +162,9 @@ public class SimplePersonName implements PersonName { * was provided at construction time. * @return The value of the requested field, optionally modified by some or all of the requested modifiers, or * null if the requested field isn't present in the name. - * @internal ICU 72 technology preview - * @deprecated This API is for technology preview only. + * @draft ICU 73 */ @Override - @Deprecated public String getFieldValue(NameField nameField, Set modifiers) { // first look for the fully modified name in the internal table String fieldName = nameField.toString(); @@ -221,5 +229,6 @@ public class SimplePersonName implements PersonName { } private final Locale nameLocale; + private final PreferredOrder preferredOrder; private final Map fieldValues; } \ No newline at end of file diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PersonNameFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PersonNameFormatterTest.java index fcce48d780c..d4ce68ab9b0 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PersonNameFormatterTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PersonNameFormatterTest.java @@ -46,6 +46,12 @@ public class PersonNameFormatterTest extends TestFmwk{ // cheating here, because java.util.Locale doesn't have a constructor that parses an ICU-style // locale ID builder.setLocale(Locale.forLanguageTag(fieldValue.replace("_", "-"))); + } else if (fieldName.equals("preferredOrder")) { + if (fieldValue.equals("givenFirst")) { + builder.setPreferredOrder(PersonName.PreferredOrder.GIVEN_FIRST); + } else if (fieldValue.equals("surnameFirst")) { + builder.setPreferredOrder(PersonName.PreferredOrder.SURNAME_FIRST); + } } else if (fieldName.indexOf('-') < 0) { builder.addField(PersonName.NameField.forString(fieldName), null, fieldValue); } else { @@ -73,15 +79,17 @@ public class PersonNameFormatterTest extends TestFmwk{ PersonNameFormatter.Length formatterLength = PersonNameFormatter.Length.valueOf(testCase[1]); PersonNameFormatter.Usage formatterUsage = PersonNameFormatter.Usage.valueOf(testCase[2]); PersonNameFormatter.Formality formatterFormality = PersonNameFormatter.Formality.valueOf(testCase[3]); - Set formatterOptions = makeOptionsSet(testCase[4]); - String expectedResult = testCase[5]; + PersonNameFormatter.DisplayOrder formatterDisplayOrder = PersonNameFormatter.DisplayOrder.valueOf(testCase[4]); + boolean surnameAllCaps = testCase[5].equals("SURNAME_ALLCAPS"); + String expectedResult = testCase[6]; PersonNameFormatter formatter = PersonNameFormatter.builder().setLocale(formatterLocale).setLength(formatterLength). - setUsage(formatterUsage).setFormality(formatterFormality).setOptions(formatterOptions).build(); + setUsage(formatterUsage).setFormality(formatterFormality).setDisplayOrder(formatterDisplayOrder). + setSurnameAllCaps(surnameAllCaps).build(); String actualResult = formatter.formatToString(name); if (forDebugging) { - System.out.println(" " + formatterLocale + "," + formatterLength + "," + formatterUsage + "," + formatterFormality + "," + formatterOptions + " => " + actualResult); + System.out.println(" " + formatterLocale + "," + formatterLength + "," + formatterUsage + "," + formatterFormality + "," + formatterDisplayOrder + "," + surnameAllCaps + " => " + actualResult); } else { assertEquals("Wrong formatting result for " + nameAndTestCases.nameFields + "," + Arrays.toString(testCase), expectedResult, actualResult); } @@ -89,71 +97,60 @@ public class PersonNameFormatterTest extends TestFmwk{ } } - private static Set makeOptionsSet(String optionsStr) { - Set result = new HashSet<>(); - StringTokenizer tok = new StringTokenizer(optionsStr, ","); - while (tok.hasMoreTokens()) { - String optionStr = tok.nextToken(); - PersonNameFormatter.Options option = PersonNameFormatter.Options.valueOf(optionStr); - result.add(option); - } - return result; - } - @Test public void TestEnglishName() { executeTestCases(new NameAndTestCases[]{ new NameAndTestCases("locale=en_US,title=Mr.,given=Richard,given-informal=Rich,given2=Theodore,surname=Gillam", new String[][] { // test all the different combinations of parameters with the normal name order - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Mr. Richard Theodore Gillam" }, - { "en_US", "LONG", "REFERRING", "INFORMAL", "", "Rich Gillam" }, - { "en_US", "LONG", "ADDRESSING", "FORMAL", "", "Mr. Gillam" }, - { "en_US", "LONG", "ADDRESSING", "INFORMAL", "", "Rich" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "", "Richard T. Gillam" }, - { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "", "Rich Gillam" }, - { "en_US", "MEDIUM", "ADDRESSING", "FORMAL", "", "Mr. Gillam" }, - { "en_US", "MEDIUM", "ADDRESSING", "INFORMAL", "", "Rich" }, - //{ "en_US", "SHORT", "REFERRING", "FORMAL", "", "R. T. Gillam" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "", "R.T. Gillam" }, // result changed with CLDR 43-alpha1 - { "en_US", "SHORT", "REFERRING", "INFORMAL", "", "Rich G." }, - { "en_US", "SHORT", "ADDRESSING", "FORMAL", "", "Mr. Gillam" }, - { "en_US", "SHORT", "ADDRESSING", "INFORMAL", "", "Rich" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Mr. Richard Theodore Gillam" }, + { "en_US", "LONG", "REFERRING", "INFORMAL", "DEFAULT", "", "Rich Gillam" }, + { "en_US", "LONG", "ADDRESSING", "FORMAL", "DEFAULT", "", "Mr. Gillam" }, + { "en_US", "LONG", "ADDRESSING", "INFORMAL", "DEFAULT", "", "Rich" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "DEFAULT", "", "Richard T. Gillam" }, + { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "DEFAULT", "", "Rich Gillam" }, + { "en_US", "MEDIUM", "ADDRESSING", "FORMAL", "DEFAULT", "", "Mr. Gillam" }, + { "en_US", "MEDIUM", "ADDRESSING", "INFORMAL", "DEFAULT", "", "Rich" }, + //{ "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "R. T. Gillam" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "R.T. Gillam" }, // result changed with CLDR 43-alpha1 + { "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "Rich G." }, + { "en_US", "SHORT", "ADDRESSING", "FORMAL", "DEFAULT", "", "Mr. Gillam" }, + { "en_US", "SHORT", "ADDRESSING", "INFORMAL", "DEFAULT", "", "Rich" }, // test all the different combinations of parameters for "sorting" order - { "en_US", "LONG", "REFERRING", "FORMAL", "SORTING", "Gillam, Richard Theodore" }, - { "en_US", "LONG", "REFERRING", "INFORMAL", "SORTING", "Gillam, Rich" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "SORTING", "Gillam, Richard T." }, - { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "SORTING", "Gillam, Rich" }, - //{ "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "Gillam, R. T." }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "Gillam, R.T." }, // result changed with CLDR 43-alpha1 - { "en_US", "SHORT", "REFERRING", "INFORMAL", "SORTING", "Gillam, Rich" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "SORTING", "", "Gillam, Richard Theodore" }, + { "en_US", "LONG", "REFERRING", "INFORMAL", "SORTING", "", "Gillam, Rich" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "SORTING", "", "Gillam, Richard T." }, + { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "SORTING", "", "Gillam, Rich" }, + //{ "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "", "Gillam, R. T." }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "", "Gillam, R.T." }, // result changed with CLDR 43-alpha1 + { "en_US", "SHORT", "REFERRING", "INFORMAL", "SORTING", "", "Gillam, Rich" }, // we don't really support ADDRESSING in conjunction with SORTING-- it should always // do the same thing as REFERRING - { "en_US", "LONG", "ADDRESSING", "FORMAL", "SORTING", "Gillam, Richard Theodore" }, - { "en_US", "LONG", "ADDRESSING", "INFORMAL", "SORTING", "Gillam, Rich" }, - { "en_US", "MEDIUM", "ADDRESSING", "FORMAL", "SORTING", "Gillam, Richard T." }, - { "en_US", "MEDIUM", "ADDRESSING", "INFORMAL", "SORTING", "Gillam, Rich" }, - //{ "en_US", "SHORT", "ADDRESSING", "FORMAL", "SORTING", "Gillam, R. T." }, - { "en_US", "SHORT", "ADDRESSING", "FORMAL", "SORTING", "Gillam, R.T." }, // result changed with CLDR 43-alpha1 - { "en_US", "SHORT", "ADDRESSING", "INFORMAL", "SORTING", "Gillam, Rich" }, + { "en_US", "LONG", "ADDRESSING", "FORMAL", "SORTING", "", "Gillam, Richard Theodore" }, + { "en_US", "LONG", "ADDRESSING", "INFORMAL", "SORTING", "", "Gillam, Rich" }, + { "en_US", "MEDIUM", "ADDRESSING", "FORMAL", "SORTING", "", "Gillam, Richard T." }, + { "en_US", "MEDIUM", "ADDRESSING", "INFORMAL", "SORTING", "", "Gillam, Rich" }, + //{ "en_US", "SHORT", "ADDRESSING", "FORMAL", "SORTING", "", "Gillam, R. T." }, + { "en_US", "SHORT", "ADDRESSING", "FORMAL", "SORTING", "", "Gillam, R.T." }, // result changed with CLDR 43-alpha1 + { "en_US", "SHORT", "ADDRESSING", "INFORMAL", "SORTING", "", "Gillam, Rich" }, // finally, try the different variations of MONOGRAM - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "RTG" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "RG" }, - { "en_US", "MEDIUM", "MONOGRAM", "FORMAL", "", "G" }, - { "en_US", "MEDIUM", "MONOGRAM", "INFORMAL", "", "R" }, - { "en_US", "SHORT", "MONOGRAM", "FORMAL", "", "G" }, - { "en_US", "SHORT", "MONOGRAM", "INFORMAL", "", "R" }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "RTG" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "RG" }, + { "en_US", "MEDIUM", "MONOGRAM", "FORMAL", "DEFAULT", "", "G" }, + { "en_US", "MEDIUM", "MONOGRAM", "INFORMAL", "DEFAULT", "", "R" }, + { "en_US", "SHORT", "MONOGRAM", "FORMAL", "DEFAULT", "", "G" }, + { "en_US", "SHORT", "MONOGRAM", "INFORMAL", "DEFAULT", "", "R" }, // and again, we don't support SORTING for monograms, so it should also do the // same thing as GIVEN_FIRST - { "en_US", "LONG", "MONOGRAM", "FORMAL", "SORTING", "RTG" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "SORTING", "RG" }, - { "en_US", "MEDIUM", "MONOGRAM", "FORMAL", "SORTING", "G" }, - { "en_US", "MEDIUM", "MONOGRAM", "INFORMAL", "SORTING", "R" }, - { "en_US", "SHORT", "MONOGRAM", "FORMAL", "SORTING", "G" }, - { "en_US", "SHORT", "MONOGRAM", "INFORMAL", "SORTING", "R" }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "SORTING", "", "RTG" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "SORTING", "", "RG" }, + { "en_US", "MEDIUM", "MONOGRAM", "FORMAL", "SORTING", "", "G" }, + { "en_US", "MEDIUM", "MONOGRAM", "INFORMAL", "SORTING", "", "R" }, + { "en_US", "SHORT", "MONOGRAM", "FORMAL", "SORTING", "", "G" }, + { "en_US", "SHORT", "MONOGRAM", "INFORMAL", "SORTING", "", "R" }, }) }, false); } @@ -163,63 +160,63 @@ public class PersonNameFormatterTest extends TestFmwk{ executeTestCases(new NameAndTestCases[]{ new NameAndTestCases("locale=en_US,given=Willem,surname-prefix=van der,surname-core=Plas", new String[][] { // for normal formatting, the {surname} field is just "{surname-prefix} {surname-core}" - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Willem van der Plas" }, - { "en_US", "LONG", "REFERRING", "INFORMAL", "", "Willem van der Plas" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "", "Willem van der Plas" }, - { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "", "Willem van der Plas" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "", "W. van der Plas" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Willem van der Plas" }, + { "en_US", "LONG", "REFERRING", "INFORMAL", "DEFAULT", "", "Willem van der Plas" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "DEFAULT", "", "Willem van der Plas" }, + { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "DEFAULT", "", "Willem van der Plas" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "W. van der Plas" }, // for FORMAL SORTING, we sort by "surname-core", with "surname-prefix" at the end - { "en_US", "LONG", "REFERRING", "FORMAL", "SORTING", "Plas, Willem van der" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "SORTING", "Plas, Willem van der" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "Plas, W. van der" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "SORTING", "", "Plas, Willem van der" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "SORTING", "", "Plas, Willem van der" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "", "Plas, W. van der" }, // but for INFORMAL SORTING, we keep the surname together and sort by the prefix - { "en_US", "LONG", "REFERRING", "INFORMAL", "SORTING", "van der Plas, Willem" }, - { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "SORTING", "van der Plas, Willem" }, - { "en_US", "SHORT", "REFERRING", "INFORMAL", "SORTING", "van der Plas, Willem" }, + { "en_US", "LONG", "REFERRING", "INFORMAL", "SORTING", "", "van der Plas, Willem" }, + { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "SORTING", "", "van der Plas, Willem" }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "SORTING", "", "van der Plas, Willem" }, // the default (English) logic for initials doesn't do anything special with the surname-prefix-- // it gets initials too, which is probably wrong - //{ "en_US", "SHORT", "REFERRING", "INFORMAL", "", "Willem v. d. P." }, - { "en_US", "SHORT", "REFERRING", "INFORMAL", "", "Willem v.d.P." }, // result changed with CLDR 43-alpha1 + //{ "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "Willem v. d. P." }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "Willem v.d.P." }, // result changed with CLDR 43-alpha1 // and (English) monogram generation doesn't do anything special with the prefix either - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "WV" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "WV" }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "WV" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "WV" }, // but Dutch monogram generation _does_ handle the prefix specially - { "nl_NL", "LONG", "MONOGRAM", "FORMAL", "", "WvP" }, - { "nl_NL", "LONG", "MONOGRAM", "INFORMAL", "", "WvP" }, + { "nl_NL", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "WvP" }, + { "nl_NL", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "WvP" }, }), new NameAndTestCases("locale=en_US,given=Willem,surname=van der Plas", new String[][] { // if we just use the "surname" field instead of "surname-prefix" and "surname-core", everything's // the same, except (obviously) for the cases where we were doing something special with the // prefix and core - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Willem van der Plas" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "", "W. van der Plas" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Willem van der Plas" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "W. van der Plas" }, // for example, SORTING works the same way regardless of formality - { "en_US", "LONG", "REFERRING", "FORMAL", "SORTING", "van der Plas, Willem" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "SORTING", "van der Plas, Willem" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "van der Plas, W." }, - { "en_US", "LONG", "REFERRING", "INFORMAL", "SORTING", "van der Plas, Willem" }, - { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "SORTING", "van der Plas, Willem" }, - { "en_US", "SHORT", "REFERRING", "INFORMAL", "SORTING", "van der Plas, Willem" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "SORTING", "", "van der Plas, Willem" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "SORTING", "", "van der Plas, Willem" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "SORTING", "", "van der Plas, W." }, + { "en_US", "LONG", "REFERRING", "INFORMAL", "SORTING", "", "van der Plas, Willem" }, + { "en_US", "MEDIUM", "REFERRING", "INFORMAL", "SORTING", "", "van der Plas, Willem" }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "SORTING", "", "van der Plas, Willem" }, // and monogram generation works the same in English and Dutch - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "WV" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "WV" }, - { "nl_NL", "LONG", "MONOGRAM", "FORMAL", "", "WV" }, - { "nl_NL", "LONG", "MONOGRAM", "INFORMAL", "", "WV" }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "WV" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "WV" }, + { "nl_NL", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "WV" }, + { "nl_NL", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "WV" }, }), new NameAndTestCases("locale=en_US,given=Willem,surname-prefix=van der,surname-core=Plas,surname-initial=vdP.,surname-monogram=vdP", new String[][] { // we can work around the initial generation by providing a "surname-initial" field in the name object - { "en_US", "SHORT", "REFERRING", "INFORMAL", "", "Willem vdP." }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "Willem vdP." }, // we could also (theoretically) work around the monogram-generation problem in English in the same way - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "WVDP" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "WVDP" }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "WVDP" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "WVDP" }, }), }, false); } @@ -228,28 +225,28 @@ public class PersonNameFormatterTest extends TestFmwk{ public void TestInitialGeneration() { executeTestCases(new NameAndTestCases[]{ new NameAndTestCases("locale=en_US,given=George,given2=Herbert Walker,surname=Bush", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "George Herbert Walker Bush" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "", "George H. W. Bush" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "", "G. H. W. Bush" }, - { "en_US", "SHORT", "REFERRING", "INFORMAL", "", "George B." }, - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "GHB" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "GB" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "George Herbert Walker Bush" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "DEFAULT", "", "George H. W. Bush" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "G. H. W. Bush" }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "George B." }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "GHB" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "GB" }, }), new NameAndTestCases("locale=en_US,given=Ralph,surname=Vaughan Williams", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Ralph Vaughan Williams" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "", "Ralph Vaughan Williams" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "", "R. Vaughan Williams" }, - { "en_US", "SHORT", "REFERRING", "INFORMAL", "", "Ralph V. W." }, - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "RV" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "RV" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Ralph Vaughan Williams" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "DEFAULT", "", "Ralph Vaughan Williams" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "R. Vaughan Williams" }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "Ralph V. W." }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "RV" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "RV" }, }), new NameAndTestCases("locale=en_US,given=John Paul,given2=Stephen David George,surname=Smith", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "John Paul Stephen David George Smith" }, - { "en_US", "MEDIUM", "REFERRING", "FORMAL", "", "John Paul S. D. G. Smith" }, - { "en_US", "SHORT", "REFERRING", "FORMAL", "", "J. P. S. D. G. Smith" }, - { "en_US", "SHORT", "REFERRING", "INFORMAL", "", "John Paul S." }, - { "en_US", "LONG", "MONOGRAM", "FORMAL", "", "JSS" }, - { "en_US", "LONG", "MONOGRAM", "INFORMAL", "", "JS" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "John Paul Stephen David George Smith" }, + { "en_US", "MEDIUM", "REFERRING", "FORMAL", "DEFAULT", "", "John Paul S. D. G. Smith" }, + { "en_US", "SHORT", "REFERRING", "FORMAL", "DEFAULT", "", "J. P. S. D. G. Smith" }, + { "en_US", "SHORT", "REFERRING", "INFORMAL", "DEFAULT", "", "John Paul S." }, + { "en_US", "LONG", "MONOGRAM", "FORMAL", "DEFAULT", "", "JSS" }, + { "en_US", "LONG", "MONOGRAM", "INFORMAL", "DEFAULT", "", "JS" }, }), }, true); } @@ -260,22 +257,22 @@ public class PersonNameFormatterTest extends TestFmwk{ // literal text elision is difficult to test with the real locale data, although this is a start // perhaps we could add an API for debugging that lets us pass in real pattern strings, but I'd like to stay away from that new NameAndTestCases("locale=en_US,given=John,given2=Paul,surname=Smith,generation=Jr.", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "John Paul Smith Jr." }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "John Paul Smith Jr." }, }), new NameAndTestCases("locale=en_US,given=John,given2=Paul,surname=Smith", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "John Paul Smith" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "John Paul Smith" }, }), new NameAndTestCases("locale=en_US,given2=Paul,surname=Smith", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Paul Smith" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Paul Smith" }, }), new NameAndTestCases("locale=en_US,given2=Paul", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Paul" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Paul" }, }), new NameAndTestCases("locale=en_US,given=John", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "John" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "John" }, }), new NameAndTestCases("locale=en_US,given=John,generation=Jr.", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "John Jr." }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "John Jr." }, }), }, false); } @@ -288,12 +285,12 @@ public class PersonNameFormatterTest extends TestFmwk{ // in the right place. This test checks to make sure we're using the right pattern based on which // fields are present in the actual name new NameAndTestCases("locale=es_ES,given=Andrés,given2=Manuel,surname=López,surname2=Obrador", new String[][] { - { "es_ES", "LONG", "REFERRING", "FORMAL", "", "Andrés Manuel López" }, - { "es_ES", "LONG", "REFERRING", "FORMAL", "SORTING" , "López Obrador, Andrés Manuel" }, + { "es_ES", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Andrés Manuel López" }, + { "es_ES", "LONG", "REFERRING", "FORMAL", "SORTING", "", "López Obrador, Andrés Manuel" }, }), new NameAndTestCases("locale=es_ES,given=Andrés,given2=Manuel,surname=López", new String[][] { - { "es_ES", "LONG", "REFERRING", "FORMAL", "", "Andrés Manuel López" }, - { "es_ES", "LONG", "REFERRING", "FORMAL", "SORTING" , "López, Andrés Manuel" }, + { "es_ES", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Andrés Manuel López" }, + { "es_ES", "LONG", "REFERRING", "FORMAL", "SORTING", "", "López, Andrés Manuel" }, }), }, false); } @@ -305,23 +302,23 @@ public class PersonNameFormatterTest extends TestFmwk{ // name is English, the order is GN first. If it's Japanese, it's SN first. This is true whether the // Japanese name is written in Latin letters or Han characters new NameAndTestCases("locale=en_US,given=Shinzo,surname=Abe", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Shinzo Abe" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Shinzo Abe" }, }), new NameAndTestCases("locale=ja_JP,given=Shinzo,surname=Abe", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Abe Shinzo" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Abe Shinzo" }, }), new NameAndTestCases("locale=ja_JP,given=晋三,surname=安倍", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "安倍 晋三" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "安倍 晋三" }, }), // the name can also declare its order directly, with the optional "preferredOrder" field. If it does this, // the value of that field holds for all formatter locales and overrides determining the order // by looking at the name's locale new NameAndTestCases("locale=en_US,given=Shinzo,surname=Abe,preferredOrder=surnameFirst", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Abe Shinzo" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Abe Shinzo" }, }), new NameAndTestCases("locale=ja_JP,given=Shinzo,surname=Abe,preferredOrder=givenFirst", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Shinzo Abe" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Shinzo Abe" }, }), }, false); } @@ -332,12 +329,12 @@ public class PersonNameFormatterTest extends TestFmwk{ // the SURNAME_ALLCAPS option does just what it says: it causes the surname field // to be displayed in all caps new NameAndTestCases("locale=en_US,given=Shinzo,surname=Abe", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Shinzo Abe" }, - { "en_US", "LONG", "REFERRING", "FORMAL", "SURNAME_ALLCAPS", "Shinzo ABE" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Shinzo Abe" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "SURNAME_ALLCAPS", "Shinzo ABE" }, }), new NameAndTestCases("locale=ja_JP,given=Shinzo,surname=Abe", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Abe Shinzo" }, - { "en_US", "LONG", "REFERRING", "FORMAL", "SURNAME_ALLCAPS", "ABE Shinzo" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Abe Shinzo" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "SURNAME_ALLCAPS", "ABE Shinzo" }, }), }, false); } @@ -348,31 +345,31 @@ public class PersonNameFormatterTest extends TestFmwk{ // if the formatter locale uses spaces, the result will use its formats (complete with spaces), // regardless of locale new NameAndTestCases("locale=ja_JP,given=Hayao,surname=Miyazaki", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "Miyazaki Hayao" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Miyazaki Hayao" }, }), new NameAndTestCases("locale=ja_JP,given=駿,surname=宮崎", new String[][] { - { "en_US", "LONG", "REFERRING", "FORMAL", "", "宮崎 駿" }, + { "en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "宮崎 駿" }, }), // if the formatter locale doesn't use spaces and the name's locale doesn't either, just use // the native formatter new NameAndTestCases("locale=ja_JP,given=駿,surname=宮崎", new String[][] { - { "ja_JP", "LONG", "REFERRING", "FORMAL", "", "宮崎駿" }, - { "zh_CN", "LONG", "REFERRING", "FORMAL", "", "宮崎 駿" }, + { "ja_JP", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "宮崎駿" }, + { "zh_CN", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "宮崎 駿" }, }), // if the formatter locale doesn't use spaces and the name's locale does, use the name locale's formatter, // but if the name is still using the formatter locale's script, use the native formatter's // "foreign space replacement" character instead of spaces new NameAndTestCases("locale=en_US,given=Albert,surname=Einstein", new String[][] { - { "ja_JP", "LONG", "REFERRING", "FORMAL", "", "Albert Einstein" }, - { "zh_CN", "LONG", "REFERRING", "FORMAL", "", "Albert Einstein" }, + { "ja_JP", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Albert Einstein" }, + { "zh_CN", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Albert Einstein" }, }), new NameAndTestCases("locale=en_US,given=アルベルト,surname=アインシュタイン", new String[][] { - { "ja_JP", "LONG", "REFERRING", "FORMAL", "", "アルベルト・アインシュタイン" }, + { "ja_JP", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "アルベルト・アインシュタイン" }, }), new NameAndTestCases("locale=en_US,given=阿尔伯特,surname=爱因斯坦", new String[][] { - { "zh_CN", "LONG", "REFERRING", "FORMAL", "", "阿尔伯特·爱因斯坦" }, + { "zh_CN", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "阿尔伯特·爱因斯坦" }, }), }, false); } @@ -384,10 +381,10 @@ public class PersonNameFormatterTest extends TestFmwk{ // see the Latin letters and assume English, giving us GN-first ordering. In the // second, we see the Han characters and guess Japanese, giving us SN-first ordering. new NameAndTestCases("given=Hayao,surname=Miyazaki", new String[][]{ - {"en_US", "LONG", "REFERRING", "FORMAL", "", "Hayao Miyazaki"}, + {"en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "Hayao Miyazaki"}, }), new NameAndTestCases("given=駿,surname=宮崎", new String[][]{ - {"en_US", "LONG", "REFERRING", "FORMAL", "", "宮崎 駿"}, + {"en_US", "LONG", "REFERRING", "FORMAL", "DEFAULT", "", "宮崎 駿"}, }), }, false); }