|
5 | 5 | */ |
6 | 6 | package io.jooby; |
7 | 7 |
|
| 8 | +import io.jooby.internal.LocaleUtils; |
8 | 9 | import io.jooby.internal.ParamLookupImpl; |
9 | 10 | import io.jooby.internal.ReadOnlyContext; |
10 | 11 | import io.jooby.internal.WebSocketSender; |
|
24 | 25 | import java.time.ZoneId; |
25 | 26 | import java.time.format.DateTimeFormatter; |
26 | 27 | import java.util.Arrays; |
| 28 | +import java.util.Collections; |
27 | 29 | import java.util.Date; |
28 | 30 | import java.util.List; |
29 | 31 | import java.util.Locale; |
30 | 32 | import java.util.Map; |
| 33 | +import java.util.Optional; |
31 | 34 | import java.util.concurrent.Executor; |
| 35 | +import java.util.function.BiFunction; |
32 | 36 |
|
33 | 37 | /** |
34 | 38 | * HTTP context allows you to interact with the HTTP Request and manipulate the HTTP Response. |
@@ -434,6 +438,78 @@ public interface Context extends Registry { |
434 | 438 | */ |
435 | 439 | long getRequestLength(); |
436 | 440 |
|
| 441 | + /** |
| 442 | + * Returns a list of locales that best matches the current request. |
| 443 | + * |
| 444 | + * The first filter argument is the value of <code>Accept-Language</code> as a list of |
| 445 | + * {@link Locale.LanguageRange} instances while the second argument is a list of supported |
| 446 | + * locales specified by {@link Jooby#setLocales(List)} or by the |
| 447 | + * <code>application.lang</code> configuration property. |
| 448 | + * |
| 449 | + * The next example returns a list of matching {@code Locale} instances using the filtering |
| 450 | + * mechanism defined in RFC 4647: |
| 451 | + * |
| 452 | + * <pre>{@code |
| 453 | + * ctx.locales(Locale::filter) |
| 454 | + * }</pre> |
| 455 | + * |
| 456 | + * @param filter A locale filter. |
| 457 | + * @return A list of matching locales. |
| 458 | + */ |
| 459 | + @Nonnull default List<Locale> locales(BiFunction<List<Locale.LanguageRange>, List<Locale>, List<Locale>> filter) { |
| 460 | + return filter.apply(header("Accept-Language") |
| 461 | + .toOptional() |
| 462 | + .flatMap(LocaleUtils::parseRanges) |
| 463 | + .orElseGet(Collections::emptyList), getRouter().getLocales()); |
| 464 | + } |
| 465 | + |
| 466 | + /** |
| 467 | + * Returns a list of locales that best matches the current request as per {@link Locale#filter}. |
| 468 | + * |
| 469 | + * @return A list of matching locales or empty list. |
| 470 | + * @see #locales(BiFunction) |
| 471 | + */ |
| 472 | + @Nonnull default List<Locale> locales() { |
| 473 | + return locales(Locale::filter); |
| 474 | + } |
| 475 | + |
| 476 | + /** |
| 477 | + * Returns a locale that best matches the current request. |
| 478 | + * |
| 479 | + * The first filter argument is the value of <code>Accept-Language</code> as a list of |
| 480 | + * {@link Locale.LanguageRange} instances while the second argument is a list of supported |
| 481 | + * locales specified by {@link Jooby#setLocales(List)} or by the |
| 482 | + * <code>application.lang</code> configuration property. |
| 483 | + * |
| 484 | + * The next example returns a {@code Locale} instance for the best-matching language |
| 485 | + * tag using the lookup mechanism defined in RFC 4647. |
| 486 | + * |
| 487 | + * <pre>{@code |
| 488 | + * ctx.locale(Locale::lookup) |
| 489 | + * }</pre> |
| 490 | + * |
| 491 | + * @param filter A locale filter. |
| 492 | + * @return A matching locale. |
| 493 | + */ |
| 494 | + @Nonnull default Locale locale(BiFunction<List<Locale.LanguageRange>, List<Locale>, Locale> filter) { |
| 495 | + return filter.apply(header("Accept-Language") |
| 496 | + .toOptional() |
| 497 | + .flatMap(LocaleUtils::parseRanges) |
| 498 | + .orElseGet(Collections::emptyList), getRouter().getLocales()); |
| 499 | + } |
| 500 | + |
| 501 | + /** |
| 502 | + * Returns a locale that best matches the current request or the default locale specified |
| 503 | + * by {@link Jooby#setLocales(List)} or by the <code>application.lang</code> |
| 504 | + * configuration property. |
| 505 | + * |
| 506 | + * @return A matching locale. |
| 507 | + */ |
| 508 | + @Nonnull default Locale locale() { |
| 509 | + return locale((priorityList, locales) -> Optional.ofNullable(Locale.lookup(priorityList, locales)) |
| 510 | + .orElse(locales.get(0))); |
| 511 | + } |
| 512 | + |
437 | 513 | /** |
438 | 514 | * Current user or <code>null</code> if none was set. |
439 | 515 | * |
|
0 commit comments