rewrite i18n key handling
- Translation keys are now based on KeyPath type which is simply a string list - Handling delimiter character within a section layer is now easier - Only the presentation layer has to deal with displaying the correct concatenated key
This commit is contained in:
parent
44310d5459
commit
c0e385000a
@ -5,12 +5,14 @@
|
||||
## [Unreleased]
|
||||
### BREAKING CHANGES
|
||||
- Translation file pattern matcher needs to be updated to <kbd>\*.*</kbd> or equivalent wildcard rule
|
||||
- I18n key nesting will now escape every delimiter within a section layer (can be inverted via option)
|
||||
|
||||
### Added
|
||||
- Full keyboard shortcut support inside tool-window
|
||||
- Support for dots within key nodes in YAML files
|
||||
|
||||
### Changed
|
||||
- Key completion inside editor suggests all keys without any logic
|
||||
- Translation file pattern uses wildcard matcher instead of regex
|
||||
- Improve exception handling on IO operations
|
||||
- Update Qodana to latest version
|
||||
|
@ -1,5 +1,6 @@
|
||||
package de.marhali.easyi18n;
|
||||
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.bus.BusListener;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
|
||||
@ -42,7 +43,7 @@ public class DataBus {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusKey(@Nullable String key) {
|
||||
public void onFocusKey(@Nullable KeyPath key) {
|
||||
listener.forEach(li -> li.onFocusKey(key));
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class DataStore {
|
||||
|
||||
protected DataStore(@NotNull Project project) {
|
||||
this.project = project;
|
||||
this.data = new TranslationData(true, true); // Initialize with hard-coded configuration
|
||||
this.data = new TranslationData(true); // Initialize with hard-coded configuration
|
||||
this.changeListener = new FileChangeListener(project);
|
||||
|
||||
VirtualFileManager.getInstance().addAsyncFileListener(
|
||||
@ -63,7 +63,7 @@ public class DataStore {
|
||||
String localesPath = state.getLocalesPath();
|
||||
|
||||
if(localesPath == null || localesPath.isEmpty()) { // Populate empty instance
|
||||
this.data = new TranslationData(state.isSortKeys(), state.isNestedKeys());
|
||||
this.data = new TranslationData(state.isSortKeys());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ public class DataStore {
|
||||
|
||||
strategy.read(this.project, localesPath, state, (data) -> {
|
||||
this.data = data == null
|
||||
? new TranslationData(state.isSortKeys(), state.isNestedKeys())
|
||||
? new TranslationData(state.isSortKeys())
|
||||
: data;
|
||||
|
||||
successResult.accept(data != null);
|
||||
|
@ -3,15 +3,20 @@ package de.marhali.easyi18n.action;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.content.Content;
|
||||
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.KeyPathConverter;
|
||||
import de.marhali.easyi18n.service.WindowManager;
|
||||
import de.marhali.easyi18n.dialog.AddDialog;
|
||||
import de.marhali.easyi18n.util.PathUtil;
|
||||
import de.marhali.easyi18n.util.TreeUtil;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
@ -27,32 +32,33 @@ public class AddAction extends AnAction {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
new AddDialog(e.getProject(), detectPreKey()).showAndHandle();
|
||||
new AddDialog(Objects.requireNonNull(e.getProject()), detectPreKey(e.getProject())).showAndHandle();
|
||||
}
|
||||
|
||||
private String detectPreKey() {
|
||||
WindowManager manager = WindowManager.getInstance();
|
||||
private @Nullable KeyPath detectPreKey(@NotNull Project project) {
|
||||
KeyPathConverter converter = new KeyPathConverter(project);
|
||||
WindowManager window = WindowManager.getInstance();
|
||||
Content manager = window.getToolWindow().getContentManager().getSelectedContent();
|
||||
|
||||
if(manager == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(manager.getToolWindow().getContentManager().getSelectedContent()
|
||||
.getDisplayName().equals(ResourceBundle.getBundle("messages").getString("view.tree.title"))) {
|
||||
if(manager.getDisplayName().equals(
|
||||
ResourceBundle.getBundle("messages").getString("view.tree.title"))) { // Tree View
|
||||
|
||||
TreePath path = manager.getTreeView().getTree().getSelectionPath();
|
||||
TreePath path = window.getTreeView().getTree().getSelectionPath();
|
||||
|
||||
if(path != null) {
|
||||
return TreeUtil.getFullPath(path) + PathUtil.DELIMITER;
|
||||
return TreeUtil.getFullPath(path);
|
||||
}
|
||||
|
||||
} else { // Table View
|
||||
|
||||
int row = manager.getTableView().getTable().getSelectedRow();
|
||||
int row = window.getTableView().getTable().getSelectedRow();
|
||||
|
||||
if(row >= 0) {
|
||||
String fullPath = String.valueOf(manager.getTableView().getTable().getValueAt(row, 0));
|
||||
return fullPath + ".";
|
||||
String path = String.valueOf(window.getTableView().getTable().getValueAt(row, 0));
|
||||
return converter.split(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,10 @@ import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.components.JBTextField;
|
||||
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationCreate;
|
||||
import de.marhali.easyi18n.model.*;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
@ -25,19 +26,23 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
public class AddDialog {
|
||||
|
||||
private final Project project;
|
||||
private String preKey;
|
||||
private final @NotNull Project project;
|
||||
private final @NotNull KeyPathConverter converter;
|
||||
|
||||
private @NotNull KeyPath preKey;
|
||||
|
||||
private JBTextField keyTextField;
|
||||
private Map<String, JBTextField> valueTextFields;
|
||||
|
||||
public AddDialog(Project project, String preKey) {
|
||||
public AddDialog(@NotNull Project project, @Nullable KeyPath preKey) {
|
||||
this(project);
|
||||
this.preKey = preKey;
|
||||
this.preKey = preKey == null ? new KeyPath() : preKey;
|
||||
}
|
||||
|
||||
public AddDialog(Project project) {
|
||||
public AddDialog(@NotNull Project project) {
|
||||
this.project = project;
|
||||
this.converter = new KeyPathConverter(project);
|
||||
this.preKey = new KeyPath();
|
||||
}
|
||||
|
||||
public void showAndHandle() {
|
||||
@ -57,7 +62,8 @@ public class AddDialog {
|
||||
}
|
||||
});
|
||||
|
||||
TranslationCreate creation = new TranslationCreate(new KeyedTranslation(keyTextField.getText(), translation));
|
||||
KeyedTranslation keyedTranslation = new KeyedTranslation(converter.split(keyTextField.getText()), translation);
|
||||
TranslationCreate creation = new TranslationCreate(keyedTranslation);
|
||||
InstanceManager.get(project).processUpdate(creation);
|
||||
}
|
||||
|
||||
@ -67,13 +73,17 @@ public class AddDialog {
|
||||
|
||||
JPanel keyPanel = new JPanel(new GridLayout(0, 1, 2, 2));
|
||||
JBLabel keyLabel = new JBLabel(ResourceBundle.getBundle("messages").getString("translation.key"));
|
||||
keyTextField = new JBTextField(this.preKey);
|
||||
keyTextField = new JBTextField(this.converter.concat(this.preKey));
|
||||
keyLabel.setLabelFor(keyTextField);
|
||||
keyPanel.add(keyLabel);
|
||||
keyPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
|
||||
keyPanel.add(keyTextField);
|
||||
rootPanel.add(keyPanel);
|
||||
|
||||
if(!this.preKey.isEmpty()) { // Add delimiter if pre key is defined
|
||||
keyTextField.setText(keyTextField.getText() + KeyPath.DELIMITER);
|
||||
}
|
||||
|
||||
JPanel valuePanel = new JPanel(new GridLayout(0, 1, 2, 2));
|
||||
valueTextFields = new HashMap<>();
|
||||
|
||||
|
@ -6,12 +6,10 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.components.JBTextField;
|
||||
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationDelete;
|
||||
import de.marhali.easyi18n.model.*;
|
||||
import de.marhali.easyi18n.dialog.descriptor.DeleteActionDescriptor;
|
||||
import de.marhali.easyi18n.model.TranslationUpdate;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
@ -27,6 +25,8 @@ import java.util.ResourceBundle;
|
||||
public class EditDialog {
|
||||
|
||||
private final Project project;
|
||||
private final KeyPathConverter converter;
|
||||
|
||||
private final KeyedTranslation origin;
|
||||
|
||||
private JBTextField keyTextField;
|
||||
@ -34,6 +34,7 @@ public class EditDialog {
|
||||
|
||||
public EditDialog(Project project, KeyedTranslation origin) {
|
||||
this.project = project;
|
||||
this.converter = new KeyPathConverter(project);
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ public class EditDialog {
|
||||
}
|
||||
});
|
||||
|
||||
return new KeyedTranslation(keyTextField.getText(), translation);
|
||||
return new KeyedTranslation(converter.split(keyTextField.getText()), translation);
|
||||
}
|
||||
|
||||
private DialogBuilder prepare() {
|
||||
@ -65,7 +66,7 @@ public class EditDialog {
|
||||
|
||||
JPanel keyPanel = new JPanel(new GridLayout(0, 1, 2,2));
|
||||
JBLabel keyLabel = new JBLabel(ResourceBundle.getBundle("messages").getString("translation.key"));
|
||||
keyTextField = new JBTextField(this.origin.getKey());
|
||||
keyTextField = new JBTextField(this.converter.concat(this.origin.getKey()));
|
||||
keyLabel.setLabelFor(keyTextField);
|
||||
keyPanel.add(keyLabel);
|
||||
keyPanel.add(keyTextField);
|
||||
|
@ -51,9 +51,8 @@ public class SettingsDialog {
|
||||
|
||||
// Reload instance
|
||||
InstanceManager manager = InstanceManager.get(project);
|
||||
manager.store().loadFromPersistenceLayer((success) -> {
|
||||
manager.bus().propagate().onUpdateData(manager.store().getData());
|
||||
});
|
||||
manager.store().loadFromPersistenceLayer((success) ->
|
||||
manager.bus().propagate().onUpdateData(manager.store().getData()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,9 @@ import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.KeyPathConverter;
|
||||
import de.marhali.easyi18n.model.SettingsState;
|
||||
import de.marhali.easyi18n.model.TranslationNode;
|
||||
import de.marhali.easyi18n.service.SettingsService;
|
||||
|
||||
@ -28,18 +31,21 @@ public class KeyAnnotator {
|
||||
return;
|
||||
}
|
||||
|
||||
String previewLocale = SettingsService.getInstance(project).getState().getPreviewLocale();
|
||||
String pathPrefix = SettingsService.getInstance(project).getState().getPathPrefix();
|
||||
SettingsState state = SettingsService.getInstance(project).getState();
|
||||
String pathPrefix = state.getPathPrefix();
|
||||
String previewLocale = state.getPreviewLocale();
|
||||
|
||||
KeyPathConverter converter = new KeyPathConverter(project);
|
||||
|
||||
String searchKey = key.length() >= pathPrefix.length()
|
||||
? key.substring(pathPrefix.length())
|
||||
: key;
|
||||
|
||||
if(searchKey.startsWith(".")) {
|
||||
searchKey = searchKey.substring(1);
|
||||
if(searchKey.startsWith(KeyPath.DELIMITER)) {
|
||||
searchKey = searchKey.substring(KeyPath.DELIMITER.length());
|
||||
}
|
||||
|
||||
TranslationNode node = InstanceManager.get(project).store().getData().getNode(searchKey);
|
||||
TranslationNode node = InstanceManager.get(project).store().getData().getNode(converter.split(searchKey));
|
||||
|
||||
if(node == null) { // Unknown translation. Just ignore it
|
||||
return;
|
||||
|
@ -5,11 +5,13 @@ import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.*;
|
||||
import com.intellij.util.*;
|
||||
|
||||
import de.marhali.easyi18n.DataStore;
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.service.*;
|
||||
import de.marhali.easyi18n.util.PathUtil;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
@ -32,58 +34,29 @@ public class KeyCompletionProvider extends CompletionProvider<CompletionParamete
|
||||
}
|
||||
|
||||
DataStore store = InstanceManager.get(project).store();
|
||||
PathUtil pathUtil = new PathUtil(project);
|
||||
|
||||
String previewLocale = SettingsService.getInstance(project).getState().getPreviewLocale();
|
||||
String pathPrefix = SettingsService.getInstance(project).getState().getPathPrefix();
|
||||
|
||||
String path = result.getPrefixMatcher().getPrefix();
|
||||
|
||||
if(path.startsWith(pathPrefix)) {
|
||||
path = path.substring(pathPrefix.length());
|
||||
|
||||
if(path.startsWith(".")) { // Remove leading dot
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
path = ""; // Show suggestions for root view
|
||||
if(pathPrefix.length() > 0 && !pathPrefix.endsWith(KeyPath.DELIMITER)) {
|
||||
pathPrefix += KeyPath.DELIMITER;
|
||||
}
|
||||
|
||||
if(pathPrefix.length() > 0 && !pathPrefix.endsWith(".")) {
|
||||
pathPrefix += ".";
|
||||
}
|
||||
Set<KeyPath> fullKeys = store.getData().getFullKeys();
|
||||
|
||||
Set<String> fullKeys = store.getData().getFullKeys();
|
||||
|
||||
int sections = path.split("\\.").length;
|
||||
int maxSectionForwardLookup = 5;
|
||||
|
||||
for(String key : fullKeys) {
|
||||
// Path matches
|
||||
if(key.startsWith(path)) {
|
||||
String[] keySections = key.split("\\.");
|
||||
|
||||
if(keySections.length > sections + maxSectionForwardLookup) { // Key is too deep nested
|
||||
String shrinkKey = pathUtil.concat(Arrays.asList(
|
||||
Arrays.copyOf(keySections, sections + maxSectionForwardLookup)
|
||||
));
|
||||
|
||||
result.addElement(LookupElementBuilder.create(pathPrefix + shrinkKey)
|
||||
.appendTailText(" I18n([])", true));
|
||||
|
||||
} else {
|
||||
Translation translation = store.getData().getTranslation(key);
|
||||
|
||||
if(translation != null) {
|
||||
String content = translation.get(previewLocale);
|
||||
|
||||
result.addElement(LookupElementBuilder.create(pathPrefix + key)
|
||||
.withIcon(AllIcons.Actions.PreserveCaseHover)
|
||||
.appendTailText(" I18n(" + previewLocale + ": " + content + ")", true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(KeyPath currentKey : fullKeys) {
|
||||
result.addElement(createElement(
|
||||
pathPrefix,
|
||||
currentKey,
|
||||
previewLocale,
|
||||
Objects.requireNonNull(store.getData().getTranslation(currentKey))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private LookupElement createElement(String prefix, KeyPath path, String locale, Translation translation) {
|
||||
return LookupElementBuilder.create(prefix + path.toSimpleString())
|
||||
.withIcon(AllIcons.Actions.PreserveCaseHover)
|
||||
.appendTailText(" I18n(" + locale + ": " + translation.get(locale) + ")", true);
|
||||
}
|
||||
}
|
@ -7,12 +7,18 @@ import com.intellij.psi.impl.FakePsiElement;
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.dialog.AddDialog;
|
||||
import de.marhali.easyi18n.dialog.EditDialog;
|
||||
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.KeyPathConverter;
|
||||
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Go to declaration reference for i18n keys.
|
||||
* @author marhali
|
||||
*/
|
||||
public class KeyReference extends PsiReferenceBase<PsiElement> {
|
||||
|
||||
@Nullable private final String myKey;
|
||||
@ -52,12 +58,14 @@ public class KeyReference extends PsiReferenceBase<PsiElement> {
|
||||
|
||||
@Override
|
||||
public void navigate(boolean requestFocus) {
|
||||
Translation translation = InstanceManager.get(getProject()).store().getData().getTranslation(getKey());
|
||||
KeyPathConverter converter = new KeyPathConverter(getProject());
|
||||
KeyPath path = converter.split(getKey());
|
||||
Translation translation = InstanceManager.get(getProject()).store().getData().getTranslation(path);
|
||||
|
||||
if(translation != null) {
|
||||
new EditDialog(getProject(), new KeyedTranslation(getKey(), translation)).showAndHandle();
|
||||
new EditDialog(getProject(), new KeyedTranslation(path, translation)).showAndHandle();
|
||||
} else {
|
||||
new AddDialog(getProject(), getKey()).showAndHandle();
|
||||
new AddDialog(getProject(), path).showAndHandle();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
|
||||
import de.marhali.easyi18n.DataStore;
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.model.KeyPathConverter;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.service.SettingsService;
|
||||
|
||||
@ -37,12 +38,13 @@ public class GenericFoldingBuilder extends FoldingBuilderEx {
|
||||
}
|
||||
|
||||
DataStore store = InstanceManager.get(root.getProject()).store();
|
||||
KeyPathConverter converter = new KeyPathConverter(root.getProject());
|
||||
|
||||
for(final PsiLiteralValue literalValue : literalValues) {
|
||||
String value = literalValue.getValue() instanceof String ? (String) literalValue.getValue() : null;
|
||||
|
||||
// Undefined string literal or not a translation
|
||||
if(value == null || store.getData().getTranslation(value) == null) {
|
||||
if(value == null || store.getData().getTranslation(converter.split(value)) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -65,7 +67,9 @@ public class GenericFoldingBuilder extends FoldingBuilderEx {
|
||||
}
|
||||
|
||||
DataStore store = InstanceManager.get(literalValue.getProject()).store();
|
||||
Translation translation = store.getData().getTranslation(value);
|
||||
KeyPathConverter converter = new KeyPathConverter(literalValue.getProject());
|
||||
|
||||
Translation translation = store.getData().getTranslation(converter.split(value));
|
||||
|
||||
if(translation == null) {
|
||||
return null;
|
||||
|
@ -6,6 +6,7 @@ import com.intellij.util.ProcessingContext;
|
||||
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.editor.KeyReference;
|
||||
import de.marhali.easyi18n.model.KeyPathConverter;
|
||||
import de.marhali.easyi18n.service.SettingsService;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -38,7 +39,9 @@ public class GenericKeyReferenceContributor extends PsiReferenceContributor {
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
if(InstanceManager.get(element.getProject()).store().getData().getTranslation(value) == null) {
|
||||
KeyPathConverter converter = new KeyPathConverter(element.getProject());
|
||||
|
||||
if(InstanceManager.get(element.getProject()).store().getData().getTranslation(converter.split(value)) == null) {
|
||||
if(!KeyReference.isReferencable(value)) { // Creation policy
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.intellij.util.ProcessingContext;
|
||||
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.editor.KeyReference;
|
||||
import de.marhali.easyi18n.model.KeyPathConverter;
|
||||
import de.marhali.easyi18n.service.SettingsService;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -45,7 +46,9 @@ public class KotlinKeyReferenceContributor extends PsiReferenceContributor {
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
if(InstanceManager.get(element.getProject()).store().getData().getNode(value) == null) {
|
||||
KeyPathConverter converter = new KeyPathConverter(element.getProject());
|
||||
|
||||
if(InstanceManager.get(element.getProject()).store().getData().getNode(converter.split(value)) == null) {
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class JsonIOStrategy implements IOStrategy {
|
||||
throw new IllegalArgumentException("Specified folder is invalid (" + localesPath + ")");
|
||||
}
|
||||
|
||||
TranslationData data = new TranslationData(state.isSortKeys(), state.isNestedKeys());
|
||||
TranslationData data = new TranslationData(state.isSortKeys());
|
||||
|
||||
for(VirtualFile file : directory.getChildren()) {
|
||||
if(file.isDirectory() || !isFileRelevant(state, file)) {
|
||||
|
@ -9,6 +9,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import de.marhali.easyi18n.io.IOStrategy;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.SettingsState;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
import de.marhali.easyi18n.model.TranslationNode;
|
||||
@ -80,7 +81,7 @@ public class ModularizedJsonIOStrategy implements IOStrategy {
|
||||
throw new IllegalArgumentException("Specified folder is invalid (" + localesPath + ")");
|
||||
}
|
||||
|
||||
TranslationData data = new TranslationData(state.isSortKeys(), state.isNestedKeys());
|
||||
TranslationData data = new TranslationData(state.isSortKeys());
|
||||
VirtualFile[] localeDirectories = directory.getChildren();
|
||||
|
||||
for(VirtualFile localeDir : localeDirectories) {
|
||||
@ -95,8 +96,8 @@ public class ModularizedJsonIOStrategy implements IOStrategy {
|
||||
|
||||
String moduleName = module.getNameWithoutExtension();
|
||||
|
||||
TranslationNode moduleNode = data.getNode(moduleName) != null
|
||||
? data.getNode(moduleName)
|
||||
TranslationNode moduleNode = data.getNode(KeyPath.of(moduleName)) != null
|
||||
? data.getNode(KeyPath.of(moduleName))
|
||||
: new TranslationNode(state.isSortKeys() ? new TreeMap<>() : new LinkedHashMap<>());
|
||||
|
||||
try {
|
||||
|
@ -59,7 +59,7 @@ public class PropertiesIOStrategy implements IOStrategy {
|
||||
throw new IllegalArgumentException("Specified folder is invalid (" + localesPath + ")");
|
||||
}
|
||||
|
||||
TranslationData data = new TranslationData(state.isSortKeys(), state.isNestedKeys());
|
||||
TranslationData data = new TranslationData(state.isSortKeys());
|
||||
|
||||
for(VirtualFile file : directory.getChildren()) {
|
||||
if(file.isDirectory() || !isFileRelevant(state, file)) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package de.marhali.easyi18n.io.properties;
|
||||
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
import de.marhali.easyi18n.model.TranslationNode;
|
||||
import de.marhali.easyi18n.util.StringUtil;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
@ -17,7 +17,7 @@ public class PropertiesMapper {
|
||||
|
||||
public static void read(String locale, SortableProperties properties, TranslationData data) {
|
||||
for(Map.Entry<Object, Object> entry : properties.entrySet()) {
|
||||
String key = String.valueOf(entry.getKey());
|
||||
KeyPath key = new KeyPath(String.valueOf(entry.getKey()));
|
||||
Object value = entry.getValue();
|
||||
|
||||
Translation translation = data.getTranslation(key);
|
||||
@ -36,18 +36,19 @@ public class PropertiesMapper {
|
||||
}
|
||||
|
||||
public static void write(String locale, SortableProperties properties, TranslationData data) {
|
||||
for(String key : data.getFullKeys()) {
|
||||
for(KeyPath key : data.getFullKeys()) {
|
||||
Translation translation = data.getTranslation(key);
|
||||
|
||||
if(translation != null && translation.containsKey(locale)) {
|
||||
String simpleKey = key.toSimpleString();
|
||||
String content = translation.get(locale);
|
||||
|
||||
if(PropertiesArrayMapper.isArray(content)) {
|
||||
properties.put(key, PropertiesArrayMapper.write(content));
|
||||
properties.put(simpleKey, PropertiesArrayMapper.write(content));
|
||||
} else if(NumberUtils.isNumber(content)) {
|
||||
properties.put(key, NumberUtils.createNumber(content));
|
||||
properties.put(simpleKey, NumberUtils.createNumber(content));
|
||||
} else {
|
||||
properties.put(key, content);
|
||||
properties.put(simpleKey, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class YamlIOStrategy implements IOStrategy {
|
||||
throw new IllegalArgumentException("Specified folder is invalid (" + localesPath + ")");
|
||||
}
|
||||
|
||||
TranslationData data = new TranslationData(state.isSortKeys(), state.isNestedKeys());
|
||||
TranslationData data = new TranslationData(state.isSortKeys());
|
||||
|
||||
for(VirtualFile file : directory.getChildren()) {
|
||||
if(file.isDirectory() || !isFileRelevant(state, file)) {
|
||||
|
@ -2,7 +2,6 @@ package de.marhali.easyi18n.io.yaml;
|
||||
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationNode;
|
||||
import de.marhali.easyi18n.util.PathUtil;
|
||||
import de.marhali.easyi18n.util.StringUtil;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
@ -23,10 +22,6 @@ public class YamlMapper {
|
||||
public static void read(String locale, Section section, TranslationNode node) {
|
||||
for(String key : section.getKeys()) {
|
||||
Object value = section.getInScope(key).get();
|
||||
|
||||
key = StringUtil.escapeControls(
|
||||
key.replace(PathUtil.DELIMITER, "\\" + PathUtil.DELIMITER), true);
|
||||
|
||||
TranslationNode childNode = node.getOrCreateChildren(key);
|
||||
|
||||
if(value instanceof MapSection) {
|
||||
@ -47,9 +42,7 @@ public class YamlMapper {
|
||||
|
||||
public static void write(String locale, Section section, TranslationNode node) {
|
||||
for(Map.Entry<String, TranslationNode> entry : node.getChildren().entrySet()) {
|
||||
String key = StringEscapeUtils.unescapeJava(
|
||||
entry.getKey().replace("\\" + PathUtil.DELIMITER, PathUtil.DELIMITER));
|
||||
|
||||
String key = entry.getKey();
|
||||
TranslationNode childNode = entry.getValue();
|
||||
|
||||
if(!childNode.isLeaf()) {
|
||||
|
@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Represents a full translation key with all sections.
|
||||
@ -16,7 +17,7 @@ public class KeyPath extends ArrayList<String> {
|
||||
|
||||
public static final String DELIMITER = ".";
|
||||
|
||||
public static KeyPath of(String... path) {
|
||||
public static KeyPath of(@NotNull String... path) {
|
||||
return new KeyPath(List.of(path));
|
||||
}
|
||||
|
||||
@ -24,7 +25,34 @@ public class KeyPath extends ArrayList<String> {
|
||||
super();
|
||||
}
|
||||
|
||||
public KeyPath(@NotNull KeyPath path, String... pathToAppend) {
|
||||
this(path);
|
||||
this.addAll(List.of(pathToAppend));
|
||||
}
|
||||
|
||||
public KeyPath(@NotNull Collection<? extends String> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public KeyPath(@NotNull String simplePath) {
|
||||
this(List.of(simplePath.split(Pattern.quote(DELIMITER))));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Note: </b>Use {@link KeyPathConverter} if you want to keep hierarchy.
|
||||
* @return simple path representation by adding delimiter between the secton nodes
|
||||
*/
|
||||
public String toSimpleString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for(String section : this) {
|
||||
if(builder.length() > 0) {
|
||||
builder.append(DELIMITER);
|
||||
}
|
||||
|
||||
builder.append(section);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@ -9,19 +9,19 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class KeyedTranslation {
|
||||
|
||||
private @NotNull String key;
|
||||
private @NotNull KeyPath key;
|
||||
private @Nullable Translation translation;
|
||||
|
||||
public KeyedTranslation(@NotNull String key, @Nullable Translation translation) {
|
||||
public KeyedTranslation(@NotNull KeyPath key, @Nullable Translation translation) {
|
||||
this.key = key;
|
||||
this.translation = translation;
|
||||
}
|
||||
|
||||
public @NotNull String getKey() {
|
||||
public KeyPath getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(@NotNull String key) {
|
||||
public void setKey(KeyPath key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package de.marhali.easyi18n.model;
|
||||
|
||||
import de.marhali.easyi18n.util.PathUtil;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -11,21 +9,21 @@ 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:
|
||||
* <br/>
|
||||
* user: <br/>
|
||||
* -- principal: 'Principal' <br/>
|
||||
* -- username: <br/>
|
||||
* -- -- title: 'Username' <br/>
|
||||
* auth: <br/>
|
||||
* -- logout: 'Logout' <br/>
|
||||
* -- login: 'Login' <br/>
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* user:
|
||||
* principal: 'Principal'
|
||||
* username:
|
||||
* title: 'Username'
|
||||
* auth:
|
||||
* logout: 'Logout'
|
||||
* login: 'Login'
|
||||
* }
|
||||
* </pre>
|
||||
* @author marhali
|
||||
*/
|
||||
public class TranslationData {
|
||||
|
||||
private final PathUtil pathUtil;
|
||||
|
||||
@NotNull
|
||||
private final Set<String> locales;
|
||||
|
||||
@ -36,17 +34,15 @@ public class TranslationData {
|
||||
* 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<>()));
|
||||
public TranslationData(boolean sort) {
|
||||
this(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);
|
||||
public TranslationData(@NotNull Set<String> locales, @NotNull TranslationNode rootNode) {
|
||||
this.locales = locales;
|
||||
this.rootNode = rootNode;
|
||||
}
|
||||
@ -76,15 +72,14 @@ public class TranslationData {
|
||||
* @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);
|
||||
public @Nullable TranslationNode getNode(@NotNull KeyPath fullPath) {
|
||||
TranslationNode node = this.rootNode;
|
||||
|
||||
if(fullPath.isEmpty()) { // Return root node if empty path was supplied
|
||||
return node;
|
||||
}
|
||||
|
||||
for(String section : sections) {
|
||||
for(String section : fullPath) {
|
||||
if(node == null) {
|
||||
return null;
|
||||
}
|
||||
@ -98,7 +93,7 @@ public class TranslationData {
|
||||
* @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) {
|
||||
public @Nullable Translation getTranslation(@NotNull KeyPath fullPath) {
|
||||
TranslationNode node = this.getNode(fullPath);
|
||||
|
||||
if(node == null || !node.isLeaf()) {
|
||||
@ -109,50 +104,52 @@ public class TranslationData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create / Update or Delete a specific translation.
|
||||
* The parent path of the translation will be changed if necessary.
|
||||
* @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) {
|
||||
List<String> sections = this.pathUtil.split(fullPath);
|
||||
String nodeKey = sections.remove(sections.size() - 1); // Edge case last section
|
||||
TranslationNode node = this.rootNode;
|
||||
|
||||
public void setTranslation(@NotNull KeyPath fullPath, @Nullable Translation translation) {
|
||||
if(fullPath.isEmpty()) {
|
||||
throw new IllegalArgumentException("Path cannot be empty");
|
||||
throw new IllegalArgumentException("Key path cannot be empty");
|
||||
}
|
||||
|
||||
for(String section : sections) { // Go to the level of the key (@nodeKey)
|
||||
fullPath = new KeyPath(fullPath);
|
||||
String leafKey = fullPath.remove(fullPath.size() - 1); // Extract edge section as children key of parent
|
||||
TranslationNode node = this.rootNode;
|
||||
|
||||
for(String section : fullPath) { // Go to nested level at @leafKey
|
||||
TranslationNode childNode = node.getChildren().get(section);
|
||||
|
||||
if(childNode == null) {
|
||||
if(translation == null) { // Path should not be empty for delete
|
||||
if(translation == null) { // Path must not be empty on delete
|
||||
throw new IllegalArgumentException("Delete action on empty path");
|
||||
}
|
||||
|
||||
// Created nested section
|
||||
childNode = node.setChildren(section);
|
||||
}
|
||||
|
||||
node = childNode;
|
||||
}
|
||||
|
||||
if(translation == null) { // Delete
|
||||
node.removeChildren(nodeKey);
|
||||
if(translation == null) { // Delete action
|
||||
node.removeChildren(leafKey);
|
||||
|
||||
if(node.getChildren().isEmpty() && !node.isRoot()) { // Parent is empty now. Run delete recursively
|
||||
this.setTranslation(this.pathUtil.concat(sections), null);
|
||||
if(node.getChildren().isEmpty() && !node.isRoot()) { // Node is empty now. Run delete recursively
|
||||
this.setTranslation(fullPath, null);
|
||||
}
|
||||
|
||||
} else { // Create or overwrite
|
||||
node.setChildren(nodeKey, translation);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create or overwrite
|
||||
node.setChildren(leafKey, translation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All translation keys as absolute paths (full-key)
|
||||
*/
|
||||
public @NotNull Set<String> getFullKeys() {
|
||||
return this.getFullKeys("", this.rootNode); // Just use root node
|
||||
public @NotNull Set<KeyPath> getFullKeys() {
|
||||
return this.getFullKeys(new KeyPath(), this.rootNode); // Just use root node
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,15 +157,15 @@ public class TranslationData {
|
||||
* @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<>();
|
||||
public @NotNull Set<KeyPath> getFullKeys(KeyPath parentPath, TranslationNode node) {
|
||||
Set<KeyPath> 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()));
|
||||
keys.addAll(this.getFullKeys(new KeyPath(parentPath, children.getKey()), children.getValue()));
|
||||
}
|
||||
|
||||
return keys;
|
||||
@ -178,7 +175,6 @@ public class TranslationData {
|
||||
public String toString() {
|
||||
return "TranslationData{" +
|
||||
"mapClass=" + rootNode.getChildren().getClass().getSimpleName() +
|
||||
", pathUtil=" + pathUtil +
|
||||
", locales=" + locales +
|
||||
", rootNode=" + rootNode +
|
||||
'}';
|
||||
|
@ -7,14 +7,13 @@ 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.
|
||||
* nodes which can lead to another translation or node.<br>
|
||||
* Navigation inside a node can be upward and downward. To construct the full
|
||||
* translation key (full-key) every parent needs to be resolved recursively.
|
||||
* -
|
||||
* translation key (full-key) every parent needs to be resolved recursively. <br>
|
||||
* <br>
|
||||
* 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 {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package de.marhali.easyi18n.model.bus;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Single event listener.
|
||||
@ -11,5 +13,5 @@ public interface FocusKeyListener {
|
||||
* Move the specified translation key (full-key) into focus.
|
||||
* @param key Absolute translation key
|
||||
*/
|
||||
void onFocusKey(@Nullable String key);
|
||||
void onFocusKey(@NotNull KeyPath key);
|
||||
}
|
@ -28,15 +28,16 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
public class TableView implements BusListener {
|
||||
|
||||
private final JBTable table;
|
||||
|
||||
private final Project project;
|
||||
|
||||
private TableModelMapper currentMapper;
|
||||
private KeyPathConverter converter;
|
||||
|
||||
private JPanel rootPanel;
|
||||
private JPanel containerPanel;
|
||||
|
||||
private JBTable table;
|
||||
|
||||
public TableView(Project project) {
|
||||
this.project = project;
|
||||
|
||||
@ -55,7 +56,7 @@ public class TableView implements BusListener {
|
||||
return;
|
||||
}
|
||||
|
||||
String fullPath = String.valueOf(table.getValueAt(row, 0));
|
||||
KeyPath fullPath = this.converter.split(String.valueOf(this.table.getValueAt(row, 0)));
|
||||
Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath);
|
||||
|
||||
if (translation != null) {
|
||||
@ -65,7 +66,7 @@ public class TableView implements BusListener {
|
||||
|
||||
private void deleteSelectedRows() {
|
||||
for (int selectedRow : table.getSelectedRows()) {
|
||||
String fullPath = String.valueOf(table.getValueAt(selectedRow, 0));
|
||||
KeyPath fullPath = this.converter.split(String.valueOf(table.getValueAt(selectedRow, 0)));
|
||||
|
||||
InstanceManager.get(project).processUpdate(
|
||||
new TranslationDelete(new KeyedTranslation(fullPath, null))
|
||||
@ -75,16 +76,19 @@ public class TableView implements BusListener {
|
||||
|
||||
@Override
|
||||
public void onUpdateData(@NotNull TranslationData data) {
|
||||
table.setModel(this.currentMapper = new TableModelMapper(data, update ->
|
||||
this.converter = new KeyPathConverter(project);
|
||||
|
||||
table.setModel(this.currentMapper = new TableModelMapper(data, this.converter, update ->
|
||||
InstanceManager.get(project).processUpdate(update)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusKey(@Nullable String key) {
|
||||
public void onFocusKey(@NotNull KeyPath key) {
|
||||
String concatKey = this.converter.concat(key);
|
||||
int row = -1;
|
||||
|
||||
for (int i = 0; i < table.getRowCount(); i++) {
|
||||
if (String.valueOf(table.getValueAt(i, 0)).equals(key)) {
|
||||
if (table.getValueAt(i, 0).equals(concatKey)) {
|
||||
row = i;
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,7 @@ import com.intellij.ui.treeStructure.Tree;
|
||||
|
||||
import de.marhali.easyi18n.InstanceManager;
|
||||
import de.marhali.easyi18n.listener.ReturnKeyListener;
|
||||
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
import de.marhali.easyi18n.model.TranslationDelete;
|
||||
import de.marhali.easyi18n.model.*;
|
||||
import de.marhali.easyi18n.model.bus.BusListener;
|
||||
import de.marhali.easyi18n.action.treeview.CollapseTreeViewAction;
|
||||
import de.marhali.easyi18n.action.treeview.ExpandTreeViewAction;
|
||||
@ -40,6 +37,8 @@ import java.util.ResourceBundle;
|
||||
*/
|
||||
public class TreeView implements BusListener {
|
||||
|
||||
private final Tree tree;
|
||||
|
||||
private final Project project;
|
||||
|
||||
private TreeModelMapper currentMapper;
|
||||
@ -48,8 +47,6 @@ public class TreeView implements BusListener {
|
||||
private JPanel toolBarPanel;
|
||||
private JPanel containerPanel;
|
||||
|
||||
private Tree tree;
|
||||
|
||||
public TreeView(Project project) {
|
||||
this.project = project;
|
||||
|
||||
@ -87,8 +84,8 @@ public class TreeView implements BusListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusKey(@Nullable String key) {
|
||||
if (key != null && currentMapper != null) {
|
||||
public void onFocusKey(@NotNull KeyPath key) {
|
||||
if (currentMapper != null) {
|
||||
TreePath path = currentMapper.findTreePath(key);
|
||||
|
||||
this.tree.getSelectionModel().setSelectionPath(path);
|
||||
@ -120,7 +117,7 @@ public class TreeView implements BusListener {
|
||||
return;
|
||||
}
|
||||
|
||||
String fullPath = TreeUtil.getFullPath(path);
|
||||
KeyPath fullPath = TreeUtil.getFullPath(path);
|
||||
Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath);
|
||||
|
||||
if (translation == null) {
|
||||
@ -138,7 +135,7 @@ public class TreeView implements BusListener {
|
||||
}
|
||||
|
||||
for (TreePath path : tree.getSelectionPaths()) {
|
||||
String fullPath = TreeUtil.getFullPath(path);
|
||||
KeyPath fullPath = TreeUtil.getFullPath(path);
|
||||
|
||||
InstanceManager.get(project).processUpdate(
|
||||
new TranslationDelete(new KeyedTranslation(fullPath, null))
|
||||
|
@ -20,13 +20,18 @@ import java.util.function.Consumer;
|
||||
public class TableModelMapper implements TableModel, SearchQueryListener {
|
||||
|
||||
private final @NotNull TranslationData data;
|
||||
private final @NotNull KeyPathConverter converter;
|
||||
|
||||
private final @NotNull List<String> locales;
|
||||
private @NotNull List<String> fullKeys;
|
||||
private @NotNull List<KeyPath> fullKeys;
|
||||
|
||||
private final @NotNull Consumer<TranslationUpdate> updater;
|
||||
|
||||
public TableModelMapper(@NotNull TranslationData data, @NotNull Consumer<TranslationUpdate> updater) {
|
||||
public TableModelMapper(@NotNull TranslationData data, @NotNull KeyPathConverter converter,
|
||||
@NotNull Consumer<TranslationUpdate> updater) {
|
||||
this.data = data;
|
||||
this.converter = converter;
|
||||
|
||||
this.locales = new ArrayList<>(data.getLocales());
|
||||
this.fullKeys = new ArrayList<>(data.getFullKeys());
|
||||
|
||||
@ -41,10 +46,10 @@ public class TableModelMapper implements TableModel, SearchQueryListener {
|
||||
}
|
||||
|
||||
query = query.toLowerCase();
|
||||
List<String> matches = new ArrayList<>();
|
||||
List<KeyPath> matches = new ArrayList<>();
|
||||
|
||||
for(String key : this.data.getFullKeys()) {
|
||||
if(key.toLowerCase().contains(query)) {
|
||||
for(KeyPath key : this.data.getFullKeys()) {
|
||||
if(this.converter.concat(key).toLowerCase().contains(query)) {
|
||||
matches.add(key);
|
||||
} else {
|
||||
for(String content : this.data.getTranslation(key).values()) {
|
||||
@ -90,11 +95,12 @@ public class TableModelMapper implements TableModel, SearchQueryListener {
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
KeyPath key = this.fullKeys.get(rowIndex);
|
||||
|
||||
if(columnIndex == 0) { // Keys
|
||||
return this.fullKeys.get(rowIndex);
|
||||
return this.converter.concat(key);
|
||||
}
|
||||
|
||||
String key = this.fullKeys.get(rowIndex);
|
||||
String locale = this.locales.get(columnIndex - 1);
|
||||
Translation translation = this.data.getTranslation(key);
|
||||
|
||||
@ -103,14 +109,14 @@ public class TableModelMapper implements TableModel, SearchQueryListener {
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
String key = String.valueOf(this.getValueAt(rowIndex, 0));
|
||||
KeyPath key = this.fullKeys.get(rowIndex);
|
||||
Translation translation = this.data.getTranslation(key);
|
||||
|
||||
if(translation == null) { // Unknown cell
|
||||
return;
|
||||
}
|
||||
|
||||
String newKey = columnIndex == 0 ? String.valueOf(aValue) : key;
|
||||
KeyPath newKey = columnIndex == 0 ? this.converter.split(String.valueOf(aValue)) : key;
|
||||
|
||||
// Translation content update
|
||||
if(columnIndex > 0) {
|
||||
|
@ -3,12 +3,8 @@ package de.marhali.easyi18n.tabs.mapper;
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.ui.JBColor;
|
||||
|
||||
import de.marhali.easyi18n.model.SettingsState;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
import de.marhali.easyi18n.model.TranslationNode;
|
||||
import de.marhali.easyi18n.model.*;
|
||||
import de.marhali.easyi18n.model.bus.SearchQueryListener;
|
||||
import de.marhali.easyi18n.util.PathUtil;
|
||||
import de.marhali.easyi18n.util.UiUtil;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -26,12 +22,14 @@ import java.util.Map;
|
||||
public class TreeModelMapper extends DefaultTreeModel implements SearchQueryListener {
|
||||
|
||||
private final TranslationData data;
|
||||
private final KeyPathConverter converter;
|
||||
private final SettingsState state;
|
||||
|
||||
public TreeModelMapper(TranslationData data, SettingsState state) {
|
||||
super(null);
|
||||
|
||||
this.data = data;
|
||||
this.converter = new KeyPathConverter(state.isNestedKeys());
|
||||
this.state = state;
|
||||
|
||||
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||
@ -42,7 +40,7 @@ public class TreeModelMapper extends DefaultTreeModel implements SearchQueryList
|
||||
@Override
|
||||
public void onSearchQuery(@Nullable String query) {
|
||||
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||
TranslationData shadow = new TranslationData(this.state.isSortKeys(), this.state.isNestedKeys());
|
||||
TranslationData shadow = new TranslationData(this.state.isSortKeys());
|
||||
|
||||
if(query == null) {
|
||||
this.generateNodes(rootNode, this.data.getRootNode());
|
||||
@ -52,9 +50,9 @@ public class TreeModelMapper extends DefaultTreeModel implements SearchQueryList
|
||||
|
||||
query = query.toLowerCase();
|
||||
|
||||
for(String currentKey : this.data.getFullKeys()) {
|
||||
for(KeyPath currentKey : this.data.getFullKeys()) {
|
||||
Translation translation = this.data.getTranslation(currentKey);
|
||||
String loweredKey = currentKey.toLowerCase();
|
||||
String loweredKey = this.converter.concat(currentKey).toLowerCase();
|
||||
|
||||
if(query.contains(loweredKey) || loweredKey.contains(query)) {
|
||||
shadow.setTranslation(currentKey, translation);
|
||||
@ -100,14 +98,13 @@ public class TreeModelMapper extends DefaultTreeModel implements SearchQueryList
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull TreePath findTreePath(@NotNull String fullPath) {
|
||||
List<String> sections = new PathUtil(this.state.isNestedKeys()).split(fullPath);
|
||||
public @NotNull TreePath findTreePath(@NotNull KeyPath fullPath) {
|
||||
List<Object> nodes = new ArrayList<>();
|
||||
|
||||
TreeNode currentNode = (TreeNode) this.getRoot();
|
||||
nodes.add(currentNode);
|
||||
|
||||
for(String section : sections) {
|
||||
for(String section : fullPath) {
|
||||
currentNode = this.findNode(currentNode, section);
|
||||
|
||||
if(currentNode == null) {
|
||||
@ -120,7 +117,7 @@ public class TreeModelMapper extends DefaultTreeModel implements SearchQueryList
|
||||
return new TreePath(nodes.toArray());
|
||||
}
|
||||
|
||||
public @Nullable DefaultMutableTreeNode findNode(@NotNull TreeNode parent, @NotNull String key) {
|
||||
private @Nullable DefaultMutableTreeNode findNode(@NotNull TreeNode parent, @NotNull String key) {
|
||||
for(int i = 0; i < parent.getChildCount(); i++) {
|
||||
TreeNode child = parent.getChildAt(i);
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
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;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @deprecated Replaced by KeyPathConverter
|
||||
*/
|
||||
@Deprecated
|
||||
public class PathUtil {
|
||||
|
||||
public static final String 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(DELIMITER) || !nestKeys) {
|
||||
return new ArrayList<>(Collections.singletonList(path));
|
||||
}
|
||||
|
||||
return new ArrayList<>(Arrays.asList(
|
||||
path.split("(?<!\\\\)" + Pattern.quote(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 +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package de.marhali.easyi18n.util;
|
||||
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
@ -13,13 +14,13 @@ public class TreeUtil {
|
||||
|
||||
/**
|
||||
* Constructs the full path for a given {@link TreePath}
|
||||
* @param path TreePath
|
||||
* @return Full key (e.g user.username.title)
|
||||
* @param treePath TreePath
|
||||
* @return Corresponding key path
|
||||
*/
|
||||
public static String getFullPath(TreePath path) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
public static KeyPath getFullPath(TreePath treePath) {
|
||||
KeyPath keyPath = new KeyPath();
|
||||
|
||||
for (Object obj : path.getPath()) {
|
||||
for (Object obj : treePath.getPath()) {
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
|
||||
Object value = node.getUserObject();
|
||||
String section = value instanceof PresentationData ?
|
||||
@ -29,13 +30,9 @@ public class TreeUtil {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(builder.length() != 0) {
|
||||
builder.append(PathUtil.DELIMITER);
|
||||
}
|
||||
|
||||
builder.append(section);
|
||||
keyPath.add(section);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
return keyPath;
|
||||
}
|
||||
}
|
@ -19,6 +19,6 @@ settings.path.file-pattern-tooltip=Defines a wildcard matcher to filter relevant
|
||||
settings.path.prefix=Path prefix
|
||||
settings.preview=Preview locale
|
||||
settings.keys.sort=Sort translation keys alphabetically
|
||||
settings.keys.nested=Nest translation keys if possible
|
||||
settings.keys.nested=Escape delimiter character within a section layer.
|
||||
settings.editor.assistance=I18n key completion, annotation and reference inside editor
|
||||
error.io=Could not process file {0} with {1}. Unwanted files can be ignored via Translation file wildcard matcher option.
|
@ -1,5 +1,6 @@
|
||||
package de.marhali.easyi18n;
|
||||
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.Translation;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
import de.marhali.easyi18n.model.TranslationNode;
|
||||
@ -15,256 +16,184 @@ import java.util.*;
|
||||
*/
|
||||
public class TranslationDataTest {
|
||||
|
||||
private final int numOfTranslations = 18;
|
||||
private final int numOfTranslations = 14;
|
||||
private final Translation translation = new Translation("en", "test");
|
||||
|
||||
private void addTranslations(TranslationData data) {
|
||||
data.setTranslation("zulu", new Translation("en", "test"));
|
||||
data.setTranslation("gamma", new Translation("en", "test"));
|
||||
data.setTranslation(KeyPath.of("zulu"), translation);
|
||||
data.setTranslation(KeyPath.of("gamma"), translation);
|
||||
|
||||
data.setTranslation("foxtrot.super.long.key", new Translation("en", "test"));
|
||||
data.setTranslation(KeyPath.of("foxtrot.super.long.key"), translation);
|
||||
data.setTranslation(KeyPath.of("foxtrot", "super", "long", "key"), translation);
|
||||
|
||||
data.setTranslation("bravo.b", new Translation("en", "test"));
|
||||
data.setTranslation("bravo.c", new Translation("en", "test"));
|
||||
data.setTranslation("bravo.a", new Translation("en", "test"));
|
||||
data.setTranslation("bravo.d", new Translation("en", "test"));
|
||||
data.setTranslation("bravo.long.bravo", new Translation("en", "test"));
|
||||
data.setTranslation("bravo.long.charlie.a", new Translation("en", "test"));
|
||||
data.setTranslation("bravo.long.alpha", new Translation("en", "test"));
|
||||
data.setTranslation(KeyPath.of("charlie.b", "sub"), translation);
|
||||
data.setTranslation(KeyPath.of("charlie.a", "sub"), translation);
|
||||
|
||||
data.setTranslation("alpha.b", new Translation("en", "test"));
|
||||
data.setTranslation("alpha.c", new Translation("en", "test"));
|
||||
data.setTranslation("alpha.a", new Translation("en", "test"));
|
||||
data.setTranslation("alpha.d", new Translation("en", "test"));
|
||||
data.setTranslation(KeyPath.of("bravo.b"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo.c"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo.a"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo.d"), translation);
|
||||
|
||||
data.setTranslation("charlie.b", new Translation("en", "test"));
|
||||
data.setTranslation("charlie.c", new Translation("en", "test"));
|
||||
data.setTranslation("charlie.a", new Translation("en", "test"));
|
||||
data.setTranslation("charlie.d", new Translation("en", "test"));
|
||||
data.setTranslation(KeyPath.of("bravo", "b"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo", "c"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo", "a"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo", "d"), translation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeySorting() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
TranslationData data = new TranslationData(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"
|
||||
Set<KeyPath> expectation = new LinkedHashSet<>(Arrays.asList(
|
||||
KeyPath.of("bravo", "a"), KeyPath.of("bravo", "b"), KeyPath.of("bravo", "c"), KeyPath.of("bravo", "d"),
|
||||
KeyPath.of("bravo.a"), KeyPath.of("bravo.b"), KeyPath.of("bravo.c"), KeyPath.of("bravo.d"),
|
||||
KeyPath.of("charlie.a", "sub"), KeyPath.of("charlie.b", "sub"),
|
||||
KeyPath.of("foxtrot", "super", "long", "key"),
|
||||
KeyPath.of("foxtrot.super.long.key"),
|
||||
KeyPath.of("gamma"),
|
||||
KeyPath.of("zulu")
|
||||
));
|
||||
|
||||
Assert.assertEquals(data.getFullKeys(), expectation);
|
||||
Assert.assertEquals(data.getFullKeys().size(), numOfTranslations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyUnordered() {
|
||||
TranslationData data = new TranslationData(false, true);
|
||||
TranslationData data = new TranslationData(false);
|
||||
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"
|
||||
Set<KeyPath> expectation = new LinkedHashSet<>(Arrays.asList(
|
||||
KeyPath.of("zulu"),
|
||||
KeyPath.of("gamma"),
|
||||
KeyPath.of("foxtrot.super.long.key"),
|
||||
KeyPath.of("foxtrot", "super", "long", "key"),
|
||||
KeyPath.of("charlie.b", "sub"), KeyPath.of("charlie.a", "sub"),
|
||||
KeyPath.of("bravo.b"), KeyPath.of("bravo.c"), KeyPath.of("bravo.a"), KeyPath.of("bravo.d"),
|
||||
KeyPath.of("bravo", "b"), KeyPath.of("bravo", "c"), KeyPath.of("bravo", "a"), KeyPath.of("bravo", "d")
|
||||
));
|
||||
|
||||
Assert.assertEquals(data.getFullKeys(), expectation);
|
||||
Assert.assertEquals(data.getFullKeys().size(), numOfTranslations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyNesting() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
public void testDelete() {
|
||||
TranslationData data = new TranslationData(true);
|
||||
|
||||
data.setTranslation("nested.alpha", new Translation("en", "test"));
|
||||
data.setTranslation("nested.bravo", new Translation("en", "test"));
|
||||
data.setTranslation("other.alpha", new Translation("en", "test"));
|
||||
data.setTranslation("other.bravo", new Translation("en", "test"));
|
||||
data.setTranslation(KeyPath.of("alpha"), translation);
|
||||
data.setTranslation(KeyPath.of("nested.alpha"), translation);
|
||||
data.setTranslation(KeyPath.of("nested.long.bravo"), translation);
|
||||
|
||||
Assert.assertEquals(data.getRootNode().getChildren().size(), 2);
|
||||
data.setTranslation(KeyPath.of("beta"), translation);
|
||||
data.setTranslation(KeyPath.of("nested", "alpha"), translation);
|
||||
data.setTranslation(KeyPath.of("nested", "long", "bravo"), translation);
|
||||
|
||||
for(TranslationNode node : data.getRootNode().getChildren().values()) {
|
||||
Assert.assertFalse(node.isLeaf());
|
||||
}
|
||||
}
|
||||
Assert.assertEquals(data.getFullKeys().size(), 6);
|
||||
|
||||
@Test
|
||||
public void testKeyNonNested() {
|
||||
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() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
|
||||
Translation value = new Translation("en", "test");
|
||||
|
||||
data.setTranslation("alpha", value);
|
||||
data.setTranslation("nested.alpha", value);
|
||||
data.setTranslation("nested.long.bravo", value);
|
||||
data.setTranslation(KeyPath.of("alpha"), null);
|
||||
data.setTranslation(KeyPath.of("nested.alpha"), null);
|
||||
data.setTranslation(KeyPath.of("nested.long.bravo"), null);
|
||||
|
||||
Assert.assertEquals(data.getFullKeys().size(), 3);
|
||||
|
||||
data.setTranslation("alpha", null);
|
||||
data.setTranslation("nested.alpha", null);
|
||||
data.setTranslation("nested.long.bravo", null);
|
||||
data.setTranslation(KeyPath.of("beta"), null);
|
||||
data.setTranslation(KeyPath.of("nested", "alpha"), null);
|
||||
data.setTranslation(KeyPath.of("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"));
|
||||
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("alpha")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("nested.alpha")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("nested.long.bravo")));
|
||||
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("beta")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("nested", "alpha")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("nested", "long", "bravo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNonNested() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
|
||||
Translation value = new Translation("en", "test");
|
||||
|
||||
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() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
public void testDeleteRecursively() {
|
||||
TranslationData data = new TranslationData(true);
|
||||
this.addTranslations(data);
|
||||
|
||||
data.setTranslation("foxtrot.super.long.key", null);
|
||||
data.setTranslation(KeyPath.of("foxtrot.super.long.key"), null);
|
||||
data.setTranslation(KeyPath.of("foxtrot", "super", "long", "key"), null);
|
||||
|
||||
Assert.assertNull(data.getTranslation("foxtrot.super.long.key"));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("foxtrot.super.long.key")));
|
||||
Assert.assertNull(data.getRootNode().getChildren().get("foxtrot"));
|
||||
Assert.assertEquals(data.getFullKeys().size(), numOfTranslations - 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecurseDeleteNested() {
|
||||
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() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
public void testOverwrite() {
|
||||
TranslationData data = new TranslationData(true);
|
||||
|
||||
Translation before = new Translation("en", "before");
|
||||
Translation after = new Translation("en", "after");
|
||||
|
||||
data.setTranslation("alpha", before);
|
||||
data.setTranslation("nested.alpha", before);
|
||||
data.setTranslation("nested.long.bravo", before);
|
||||
data.setTranslation(KeyPath.of("alpha"), before);
|
||||
data.setTranslation(KeyPath.of("nested.alpha"), before);
|
||||
data.setTranslation(KeyPath.of("nested.long.bravo"), before);
|
||||
data.setTranslation(KeyPath.of("beta"), before);
|
||||
data.setTranslation(KeyPath.of("nested", "alpha"), before);
|
||||
data.setTranslation(KeyPath.of("nested", "long", "bravo"), before);
|
||||
|
||||
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("alpha")), before);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested.alpha")), before);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested.long.bravo")), before);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("beta")), before);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested", "alpha")), before);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested", "long", "bravo")), before);
|
||||
|
||||
data.setTranslation("alpha", after);
|
||||
data.setTranslation("nested.alpha", after);
|
||||
data.setTranslation("nested.long.bravo", after);
|
||||
data.setTranslation(KeyPath.of("alpha"), after);
|
||||
data.setTranslation(KeyPath.of("nested.alpha"), after);
|
||||
data.setTranslation(KeyPath.of("nested.long.bravo"), after);
|
||||
data.setTranslation(KeyPath.of("beta"), after);
|
||||
data.setTranslation(KeyPath.of("nested", "alpha"), after);
|
||||
data.setTranslation(KeyPath.of("nested", "long", "bravo"), after);
|
||||
|
||||
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("alpha")), after);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested.alpha")), after);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested.long.bravo")), after);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("beta")), after);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested", "alpha")), after);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("nested", "long", "bravo")), after);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverwriteNested() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
public void testTransformRecursively() {
|
||||
TranslationData data = new TranslationData(true);
|
||||
|
||||
Translation before = new Translation("en", "before");
|
||||
Translation after = new Translation("en", "after");
|
||||
data.setTranslation(KeyPath.of("alpha.nested.key"), translation);
|
||||
data.setTranslation(KeyPath.of("alpha.other"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo"), translation);
|
||||
data.setTranslation(KeyPath.of("alpha", "nested", "key"), translation);
|
||||
data.setTranslation(KeyPath.of("alpha", "other"), translation);
|
||||
data.setTranslation(KeyPath.of("charlie"), translation);
|
||||
|
||||
data.setTranslation("alpha", before);
|
||||
data.setTranslation("nested.alpha", before);
|
||||
data.setTranslation("nested.long.bravo", before);
|
||||
Assert.assertEquals(6, data.getFullKeys().size());
|
||||
|
||||
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), before);
|
||||
data.setTranslation(KeyPath.of("alpha.nested"), translation);
|
||||
data.setTranslation(KeyPath.of("alpha.other.new"), translation);
|
||||
data.setTranslation(KeyPath.of("bravo"), null);
|
||||
data.setTranslation(KeyPath.of("alpha", "nested"), translation);
|
||||
data.setTranslation(KeyPath.of("alpha", "other", "new"), translation);
|
||||
data.setTranslation(KeyPath.of("charlie"), null);
|
||||
|
||||
data.setTranslation("alpha", after);
|
||||
data.setTranslation("nested.alpha", after);
|
||||
data.setTranslation("nested.long.bravo", after);
|
||||
Assert.assertEquals(6, data.getFullKeys().size());
|
||||
|
||||
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||
Assert.assertEquals(data.getTranslation("alpha"), after);
|
||||
}
|
||||
Assert.assertNotNull(data.getTranslation(KeyPath.of("alpha.nested.key")));
|
||||
Assert.assertNotNull(data.getTranslation(KeyPath.of("alpha.other")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("bravo")));
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("alpha.nested")), translation);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("alpha.other.new")), translation);
|
||||
|
||||
@Test
|
||||
public void testRecurseTransformNested() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
|
||||
Translation value = new Translation("en", "test");
|
||||
|
||||
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() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
|
||||
Translation value = new Translation("en", "test");
|
||||
|
||||
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);
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("alpha", "nested", "key")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("alpha", "other")));
|
||||
Assert.assertNull(data.getTranslation(KeyPath.of("charlie")));
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("alpha", "nested")), translation);
|
||||
Assert.assertEquals(data.getTranslation(KeyPath.of("alpha", "other", "new")), translation);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import com.google.gson.JsonPrimitive;
|
||||
|
||||
import de.marhali.easyi18n.io.json.JsonArrayMapper;
|
||||
import de.marhali.easyi18n.io.json.JsonMapper;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
@ -16,7 +17,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link de.marhali.easyi18n.io.json.JsonMapper}
|
||||
* Unit tests for {@link JsonMapper}.
|
||||
* @author marhali
|
||||
*/
|
||||
public class JsonMapperTest extends AbstractMapperTest {
|
||||
@ -28,7 +29,7 @@ public class JsonMapperTest extends AbstractMapperTest {
|
||||
input.add("alpha", new JsonPrimitive("test"));
|
||||
input.add("bravo", new JsonPrimitive("test"));
|
||||
|
||||
TranslationData data = new TranslationData(false, true);
|
||||
TranslationData data = new TranslationData(false);
|
||||
JsonMapper.read("en", input, data.getRootNode());
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
@ -45,7 +46,7 @@ public class JsonMapperTest extends AbstractMapperTest {
|
||||
input.add("alpha", new JsonPrimitive("test"));
|
||||
input.add("bravo", new JsonPrimitive("test"));
|
||||
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
TranslationData data = new TranslationData(true);
|
||||
JsonMapper.read("en", input, data.getRootNode());
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
@ -57,9 +58,9 @@ public class JsonMapperTest extends AbstractMapperTest {
|
||||
|
||||
@Override
|
||||
public void testArrays() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("simple", create(arraySimple));
|
||||
data.setTranslation("escaped", create(arrayEscaped));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("simple"), create(arraySimple));
|
||||
data.setTranslation(KeyPath.of("escaped"), create(arrayEscaped));
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
JsonMapper.write("en", output, data.getRootNode());
|
||||
@ -69,81 +70,82 @@ public class JsonMapperTest extends AbstractMapperTest {
|
||||
Assert.assertTrue(output.get("escaped").isJsonArray());
|
||||
Assert.assertEquals(arrayEscaped, StringEscapeUtils.unescapeJava(JsonArrayMapper.read(output.get("escaped").getAsJsonArray())));
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
JsonMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertTrue(JsonArrayMapper.isArray(input.getTranslation("simple").get("en")));
|
||||
Assert.assertTrue(JsonArrayMapper.isArray(input.getTranslation("escaped").get("en")));
|
||||
Assert.assertTrue(JsonArrayMapper.isArray(input.getTranslation(KeyPath.of("simple")).get("en")));
|
||||
Assert.assertTrue(JsonArrayMapper.isArray(input.getTranslation(KeyPath.of("escaped")).get("en")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testSpecialCharacters() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("chars", create(specialCharacters));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("chars"), create(specialCharacters));
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
JsonMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertEquals(specialCharacters, output.get("chars").getAsString());
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
JsonMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals(specialCharacters, StringEscapeUtils.unescapeJava(input.getTranslation("chars").get("en")));
|
||||
Assert.assertEquals(specialCharacters,
|
||||
StringEscapeUtils.unescapeJava(input.getTranslation(KeyPath.of("chars")).get("en")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNestedKeys() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("nested.key.section", create("test"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("nested", "key", "section"), create("test"));
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
JsonMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertEquals("test", output.getAsJsonObject("nested").getAsJsonObject("key").get("section").getAsString());
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
JsonMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals("test", input.getTranslation("nested.key.section").get("en"));
|
||||
Assert.assertEquals("test", input.getTranslation(KeyPath.of("nested", "key", "section")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNonNestedKeys() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
data.setTranslation("long.key.with.many.sections", create("test"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("long.key.with.many.sections"), create("test"));
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
JsonMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertTrue(output.has("long.key.with.many.sections"));
|
||||
|
||||
TranslationData input = new TranslationData(true, false);
|
||||
TranslationData input = new TranslationData(true);
|
||||
JsonMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals("test", input.getTranslation("long.key.with.many.sections").get("en"));
|
||||
Assert.assertEquals("test", input.getTranslation(KeyPath.of("long.key.with.many.sections")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testLeadingSpace() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("space", create(leadingSpace));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("space"), create(leadingSpace));
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
JsonMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertEquals(leadingSpace, output.get("space").getAsString());
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
JsonMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals(leadingSpace, input.getTranslation("space").get("en"));
|
||||
Assert.assertEquals(leadingSpace, input.getTranslation(KeyPath.of("space")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNumbers() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("numbered", create("15000"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("numbered"), create("15000"));
|
||||
|
||||
JsonObject output = new JsonObject();
|
||||
JsonMapper.write("en", output, data.getRootNode());
|
||||
@ -154,6 +156,6 @@ public class JsonMapperTest extends AbstractMapperTest {
|
||||
input.addProperty("numbered", 143.23);
|
||||
JsonMapper.read("en", input, data.getRootNode());
|
||||
|
||||
Assert.assertEquals("143.23", data.getTranslation("numbered").get("en"));
|
||||
Assert.assertEquals("143.23", data.getTranslation(KeyPath.of("numbered")).get("en"));
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package de.marhali.easyi18n.mapper;
|
||||
import de.marhali.easyi18n.io.properties.PropertiesArrayMapper;
|
||||
import de.marhali.easyi18n.io.properties.PropertiesMapper;
|
||||
import de.marhali.easyi18n.io.properties.SortableProperties;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
@ -11,7 +12,7 @@ import org.junit.Assert;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link de.marhali.easyi18n.io.properties.PropertiesMapper}
|
||||
* Unit tests for {@link PropertiesMapper}.
|
||||
* @author marhali
|
||||
*/
|
||||
public class PropertiesMapperTest extends AbstractMapperTest {
|
||||
@ -23,7 +24,7 @@ public class PropertiesMapperTest extends AbstractMapperTest {
|
||||
input.setProperty("alpha", "test");
|
||||
input.setProperty("bravo", "test");
|
||||
|
||||
TranslationData data = new TranslationData(false, true);
|
||||
TranslationData data = new TranslationData(false);
|
||||
PropertiesMapper.read("en", input, data);
|
||||
|
||||
SortableProperties output = new SortableProperties(false);
|
||||
@ -40,7 +41,7 @@ public class PropertiesMapperTest extends AbstractMapperTest {
|
||||
input.setProperty("alpha", "test");
|
||||
input.setProperty("bravo", "test");
|
||||
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
TranslationData data = new TranslationData(true);
|
||||
PropertiesMapper.read("en", input, data);
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
@ -52,9 +53,9 @@ public class PropertiesMapperTest extends AbstractMapperTest {
|
||||
|
||||
@Override
|
||||
public void testArrays() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("simple", create(arraySimple));
|
||||
data.setTranslation("escaped", create(arrayEscaped));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("simple"), create(arraySimple));
|
||||
data.setTranslation(KeyPath.of("escaped"), create(arrayEscaped));
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
PropertiesMapper.write("en", output, data);
|
||||
@ -64,83 +65,84 @@ public class PropertiesMapperTest extends AbstractMapperTest {
|
||||
Assert.assertTrue(output.get("escaped") instanceof String[]);
|
||||
Assert.assertEquals(arrayEscaped, StringEscapeUtils.unescapeJava(PropertiesArrayMapper.read((String[]) output.get("escaped"))));
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
PropertiesMapper.read("en", output, input);
|
||||
|
||||
Assert.assertTrue(PropertiesArrayMapper.isArray(input.getTranslation("simple").get("en")));
|
||||
Assert.assertTrue(PropertiesArrayMapper.isArray(input.getTranslation("escaped").get("en")));
|
||||
Assert.assertTrue(PropertiesArrayMapper.isArray(input.getTranslation(KeyPath.of("simple")).get("en")));
|
||||
Assert.assertTrue(PropertiesArrayMapper.isArray(input.getTranslation(KeyPath.of("escaped")).get("en")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testSpecialCharacters() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("chars", create(specialCharacters));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("chars"), create(specialCharacters));
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
PropertiesMapper.write("en", output, data);
|
||||
|
||||
Assert.assertEquals(specialCharacters, output.get("chars"));
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
PropertiesMapper.read("en", output, input);
|
||||
|
||||
Assert.assertEquals(specialCharacters, StringEscapeUtils.unescapeJava(input.getTranslation("chars").get("en")));
|
||||
Assert.assertEquals(specialCharacters, StringEscapeUtils.unescapeJava(input.getTranslation(KeyPath.of("chars")).get("en")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNestedKeys() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("nested.key.sections", create("test"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("nested", "key", "sections"), create("test"));
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
PropertiesMapper.write("en", output, data);
|
||||
|
||||
Assert.assertEquals("test", output.get("nested.key.sections"));
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
PropertiesMapper.read("en", output, input);
|
||||
|
||||
System.out.println(input);
|
||||
|
||||
Assert.assertTrue(input.getRootNode().getChildren().containsKey("nested"));
|
||||
Assert.assertEquals("test", input.getTranslation("nested.key.sections").get("en"));
|
||||
Assert.assertEquals("test", input.getTranslation(KeyPath.of("nested", "key", "sections")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNonNestedKeys() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
data.setTranslation("long.key.with.many.sections", create("test"));
|
||||
public void testNonNestedKeys() { // Note: Key nesting is not supported in properties file.
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("long.key.with.many.sections"), create("test"));
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
PropertiesMapper.write("en", output, data);
|
||||
|
||||
Assert.assertNotNull(output.get("long.key.with.many.sections"));
|
||||
|
||||
TranslationData input = new TranslationData(true, false);
|
||||
TranslationData input = new TranslationData(true);
|
||||
PropertiesMapper.read("en", output, input);
|
||||
|
||||
Assert.assertEquals("test", input.getRootNode().getChildren()
|
||||
.get("long.key.with.many.sections").getValue().get("en"));
|
||||
Assert.assertEquals("test", input.getTranslation(KeyPath.of("long", "key", "with", "many", "sections")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testLeadingSpace() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("space", create(leadingSpace));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("space"), create(leadingSpace));
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
PropertiesMapper.write("en", output, data);
|
||||
|
||||
Assert.assertEquals(leadingSpace, output.get("space"));
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
PropertiesMapper.read("en", output, input);
|
||||
|
||||
Assert.assertEquals(leadingSpace, input.getTranslation("space").get("en"));
|
||||
Assert.assertEquals(leadingSpace, input.getTranslation(KeyPath.of("space")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNumbers() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("numbered", create("15000"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("numbered"), create("15000"));
|
||||
|
||||
SortableProperties output = new SortableProperties(true);
|
||||
PropertiesMapper.write("en", output, data);
|
||||
@ -151,6 +153,6 @@ public class PropertiesMapperTest extends AbstractMapperTest {
|
||||
input.put("numbered", 143.23);
|
||||
PropertiesMapper.read("en", input, data);
|
||||
|
||||
Assert.assertEquals("143.23", data.getTranslation("numbered").get("en"));
|
||||
Assert.assertEquals("143.23", data.getTranslation(KeyPath.of("numbered")).get("en"));
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package de.marhali.easyi18n.mapper;
|
||||
|
||||
import de.marhali.easyi18n.io.yaml.YamlArrayMapper;
|
||||
import de.marhali.easyi18n.io.yaml.YamlMapper;
|
||||
import de.marhali.easyi18n.model.KeyPath;
|
||||
import de.marhali.easyi18n.model.TranslationData;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
|
||||
@ -15,7 +16,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link de.marhali.easyi18n.io.yaml.YamlMapper}
|
||||
* Unit tests for {@link YamlMapper}.
|
||||
* @author marhali
|
||||
*/
|
||||
public class YamlMapperTest extends AbstractMapperTest {
|
||||
@ -27,7 +28,7 @@ public class YamlMapperTest extends AbstractMapperTest {
|
||||
input.set("alpha", "test");
|
||||
input.set("bravo", "test");
|
||||
|
||||
TranslationData data = new TranslationData(false, true);
|
||||
TranslationData data = new TranslationData(false);
|
||||
YamlMapper.read("en", input, data.getRootNode());
|
||||
|
||||
Section output = new MapSection();
|
||||
@ -44,7 +45,7 @@ public class YamlMapperTest extends AbstractMapperTest {
|
||||
input.set("alpha", "test");
|
||||
input.set("bravo", "test");
|
||||
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
TranslationData data = new TranslationData(true);
|
||||
YamlMapper.read("en", input, data.getRootNode());
|
||||
|
||||
Section output = new MapSection();
|
||||
@ -56,9 +57,9 @@ public class YamlMapperTest extends AbstractMapperTest {
|
||||
|
||||
@Override
|
||||
public void testArrays() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("simple", create(arraySimple));
|
||||
data.setTranslation("escaped", create(arrayEscaped));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("simple"), create(arraySimple));
|
||||
data.setTranslation(KeyPath.of("escaped"), create(arrayEscaped));
|
||||
|
||||
Section output = new MapSection();
|
||||
YamlMapper.write("en", output, data.getRootNode());
|
||||
@ -68,81 +69,82 @@ public class YamlMapperTest extends AbstractMapperTest {
|
||||
Assert.assertTrue(output.isList("escaped"));
|
||||
Assert.assertEquals(arrayEscaped, StringEscapeUtils.unescapeJava(YamlArrayMapper.read(output.getList("escaped").get())));
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
YamlMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertTrue(YamlArrayMapper.isArray(input.getTranslation("simple").get("en")));
|
||||
Assert.assertTrue(YamlArrayMapper.isArray(input.getTranslation("escaped").get("en")));
|
||||
Assert.assertTrue(YamlArrayMapper.isArray(input.getTranslation(KeyPath.of("simple")).get("en")));
|
||||
Assert.assertTrue(YamlArrayMapper.isArray(input.getTranslation(KeyPath.of("escaped")).get("en")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testSpecialCharacters() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("chars", create(specialCharacters));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("chars"), create(specialCharacters));
|
||||
|
||||
Section output = new MapSection();
|
||||
YamlMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertEquals(specialCharacters, output.getString("chars").get());
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
YamlMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals(specialCharacters, StringEscapeUtils.unescapeJava(input.getTranslation("chars").get("en")));
|
||||
Assert.assertEquals(specialCharacters,
|
||||
StringEscapeUtils.unescapeJava(input.getTranslation(KeyPath.of("chars")).get("en")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNestedKeys() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("nested.key.section", create("test"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("nested", "key", "section"), create("test"));
|
||||
|
||||
Section output = new MapSection();
|
||||
YamlMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertEquals("test", output.getString("nested.key.section").get());
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
YamlMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals("test", input.getTranslation("nested.key.section").get("en"));
|
||||
Assert.assertEquals("test", input.getTranslation(KeyPath.of("nested", "key", "section")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNonNestedKeys() {
|
||||
TranslationData data = new TranslationData(true, false);
|
||||
data.setTranslation("long.key.with.many.sections", create("test"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("long.key.with.many.sections"), create("test"));
|
||||
|
||||
Section output = new MapSection();
|
||||
YamlMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertTrue(output.getKeys().contains("long.key.with.many.sections"));
|
||||
|
||||
TranslationData input = new TranslationData(true, false);
|
||||
TranslationData input = new TranslationData(true);
|
||||
YamlMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals("test", input.getTranslation("long.key.with.many.sections").get("en"));
|
||||
Assert.assertEquals("test", input.getTranslation(KeyPath.of("long.key.with.many.sections")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testLeadingSpace() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("space", create(leadingSpace));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("space"), create(leadingSpace));
|
||||
|
||||
Section output = new MapSection();
|
||||
YamlMapper.write("en", output, data.getRootNode());
|
||||
|
||||
Assert.assertEquals(leadingSpace, output.getString("space").get());
|
||||
|
||||
TranslationData input = new TranslationData(true, true);
|
||||
TranslationData input = new TranslationData(true);
|
||||
YamlMapper.read("en", output, input.getRootNode());
|
||||
|
||||
Assert.assertEquals(leadingSpace, input.getTranslation("space").get("en"));
|
||||
Assert.assertEquals(leadingSpace, input.getTranslation(KeyPath.of("space")).get("en"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testNumbers() {
|
||||
TranslationData data = new TranslationData(true, true);
|
||||
data.setTranslation("numbered", create("15000"));
|
||||
TranslationData data = new TranslationData(true);
|
||||
data.setTranslation(KeyPath.of("numbered"), create("15000"));
|
||||
|
||||
Section output = new MapSection();
|
||||
YamlMapper.write("en", output, data.getRootNode());
|
||||
@ -153,6 +155,6 @@ public class YamlMapperTest extends AbstractMapperTest {
|
||||
input.set("numbered", 143.23);
|
||||
YamlMapper.read("en", input, data.getRootNode());
|
||||
|
||||
Assert.assertEquals("143.23", data.getTranslation("numbered").get("en"));
|
||||
Assert.assertEquals("143.23", data.getTranslation(KeyPath.of("numbered")).get("en"));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user