188 lines
7.6 KiB
Java
188 lines
7.6 KiB
Java
/* GENERATED SOURCE. DO NOT MODIFY. */
|
|
// © 2022 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
package android.icu.impl.personname;
|
|
|
|
import java.util.Locale;
|
|
|
|
import android.icu.lang.UCharacter;
|
|
import android.icu.text.BreakIterator;
|
|
import android.icu.text.CaseMap;
|
|
import android.icu.text.PersonName;
|
|
import android.icu.text.SimpleFormatter;
|
|
|
|
/**
|
|
* Parent class for classes that implement field-modifier behavior.
|
|
*/
|
|
abstract class FieldModifierImpl {
|
|
public abstract String modifyField(String fieldValue);
|
|
|
|
public static FieldModifierImpl forName(PersonName.FieldModifier modifierID, PersonNameFormatterImpl formatterImpl) {
|
|
switch (modifierID) {
|
|
case INFORMAL:
|
|
return NOOP_MODIFIER;
|
|
case PREFIX:
|
|
return NULL_MODIFIER;
|
|
case CORE:
|
|
return NOOP_MODIFIER;
|
|
case ALL_CAPS:
|
|
return new AllCapsModifier(formatterImpl.getLocale());
|
|
case INITIAL_CAP:
|
|
return new InitialCapModifier(formatterImpl.getLocale());
|
|
case INITIAL:
|
|
return new InitialModifier(formatterImpl.getLocale(), formatterImpl.getInitialPattern(), formatterImpl.getInitialSequencePattern());
|
|
case RETAIN:
|
|
// "retain" is handled by InitialMofidier and PersonNamePattern.NameFieldImpl
|
|
return NOOP_MODIFIER;
|
|
case MONOGRAM:
|
|
return MONOGRAM_MODIFIER;
|
|
case GENITIVE:
|
|
// no built-in implementation for deriving genitive from nominative; PersonName object must supply
|
|
return NOOP_MODIFIER;
|
|
case VOCATIVE:
|
|
// no built-in implementation for deriving vocative from nominative; PersonName object must supply
|
|
return NOOP_MODIFIER;
|
|
default:
|
|
throw new IllegalArgumentException("Invalid modifier ID " + modifierID);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A field modifier that just returns the field value unmodified. This is used to implement the default
|
|
* behavior of the "informal" and "core" modifiers ("real" informal or core variants have to be supplied or
|
|
* calculated by the PersonName object).
|
|
*/
|
|
private static final FieldModifierImpl NOOP_MODIFIER = new FieldModifierImpl() {
|
|
@Override
|
|
public String modifyField(String fieldValue) {
|
|
return fieldValue;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A field modifier that just returns the empty string. This is used to implement the default behavior of the
|
|
* "prefix" modifier ("real" prefix variants have to be supplied to calculated by the PersonName object).
|
|
*/
|
|
private static final FieldModifierImpl NULL_MODIFIER = new FieldModifierImpl() {
|
|
@Override
|
|
public String modifyField(String fieldValue) {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A field modifier that returns the field value converted to ALL CAPS. This is the default behavior
|
|
* for the "allCaps" modifier.
|
|
*/
|
|
private static class AllCapsModifier extends FieldModifierImpl {
|
|
private final Locale locale;
|
|
|
|
public AllCapsModifier(Locale locale) {
|
|
this.locale = locale;
|
|
}
|
|
|
|
@Override
|
|
public String modifyField(String fieldValue) {
|
|
return UCharacter.toUpperCase(locale, fieldValue);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A field modifier that returns the field value with the first letter of each word capitalized. This is
|
|
* the default behavior of the "initialCap" modifier.
|
|
*/
|
|
private static class InitialCapModifier extends FieldModifierImpl {
|
|
private final Locale locale;
|
|
private static final CaseMap.Title TO_TITLE_WHOLE_STRING_NO_LOWERCASE = CaseMap.toTitle().wholeString().noLowercase();
|
|
|
|
public InitialCapModifier(Locale locale) {
|
|
this.locale = locale;
|
|
}
|
|
|
|
@Override
|
|
public String modifyField(String fieldValue) {
|
|
return TO_TITLE_WHOLE_STRING_NO_LOWERCASE.apply(locale, null, fieldValue);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A field modifier that returns the field value converted into one or more initials. This is the first grapheme
|
|
* cluster of each word in the field value, modified using the initialPattern/initial resource value from the
|
|
* locale data, and strung together using the initialPattern/initialSequence resource value from the locale data.
|
|
* (In English, these patterns put periods after each initial and connect them with spaces.)
|
|
* This is default behavior of the "initial" modifier.
|
|
*/
|
|
static class InitialModifier extends FieldModifierImpl {
|
|
private final Locale locale;
|
|
private final SimpleFormatter initialFormatter;
|
|
private final SimpleFormatter initialSequenceFormatter;
|
|
private boolean retainPunctuation;
|
|
|
|
public InitialModifier(Locale locale, String initialPattern, String initialSequencePattern) {
|
|
this.locale = locale;
|
|
this.initialFormatter = SimpleFormatter.compile(initialPattern);
|
|
this.initialSequenceFormatter = SimpleFormatter.compile(initialSequencePattern);
|
|
this.retainPunctuation = false;
|
|
}
|
|
|
|
public void setRetainPunctuation(boolean retain) {
|
|
this.retainPunctuation = retain;
|
|
}
|
|
|
|
@Override
|
|
public String modifyField(String fieldValue) {
|
|
String separator = "";
|
|
String result = null;
|
|
BreakIterator bi = BreakIterator.getWordInstance(locale);
|
|
bi.setText(fieldValue);
|
|
int wordStart = bi.first();
|
|
for (int wordEnd = bi.next(); wordEnd != BreakIterator.DONE; wordStart = wordEnd, wordEnd = bi.next()) {
|
|
String word = fieldValue.substring(wordStart, wordEnd);
|
|
if (Character.isLetter(word.charAt(0))) {
|
|
String curInitial = getFirstGrapheme(word);
|
|
if (result == null) {
|
|
result = initialFormatter.format(curInitial);
|
|
} else if (retainPunctuation) {
|
|
result = result + separator + initialFormatter.format(curInitial);
|
|
separator = "";
|
|
} else {
|
|
result = initialSequenceFormatter.format(result, initialFormatter.format(curInitial));
|
|
}
|
|
} else if (Character.isWhitespace(word.charAt(0))) {
|
|
// coalesce a sequence of whitespace characters down to a single space
|
|
separator = separator + word.charAt(0);
|
|
} else {
|
|
separator = separator + word;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A field modifier that simply returns the first grapheme cluster in the field value.
|
|
* This is the default implementation of the "monogram" modifier.
|
|
*/
|
|
private static final FieldModifierImpl MONOGRAM_MODIFIER = new FieldModifierImpl() {
|
|
@Override
|
|
public String modifyField(String fieldValue) {
|
|
return getFirstGrapheme(fieldValue);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A utility function that just returns the first grapheme cluster in the string.
|
|
*/
|
|
private static String getFirstGrapheme(String s) {
|
|
// early out if the string is empty to avoid StringIndexOutOfBoundsException
|
|
if (s.isEmpty()) {
|
|
return "";
|
|
}
|
|
|
|
// (currently, no locale overrides the grapheme-break rules, so we just use "root" instead of passing in the locale)
|
|
BreakIterator bi = BreakIterator.getCharacterInstance(Locale.ROOT);
|
|
bi.setText(s);
|
|
return s.substring(0, bi.next());
|
|
}
|
|
}
|