ICU-22081 More API-review fixes: Hoisted the PersonName object to the top level (in its own source file) and moved

NameField and FieldModifier there, plus a number of smaller changes.
This commit is contained in:
Rich Gillam 2022-08-30 17:43:30 -07:00 committed by Rich Gillam
parent df93dd00bf
commit 69dcdde885
7 changed files with 307 additions and 294 deletions

View file

@ -3,10 +3,7 @@
package com.ibm.icu.impl.personname;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.CaseMap;
import com.ibm.icu.text.PersonNameFormatter;
import com.ibm.icu.text.SimpleFormatter;
import com.ibm.icu.text.*;
import java.util.Locale;
import java.util.StringTokenizer;
@ -17,7 +14,7 @@ import java.util.StringTokenizer;
abstract class FieldModifierImpl {
public abstract String modifyField(String fieldValue);
public static FieldModifierImpl forName(PersonNameFormatter.FieldModifier modifierID, PersonNameFormatterImpl formatterImpl) {
public static FieldModifierImpl forName(PersonName.FieldModifier modifierID, PersonNameFormatterImpl formatterImpl) {
switch (modifierID) {
case INFORMAL:
return NOOP_MODIFIER;

View file

@ -5,6 +5,7 @@ package com.ibm.icu.impl.personname;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.PersonName;
import com.ibm.icu.text.PersonNameFormatter;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
@ -124,7 +125,7 @@ public class PersonNameFormatterImpl {
}
public String formatToString(PersonNameFormatter.PersonName name) {
public String formatToString(PersonName name) {
// TODO: Should probably return a FormattedPersonName object
// if the formatter is for a language that doesn't use spaces between words and the name is from a language
@ -201,10 +202,10 @@ public class PersonNameFormatterImpl {
* @param name The name to be formatted.
* @return If true, use given-first order to format the name; if false, use surname-first order.
*/
private boolean nameIsGnFirst(PersonNameFormatter.PersonName name) {
private boolean nameIsGnFirst(PersonName name) {
// the name can declare its order-- check that first (it overrides any locale-based calculation)
Set<PersonNameFormatter.FieldModifier> modifiers = new HashSet<>();
String preferredOrder = name.getFieldValue(PersonNameFormatter.NameField.PREFERRED_ORDER, modifiers);
Set<PersonName.FieldModifier> modifiers = new HashSet<>();
String preferredOrder = name.getFieldValue(PersonName.NameField.PREFERRED_ORDER, modifiers);
if (preferredOrder != null) {
if (preferredOrder.equals("givenFirst")) {
return true;
@ -235,7 +236,7 @@ public class PersonNameFormatterImpl {
return true;
}
private PersonNamePattern getBestPattern(PersonNamePattern[] patterns, PersonNameFormatter.PersonName name) {
private PersonNamePattern getBestPattern(PersonNamePattern[] patterns, PersonName name) {
// early out if there's only one pattern
if (patterns.length == 1) {
return patterns[0];
@ -270,14 +271,14 @@ public class PersonNameFormatterImpl {
* @param name The name for which we need the locale
* @return The name's (real or guessed) locale.
*/
private Locale getNameLocale(PersonNameFormatter.PersonName name) {
private Locale getNameLocale(PersonName name) {
// if the name specifies its locale, we can just return it
Locale nameLocale = name.getNameLocale();
if (nameLocale == null) {
// if not, we look at the characters in the name. If their script matches the default script for the formatter's
// locale, we use the formatter's locale as the name's locale
int formatterScript = UScript.getCodeFromName(ULocale.addLikelySubtags(ULocale.forLocale(locale)).getScript());
String givenName = name.getFieldValue(PersonNameFormatter.NameField.GIVEN, new HashSet<PersonNameFormatter.FieldModifier>());
String givenName = name.getFieldValue(PersonName.NameField.GIVEN, new HashSet<PersonName.FieldModifier>());
int nameScript = UScript.INVALID_CODE;
for (int i = 0; nameScript == UScript.INVALID_CODE && i < givenName.length(); i++) {
// the script of the name is the script of the first character in the name whose script isn't

View file

@ -2,7 +2,7 @@
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl.personname;
import com.ibm.icu.text.PersonNameFormatter;
import com.ibm.icu.text.PersonName;
import java.util.*;
@ -74,7 +74,7 @@ class PersonNamePattern {
this.patternElements = elements.toArray(new Element[0]);
}
public String format(PersonNameFormatter.PersonName name) {
public String format(PersonName name) {
StringBuilder result = new StringBuilder();
boolean seenLeadingField = false;
boolean seenEmptyLeadingField = false;
@ -131,7 +131,7 @@ class PersonNamePattern {
return result.toString();
}
public int numPopulatedFields(PersonNameFormatter.PersonName name) {
public int numPopulatedFields(PersonName name) {
int result = 0;
for (Element element : patternElements) {
result += element.isPopulated(name) ? 1 : 0;
@ -139,7 +139,7 @@ class PersonNamePattern {
return result;
}
public int numEmptyFields(PersonNameFormatter.PersonName name) {
public int numEmptyFields(PersonName name) {
int result = 0;
for (Element element : patternElements) {
result += element.isPopulated(name) ? 0 : 1;
@ -190,8 +190,8 @@ class PersonNamePattern {
*/
private interface Element {
boolean isLiteral();
String format(PersonNameFormatter.PersonName name);
boolean isPopulated(PersonNameFormatter.PersonName name);
String format(PersonName name);
boolean isPopulated(PersonName name);
}
/**
@ -208,11 +208,11 @@ class PersonNamePattern {
return true;
}
public String format(PersonNameFormatter.PersonName name) {
public String format(PersonName name) {
return text;
}
public boolean isPopulated(PersonNameFormatter.PersonName name) {
public boolean isPopulated(PersonName name) {
return false;
}
}
@ -223,23 +223,23 @@ class PersonNamePattern {
* PersonName object and applying any modifiers to it.
*/
private static class NameFieldImpl implements Element {
private PersonNameFormatter.NameField fieldID;
private Map<PersonNameFormatter.FieldModifier, FieldModifierImpl> modifiers;
private PersonName.NameField fieldID;
private Map<PersonName.FieldModifier, FieldModifierImpl> modifiers;
public NameFieldImpl(String fieldNameAndModifiers, PersonNameFormatterImpl formatterImpl) {
List<PersonNameFormatter.FieldModifier> modifierIDs = new ArrayList<>();
List<PersonName.FieldModifier> modifierIDs = new ArrayList<>();
StringTokenizer tok = new StringTokenizer(fieldNameAndModifiers, "-");
this.fieldID = PersonNameFormatter.NameField.forString(tok.nextToken());
this.fieldID = PersonName.NameField.forString(tok.nextToken());
while (tok.hasMoreTokens()) {
modifierIDs.add(PersonNameFormatter.FieldModifier.forString(tok.nextToken()));
modifierIDs.add(PersonName.FieldModifier.forString(tok.nextToken()));
}
if (this.fieldID == PersonNameFormatter.NameField.SURNAME && formatterImpl.shouldCapitalizeSurname()) {
modifierIDs.add(PersonNameFormatter.FieldModifier.ALL_CAPS);
if (this.fieldID == PersonName.NameField.SURNAME && formatterImpl.shouldCapitalizeSurname()) {
modifierIDs.add(PersonName.FieldModifier.ALL_CAPS);
}
this.modifiers = new HashMap<>();
for (PersonNameFormatter.FieldModifier modifierID : modifierIDs) {
for (PersonName.FieldModifier modifierID : modifierIDs) {
this.modifiers.put(modifierID, FieldModifierImpl.forName(modifierID, formatterImpl));
}
}
@ -248,20 +248,20 @@ class PersonNamePattern {
return false;
}
public String format(PersonNameFormatter.PersonName name) {
Set<PersonNameFormatter.FieldModifier> modifierIDs = new HashSet<>(modifiers.keySet());
public String format(PersonName name) {
Set<PersonName.FieldModifier> modifierIDs = new HashSet<>(modifiers.keySet());
String result = name.getFieldValue(fieldID, modifierIDs);
if (result != null) {
for (PersonNameFormatter.FieldModifier modifierID : modifierIDs) {
for (PersonName.FieldModifier modifierID : modifierIDs) {
result = modifiers.get(modifierID).modifyField(result);
}
}
return result;
}
public boolean isPopulated(PersonNameFormatter.PersonName name) {
public boolean isPopulated(PersonName name) {
// just check whether the unmodified field contains a value
Set<PersonNameFormatter.FieldModifier> modifierIDs = new HashSet<>();
Set<PersonName.FieldModifier> modifierIDs = new HashSet<>();
String fieldValue = name.getFieldValue(fieldID, modifierIDs);
return fieldValue != null && !fieldValue.isEmpty();
}

View file

@ -0,0 +1,241 @@
package com.ibm.icu.text;
import java.util.Locale;
import java.util.Set;
/**
* An object used to provide name data to the PersonNameFormatter for formatting.
* Clients can implement this interface to talk directly to some other subsystem
* that actually contains the name data (instead of having to copy it into a separate
* object just for formatting) or to override the default modifier behavior described
* above. A concrete SimplePersonName object that does store the field values directly
* is provided.
*
* @internal ICU 72 technology preview
* @see SimplePersonName
* @deprecated This API is for technology preview only.
*/
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.
*/
enum NameField {
/**
* Contains titles and other words that precede the actual name, such as "Mr."
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
PREFIX("prefix"),
/**
* The given name. May contain more than one token.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
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.
*/
GIVEN2("given2"),
/**
* The surname. In Spanish, this is the patronymic surname.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
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.
*/
SURNAME2("surname2"),
/**
* Generational and professional qualifiers that generally follow the actual name,
* such as "Jr." or "M.D."
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
SUFFIX("suffix"),
/**
* 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.
*/
PREFERRED_ORDER("preferredOrder");
private final String name;
private NameField(String name) {
this.name = name;
}
/**
* Returns the NameField's display name.
* @internal
*/
@Override
public String toString() {
return name;
}
/**
* Returns the appropriate NameField for its display name.
* @internal
*/
public static NameField forString(String name) {
for (NameField field : values()) {
if (field.name.equals(name)) {
return field;
}
}
throw new IllegalArgumentException("Invalid field name " + name);
}
}
/**
* 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.
*/
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.
*/
INFORMAL("informal"),
/**
* If the field contains a main word with one or more separate prefixes, such as
* "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.
*/
PREFIX("prefix"),
/**
* If the field contains a main word with one or more separate prefixes, such as
* "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.
*/
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.
*/
INITIAL("initial"),
/**
* Requests an initial for the specified field, suitable for use in a monogram
* (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.
*/
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.
*/
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.
*/
INITIAL_CAP("initialCap");
private final String name;
private FieldModifier(String name) {
this.name = name;
}
/**
* Returns the FieldModifier's display name.
* @internal
*/
@Override
public String toString() {
return name;
}
/**
* Returns the appropriate fieldModifier for its display name.
* @internal
*/
public static FieldModifier forString(String name) {
for (FieldModifier modifier : values()) {
if (modifier.name.equals(name)) {
return modifier;
}
}
throw new IllegalArgumentException("Invalid modifier name " + name);
}
}
//==============================================================================
// Public API on PersonName
/**
* Returns the locale of the name-- that is, the language or country of origin for the person being named.
* 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.
*/
public Locale getNameLocale();
/**
* Returns one field of the name, possibly in a modified form.
*
* @param identifier The identifier of the requested field.
* @param modifiers An **IN/OUT** parameter that specifies modifiers to apply to the basic field value.
* An implementing class can choose to handle or ignore any modifiers; it should modify
* the passed-in Set so that on exit, it contains only the requested modifiers that it
* 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.
*/
public String getFieldValue(NameField identifier, Set<FieldModifier> modifiers);
}

View file

@ -136,264 +136,29 @@ public class PersonNameFormatter {
SURNAME_ALLCAPS
}
//==============================================================================
// 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.
*/
public enum NameField {
/**
* Contains titles and other words that precede the actual name, such as "Mr."
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
PREFIX("prefix"),
/**
* The given name. May contain more than one token.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
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.
*/
GIVEN2("given2"),
/**
* The surname. In Spanish, this is the patronymic surname.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
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.
*/
SURNAME2("surname2"),
/**
* Generational and professional qualifiers that generally follow the actual name,
* such as "Jr." or "M.D."
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
SUFFIX("suffix"),
/**
* 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.
*/
PREFERRED_ORDER("preferredOrder");
private final String name;
private NameField(String name) {
this.name = name;
}
/**
* Returns the NameField's display name.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
@Override
public String toString() {
return name;
}
/**
* Returns the appropriate NameField for its display name.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
public static NameField forString(String name) {
for (NameField field : values()) {
if (field.name.equals(name)) {
return field;
}
}
throw new IllegalArgumentException("Invalid field name " + name);
}
}
/**
* 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.
*/
public 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.
*/
INFORMAL("informal"),
/**
* If the field contains a main word with one or more separate prefixes, such as
* "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.
*/
PREFIX("prefix"),
/**
* If the field contains a main word with one or more separate prefixes, such as
* "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.
*/
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.
*/
INITIAL("initial"),
/**
* Requests an initial for the specified field, suitable for use in a monogram
* (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.
*/
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.
*/
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.
*/
INITIAL_CAP("initialCap");
private final String name;
private FieldModifier(String name) {
this.name = name;
}
/**
* Returns the FieldModifier's display name.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
@Override
public String toString() {
return name;
}
/**
* Returns the appropriate fieldModifier for its display name.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
public static FieldModifier forString(String name) {
for (FieldModifier modifier : values()) {
if (modifier.name.equals(name)) {
return modifier;
}
}
throw new IllegalArgumentException("Invalid modifier name " + name);
}
}
//==============================================================================
// The PersonName object
/**
* An object used to provide name data to the PersonNameFormatter for formatting.
* Clients can implement this interface to talk directly to some other subsystem
* that actually contains the name data (instead of having to copy it into a separate
* object just for formatting) or to override the default modifier behavior described
* above. A concrete SimplePersonName object that does store the field values directly
* is provided.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
* @see SimplePersonName
*/
public interface PersonName {
/**
* 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 not known.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
public Locale getNameLocale();
/**
* Returns one field of the name, possibly in a modified form.
* @param identifier The identifier of the requested field.
* @param modifiers An **IN/OUT** parameter that specifies modifiers to apply to the basic field value.
* An implementing class can choose to handle or ignore any modifiers; it should modify
* this parameter so that on exit, it contains only the requested modifiers that it
* DIDN'T handle.
* @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.
*/
public String getFieldValue(NameField identifier, Set<FieldModifier> modifiers);
}
private final PersonNameFormatterImpl impl;
//==============================================================================
// Builder for PersonNameformatter
// Builder for 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.
*/
public static class Builder {
/**
* Sets the locale for the formatter to be constructed.
* @param locale The new formatter locale.
* @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.
*/
public Builder setLocale(Locale locale) {
this.locale = locale;
if (locale != null) {
this.locale = locale;
}
return this;
}
@ -434,7 +199,9 @@ public class PersonNameFormatter {
}
/**
* Sets the options set for the formatter to be constructed.
* 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.
* @return This builder.
* @internal ICU 72 technology preview
@ -447,6 +214,9 @@ public class PersonNameFormatter {
/**
* Returns a new PersonNameFormatter with the values that were passed to this builder.
* This method doesn't freeze or delete the builder; you can call build() more than once
* (presumably after calling the other methods to change the parameter) to create more
* than one PersonNameFormatter; you don't need a new Builder for each PersonNameFormatter.
* @return A new PersonNameFormatter.
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
@ -458,7 +228,7 @@ public class PersonNameFormatter {
private Builder() {
}
private Locale locale = null;
private Locale locale = Locale.getDefault();
private Length length = Length.MEDIUM;
private Usage usage = Usage.REFERRING;
private Formality formality = Formality.FORMAL;
@ -485,7 +255,7 @@ public class PersonNameFormatter {
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
public Builder builderFromThis() {
public Builder toBuilder() {
Builder builder = builder();
builder.setLocale(impl.getLocale());
builder.setLength(impl.getLength());

View file

@ -21,8 +21,10 @@ import java.util.TreeSet;
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
public class SimplePersonName implements PersonNameFormatter.PersonName {
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.
*
@ -30,7 +32,8 @@ public class SimplePersonName implements PersonNameFormatter.PersonName {
public static class Builder {
/**
* Set the locale for the new name object.
* @param locale 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.
@ -50,13 +53,13 @@ public class SimplePersonName implements PersonNameFormatter.PersonName {
* @internal ICU 72 technology preview
* @deprecated This API is for technology preview only.
*/
public Builder addField(PersonNameFormatter.NameField field,
Collection<PersonNameFormatter.FieldModifier> modifiers,
public Builder addField(NameField field,
Collection<FieldModifier> modifiers,
String value) {
// generate the modifiers' internal names, and sort them alphabetically
Set<String> modifierNames = new TreeSet<>();
if (modifiers != null) {
for (PersonNameFormatter.FieldModifier modifier : modifiers) {
for (FieldModifier modifier : modifiers) {
modifierNames.add(modifier.toString());
}
}
@ -147,7 +150,7 @@ public class SimplePersonName implements PersonNameFormatter.PersonName {
* @deprecated This API is for technology preview only.
*/
@Override
public String getFieldValue(PersonNameFormatter.NameField nameField, Set<PersonNameFormatter.FieldModifier> modifiers) {
public String getFieldValue(NameField nameField, Set<FieldModifier> modifiers) {
// first look for the fully modified name in the internal table
String fieldName = nameField.toString();
String result = fieldValues.get(makeModifiedFieldName(nameField, modifiers));
@ -170,7 +173,7 @@ public class SimplePersonName implements PersonNameFormatter.PersonName {
int winningScore = 0;
for (String key : fieldValues.keySet()) {
if (key.startsWith(fieldName)) {
Set<PersonNameFormatter.FieldModifier> keyModifiers = makeModifiersFromName(key);
Set<FieldModifier> keyModifiers = makeModifiersFromName(key);
if (modifiers.containsAll(keyModifiers)) {
if (keyModifiers.size() > winningScore || (keyModifiers.size() == winningScore && key.compareTo(winningKey) < 0)) {
winningKey = key;
@ -184,13 +187,13 @@ public class SimplePersonName implements PersonNameFormatter.PersonName {
return result;
}
private static String makeModifiedFieldName(PersonNameFormatter.NameField fieldName,
Collection<PersonNameFormatter.FieldModifier> modifiers) {
private static String makeModifiedFieldName(NameField fieldName,
Collection<FieldModifier> modifiers) {
StringBuilder result = new StringBuilder();
result.append(fieldName);
TreeSet<String> sortedModifierNames = new TreeSet<>();
for (PersonNameFormatter.FieldModifier modifier : modifiers) {
for (FieldModifier modifier : modifiers) {
sortedModifierNames.add(modifier.toString());
}
for (String modifierName : sortedModifierNames) {
@ -200,12 +203,12 @@ public class SimplePersonName implements PersonNameFormatter.PersonName {
return result.toString();
}
private static Set<PersonNameFormatter.FieldModifier> makeModifiersFromName(String modifiedName) {
private static Set<FieldModifier> makeModifiersFromName(String modifiedName) {
StringTokenizer tok = new StringTokenizer(modifiedName, "-");
Set<PersonNameFormatter.FieldModifier> result = new HashSet<>();
Set<FieldModifier> result = new HashSet<>();
String fieldName = tok.nextToken(); // throw away the field name
while (tok.hasMoreTokens()) {
result.add(PersonNameFormatter.FieldModifier.forString(tok.nextToken()));
result.add(PersonName.FieldModifier.forString(tok.nextToken()));
}
return result;
}

View file

@ -3,6 +3,7 @@
package com.ibm.icu.dev.test.format;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.PersonName;
import com.ibm.icu.text.PersonNameFormatter;
import com.ibm.icu.text.SimplePersonName;
import org.junit.Test;
@ -41,13 +42,13 @@ public class PersonNameFormatterTest extends TestFmwk{
// locale ID
builder.setLocale(Locale.forLanguageTag(fieldValue.replace("_", "-")));
} else if (fieldName.indexOf('-') < 0) {
builder.addField(PersonNameFormatter.NameField.forString(fieldName), null, fieldValue);
builder.addField(PersonName.NameField.forString(fieldName), null, fieldValue);
} else {
StringTokenizer fieldNameSplitter = new StringTokenizer(fieldName, "-");
Set<PersonNameFormatter.FieldModifier> modifiers = new HashSet<>();
PersonNameFormatter.NameField fieldID = PersonNameFormatter.NameField.forString(fieldNameSplitter.nextToken());
Set<PersonName.FieldModifier> modifiers = new HashSet<>();
PersonName.NameField fieldID = PersonName.NameField.forString(fieldNameSplitter.nextToken());
while (fieldNameSplitter.hasMoreTokens()) {
modifiers.add(PersonNameFormatter.FieldModifier.forString(fieldNameSplitter.nextToken()));
modifiers.add(PersonName.FieldModifier.forString(fieldNameSplitter.nextToken()));
}
builder.addField(fieldID, modifiers, fieldValue);
}