Interface LocaleMatcher
- All Known Subinterfaces:
Strings
Locale or List<Locale.LanguageRange> to an appropriate localized strings Locale.
Lokalized's implementation prefers exact and CLDR-canonical matches, then CLDR parent-locale fallback,
then script-aware likely-subtag matches. If multiple supported localized strings files still share the same language,
configured tiebreakers determine which locale wins. Unmatched, root, and undetermined requests resolve to the
configured fallback locale when using bestMatchFor(...). The strict matchFor(...) methods represent
the same state as an unmatched LocaleMatchResult instead of manufacturing a match.
Non-bare wildcard language ranges use RFC 4647 extended filtering only; they are not broadened through
CLDR, likely-subtag, or primary-language heuristics, and successful results report
LocaleMatchType.EXTENDED_RANGE. When multiple ranges match one supported locale, the most-specific exact,
canonical, or structural range determines its effective quality, including a q=0 exclusion.
- Author:
- Mark Allen
-
Field Summary
FieldsModifier and TypeFieldDescriptionMaximum number of parsed language ranges accepted by one matching operation: 32. -
Method Summary
Modifier and TypeMethodDescriptionbestMatchFor(@NonNull List<@NonNull Locale.LanguageRange> languageRanges) Given a list of language ranges (e.g. as parsed from anAccept-LanguageHTTP request header), determine the best-matching localized strings file's locale.bestMatchFor(@NonNull Locale locale) Given a locale, determine the best-matching localized strings file's locale.bestMatchForAcceptLanguage(@Nullable String acceptLanguage) Given a rawAccept-LanguageHTTP field value, determines the best-matching localized strings file's locale.matchFor(@NonNull List<@NonNull Locale.LanguageRange> languageRanges) Strictly negotiates language ranges without manufacturing a configured-fallback match.default @NonNull LocaleMatchResultStrictly negotiates a locale without manufacturing a configured-fallback match.default @NonNull List<@NonNull Locale.LanguageRange> parseLanguageRanges(@NonNull String ranges) Parses a language-range list, such as anAccept-Languagefield value, adding IANA-equivalent ranges.
-
Field Details
-
MAXIMUM_LANGUAGE_RANGES
Maximum number of parsed language ranges accepted by one matching operation: 32.Parsing a header, whether with
parseLanguageRanges(String)orLocale.LanguageRange.parse(String), may add IANA-equivalent ranges, so this limit applies to the parsed list, not the number of comma-separated ranges in the source header. The two parsers can add different equivalents, andLocale.LanguageRange.parse(String)adds whatever the running JDK's table holds, so the same header can be within the limit under one and over it under the other.- Since:
- 3.0.0
-
-
Method Details
-
matchFor
Strictly negotiates a locale without manufacturing a configured-fallback match.- Parameters:
locale- requested locale, not null- Returns:
- diagnostic match result, not null
- Throws:
IllegalArgumentException- if the locale is not well-formed- Since:
- 3.0.0
-
matchFor
Strictly negotiates language ranges without manufacturing a configured-fallback match.- Parameters:
languageRanges- requested language ranges, not null- Returns:
- diagnostic match result, not null
- Throws:
IllegalArgumentException- if more thanMAXIMUM_LANGUAGE_RANGESlanguage ranges are supplied- Since:
- 3.0.0
-
bestMatchFor
Given a locale, determine the best-matching localized strings file's locale.- Parameters:
locale- the locale for which to find the best match.- Returns:
- the best-matching locale, not null
- Throws:
IllegalArgumentException- if the locale is not well-formed
-
bestMatchFor
Given a list of language ranges (e.g. as parsed from anAccept-LanguageHTTP request header), determine the best-matching localized strings file's locale.- Parameters:
languageRanges- the ordered list of language ranges for which to find the best match.- Returns:
- the best-matching locale, not null
- Throws:
IllegalArgumentException- if more thanMAXIMUM_LANGUAGE_RANGESlanguage ranges are supplied
-
bestMatchForAcceptLanguage
Given a rawAccept-LanguageHTTP field value, determines the best-matching localized strings file's locale.This is a fail-soft convenience for request handling. A missing, blank, malformed, or longer than 4,096 UTF-16 code-unit value returns the configured fallback locale. The length limit is applied before parsing so parser work is bounded independently of the parsed-range limit. HTTP optional whitespace and empty list elements are normalized before parsing, and the value is then parsed with
parseLanguageRanges(String). The configured fallback is also returned if parsing produces more thanMAXIMUM_LANGUAGE_RANGESranges, which can happen when parsing adds IANA-equivalent ranges. A valid parsed list is passed through whole; preferences are never truncated. UsematchFor(List)orbestMatchFor(List)when language ranges have already been parsed and strict limit enforcement is desired.- Parameters:
acceptLanguage- raw, already-combinedAccept-Languagefield value, or null if absent- Returns:
- the best-matching locale, or the configured fallback for unusable input, not null
- Since:
- 3.0.0
-
parseLanguageRanges
Parses a language-range list, such as anAccept-Languagefield value, adding IANA-equivalent ranges.The grammar, weights, result order, de-duplication, and exceptions are those of
Locale.LanguageRange.parse(String): spaces are removed, the value is lowercased, anaccept-language:prefix is dropped, members are separated by commas, and each member may carry a;q=weight. Only the source of the added equivalent ranges differs. This default takes them from the IANA Language Subtag Registry snapshot bundled in Lokalized (LanguageRangeEquivalents.IANA_REGISTRY), so the equivalents it adds are the same on every JDK, whereLocale.LanguageRange.parse(String)uses the running JDK's table. AStringsinstance uses the source configured withStrings.Builder.languageRangeEquivalents(LanguageRangeEquivalents).Unlike
bestMatchForAcceptLanguage(String), this method is strict: it applies no length limit, rejects an empty value, horizontal tabs, and empty list elements other than trailing ones instead of normalizing them, and propagates every failure. It does not enforceMAXIMUM_LANGUAGE_RANGES;matchFor(List)andbestMatchFor(List)reject a longer list.- Parameters:
ranges- comma-separated language ranges, optionally weighted, not null- Returns:
- the parsed ranges and their equivalents in descending weight order, as an unmodifiable list, not null
- Throws:
NullPointerException- ifrangesis nullIllegalArgumentException- if a language range or weight is ill-formed, or a weight is not between0.0and1.0IndexOutOfBoundsException- if a language range consists only of hyphens and the running JDK'sLocale.LanguageRangeconstructor rejects it this way, as it does on JDK 17 and 21 (JDK 25 through 27 throwIllegalArgumentExceptioninstead);Locale.LanguageRange.parse(String)fails the same way on each JDK- Since:
- 3.1.0
-