From 41d9b5fad193b35383f1abe36f1059563d054815 Mon Sep 17 00:00:00 2001 From: ogesaku Date: Sat, 27 Apr 2024 15:04:23 +0200 Subject: [PATCH] Improve query prefixes --- README.md | 9 +-- .../src/main/kotlin/build.version.gradle.kts | 34 ++++---- .../coditory/quark/i18n/I18nKeyGenerator.java | 64 ++++++++------- .../coditory/quark/i18n/I18nMessagePack.java | 17 +++- .../quark/i18n/I18nMessagePackBuilder.java | 80 ++++++------------- .../com/coditory/quark/i18n/I18nMessages.java | 2 +- .../quark/i18n/I18nMissingMessageHandler.java | 45 +++++++++-- .../quark/i18n/ImmutableI18nMessagePack.java | 26 ++---- .../quark/i18n/Reloadable18nMessagePack.java | 4 +- .../quark/i18n/MessageHierarchySpec.groovy | 2 +- .../quark/i18n/MessageResolutionSpec.groovy | 2 +- .../quark/i18n/ReferenceHierarchySpec.groovy | 2 +- 12 files changed, 148 insertions(+), 139 deletions(-) diff --git a/README.md b/README.md index 60c23e3..8ae97cb 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,6 @@ If there is still no match then the default locale (followed by a less strict de I18nMessagePack messages = I18nMessagePack.builder() .scanClassPath("/i18n/messages-{locale}.yml") .setDefaultLocale(PL_PL) - .addFallbackKeyPrefix("glossary") .build(); String message = messages.getMessage(Locales.en_US, "hello"); @@ -203,7 +202,7 @@ Sometimes it is useful to specify a common path prefix for all unmatched queries I18nMessagePack messages = I18nMessagePack.builder() .scanClassPath("/i18n/messages-{locale}.yml") .setDefaultLocale(PL_PL) - .addMessageFallbackKeyPrefix("common") + .prefixQueries("", "common") .build(); String message = messages.getMessage(Locales.en_US, "hello"); @@ -304,7 +303,7 @@ I18nMessagePack messagePack = I18nMessagePack.builder() .addMessage(EN_US, "msg", "${company.name} was established on 1988") .scanClassPath("/i18n/messages-{locale}.yml") .setDefaultLocale(PL_PL) - .addFallbackKeyPrefix("fallback") + .prefixQueries("", "fallback") .build(); ``` @@ -325,7 +324,7 @@ If the reference is defined in a message stored in a prefixed file it will be au I18nMessagePack messagePack = I18nMessagePack.builder() .scanClassPathLocation("i18n/{prefix}/message_{locale}.yml") .setDefaultLocale(PL_PL) - .addFallbackKeyPrefix("fallback") + .prefixQueries("", "fallback") .build(); ``` @@ -442,7 +441,7 @@ You can skip them using a custom missing message detector: I18nMissingMessagesDetector detector = I18nMissingMessagesDetector.builder() .skipPath(skipPath) .logMissingMessages() - .build() + .build(); I18nMessagePack. diff --git a/build-logic/src/main/kotlin/build.version.gradle.kts b/build-logic/src/main/kotlin/build.version.gradle.kts index 9fce542..f84ee42 100644 --- a/build-logic/src/main/kotlin/build.version.gradle.kts +++ b/build-logic/src/main/kotlin/build.version.gradle.kts @@ -41,7 +41,7 @@ data class Semver( fun nextPatchSnapshot(): Semver { return copy( patch = patch + 1, - suffix = "SNAPSHOT" + suffix = "SNAPSHOT", ) } @@ -60,7 +60,10 @@ data class Semver( companion object { private val REGEX = Regex("v?([0-9]+)\\.([0-9]+)\\.([0-9]+)(-.+)?") - fun parse(text: String, strict: Boolean = true): Semver? { + fun parse( + text: String, + strict: Boolean = true, + ): Semver? { val groups = REGEX.matchEntire(text)?.groups ?: return null if (groups.size < 4 || groups.size > 5) return null if (strict && groups[0]?.value?.startsWith("v") == true) return null @@ -84,19 +87,20 @@ data class Semver( command: String, workingDir: File = File("."), timeoutAmount: Long = 60, - timeoutUnit: TimeUnit = TimeUnit.SECONDS - ): String = ProcessBuilder("sh", "-c", command) - .directory(workingDir) - .redirectOutput(ProcessBuilder.Redirect.PIPE) - .redirectError(ProcessBuilder.Redirect.PIPE) - .start() - .apply { waitFor(timeoutAmount, timeoutUnit) } - .run { - val error = errorStream.bufferedReader().readText().trim() - if (error.isNotEmpty()) { - throw IOException(error) + timeoutUnit: TimeUnit = TimeUnit.SECONDS, + ): String = + ProcessBuilder("sh", "-c", command) + .directory(workingDir) + .redirectOutput(ProcessBuilder.Redirect.PIPE) + .redirectError(ProcessBuilder.Redirect.PIPE) + .start() + .apply { waitFor(timeoutAmount, timeoutUnit) } + .run { + val error = errorStream.bufferedReader().readText().trim() + if (error.isNotEmpty()) { + throw IOException(error) + } + inputStream.bufferedReader().readText().trim() } - inputStream.bufferedReader().readText().trim() - } } } diff --git a/src/main/java/com/coditory/quark/i18n/I18nKeyGenerator.java b/src/main/java/com/coditory/quark/i18n/I18nKeyGenerator.java index 50b5b7d..f848c87 100644 --- a/src/main/java/com/coditory/quark/i18n/I18nKeyGenerator.java +++ b/src/main/java/com/coditory/quark/i18n/I18nKeyGenerator.java @@ -8,19 +8,27 @@ final class I18nKeyGenerator { private final List defaultLocales; - private final List globalPrefixes; + private final List defaultPrefixes; private final LocaleResolver localeResolver; - public I18nKeyGenerator(Locale defaultLocale, List globalPrefixes, LocaleResolver localeResolver) { + public I18nKeyGenerator(Locale defaultLocale, List prefixes, LocaleResolver localeResolver) { + this(defaultLocale != null ? localeResolver.getLocaleHierarchy(defaultLocale) : List.of(), prefixes, localeResolver); + } + + private I18nKeyGenerator(List defaultLocales, List prefixes, LocaleResolver localeResolver) { + expectNonNull(defaultLocales, "defaultLocales"); expectNonNull(localeResolver, "localeResolver"); - expectNonNull(globalPrefixes, "globalPrefixes"); - this.defaultLocales = defaultLocale != null - ? localeResolver.getLocaleHierarchy(defaultLocale) - : List.of(); - this.globalPrefixes = List.copyOf(globalPrefixes); + expectNonNull(prefixes, "prefixes"); + this.defaultLocales = defaultLocales; + this.defaultPrefixes = prefixes.isEmpty() ? List.of(I18nPath.root()) : List.copyOf(prefixes); this.localeResolver = localeResolver; } + I18nKeyGenerator withPrefixes(List prefixes) { + expectNonNull(prefixes, "prefixes"); + return new I18nKeyGenerator(defaultLocales, prefixes, localeResolver); + } + List keys(I18nKey key) { expectNonNull(key, "key"); return keys(key, List.of()); @@ -28,9 +36,7 @@ List keys(I18nKey key) { List keys(I18nKey key, I18nPath prefix) { expectNonNull(key, "key"); - return prefix == null || prefix.isRoot() - ? keys(key) - : keys(key, List.of(prefix)); + return keys(key, List.of(prefix)); } List keys(I18nKey key, List prefixes) { @@ -38,37 +44,33 @@ List keys(I18nKey key, List prefixes) { expectNonNull(prefixes, "prefixes"); List locales = localeResolver.getLocaleHierarchy(key.locale()); I18nPath path = key.path(); - List keys = new ArrayList<>(6 * (1 + prefixes.size() + globalPrefixes.size())); - // locales x prefix + path + List keys = new ArrayList<>(6 * (1 + prefixes.size() + this.defaultPrefixes.size())); + // locales x (prefix + path) for (I18nPath prefix : prefixes) { + I18nPath prefixed = prefix.child(path); for (Locale loc : locales) { - keys.add(I18nKey.of(loc, prefix.child(path))); + keys.add(I18nKey.of(loc, prefixed)); } } - // locales x path - for (Locale loc : locales) { - keys.add(I18nKey.of(loc, path)); - } - // locales x globalPrefixes - for (I18nPath prefix : globalPrefixes) { + // locales * (defaultPrefixes + path) + for (I18nPath prefix : this.defaultPrefixes) { + I18nPath prefixed = prefix.child(path); for (Locale loc : locales) { - keys.add(I18nKey.of(loc, prefix.child(path))); + keys.add(I18nKey.of(loc, prefixed)); } } - // defaultLocales x prefix + path + // defaultLocales x (prefix + path) for (I18nPath prefix : prefixes) { - for (Locale loc : defaultLocales) { - keys.add(I18nKey.of(loc, prefix.child(path))); + I18nPath prefixed = prefix.child(path); + for (Locale loc : this.defaultLocales) { + keys.add(I18nKey.of(loc, prefixed)); } } - // defaultLocales x path - for (Locale loc : defaultLocales) { - keys.add(I18nKey.of(loc, path)); - } - // defaultLocales x globalPrefixes - for (I18nPath prefix : globalPrefixes) { - for (Locale loc : defaultLocales) { - keys.add(I18nKey.of(loc, prefix.child(path))); + // defaultLocales * (defaultPrefixes + path) + for (I18nPath prefix : this.defaultPrefixes) { + I18nPath prefixed = prefix.child(path); + for (Locale loc : this.defaultLocales) { + keys.add(I18nKey.of(loc, prefixed)); } } return keys; diff --git a/src/main/java/com/coditory/quark/i18n/I18nMessagePack.java b/src/main/java/com/coditory/quark/i18n/I18nMessagePack.java index f3e5b0f..3f6a00a 100755 --- a/src/main/java/com/coditory/quark/i18n/I18nMessagePack.java +++ b/src/main/java/com/coditory/quark/i18n/I18nMessagePack.java @@ -3,6 +3,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; +import java.util.List; import java.util.Locale; import java.util.Map; @@ -114,11 +116,18 @@ default I18nMessages localize(@NotNull String locale) { } @NotNull - I18nMessagePack prefixQueries(I18nPath prefix); + I18nMessagePack prefixQueries(@NotNull List prefixes); @NotNull - default I18nMessagePack prefixQueries(@NotNull String prefix) { - expectNonNull(prefix, "prefix"); - return prefixQueries(I18nPath.of(prefix)); + default I18nMessagePack prefixQueries(@NotNull I18nPath... prefixes) { + expectNonNull(prefixes, "prefixes"); + return prefixQueries(List.of(prefixes)); + } + + @NotNull + default I18nMessagePack prefixQueries(@NotNull String... prefixes) { + expectNonNull(prefixes, "prefix"); + List paths = Arrays.stream(prefixes).map(I18nPath::of).toList(); + return prefixQueries(paths); } } diff --git a/src/main/java/com/coditory/quark/i18n/I18nMessagePackBuilder.java b/src/main/java/com/coditory/quark/i18n/I18nMessagePackBuilder.java index 3449a05..af8691f 100755 --- a/src/main/java/com/coditory/quark/i18n/I18nMessagePackBuilder.java +++ b/src/main/java/com/coditory/quark/i18n/I18nMessagePackBuilder.java @@ -21,14 +21,14 @@ public final class I18nMessagePackBuilder { private final AggregatedI18nLoader loader = new AggregatedI18nLoader(); - private final List referenceFallbackPaths = new ArrayList<>(); - private final List messageFallbackPaths = new ArrayList<>(); private final List> argTransformers = new ArrayList<>(); private I18nMissingMessageHandler missingMessageHandler = I18nMissingMessageHandler.errorThrowingHandler(); private Locale defaultLocale; private boolean transformJava8TimeTypes = true; private boolean normalizeWhitespaces = false; private boolean resolveReferences = true; + private List referencePrefixes = new ArrayList<>(); + private List queryPrefixes = new ArrayList<>(); private I18nMissingMessagesDetector missingMessagesDetector; I18nMessagePackBuilder() { @@ -38,8 +38,8 @@ public final class I18nMessagePackBuilder { private I18nMessagePackBuilder copy() { I18nMessagePackBuilder builder = new I18nMessagePackBuilder(); builder.loader.addLoader(loader.copy()); - builder.referenceFallbackPaths.addAll(referenceFallbackPaths); - builder.messageFallbackPaths.addAll(messageFallbackPaths); + builder.referencePrefixes.addAll(referencePrefixes); + builder.queryPrefixes.addAll(queryPrefixes); builder.argTransformers.addAll(argTransformers); builder.missingMessageHandler = missingMessageHandler; builder.defaultLocale = defaultLocale; @@ -251,71 +251,43 @@ public I18nMessagePackBuilder setDefaultLocale(@NotNull Locale defaultLocale) { } @NotNull - public I18nMessagePackBuilder addReferenceFallbackKeyPrefixes(@NotNull List keyPrefixes) { - expectNonNull(keyPrefixes, "keyPrefixes"); - keyPrefixes.forEach(this::addReferenceFallbackKeyPrefix); + public I18nMessagePackBuilder prefixReferenceQueries(@NotNull List prefixes) { + expectNonNull(prefixes, "prefixes"); + this.referencePrefixes = List.copyOf(prefixes); return this; } @NotNull - public I18nMessagePackBuilder addReferenceFallbackKeyPrefixes(@NotNull String... keyPrefixes) { - expectNonNull(keyPrefixes, "keyPrefixes"); - Arrays.stream(keyPrefixes).forEach(this::addReferenceFallbackKeyPrefix); - return this; - } - - @NotNull - public I18nMessagePackBuilder addReferenceFallbackKeyPrefix(@NotNull String keyPrefix) { - expectNonBlank(keyPrefix, "keyPrefix"); - I18nPath i18nPath = I18nPath.of(keyPrefix); - this.referenceFallbackPaths.add(i18nPath); - return this; - } - - @NotNull - public I18nMessagePackBuilder addMessageFallbackKeyPrefixes(@NotNull List keyPrefixes) { - expectNonNull(keyPrefixes, "keyPrefixes"); - keyPrefixes.forEach(this::addMessageFallbackKeyPrefix); - return this; - } - - @NotNull - public I18nMessagePackBuilder addMessageFallbackKeyPrefixes(@NotNull String... keyPrefixes) { - expectNonNull(keyPrefixes, "keyPrefixes"); - Arrays.stream(keyPrefixes).forEach(this::addMessageFallbackKeyPrefix); - return this; + public I18nMessagePackBuilder prefixReferenceQueries(@NotNull I18nPath... prefixes) { + expectNonNull(prefixes, "prefixes"); + return prefixReferenceQueries(List.of(prefixes)); } @NotNull - public I18nMessagePackBuilder addMessageFallbackKeyPrefix(@NotNull String keyPrefix) { - expectNonBlank(keyPrefix, "keyPrefix"); - I18nPath i18nPath = I18nPath.of(keyPrefix); - this.messageFallbackPaths.add(i18nPath); - return this; + public I18nMessagePackBuilder prefixReferenceQueries(@NotNull String... prefixes) { + expectNonNull(prefixes, "prefixes"); + List mapped = Arrays.stream(prefixes).map(I18nPath::of).toList(); + return prefixReferenceQueries(mapped); } @NotNull - public I18nMessagePackBuilder addFallbackKeyPrefixes(@NotNull List keyPrefixes) { - expectNonNull(keyPrefixes, "keyPrefixes"); - addMessageFallbackKeyPrefixes(keyPrefixes); - addReferenceFallbackKeyPrefixes(keyPrefixes); + public I18nMessagePackBuilder prefixQueries(@NotNull List prefixes) { + expectNonNull(prefixes, "prefixes"); + this.queryPrefixes = List.copyOf(prefixes); return this; } @NotNull - public I18nMessagePackBuilder addFallbackKeyPrefixes(@NotNull String... keyPrefixes) { - expectNonNull(keyPrefixes, "keyPrefixes"); - addMessageFallbackKeyPrefixes(keyPrefixes); - addReferenceFallbackKeyPrefixes(keyPrefixes); - return this; + public I18nMessagePackBuilder prefixQueries(@NotNull String... prefixes) { + expectNonNull(prefixes, "prefixes"); + List mapped = Arrays.stream(prefixes).map(I18nPath::of).toList(); + return prefixQueries(mapped); } @NotNull - public I18nMessagePackBuilder addFallbackKeyPrefix(@NotNull String keyPrefix) { - expectNonBlank(keyPrefix, "keyPrefix"); - addMessageFallbackKeyPrefix(keyPrefix); - addReferenceFallbackKeyPrefix(keyPrefix); - return this; + public I18nMessagePackBuilder prefixQueries(@NotNull I18nPath... prefixes) { + expectNonNull(prefixes, "prefixes"); + return prefixQueries(List.of(prefixes)); } @NotNull @@ -349,14 +321,14 @@ private I18nMessagePack build(List bundles) { bundles = TemplatesBundlePrefixes.prefix(bundles); detectMissingMessages(bundles); LocaleResolver localeResolver = LocaleResolver.of(defaultLocale, bundles); - I18nKeyGenerator messageKeyGenerator = new I18nKeyGenerator(defaultLocale, messageFallbackPaths, localeResolver); + I18nKeyGenerator messageKeyGenerator = new I18nKeyGenerator(defaultLocale, queryPrefixes, localeResolver); MessageTemplateParser parser = buildMessageTemplateParser(bundles, localeResolver); Map templates = parser.parseTemplates(bundles); return new ImmutableI18nMessagePack(templates, parser, missingMessageHandler, messageKeyGenerator); } private MessageTemplateParser buildMessageTemplateParser(List bundles, LocaleResolver localeResolver) { - I18nKeyGenerator referenceKeyGenerator = new I18nKeyGenerator(defaultLocale, referenceFallbackPaths, localeResolver); + I18nKeyGenerator referenceKeyGenerator = new I18nKeyGenerator(defaultLocale, referencePrefixes, localeResolver); ReferenceResolver referenceResolver = new ReferenceResolver(bundles, referenceKeyGenerator, resolveReferences); ArgumentResolver argumentResolver = buildArgumentResolver(); MessageTemplateNormalizer messageTemplateNormalizer = new MessageTemplateNormalizer(normalizeWhitespaces); diff --git a/src/main/java/com/coditory/quark/i18n/I18nMessages.java b/src/main/java/com/coditory/quark/i18n/I18nMessages.java index 589bc83..4bd7dbc 100755 --- a/src/main/java/com/coditory/quark/i18n/I18nMessages.java +++ b/src/main/java/com/coditory/quark/i18n/I18nMessages.java @@ -86,7 +86,7 @@ public String getMessageOrNull(@NotNull String key) { } @NotNull - public I18nMessages prefixQueries(@NotNull String prefix) { + public I18nMessages addMessagePrefix(@NotNull String prefix) { return messagePack.prefixQueries(prefix).localize(locale); } diff --git a/src/main/java/com/coditory/quark/i18n/I18nMissingMessageHandler.java b/src/main/java/com/coditory/quark/i18n/I18nMissingMessageHandler.java index 612a9a7..ca3083e 100755 --- a/src/main/java/com/coditory/quark/i18n/I18nMissingMessageHandler.java +++ b/src/main/java/com/coditory/quark/i18n/I18nMissingMessageHandler.java @@ -4,11 +4,18 @@ import java.util.Arrays; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import static com.coditory.quark.i18n.Preconditions.expectNonNull; import static java.lang.String.format; public interface I18nMissingMessageHandler { + @NotNull + static I18nMissingMessageHandler debugErrorThrowingHandler() { + return new DebugErrorThrowingI18NMissingMessageHandler(); + } + @NotNull static I18nMissingMessageHandler errorThrowingHandler() { return new ErrorThrowingI18NMissingMessageHandler(); @@ -20,27 +27,27 @@ static I18nMissingMessageHandler pathPrintingHandler() { } @NotNull - String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Object... args); + String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Object... args); @NotNull - String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Map args); + String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Map args); } final class PathPrintingI18NMissingMessageHandler implements I18nMissingMessageHandler { @Override - public @NotNull String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Object... args) { + public @NotNull String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Object... args) { return key.path().getValue(); } @Override - public @NotNull String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Map args) { + public @NotNull String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Map args) { return key.path().getValue(); } } final class ErrorThrowingI18NMissingMessageHandler implements I18nMissingMessageHandler { @Override - public @NotNull String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Object... args) { + public @NotNull String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Object... args) { expectNonNull(key, "key"); expectNonNull(args, "args"); String argsString = args.length == 0 ? "" : Arrays.toString(args); @@ -49,11 +56,37 @@ final class ErrorThrowingI18NMissingMessageHandler implements I18nMissingMessage } @Override - public @NotNull String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Map args) { + public @NotNull String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Map args) { expectNonNull(key, "key"); expectNonNull(args, "args"); String argsString = args.toString(); String argsStringInParenthesis = argsString.isEmpty() ? "" : "(" + argsString.substring(1, argsString.length() - 1) + ')'; throw new I18nMessagesException(format("Missing message %s%s", key.toShortString(), argsStringInParenthesis)); } +} + +final class DebugErrorThrowingI18NMissingMessageHandler implements I18nMissingMessageHandler { + @Override + public @NotNull String onUnresolvedMessage(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Object... args) { + expectNonNull(key, "key"); + expectNonNull(args, "args"); + String argsString = args.length == 0 ? "" : Arrays.toString(args); + String argsStringInParenthesis = argsString.isEmpty() ? "" : "(" + argsString.substring(1, argsString.length() - 1) + ')'; + String keys = StreamSupport.stream(checked.spliterator(), false) + .map(I18nKey::toShortString) + .collect(Collectors.joining("\n")); + throw new I18nMessagesException(format("Missing message %s%s\nChecked i18n keys:\n%s", key.toShortString(), argsStringInParenthesis, keys)); + } + + @Override + public @NotNull String onUnresolvedMessageWithNamedArguments(@NotNull I18nKey key, @NotNull Iterable checked, @NotNull Map args) { + expectNonNull(key, "key"); + expectNonNull(args, "args"); + String argsString = args.toString(); + String argsStringInParenthesis = argsString.isEmpty() ? "" : "(" + argsString.substring(1, argsString.length() - 1) + ')'; + String keys = StreamSupport.stream(checked.spliterator(), false) + .map(I18nKey::toShortString) + .collect(Collectors.joining("\n")); + throw new I18nMessagesException(format("Missing message %s%s\nChecked i18n keys:\n%s", key.toShortString(), argsStringInParenthesis, keys)); + } } \ No newline at end of file diff --git a/src/main/java/com/coditory/quark/i18n/ImmutableI18nMessagePack.java b/src/main/java/com/coditory/quark/i18n/ImmutableI18nMessagePack.java index 05261fe..7cc7cab 100755 --- a/src/main/java/com/coditory/quark/i18n/ImmutableI18nMessagePack.java +++ b/src/main/java/com/coditory/quark/i18n/ImmutableI18nMessagePack.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Arrays; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; @@ -14,7 +15,6 @@ final class ImmutableI18nMessagePack implements I18nMessagePack { private final Map templates; private final MessageTemplateParser parser; private final I18nMissingMessageHandler unresolvedMessageHandler; - private final I18nPath queryPrefix; private final I18nKeyGenerator keyGenerator; ImmutableI18nMessagePack( @@ -22,23 +22,12 @@ final class ImmutableI18nMessagePack implements I18nMessagePack { MessageTemplateParser parser, I18nMissingMessageHandler unresolvedMessageHandler, I18nKeyGenerator keyGenerator - ) { - this(templates, parser, unresolvedMessageHandler, keyGenerator, null); - } - - private ImmutableI18nMessagePack( - Map templates, - MessageTemplateParser parser, - I18nMissingMessageHandler unresolvedMessageHandler, - I18nKeyGenerator keyGenerator, - I18nPath queryPrefix ) { expectNonNull(templates, "templates"); this.templates = Map.copyOf(templates); this.parser = expectNonNull(parser, "parser"); this.unresolvedMessageHandler = expectNonNull(unresolvedMessageHandler, "unresolvedMessageHandler"); this.keyGenerator = expectNonNull(keyGenerator, "keyGenerator"); - this.queryPrefix = queryPrefix; } @NotNull @@ -55,7 +44,7 @@ public String getMessage(@NotNull I18nKey key, Object... args) { expectNonNull(args, "args"); String result = getMessageOrNull(key, args); return result == null - ? unresolvedMessageHandler.onUnresolvedMessage(key, args) + ? unresolvedMessageHandler.onUnresolvedMessage(key, keyGenerator.keys(key), args) : result; } @@ -66,7 +55,7 @@ public String getMessage(@NotNull I18nKey key, @NotNull Map args expectNonNull(args, "args"); String result = getMessageOrNull(key, args); return result == null - ? unresolvedMessageHandler.onUnresolvedMessageWithNamedArguments(key, args) + ? unresolvedMessageHandler.onUnresolvedMessageWithNamedArguments(key, keyGenerator.keys(key), args) : result; } @@ -91,7 +80,7 @@ public String getMessageOrNull(@NotNull I18nKey key, @NotNull Map getTemplate(I18nKey key) { - return keyGenerator.keys(key, queryPrefix).stream() + return keyGenerator.keys(key).stream() .filter(templates::containsKey) .map(matched -> new MessageTemplateWithKey(matched, templates.get(matched))) .findFirst(); @@ -130,9 +119,10 @@ public String format(@NotNull Locale locale, @NotNull String template, @NotNull @Override @NotNull - public I18nMessagePack prefixQueries(@NotNull I18nPath prefix) { - expectNonNull(prefix, "prefix"); - return new ImmutableI18nMessagePack(templates, parser, unresolvedMessageHandler, keyGenerator, prefix); + public I18nMessagePack prefixQueries(@NotNull List prefixes) { + expectNonNull(prefixes, "prefixes"); + I18nKeyGenerator updated = keyGenerator.withPrefixes(prefixes); + return new ImmutableI18nMessagePack(templates, parser, unresolvedMessageHandler, updated); } private record MessageTemplateWithKey(I18nKey key, MessageTemplate template) { diff --git a/src/main/java/com/coditory/quark/i18n/Reloadable18nMessagePack.java b/src/main/java/com/coditory/quark/i18n/Reloadable18nMessagePack.java index d3ee6ad..d38d0b0 100755 --- a/src/main/java/com/coditory/quark/i18n/Reloadable18nMessagePack.java +++ b/src/main/java/com/coditory/quark/i18n/Reloadable18nMessagePack.java @@ -46,8 +46,8 @@ public synchronized void stopWatching() { } @Override - public @NotNull I18nMessagePack prefixQueries(I18nPath prefix) { - return i18nMessagePack.prefixQueries(prefix); + public @NotNull I18nMessagePack prefixQueries(@NotNull List prefixes) { + return i18nMessagePack.prefixQueries(prefixes); } @Override diff --git a/src/test/groovy/com/coditory/quark/i18n/MessageHierarchySpec.groovy b/src/test/groovy/com/coditory/quark/i18n/MessageHierarchySpec.groovy index e90462b..6ee9c2b 100755 --- a/src/test/groovy/com/coditory/quark/i18n/MessageHierarchySpec.groovy +++ b/src/test/groovy/com/coditory/quark/i18n/MessageHierarchySpec.groovy @@ -80,7 +80,7 @@ class MessageHierarchySpec extends Specification { .addMessage(EN_GB, "b", "en-GB:b") .addMessage(EN_GB, "c", "en-GB:c") // common settings - .addMessageFallbackKeyPrefix("fallback") + .prefixQueries("", "fallback") .setDefaultLocale(PL_PL) .build() when: diff --git a/src/test/groovy/com/coditory/quark/i18n/MessageResolutionSpec.groovy b/src/test/groovy/com/coditory/quark/i18n/MessageResolutionSpec.groovy index 655fa93..3d0b312 100755 --- a/src/test/groovy/com/coditory/quark/i18n/MessageResolutionSpec.groovy +++ b/src/test/groovy/com/coditory/quark/i18n/MessageResolutionSpec.groovy @@ -41,7 +41,7 @@ class MessageResolutionSpec extends Specification { .addMessage(PL, "x.y.c", "pl:x.y.c") .setDefaultLocale(PL_PL) .build() - .prefixQueries("x.y") + .prefixQueries("x.y", "") expect: messagePack.getMessage(EN_US, "a") == "en-US:x.y.a" messagePack.getMessage(EN_US, "b") == "en-US:b" diff --git a/src/test/groovy/com/coditory/quark/i18n/ReferenceHierarchySpec.groovy b/src/test/groovy/com/coditory/quark/i18n/ReferenceHierarchySpec.groovy index 6957db0..9102645 100755 --- a/src/test/groovy/com/coditory/quark/i18n/ReferenceHierarchySpec.groovy +++ b/src/test/groovy/com/coditory/quark/i18n/ReferenceHierarchySpec.groovy @@ -85,7 +85,7 @@ class ReferenceHierarchySpec extends Specification { .addMessage(PL, "fallback.f", "pl:fallback.f") // common settings .setDefaultLocale(PL_PL) - .addFallbackKeyPrefix("fallback") + .prefixReferenceQueries("", "fallback") .build() .getMessage(locale, "msg") then: