diff --git a/api/src/main/java/net/kyori/adventure/translation/AbstractTranslationStore.java b/api/src/main/java/net/kyori/adventure/translation/AbstractTranslationStore.java index 848367d4d..1a165b6f3 100644 --- a/api/src/main/java/net/kyori/adventure/translation/AbstractTranslationStore.java +++ b/api/src/main/java/net/kyori/adventure/translation/AbstractTranslationStore.java @@ -140,6 +140,14 @@ public final void unregister(final String key) { this.translations.remove(key); } + @Override + public final void unregister(final String key, final Locale locale) { + this.translations.computeIfPresent(requireNonNull(key, "key"), (ignored, translation) -> { + translation.unregister(requireNonNull(locale, "locale")); + return translation.isEmpty() ? null : translation; + }); + } + @Override public final Key name() { return this.name; @@ -201,6 +209,14 @@ private void register(final Locale locale, final T translation) { } } + private void unregister(final Locale locale) { + this.translations.remove(locale); + } + + private boolean isEmpty() { + return this.translations.isEmpty(); + } + @Override public boolean equals(final Object other) { if (this == other) return true; diff --git a/api/src/main/java/net/kyori/adventure/translation/TranslationStore.java b/api/src/main/java/net/kyori/adventure/translation/TranslationStore.java index e8e5204dd..377f8c840 100644 --- a/api/src/main/java/net/kyori/adventure/translation/TranslationStore.java +++ b/api/src/main/java/net/kyori/adventure/translation/TranslationStore.java @@ -166,6 +166,18 @@ default boolean canTranslate(final String key, final Locale locale) { */ void unregister(final String key); + /** + * Unregisters a translation for a key and locale. + * + *

If this is the last translation registered for the key, the key is also + * unregistered.

+ * + * @param key a translation key + * @param locale a locale + * @since 5.2.1 + */ + void unregister(final String key, final Locale locale); + /** * An abstract, string-based translation store. * diff --git a/api/src/test/java/net/kyori/adventure/translation/TranslationStoreTest.java b/api/src/test/java/net/kyori/adventure/translation/TranslationStoreTest.java index 95e83a9e5..4a3f1585c 100644 --- a/api/src/test/java/net/kyori/adventure/translation/TranslationStoreTest.java +++ b/api/src/test/java/net/kyori/adventure/translation/TranslationStoreTest.java @@ -38,8 +38,10 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; class TranslationStoreTest { static final TranslationStore.StringBased REGISTRY = TranslationStore.messageFormat(Key.key("adventure", "test")); @@ -58,6 +60,35 @@ void testRegister_duplicate() { assertThrows(IllegalArgumentException.class, () -> REGISTRY.register("test", Locale.US, new MessageFormat("Another test."))); } + @Test + void testUnregister_locale() { + final TranslationStore.StringBased store = TranslationStore.messageFormat(Key.key("adventure", "locale-unregister")); + final MessageFormat english = new MessageFormat("Hello", Locale.US); + final MessageFormat german = new MessageFormat("Hallo", Locale.GERMANY); + store.register("hello-world", Locale.US, english); + store.register("hello-world", Locale.GERMANY, german); + + store.unregister("hello-world", Locale.GERMANY); + + assertEquals(english, store.translate("hello-world", Locale.US)); + assertFalse(store.contains("hello-world", Locale.GERMANY)); + assertTrue(store.contains("hello-world")); + } + + @Test + void testUnregister_locale_lastTranslation() { + final TranslationStore.StringBased store = TranslationStore.messageFormat(Key.key("adventure", "locale-unregister-last")); + final MessageFormat translation = new MessageFormat("Hello", Locale.US); + store.register("hello-world", Locale.US, translation); + + store.unregister("hello-world", Locale.US); + + assertFalse(store.contains("hello-world")); + assertFalse(store.contains("hello-world", Locale.US)); + store.register("hello-world", Locale.US, translation); + assertEquals(translation, store.translate("hello-world", Locale.US)); + } + @Test void testTranslate() { final MessageFormat expected = new MessageFormat("A what?", Locale.CANADA);