ICU-22287 Move PersonName/PersonNameFormatter API from Tech Preview to @draft

This commit is contained in:
Rich Gillam 2023-02-25 16:06:28 -08:00 committed by Rich Gillam
parent b6dcc95d3c
commit 797a01ee2b
5 changed files with 298 additions and 358 deletions

View file

@ -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<PersonNameFormatter.Options> options;
private final PersonNameFormatter.DisplayOrder displayOrder;
public PersonNameFormatterImpl(Locale locale,
PersonNameFormatter.Length length,
PersonNameFormatter.Usage usage,
PersonNameFormatter.Formality formality,
Set<PersonNameFormatter.Options> 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<PersonNameFormatter.Options> 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<PersonName.FieldModifier> 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();

View file

@ -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.
* @draft ICU 73
*/
@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.
*/
@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<FieldModifier> modifiers);
}

View file

@ -65,69 +65,53 @@ import com.ibm.icu.impl.personname.PersonNameFormatterImpl;
* </tr>
* </table>
*
* @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.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
* @draft ICU 73
*/
@Deprecated
public Builder setOptions(Set<Options> options) {
this.options = options;
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.
* @draft ICU 73
*/
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> 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> 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);
}
/**

View file

@ -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<FieldModifier> 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<String, String> 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<String, String> fieldValues) {
private SimplePersonName(Locale nameLocale, PreferredOrder preferredOrder, Map<String, String> 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<FieldModifier> 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<String, String> fieldValues;
}

View file

@ -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<PersonNameFormatter.Options> 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<PersonNameFormatter.Options> makeOptionsSet(String optionsStr) {
Set<PersonNameFormatter.Options> 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);
}