in locales-common/src/main/java/com/spotify/i18n/locales/common/impl/LocalesResolverBaseImpl.java [213:266]
private Stream<LanguageRange> getMatchingExtendedLanguageRanges(
final LanguageRange languageRange) {
// If there are no wildcards, we just return the range. This is the most likely outcome.
if (!languageRange.getRange().contains(LANGUAGE_RANGE_WILDCARD)) {
return Stream.of(languageRange);
}
// Strip the range of any trailing -*
String cleanedRange =
languageRange.getRange().replaceAll("(-\\" + LANGUAGE_RANGE_WILDCARD + ")*$", "");
// The range only contained wildcards, so we simply ignore it.
if (LANGUAGE_RANGE_WILDCARD.equals(cleanedRange)) {
return Stream.of();
}
// There were only trailing wildcards in this range, meaning we don't need to extend it for
// locale resolution to get the best possible match.
if (!cleanedRange.contains(LANGUAGE_RANGE_WILDCARD)) {
return Stream.of(new LanguageRange(cleanedRange, languageRange.getWeight()));
}
// In order to enable parsing, we replace * by Und
String preparedRangeForParsing =
cleanedRange.replace(LANGUAGE_RANGE_WILDCARD, ULOCALE_UNDEFINED_CODE);
// Parse the locale and extend all undefined locale codes accordingly
return LanguageTagUtils.parse(preparedRangeForParsing)
.map(
parsedLocale ->
// As candidate locales for extension, we include and prioritize the most likely
// locale according to CLDR, then add all the supported locales for translations
Stream.concat(
Stream.of(ULocale.addLikelySubtags(parsedLocale)),
supportedLocales().stream().map(SupportedLocale::localeForTranslations))
// We extend the parsed locale by defining undefined locale codes,
// using the ones from the candidate locales, and retain only the ones available
// in CLDR.
// Note: Ideally, entries corresponding to the same region/country should be
// ordered by decreasing % of language coverage, to prioritize languages
// accordingly, but we don't do it here as we do not have this data at hand.
.map(
supportedLocale ->
mitigateParsedLocaleUndefinedCodes(supportedLocale, parsedLocale))
.filter(AVAILABLE_UNICODE_LOCALES::contains)
// We remove potential duplicates
.distinct()
.map(
localeWithinRange ->
new LanguageRange(
localeWithinRange.toLanguageTag().toLowerCase(),
languageRange.getWeight())))
.orElse(Stream.empty());
}