mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 22:44:49 +00:00
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:
parent
df93dd00bf
commit
69dcdde885
7 changed files with 307 additions and 294 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
241
icu4j/main/classes/core/src/com/ibm/icu/text/PersonName.java
Normal file
241
icu4j/main/classes/core/src/com/ibm/icu/text/PersonName.java
Normal 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);
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue