implement new translation data holder with optimized tree structure
This commit is contained in:
parent
2b36b355e4
commit
594fc82be7
19
src/main/java/de/marhali/easyi18n/model/Translation.java
Normal file
19
src/main/java/de/marhali/easyi18n/model/Translation.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package de.marhali.easyi18n.model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents all translations for an element. The assignment to an element is done in the using class.
|
||||||
|
* This class contains only the translations for this unspecific element.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class Translation extends HashMap<String, String> {
|
||||||
|
public Translation() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString();
|
||||||
|
}
|
||||||
|
}
|
181
src/main/java/de/marhali/easyi18n/model/TranslationData.java
Normal file
181
src/main/java/de/marhali/easyi18n/model/TranslationData.java
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
package de.marhali.easyi18n.model;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.util.PathUtil;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached translation data. The data is stored in a tree structure.
|
||||||
|
* Tree behaviour (sorted, non-sorted) can be specified via constructor.
|
||||||
|
* For more please see {@link TranslationNode}. Example tree view:
|
||||||
|
*
|
||||||
|
* #################################
|
||||||
|
* # - user: #
|
||||||
|
* # - principal: 'Principal' #
|
||||||
|
* # - username: #
|
||||||
|
* # - title: 'Username' #
|
||||||
|
* # - auth: #
|
||||||
|
* # - logout: 'Logout' #
|
||||||
|
* # - login: 'Login' #
|
||||||
|
* #################################
|
||||||
|
*
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class TranslationData {
|
||||||
|
|
||||||
|
private final PathUtil pathUtil;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Set<String> locales;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TranslationNode rootNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty instance.
|
||||||
|
* @param sort Should the translation keys be sorted alphabetically
|
||||||
|
*/
|
||||||
|
public TranslationData(boolean sort, boolean nestKeys) {
|
||||||
|
this(nestKeys, new HashSet<>(), new TranslationNode(sort ? new TreeMap<>() : new LinkedHashMap<>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param nestKeys Apply key nesting. See {@link PathUtil}
|
||||||
|
* @param locales Languages which can be used for translation
|
||||||
|
* @param rootNode Translation tree structure
|
||||||
|
*/
|
||||||
|
public TranslationData(boolean nestKeys, @NotNull Set<String> locales, @NotNull TranslationNode rootNode) {
|
||||||
|
this.pathUtil = new PathUtil(nestKeys);
|
||||||
|
this.locales = locales;
|
||||||
|
this.rootNode = rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Set of languages which can receive translations
|
||||||
|
*/
|
||||||
|
public @NotNull Set<String> getLocales() {
|
||||||
|
return this.locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return root node which contains all translations
|
||||||
|
*/
|
||||||
|
public @NotNull TranslationNode getRootNode() {
|
||||||
|
return this.rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fullPath Absolute translation path
|
||||||
|
* @return Translation node which leads to translations or nested child's
|
||||||
|
*/
|
||||||
|
public @Nullable TranslationNode getNode(@NotNull String fullPath) {
|
||||||
|
List<String> sections = this.pathUtil.split(fullPath);
|
||||||
|
TranslationNode node = this.rootNode;
|
||||||
|
|
||||||
|
if(fullPath.isEmpty()) { // Return root node if empty path was supplied
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String section : sections) {
|
||||||
|
if(node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
node = node.getChildren().get(section);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fullPath Absolute translation key path
|
||||||
|
* @return Found translation. Can be null if path is empty or is not a leaf element
|
||||||
|
*/
|
||||||
|
public @Nullable Translation getTranslation(@NotNull String fullPath) {
|
||||||
|
TranslationNode node = this.getNode(fullPath);
|
||||||
|
|
||||||
|
if(node == null || !node.isLeaf()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fullPath Absolute translation key path
|
||||||
|
* @param translation Translation to set. Can be null to delete the corresponding node
|
||||||
|
*/
|
||||||
|
public void setTranslation(@NotNull String fullPath, @Nullable Translation translation) throws Exception {
|
||||||
|
List<String> sections = this.pathUtil.split(fullPath);
|
||||||
|
String nodeKey = sections.remove(sections.size() - 1); // Edge case last section
|
||||||
|
TranslationNode node = this.rootNode;
|
||||||
|
|
||||||
|
if(fullPath.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Path cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String section : sections) { // Go to the level of the key (@nodeKey)
|
||||||
|
TranslationNode childNode = node.getChildren().get(section);
|
||||||
|
|
||||||
|
if(childNode == null) {
|
||||||
|
if(translation == null) { // Path should not be empty for delete
|
||||||
|
throw new IllegalArgumentException("Delete action on empty path");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Created nested section
|
||||||
|
childNode = node.addChildren(section);
|
||||||
|
}
|
||||||
|
|
||||||
|
node = childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(translation == null) { // Delete
|
||||||
|
node.removeChildren(nodeKey);
|
||||||
|
|
||||||
|
if(node.getChildren().isEmpty() && !node.isRoot()) { // Parent is empty now. Run delete recursively
|
||||||
|
this.setTranslation(this.pathUtil.concat(sections), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // Create or overwrite
|
||||||
|
node.addChildren(nodeKey, translation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return All translation keys as absolute paths (full-key)
|
||||||
|
*/
|
||||||
|
public @NotNull Set<String> getFullKeys() {
|
||||||
|
return this.getFullKeys("", this.rootNode); // Just use root node
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param parentPath Parent key path
|
||||||
|
* @param node Node section to begin with
|
||||||
|
* @return All translation keys where the path contains the specified @parentPath
|
||||||
|
*/
|
||||||
|
public @NotNull Set<String> getFullKeys(String parentPath, TranslationNode node) {
|
||||||
|
Set<String> keys = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
if(node.isLeaf()) { // This node does not lead to child's - just add the key
|
||||||
|
keys.add(parentPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Map.Entry<String, TranslationNode> children : node.getChildren().entrySet()) {
|
||||||
|
keys.addAll(this.getFullKeys(this.pathUtil.append(parentPath, children.getKey()), children.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TranslationData{" +
|
||||||
|
"mapClass=" + rootNode.getChildren().getClass().getSimpleName() +
|
||||||
|
", pathUtil=" + pathUtil +
|
||||||
|
", locales=" + locales +
|
||||||
|
", rootNode=" + rootNode +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
101
src/main/java/de/marhali/easyi18n/model/TranslationNode.java
Normal file
101
src/main/java/de/marhali/easyi18n/model/TranslationNode.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package de.marhali.easyi18n.model;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translation tree node. Manages child nodes which can be translations or also
|
||||||
|
* nodes which can lead to another translation or node.
|
||||||
|
* Navigation inside a node can be upward and downward. To construct the full
|
||||||
|
* translation key (full-key) every parent needs to be resolved recursively.
|
||||||
|
* -
|
||||||
|
* Whether the children nodes should be sorted is determined by the parent node.
|
||||||
|
* For root nodes (empty parent) the {@link java.util.Map}-Type must be specified
|
||||||
|
* to determine which sorting should be applied.
|
||||||
|
*
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class TranslationNode {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private TranslationNode parent;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, TranslationNode> children;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Translation value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root node initializer. E.g. see {@link java.util.TreeMap} or {@link java.util.HashMap}
|
||||||
|
* @param children Decide which implementation should be used (sorted, non-sorted)
|
||||||
|
*/
|
||||||
|
public TranslationNode(@NotNull Map<String, TranslationNode> children) {
|
||||||
|
this.parent = null;
|
||||||
|
this.children = children;
|
||||||
|
this.value = new Translation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this node is considered as root node
|
||||||
|
*/
|
||||||
|
public boolean isRoot() {
|
||||||
|
return this.parent == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this node does not lead to other children nodes (just contains {@link Translation} itself).
|
||||||
|
* The root node is never treated as a leaf node.
|
||||||
|
*/
|
||||||
|
public boolean isLeaf() {
|
||||||
|
return this.children.isEmpty() && !this.isRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(@Nullable TranslationNode parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Translation getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(@NotNull Translation value) {
|
||||||
|
this.children.clear();
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Map<String, TranslationNode> getChildren() {
|
||||||
|
return this.children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChildren(@NotNull String key, @NotNull TranslationNode node) {
|
||||||
|
node.setParent(this); // Track parent if adding children's
|
||||||
|
this.value.clear();
|
||||||
|
this.children.put(key, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslationNode addChildren(@NotNull String key) throws Exception {
|
||||||
|
TranslationNode node = new TranslationNode(this.children.getClass().getDeclaredConstructor().newInstance());
|
||||||
|
this.addChildren(key, node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChildren(@NotNull String key, @NotNull Translation translation) throws Exception {
|
||||||
|
this.addChildren(key).setValue(translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeChildren(@NotNull String key) {
|
||||||
|
this.children.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TranslationNode{" +
|
||||||
|
"parent=" + parent +
|
||||||
|
", children=" + children.keySet() +
|
||||||
|
", value=" + value +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
73
src/main/java/de/marhali/easyi18n/util/PathUtil.java
Normal file
73
src/main/java/de/marhali/easyi18n/util/PathUtil.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package de.marhali.easyi18n.util;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility tool for split and merge translation key paths.
|
||||||
|
* Some i18n implementations require to NOT nest the translation keys.
|
||||||
|
* This util takes care of this and checks the configured setting for this case.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class PathUtil {
|
||||||
|
|
||||||
|
public static final char DELIMITER = '.';
|
||||||
|
|
||||||
|
private final boolean nestKeys;
|
||||||
|
|
||||||
|
public PathUtil(boolean nestKeys) {
|
||||||
|
this.nestKeys = nestKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathUtil(Project project) {
|
||||||
|
this.nestKeys = SettingsService.getInstance(project).getState().isNestedKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull List<String> split(@NotNull String path) {
|
||||||
|
// Does not contain any sections or key nesting is disabled
|
||||||
|
if(!path.contains(String.valueOf(DELIMITER)) || !nestKeys) {
|
||||||
|
return new ArrayList<>(Collections.singletonList(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<>(Arrays.asList(path.split("\\" + DELIMITER)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String concat(@NotNull List<String> sections) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
// For disabled key nesting this should be only one section
|
||||||
|
for(String section : sections) {
|
||||||
|
if(builder.length() > 0) {
|
||||||
|
builder.append(DELIMITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(section);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String append(@NotNull String parentPath, @NotNull String children) {
|
||||||
|
StringBuilder builder = new StringBuilder(parentPath);
|
||||||
|
|
||||||
|
if(builder.length() > 0) { // Only add delimiter between parent and child if parent is NOT empty
|
||||||
|
builder.append(DELIMITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.append(children).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PathUtil{" +
|
||||||
|
"nestKeys=" + nestKeys +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package de.marhali.easyi18n.util;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.model.Translation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translation builder utility.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class TranslationBuilder {
|
||||||
|
|
||||||
|
private Translation translation;
|
||||||
|
|
||||||
|
public TranslationBuilder() {
|
||||||
|
this.translation = new Translation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslationBuilder(String locale, String content) {
|
||||||
|
this();
|
||||||
|
this.translation.put(locale, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslationBuilder add(String locale, String content) {
|
||||||
|
this.translation.put(locale, content);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Translation build() {
|
||||||
|
return this.translation;
|
||||||
|
}
|
||||||
|
}
|
271
src/test/java/de/marhali/easyi18n/TranslationDataTest.java
Normal file
271
src/test/java/de/marhali/easyi18n/TranslationDataTest.java
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
package de.marhali.easyi18n;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.model.Translation;
|
||||||
|
import de.marhali.easyi18n.model.TranslationData;
|
||||||
|
import de.marhali.easyi18n.model.TranslationNode;
|
||||||
|
import de.marhali.easyi18n.util.TranslationBuilder;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link TranslationData} in combination with {@link TranslationNode}
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class TranslationDataTest {
|
||||||
|
|
||||||
|
private final int numOfTranslations = 18;
|
||||||
|
|
||||||
|
private void addTranslations(TranslationData data) throws Exception {
|
||||||
|
data.setTranslation("zulu", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("gamma", new TranslationBuilder("en", "test").build());
|
||||||
|
|
||||||
|
data.setTranslation("foxtrot.super.long.key", new TranslationBuilder("en", "test").build());
|
||||||
|
|
||||||
|
data.setTranslation("bravo.b", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("bravo.c", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("bravo.a", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("bravo.d", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("bravo.long.bravo", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("bravo.long.charlie.a", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("bravo.long.alpha", new TranslationBuilder("en", "test").build());
|
||||||
|
|
||||||
|
data.setTranslation("alpha.b", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("alpha.c", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("alpha.a", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("alpha.d", new TranslationBuilder("en", "test").build());
|
||||||
|
|
||||||
|
data.setTranslation("charlie.b", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("charlie.c", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("charlie.a", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("charlie.d", new TranslationBuilder("en", "test").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeySorting() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, true);
|
||||||
|
this.addTranslations(data);
|
||||||
|
|
||||||
|
Set<String> expectation = new LinkedHashSet<>(Arrays.asList(
|
||||||
|
"alpha.a", "alpha.b", "alpha.c", "alpha.d",
|
||||||
|
"bravo.a", "bravo.b", "bravo.c", "bravo.d",
|
||||||
|
"bravo.long.alpha", "bravo.long.bravo", "bravo.long.charlie.a",
|
||||||
|
"charlie.a", "charlie.b", "charlie.c", "charlie.d",
|
||||||
|
"foxtrot.super.long.key",
|
||||||
|
"gamma",
|
||||||
|
"zulu"
|
||||||
|
));
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys(), expectation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeyUnordered() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(false, true);
|
||||||
|
this.addTranslations(data);
|
||||||
|
|
||||||
|
Set<String> expectation = new LinkedHashSet<>(Arrays.asList(
|
||||||
|
"zulu",
|
||||||
|
"gamma",
|
||||||
|
"foxtrot.super.long.key",
|
||||||
|
"bravo.b", "bravo.c", "bravo.a", "bravo.d",
|
||||||
|
"bravo.long.bravo", "bravo.long.charlie.a", "bravo.long.alpha",
|
||||||
|
"alpha.b", "alpha.c", "alpha.a", "alpha.d",
|
||||||
|
"charlie.b", "charlie.c", "charlie.a", "charlie.d"
|
||||||
|
));
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys(), expectation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeyNesting() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, true);
|
||||||
|
|
||||||
|
data.setTranslation("nested.alpha", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("nested.bravo", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("other.alpha", new TranslationBuilder("en", "test").build());
|
||||||
|
data.setTranslation("other.bravo", new TranslationBuilder("en", "test").build());
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getRootNode().getChildren().size(), 2);
|
||||||
|
|
||||||
|
for(TranslationNode node : data.getRootNode().getChildren().values()) {
|
||||||
|
Assert.assertFalse(node.isLeaf());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeyNonNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, false);
|
||||||
|
this.addTranslations(data);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getRootNode().getChildren().size(), this.numOfTranslations);
|
||||||
|
|
||||||
|
for(TranslationNode node : data.getRootNode().getChildren().values()) {
|
||||||
|
Assert.assertTrue(node.isLeaf());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, true);
|
||||||
|
|
||||||
|
Translation value = new TranslationBuilder("en", "test").build();
|
||||||
|
|
||||||
|
data.setTranslation("alpha", value);
|
||||||
|
data.setTranslation("nested.alpha", value);
|
||||||
|
data.setTranslation("nested.long.bravo", value);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 3);
|
||||||
|
|
||||||
|
data.setTranslation("alpha", null);
|
||||||
|
data.setTranslation("nested.alpha", null);
|
||||||
|
data.setTranslation("nested.long.bravo", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 0);
|
||||||
|
Assert.assertNull(data.getTranslation("alpha"));
|
||||||
|
Assert.assertNull(data.getTranslation("nested.alpha"));
|
||||||
|
Assert.assertNull(data.getTranslation("nested.long.bravo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteNonNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, false);
|
||||||
|
|
||||||
|
Translation value = new TranslationBuilder("en", "test").build();
|
||||||
|
|
||||||
|
data.setTranslation("alpha", value);
|
||||||
|
data.setTranslation("nested.alpha", value);
|
||||||
|
data.setTranslation("nested.long.bravo", value);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 3);
|
||||||
|
|
||||||
|
data.setTranslation("alpha", null);
|
||||||
|
data.setTranslation("nested.alpha", null);
|
||||||
|
data.setTranslation("nested.long.bravo", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 0);
|
||||||
|
Assert.assertNull(data.getTranslation("alpha"));
|
||||||
|
Assert.assertNull(data.getTranslation("nested.alpha"));
|
||||||
|
Assert.assertNull(data.getTranslation("nested.long.bravo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecurseDeleteNonNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, false);
|
||||||
|
this.addTranslations(data);
|
||||||
|
|
||||||
|
data.setTranslation("foxtrot.super.long.key", null);
|
||||||
|
|
||||||
|
Assert.assertNull(data.getTranslation("foxtrot.super.long.key"));
|
||||||
|
Assert.assertNull(data.getRootNode().getChildren().get("foxtrot"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecurseDeleteNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, true);
|
||||||
|
this.addTranslations(data);
|
||||||
|
|
||||||
|
data.setTranslation("foxtrot.super.long.key", null);
|
||||||
|
|
||||||
|
Assert.assertNull(data.getTranslation("foxtrot.super.long.key"));
|
||||||
|
Assert.assertNull(data.getRootNode().getChildren().get("foxtrot"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOverwriteNonNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, false);
|
||||||
|
|
||||||
|
Translation before = new TranslationBuilder("en", "before").build();
|
||||||
|
Translation after = new TranslationBuilder("en", "after").build();
|
||||||
|
|
||||||
|
data.setTranslation("alpha", before);
|
||||||
|
data.setTranslation("nested.alpha", before);
|
||||||
|
data.setTranslation("nested.long.bravo", before);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||||
|
|
||||||
|
data.setTranslation("alpha", after);
|
||||||
|
data.setTranslation("nested.alpha", after);
|
||||||
|
data.setTranslation("nested.long.bravo", after);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOverwriteNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, true);
|
||||||
|
|
||||||
|
Translation before = new TranslationBuilder("en", "before").build();
|
||||||
|
Translation after = new TranslationBuilder("en", "after").build();
|
||||||
|
|
||||||
|
data.setTranslation("alpha", before);
|
||||||
|
data.setTranslation("nested.alpha", before);
|
||||||
|
data.setTranslation("nested.long.bravo", before);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||||
|
|
||||||
|
data.setTranslation("alpha", after);
|
||||||
|
data.setTranslation("nested.alpha", after);
|
||||||
|
data.setTranslation("nested.long.bravo", after);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecurseTransformNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, true);
|
||||||
|
|
||||||
|
Translation value = new TranslationBuilder("en", "test").build();
|
||||||
|
|
||||||
|
data.setTranslation("alpha.nested.key", value);
|
||||||
|
data.setTranslation("alpha.other", value);
|
||||||
|
data.setTranslation("bravo", value);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 3);
|
||||||
|
|
||||||
|
data.setTranslation("alpha.nested", value);
|
||||||
|
data.setTranslation("alpha.other.new", value);
|
||||||
|
data.setTranslation("bravo", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 2);
|
||||||
|
Assert.assertNull(data.getTranslation("alpha.nested.key"));
|
||||||
|
Assert.assertNull(data.getTranslation("alpha.other"));
|
||||||
|
Assert.assertNull(data.getTranslation("bravo"));
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha.nested"), value);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha.other.new"), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRecurseTransformNonNested() throws Exception {
|
||||||
|
TranslationData data = new TranslationData(true, false);
|
||||||
|
|
||||||
|
Translation value = new TranslationBuilder("en", "test").build();
|
||||||
|
|
||||||
|
data.setTranslation("alpha.nested.key", value);
|
||||||
|
data.setTranslation("alpha.other", value);
|
||||||
|
data.setTranslation("bravo", value);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 3);
|
||||||
|
|
||||||
|
data.setTranslation("alpha.nested", value);
|
||||||
|
data.setTranslation("alpha.other.new", value);
|
||||||
|
data.setTranslation("bravo", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(data.getFullKeys().size(), 4);
|
||||||
|
Assert.assertNull(data.getTranslation("bravo"));
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha.nested.key"), value);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha.other"), value);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha.nested"), value);
|
||||||
|
Assert.assertEquals(data.getTranslation("alpha.other.new"), value);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user