introduce improved key path representation models

This commit is contained in:
marhali 2022-01-12 09:04:06 +01:00
parent 8e4179983b
commit 939ef0b283
4 changed files with 154 additions and 0 deletions

View File

@ -0,0 +1,30 @@
package de.marhali.easyi18n.model;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Represents a full translation key with all sections.
* Implementations can use single section or variable section length variants.
* The respective layer (io, presentation) is responsible for using the correct mapping mechanism.
* @author marhali
*/
public class KeyPath extends ArrayList<String> {
public static final String DELIMITER = ".";
public static KeyPath of(String... path) {
return new KeyPath(List.of(path));
}
public KeyPath() {
super();
}
public KeyPath(@NotNull Collection<? extends String> c) {
super(c);
}
}

View File

@ -0,0 +1,69 @@
package de.marhali.easyi18n.model;
import com.intellij.openapi.project.Project;
import de.marhali.easyi18n.service.SettingsService;
import org.jetbrains.annotations.NotNull;
import java.util.regex.Pattern;
/**
* Responsible for mapping {@link KeyPath} into single string and backwards.
* If nesting is enabled the delimiter within a section is escaped otherwise the delimiter between the key sections.
* @author marhali
*/
public class KeyPathConverter {
private final boolean nestKeys;
public KeyPathConverter(boolean nestKeys) {
this.nestKeys = nestKeys;
}
public KeyPathConverter(@NotNull Project project) {
this(SettingsService.getInstance(project).getState().isNestedKeys());
}
public @NotNull String concat(@NotNull KeyPath path) {
StringBuilder builder = new StringBuilder();
for(String section : path) {
if(builder.length() > 0) {
if(!this.nestKeys) {
builder.append("\\\\");
}
builder.append(KeyPath.DELIMITER);
}
if(this.nestKeys) {
builder.append(section.replace(KeyPath.DELIMITER, "\\\\" + KeyPath.DELIMITER));
} else {
builder.append(section);
}
}
return builder.toString();
}
public @NotNull KeyPath split(@NotNull String concatPath) {
String[] sections = concatPath.split(this.nestKeys ?
"(?<!\\\\)" + Pattern.quote(KeyPath.DELIMITER) : Pattern.quote("\\\\" + KeyPath.DELIMITER));
KeyPath path = new KeyPath();
for(String section : sections) {
path.add(section.replace("\\\\" + KeyPath.DELIMITER, KeyPath.DELIMITER));
}
return path;
}
@Override
public String toString() {
return "KeyPathConverter{" +
"nestKeys=" + nestKeys +
'}';
}
}

View File

@ -16,7 +16,9 @@ import java.util.regex.Pattern;
* 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
* @deprecated Replaced by KeyPathConverter
*/
@Deprecated
public class PathUtil {
public static final String DELIMITER = ".";

View File

@ -0,0 +1,53 @@
package de.marhali.easyi18n;
import de.marhali.easyi18n.model.KeyPath;
import de.marhali.easyi18n.model.KeyPathConverter;
import org.junit.Assert;
import org.junit.Test;
/**
* Unit tests for {@link KeyPathConverter}.
* @author marhali
*/
public class KeyPathConverterTest {
private final KeyPathConverter deepMapper = new KeyPathConverter(true);
private final KeyPathConverter flatMapper = new KeyPathConverter(false);
@Test
public void testNestedConcat() {
Assert.assertEquals("first\\\\.section.second.third",
deepMapper.concat(KeyPath.of("first.section", "second", "third")));
Assert.assertEquals("first.second.third",
deepMapper.concat(KeyPath.of("first", "second", "third")));
}
@Test
public void testNestedSplit() {
Assert.assertEquals(KeyPath.of("first.section", "second", "third"),
deepMapper.split("first\\\\.section.second.third"));
Assert.assertEquals(KeyPath.of("first", "second", "third"),
deepMapper.split("first.second.third"));
}
@Test
public void testNonNestedConcat() {
Assert.assertEquals("flat.map\\\\.deeper",
flatMapper.concat(KeyPath.of("flat.map", "deeper")));
Assert.assertEquals("flat.map.keys",
flatMapper.concat(KeyPath.of("flat.map.keys")));
}
@Test
public void testNonNestedSplit() {
Assert.assertEquals(KeyPath.of("flat.keys.with", "deep.section"),
flatMapper.split("flat.keys.with\\\\.deep.section"));
Assert.assertEquals(KeyPath.of("flat.keys.only"),
flatMapper.split("flat.keys.only"));
}
}