introduce new data structure for translation values

This commit is contained in:
marhali 2022-04-07 16:10:17 +02:00
parent 29721d3016
commit 0f2b8ade4c
6 changed files with 266 additions and 0 deletions

View File

@ -0,0 +1,175 @@
package de.marhali.easyi18n.model.translation;
import de.marhali.easyi18n.model.translation.variant.Plural;
import de.marhali.easyi18n.model.translation.variant.ContextMap;
import de.marhali.easyi18n.model.translation.variant.LocaleMap;
import de.marhali.easyi18n.model.translation.variant.PluralMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Represents the set values behind a specific translation.
* Consideration is given to context, pluralization and locale.
* <br />
* Data structure can be imagined like a layered map of: context => plural => locale
*
* @author marhali
*/
public class Translation {
private @Nullable String description;
private @NotNull ContextMap contexts;
private @Nullable Object misc;
public Translation(@Nullable String description, @NotNull ContextMap contexts, @Nullable Object misc) {
this.description = description;
this.contexts = contexts;
this.misc = misc;
}
public Translation() {
this(null, new ContextMap(), null);
}
/**
* Retrieve additional description for this translation
* @return Description
*/
public @Nullable String getDescription() {
return description;
}
/**
* Override or set description for this translation
* @param description Description
*/
public void setDescription(@Nullable String description) {
this.description = description;
}
/**
* Retrieve all contexts for this translation
* @return Map of specified contexts
*/
public @NotNull ContextMap getContexts() {
return contexts;
}
/**
* Check whether a specific context has been set for this translation
* @param context Context to check
* @return True if context has been configured otherwise false
*/
public boolean hasContext(@NotNull String context) {
return contexts.containsKey(context);
}
/**
* Retrieve all plurals for a specific context.
* @param context Context to apply
* @return Map of specified plurals
*/
public @Nullable PluralMap getPlurals(@NotNull String context) {
return contexts.get(context);
}
/**
* Retrieve all locale translations for a specific context & pluralization
* @param context Context to apply
* @param plural Pluralization to apply
* @return Map of specified locales
*/
public @Nullable LocaleMap getLocales(@NotNull String context, @NotNull Plural plural) {
return contexts.getOrDefault(context, new PluralMap()).get(plural);
}
/**
* Retrieve a specific locale translation for a specific context, pluralization and locale
* @param context Context to apply
* @param plural Pluralization to apply
* @param locale Locale to apply
* @return Translated locale value for the specified variant
*/
public @Nullable String getValue(@NotNull String context, @NotNull Plural plural, @NotNull String locale) {
return contexts.getOrDefault(context, new PluralMap()).getOrDefault(plural, new LocaleMap()).get(locale);
}
/**
* Override or set context map.
* @param contexts New contexts
*/
public void set(@NotNull ContextMap contexts) {
this.contexts = contexts;
}
/**
* Override or set a specific context
* @param context Context to use
* @param plurals New plurals map
*/
public void set(@NotNull String context, @NotNull PluralMap plurals) {
contexts.put(context, plurals);
}
/**
* Override or set locales for a specific context & pluralization
* @param context Context to use
* @param plural Pluralization to use
* @param locales New locales map
*/
public void set(@NotNull String context, @NotNull Plural plural, @NotNull LocaleMap locales) {
PluralMap plurals = getPlurals(context);
if(plurals == null) {
plurals = new PluralMap();
}
plurals.put(plural, locales);
set(context, plurals);
}
/**
* Override or update a specific translation variant
* @param context Context to use
* @param plural Pluralization to use
* @param locale Locale to use
* @param value New value to set
*/
public void set(@NotNull String context, @NotNull Plural plural, @NotNull String locale, @NotNull String value) {
LocaleMap locales = getLocales(context, plural);
if(locales == null) {
locales = new LocaleMap();
}
locales.put(locale, value);
set(context, plural, locales);
}
/**
* I18n support data
* @return Data
*/
public @Nullable Object getMisc() {
return misc;
}
/**
* Set or update I18n support data
* @param misc New Data
*/
public void setMisc(@Nullable Object misc) {
this.misc = misc;
}
@Override
public String toString() {
return "Translation{" +
"description='" + description + '\'' +
", contexts=" + contexts +
", misc=" + misc +
'}';
}
}

View File

@ -0,0 +1,11 @@
package de.marhali.easyi18n.model.translation.variant;
import java.util.HashMap;
/**
* Maps context with pluralization.
* @author marhali
*/
public class ContextMap extends HashMap<String, PluralMap> {
public static final String DEFAULT = "default";
}

View File

@ -0,0 +1,17 @@
package de.marhali.easyi18n.model.translation.variant;
import java.util.HashMap;
import java.util.Map;
/**
* Maps locale type with specified value
* @author marhali
*/
public class LocaleMap extends HashMap<String, String> {
public LocaleMap() {}
public LocaleMap(Map<? extends String, ? extends String> m) {
super(m);
}
}

View File

@ -0,0 +1,11 @@
package de.marhali.easyi18n.model.translation.variant;
/**
* Represents all possible pluralization forms a translation can support.
* @author marhali
*/
public enum Plural {
ZERO, ONE, TWO, FEW, MANY, OTHER;
public static final Plural DEFAULT = Plural.ONE;
}

View File

@ -0,0 +1,9 @@
package de.marhali.easyi18n.model.translation.variant;
import java.util.HashMap;
/**
* Maps pluralization with locale values.
* @author marhali
*/
public class PluralMap extends HashMap<Plural, LocaleMap> {}

View File

@ -0,0 +1,43 @@
package de.marhali.easyi18n;
import de.marhali.easyi18n.model.translation.variant.Plural;
import de.marhali.easyi18n.model.translation.variant.ContextMap;
import de.marhali.easyi18n.model.translation.variant.LocaleMap;
import de.marhali.easyi18n.model.translation.Translation;
import org.junit.Assert;
import org.junit.Test;
import java.util.Map;
/**
* Unit tests for {@link Translation}.
* @author marhali
*/
public class TranslationTest {
@Test
public void add() {
Translation value = new Translation();
value.set(ContextMap.DEFAULT, Plural.DEFAULT, "en", "hello");
Assert.assertEquals(value.getValue(ContextMap.DEFAULT, Plural.DEFAULT, "en"), "hello");
}
@Test
public void override() {
Translation value = new Translation();
value.set(ContextMap.DEFAULT, Plural.DEFAULT, new LocaleMap(Map.of("en", "hello", "de", "hallo")));
value.set(ContextMap.DEFAULT, Plural.DEFAULT, "en", "new hello");
Assert.assertEquals(value.getValue(ContextMap.DEFAULT, Plural.DEFAULT, "en"), "new hello");
Assert.assertEquals(value.getValue(ContextMap.DEFAULT, Plural.DEFAULT, "de"), "hallo");
}
@Test
public void plurals() {
Translation value = new Translation();
value.set(ContextMap.DEFAULT, Plural.ONE, "en", "boyfriend");
value.set(ContextMap.DEFAULT, Plural.MANY, "en", "boyfriends");
Assert.assertEquals(value.getValue(ContextMap.DEFAULT, Plural.ONE, "en"), "boyfriend");
Assert.assertEquals(value.getValue(ContextMap.DEFAULT, Plural.MANY, "en"), "boyfriends");
}
}