remove legacy components
This commit is contained in:
parent
1afdac9006
commit
cdd7188769
@ -1,34 +0,0 @@
|
|||||||
package de.marhali.easyi18n.io;
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to retrieve and save localized messages.
|
|
||||||
* Can be implemented by various standards. Such as JSON, Properties-Bundle and so on.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface TranslatorIO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads localized messages from the persistence layer.
|
|
||||||
* @param project Opened intellij project
|
|
||||||
* @param directoryPath The full path for the directory which holds all locale files
|
|
||||||
* @param callback Contains loaded translations. Will be called after io operation. Content might be null on failure.
|
|
||||||
*/
|
|
||||||
void read(@NotNull Project project, @NotNull String directoryPath, @NotNull Consumer<Translations> callback);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the provided messages (translations) to the persistence layer.
|
|
||||||
* @param project Opened intellij project
|
|
||||||
* @param translations Translations instance to save
|
|
||||||
* @param directoryPath The full path for the directory which holds all locale files
|
|
||||||
* @param callback Will be called after io operation. Can be used to determine if action was successful(true) or not
|
|
||||||
*/
|
|
||||||
void save(@NotNull Project project, @NotNull Translations translations,
|
|
||||||
@NotNull String directoryPath, @NotNull Consumer<Boolean> callback);
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
package de.marhali.easyi18n.io.implementation;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation for JSON translation files.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public class JsonTranslatorIO implements TranslatorIO {
|
|
||||||
|
|
||||||
private static final String FILE_EXTENSION = "json";
|
|
||||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(@NotNull Project project, @NotNull String directoryPath, @NotNull Consumer<Translations> callback) {
|
|
||||||
ApplicationManager.getApplication().saveAll(); // Save opened files (required if new locales were added)
|
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(() -> {
|
|
||||||
VirtualFile directory = LocalFileSystem.getInstance().findFileByIoFile(new File(directoryPath));
|
|
||||||
|
|
||||||
if(directory == null || directory.getChildren() == null) {
|
|
||||||
throw new IllegalArgumentException("Specified folder is invalid (" + directoryPath + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFile[] files = directory.getChildren();
|
|
||||||
|
|
||||||
List<String> locales = new ArrayList<>();
|
|
||||||
LocalizedNode nodes = new LocalizedNode(LocalizedNode.ROOT_KEY, new ArrayList<>());
|
|
||||||
|
|
||||||
try {
|
|
||||||
for(VirtualFile file : files) {
|
|
||||||
|
|
||||||
if(!IOUtil.isFileRelevant(project, file)) { // File does not matches pattern
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
locales.add(file.getNameWithoutExtension());
|
|
||||||
|
|
||||||
JsonObject tree = GSON.fromJson(new InputStreamReader(file.getInputStream(),
|
|
||||||
file.getCharset()), JsonObject.class);
|
|
||||||
|
|
||||||
JsonUtil.readTree(file.getNameWithoutExtension(), tree, nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.accept(new Translations(locales, nodes));
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(@NotNull Project project, @NotNull Translations translations,
|
|
||||||
@NotNull String directoryPath, @NotNull Consumer<Boolean> callback) {
|
|
||||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
||||||
try {
|
|
||||||
for(String locale : translations.getLocales()) {
|
|
||||||
JsonObject content = new JsonObject();
|
|
||||||
JsonUtil.writeTree(locale, content, translations.getNodes());
|
|
||||||
|
|
||||||
String fullPath = directoryPath + "/" + locale + "." + FILE_EXTENSION;
|
|
||||||
File file = new File(fullPath);
|
|
||||||
boolean created = file.createNewFile();
|
|
||||||
|
|
||||||
VirtualFile vf = created ? LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
|
|
||||||
: LocalFileSystem.getInstance().findFileByIoFile(file);
|
|
||||||
|
|
||||||
vf.setBinaryContent(GSON.toJson(content).getBytes(vf.getCharset()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Successfully saved
|
|
||||||
callback.accept(true);
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
package de.marhali.easyi18n.io.implementation;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO operations for splitted / modularized json files. Each locale can have multiple translation files.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public class ModularizedJsonTranslatorIO implements TranslatorIO {
|
|
||||||
|
|
||||||
private static final String FILE_EXTENSION = "json";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(@NotNull Project project, @NotNull String directoryPath, @NotNull Consumer<Translations> callback) {
|
|
||||||
ApplicationManager.getApplication().saveAll(); // Save opened files (required if new locales were added)
|
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(() -> {
|
|
||||||
VirtualFile directory = LocalFileSystem.getInstance().findFileByIoFile(new File(directoryPath));
|
|
||||||
|
|
||||||
if(directory == null || directory.getChildren() == null) {
|
|
||||||
throw new IllegalArgumentException("Specified folder is invalid (" + directoryPath + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFile[] localeDirectories = directory.getChildren();
|
|
||||||
|
|
||||||
List<String> locales = new ArrayList<>();
|
|
||||||
LocalizedNode nodes = new LocalizedNode(LocalizedNode.ROOT_KEY, new ArrayList<>());
|
|
||||||
|
|
||||||
try {
|
|
||||||
for(VirtualFile localeDir : localeDirectories) {
|
|
||||||
String locale = localeDir.getName();
|
|
||||||
locales.add(locale);
|
|
||||||
|
|
||||||
// Read all json modules
|
|
||||||
for(VirtualFile module : localeDir.getChildren()) {
|
|
||||||
|
|
||||||
if(!IOUtil.isFileRelevant(project, module)) { // File does not matches pattern
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject tree = JsonParser.parseReader(new InputStreamReader(module.getInputStream(),
|
|
||||||
module.getCharset())).getAsJsonObject();
|
|
||||||
|
|
||||||
String moduleName = module.getNameWithoutExtension();
|
|
||||||
LocalizedNode moduleNode = nodes.getChildren(moduleName);
|
|
||||||
|
|
||||||
if(moduleNode == null) { // Create module / sub node
|
|
||||||
moduleNode = new LocalizedNode(moduleName, new ArrayList<>());
|
|
||||||
nodes.addChildren(moduleNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonUtil.readTree(locale, tree, moduleNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.accept(new Translations(locales, nodes));
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(@NotNull Project project, @NotNull Translations translations,
|
|
||||||
@NotNull String directoryPath, @NotNull Consumer<Boolean> callback) {
|
|
||||||
|
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
|
||||||
|
|
||||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
||||||
try {
|
|
||||||
for(String locale : translations.getLocales()) {
|
|
||||||
// Use top level children as modules
|
|
||||||
for (LocalizedNode module : translations.getNodes().getChildren()) {
|
|
||||||
JsonObject content = new JsonObject();
|
|
||||||
JsonUtil.writeTree(locale, content, module);
|
|
||||||
|
|
||||||
String fullPath = directoryPath + "/" + locale + "/" + module.getKey() + "." + FILE_EXTENSION;
|
|
||||||
File file = new File(fullPath);
|
|
||||||
boolean created = file.createNewFile();
|
|
||||||
|
|
||||||
VirtualFile vf = created ? LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
|
|
||||||
: LocalFileSystem.getInstance().findFileByIoFile(file);
|
|
||||||
|
|
||||||
vf.setBinaryContent(gson.toJson(content).getBytes(vf.getCharset()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Successfully saved
|
|
||||||
callback.accept(true);
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
package de.marhali.easyi18n.io.implementation;
|
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.TranslatorIO;
|
|
||||||
import de.marhali.easyi18n.util.SortedProperties;
|
|
||||||
import de.marhali.easyi18n.util.StringUtil;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation for properties translation files.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public class PropertiesTranslatorIO implements TranslatorIO {
|
|
||||||
|
|
||||||
public static final String FILE_EXTENSION = "properties";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(@NotNull Project project, @NotNull String directoryPath, @NotNull Consumer<Translations> callback) {
|
|
||||||
ApplicationManager.getApplication().saveAll(); // Save opened files (required if new locales were added)
|
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(() -> {
|
|
||||||
VirtualFile directory = LocalFileSystem.getInstance().findFileByIoFile(new File(directoryPath));
|
|
||||||
|
|
||||||
if(directory == null || directory.getChildren() == null) {
|
|
||||||
throw new IllegalArgumentException("Specified folder is invalid (" + directoryPath + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFile[] files = directory.getChildren();
|
|
||||||
|
|
||||||
List<String> locales = new ArrayList<>();
|
|
||||||
LocalizedNode nodes = new LocalizedNode(LocalizedNode.ROOT_KEY, new ArrayList<>());
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (VirtualFile file : files) {
|
|
||||||
|
|
||||||
if(!IOUtil.isFileRelevant(project, file)) { // File does not matches pattern
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
locales.add(file.getNameWithoutExtension());
|
|
||||||
SortedProperties properties = new SortedProperties();
|
|
||||||
properties.load(new InputStreamReader(file.getInputStream(), file.getCharset()));
|
|
||||||
readProperties(file.getNameWithoutExtension(), properties, nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.accept(new Translations(locales, nodes));
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(@NotNull Project project, @NotNull Translations translations,
|
|
||||||
@NotNull String directoryPath, @NotNull Consumer<Boolean> callback) {
|
|
||||||
|
|
||||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
||||||
try {
|
|
||||||
for(String locale : translations.getLocales()) {
|
|
||||||
SortedProperties properties = new SortedProperties();
|
|
||||||
writeProperties(locale, properties, translations.getNodes(), "");
|
|
||||||
|
|
||||||
String fullPath = directoryPath + "/" + locale + "." + FILE_EXTENSION;
|
|
||||||
VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(new File(fullPath));
|
|
||||||
|
|
||||||
StringWriter content = new StringWriter();
|
|
||||||
properties.store(content, "I18n " + locale + " keys");
|
|
||||||
|
|
||||||
file.setBinaryContent(content.toString().getBytes(file.getCharset()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Successfully saved
|
|
||||||
callback.accept(true);
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeProperties(String locale, Properties props, LocalizedNode node, String parentPath) {
|
|
||||||
if(node.isLeaf() && !node.getKey().equals(LocalizedNode.ROOT_KEY)) {
|
|
||||||
if(node.getValue().get(locale) != null) { // Translation is defined - track it
|
|
||||||
String value = StringEscapeUtils.unescapeJava(node.getValue().get(locale));
|
|
||||||
props.setProperty(parentPath, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
for(LocalizedNode children : node.getChildren()) {
|
|
||||||
writeProperties(locale, props, children,
|
|
||||||
parentPath + (parentPath.isEmpty() ? "" : ".") + children.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readProperties(String locale, Properties props, LocalizedNode parent) {
|
|
||||||
props.forEach((key, value) -> {
|
|
||||||
List<String> sections = TranslationsUtil.getSections(String.valueOf(key));
|
|
||||||
|
|
||||||
LocalizedNode node = parent;
|
|
||||||
|
|
||||||
for (String section : sections) {
|
|
||||||
LocalizedNode subNode = node.getChildren(section);
|
|
||||||
|
|
||||||
if(subNode == null) {
|
|
||||||
subNode = new LocalizedNode(section, new ArrayList<>());
|
|
||||||
node.addChildren(subNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = subNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> messages = node.getValue();
|
|
||||||
String escapedValue = StringUtil.escapeControls(String.valueOf(value), true);
|
|
||||||
messages.put(locale, escapedValue);
|
|
||||||
node.setValue(messages);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,125 +0,0 @@
|
|||||||
package de.marhali.easyi18n.io.implementation;
|
|
||||||
|
|
||||||
import com.intellij.openapi.application.*;
|
|
||||||
import com.intellij.openapi.project.*;
|
|
||||||
import com.intellij.openapi.vfs.*;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.io.*;
|
|
||||||
import de.marhali.easyi18n.model.*;
|
|
||||||
import de.marhali.easyi18n.util.*;
|
|
||||||
import de.marhali.easyi18n.util.array.YamlArrayUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.*;
|
|
||||||
|
|
||||||
import thito.nodeflow.config.*;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.charset.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.*;
|
|
||||||
|
|
||||||
public class YamlTranslatorIO implements TranslatorIO {
|
|
||||||
@Override
|
|
||||||
public void read(@NotNull Project project, @NotNull String directoryPath, @NotNull Consumer<Translations> callback) {
|
|
||||||
ApplicationManager.getApplication().saveAll(); // Save opened files (required if new locales were added)
|
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(() -> {
|
|
||||||
VirtualFile directory = LocalFileSystem.getInstance().findFileByIoFile(new File(directoryPath));
|
|
||||||
|
|
||||||
if(directory == null || directory.getChildren() == null) {
|
|
||||||
throw new IllegalArgumentException("Specified folder is invalid (" + directoryPath + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFile[] files = directory.getChildren();
|
|
||||||
|
|
||||||
List<String> locales = new ArrayList<>();
|
|
||||||
LocalizedNode nodes = new LocalizedNode(LocalizedNode.ROOT_KEY, new ArrayList<>());
|
|
||||||
|
|
||||||
try {
|
|
||||||
for(VirtualFile file : files) {
|
|
||||||
|
|
||||||
if(!IOUtil.isFileRelevant(project, file)) { // File does not matches pattern
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
locales.add(file.getNameWithoutExtension());
|
|
||||||
|
|
||||||
try (Reader reader = new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8)) {
|
|
||||||
Section section = Section.parseToMap(reader);
|
|
||||||
load(file.getNameWithoutExtension(), nodes, section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.accept(new Translations(locales, nodes));
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load(String locale, LocalizedNode node, Section section) {
|
|
||||||
if (section instanceof MapSection) {
|
|
||||||
for (String key : section.getKeys()) {
|
|
||||||
LocalizedNode child = node.getChildren(key);
|
|
||||||
if (child == null) {
|
|
||||||
node.addChildren(child = new LocalizedNode(key, new ArrayList<>()));
|
|
||||||
}
|
|
||||||
LocalizedNode finalChild = child;
|
|
||||||
MapSection map = section.getMap(key).orElse(null);
|
|
||||||
if (map != null) {
|
|
||||||
load(locale, finalChild, map);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if(section.isList(key) && section.getList(key).isPresent()) {
|
|
||||||
child.getValue().put(locale, YamlArrayUtil.read(section.getList(key).get()));
|
|
||||||
} else {
|
|
||||||
String value = section.getString(key).orElse(null);
|
|
||||||
if (value != null) {
|
|
||||||
child.getValue().put(locale, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void save(LocalizedNode node, String locale, Section section, String path) {
|
|
||||||
if (node.isLeaf() && !node.getKey().equals(LocalizedNode.ROOT_KEY)) {
|
|
||||||
String value = node.getValue().get(locale);
|
|
||||||
if (value != null) {
|
|
||||||
section.set(path, YamlArrayUtil.isArray(value) ? YamlArrayUtil.write(value) : value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (LocalizedNode child : node.getChildren()) {
|
|
||||||
save(child, locale, section, path == null ? child.getKey() : path + "." + child.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(@NotNull Project project, @NotNull Translations translations, @NotNull String directoryPath, @NotNull Consumer<Boolean> callback) {
|
|
||||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
|
||||||
try {
|
|
||||||
for(String locale : translations.getLocales()) {
|
|
||||||
Section section = new MapSection();
|
|
||||||
|
|
||||||
save(translations.getNodes(), locale, section, null);
|
|
||||||
|
|
||||||
String fullPath = directoryPath + "/" + locale + ".yml";
|
|
||||||
VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(new File(fullPath));
|
|
||||||
|
|
||||||
file.setBinaryContent(Section.toString(section).getBytes(file.getCharset()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Successfully saved
|
|
||||||
callback.accept(true);
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
callback.accept(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model.table;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nls;
|
|
||||||
|
|
||||||
import javax.swing.event.TableModelListener;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Table model to represents localized messages.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public class TableModelTranslator implements TableModel {
|
|
||||||
|
|
||||||
private final Translations translations;
|
|
||||||
private final List<String> locales;
|
|
||||||
private final List<String> fullKeys;
|
|
||||||
|
|
||||||
private final Consumer<LegacyTranslationUpdate> updater;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param translations Translations instance
|
|
||||||
* @param searchQuery Search / filter param
|
|
||||||
* @param updater Consumer which can be called on cell change / update
|
|
||||||
*/
|
|
||||||
public TableModelTranslator(Translations translations, String searchQuery, Consumer<LegacyTranslationUpdate> updater) {
|
|
||||||
this.translations = translations;
|
|
||||||
this.locales = translations.getLocales();
|
|
||||||
this.updater = updater;
|
|
||||||
|
|
||||||
List<String> fullKeys = translations.getFullKeys();
|
|
||||||
|
|
||||||
if(searchQuery != null && !searchQuery.isEmpty()) { // Filter keys by searchQuery
|
|
||||||
fullKeys.removeIf(key -> !key.startsWith(searchQuery));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fullKeys = fullKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
return fullKeys.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return locales.size() + 1; // Number of locales plus 1 for the Key's column
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nls
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int columnIndex) {
|
|
||||||
if(columnIndex == 0) {
|
|
||||||
return "<html><b>Key</b></html>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "<html><b>" + locales.get(columnIndex - 1) + "</b></html>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
|
||||||
return String.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
|
||||||
return rowIndex > 0; // Everything should be editable except the headline
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
|
||||||
if(columnIndex == 0) { // Keys
|
|
||||||
return fullKeys.get(rowIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
String key = fullKeys.get(rowIndex);
|
|
||||||
String locale = locales.get(columnIndex - 1);
|
|
||||||
LocalizedNode node = translations.getNode(key);
|
|
||||||
|
|
||||||
return node == null ? null : node.getValue().get(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
|
||||||
String key = String.valueOf(getValueAt(rowIndex, 0));
|
|
||||||
LocalizedNode node = translations.getNode(key);
|
|
||||||
|
|
||||||
if(node == null) { // Unknown cell
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String newKey = columnIndex == 0 ? String.valueOf(aValue) : key;
|
|
||||||
Map<String, String> messages = node.getValue();
|
|
||||||
|
|
||||||
// Locale message update
|
|
||||||
if(columnIndex > 0) {
|
|
||||||
if(aValue == null || ((String) aValue).isEmpty()) {
|
|
||||||
messages.remove(locales.get(columnIndex - 1));
|
|
||||||
} else {
|
|
||||||
messages.put(locales.get(columnIndex - 1), String.valueOf(aValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LegacyTranslationUpdate update = new LegacyTranslationUpdate(new LegacyKeyedTranslation(key, messages),
|
|
||||||
new LegacyKeyedTranslation(newKey, messages));
|
|
||||||
|
|
||||||
updater.accept(update);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTableModelListener(TableModelListener l) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeTableModelListener(TableModelListener l) {}
|
|
||||||
}
|
|
@ -1,129 +0,0 @@
|
|||||||
package de.marhali.easyi18n.model.tree;
|
|
||||||
|
|
||||||
import com.intellij.ide.projectView.PresentationData;
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import com.intellij.ui.JBColor;
|
|
||||||
|
|
||||||
import de.marhali.easyi18n.service.SettingsService;
|
|
||||||
import de.marhali.easyi18n.util.UiUtil;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.tree.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* I18n key tree preparation.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
public class TreeModelTranslator extends DefaultTreeModel {
|
|
||||||
|
|
||||||
private final @NotNull Project project;
|
|
||||||
private final @NotNull Translations translations;
|
|
||||||
private final @Nullable String searchQuery;
|
|
||||||
|
|
||||||
|
|
||||||
public TreeModelTranslator(
|
|
||||||
@NotNull Project project, @NotNull Translations translations, @Nullable String searchQuery) {
|
|
||||||
super(null);
|
|
||||||
|
|
||||||
this.project = project;
|
|
||||||
this.translations = translations;
|
|
||||||
this.searchQuery = searchQuery;
|
|
||||||
|
|
||||||
setRoot(generateNodes());
|
|
||||||
}
|
|
||||||
|
|
||||||
private DefaultMutableTreeNode generateNodes() {
|
|
||||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode(LocalizedNode.ROOT_KEY);
|
|
||||||
|
|
||||||
if(translations.getNodes().isLeaf()) { // Empty tree
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> searchSections = searchQuery == null ?
|
|
||||||
Collections.emptyList() : TranslationsUtil.getSections(searchQuery);
|
|
||||||
|
|
||||||
for(LocalizedNode children : translations.getNodes().getChildren()) {
|
|
||||||
generateSubNodes(root, children, new ArrayList<>(searchSections));
|
|
||||||
}
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateSubNodes(DefaultMutableTreeNode parent,
|
|
||||||
LocalizedNode localizedNode, List<String> searchSections) {
|
|
||||||
|
|
||||||
String searchKey = searchSections.isEmpty() ? null : searchSections.remove(0);
|
|
||||||
|
|
||||||
if(searchKey != null && !localizedNode.getKey().startsWith(searchKey)) { // Filter node
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(localizedNode.isLeaf()) {
|
|
||||||
String previewLocale = SettingsService.getInstance(project).getState().getPreviewLocale();
|
|
||||||
|
|
||||||
String title = localizedNode.getKey();
|
|
||||||
String sub = "(" + previewLocale + ": " + localizedNode.getValue().get(previewLocale) + ")";
|
|
||||||
String tooltip = UiUtil.generateHtmlTooltip(localizedNode.getValue());
|
|
||||||
|
|
||||||
PresentationData data = new PresentationData(title, sub, null, null);
|
|
||||||
data.setTooltip(tooltip);
|
|
||||||
|
|
||||||
if(localizedNode.getValue().size() != translations.getLocales().size()) {
|
|
||||||
data.setForcedTextForeground(JBColor.RED);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent.add(new DefaultMutableTreeNode(data));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
DefaultMutableTreeNode sub = new DefaultMutableTreeNode(localizedNode.getKey());
|
|
||||||
parent.add(sub);
|
|
||||||
|
|
||||||
for(LocalizedNode children : localizedNode.getChildren()) {
|
|
||||||
generateSubNodes(sub, children, new ArrayList<>(searchSections));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TreePath findTreePath(@NotNull String fullPath) {
|
|
||||||
List<String> sections = TranslationsUtil.getSections(fullPath);
|
|
||||||
Object[] nodes = new Object[sections.size() + 1];
|
|
||||||
|
|
||||||
int pos = 0;
|
|
||||||
TreeNode currentNode = (TreeNode) this.getRoot();
|
|
||||||
nodes[pos] = currentNode;
|
|
||||||
|
|
||||||
for(String section : sections) {
|
|
||||||
pos++;
|
|
||||||
currentNode = findNode(currentNode, section);
|
|
||||||
nodes[pos] = currentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TreePath(nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable DefaultMutableTreeNode findNode(@NotNull TreeNode parent, @NotNull String key) {
|
|
||||||
for(int i = 0; i < parent.getChildCount(); i++) {
|
|
||||||
TreeNode child = parent.getChildAt(i);
|
|
||||||
|
|
||||||
if(child instanceof DefaultMutableTreeNode) {
|
|
||||||
DefaultMutableTreeNode mutableChild = (DefaultMutableTreeNode) child;
|
|
||||||
String childKey = mutableChild.getUserObject().toString();
|
|
||||||
|
|
||||||
if(mutableChild.getUserObject() instanceof PresentationData) {
|
|
||||||
childKey = ((PresentationData) mutableChild.getUserObject()).getPresentableText();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(childKey != null && childKey.equals(key)) {
|
|
||||||
return mutableChild;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NullPointerException("Cannot find node by key: " + key);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package de.marhali.easyi18n.util;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map utilities.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class MapUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the provided list into a tree map.
|
|
||||||
* @param list List of nodes
|
|
||||||
* @return TreeMap based on node key and node object
|
|
||||||
*/
|
|
||||||
public static TreeMap<String, LocalizedNode> convertToTreeMap(List<LocalizedNode> list) {
|
|
||||||
TreeMap<String, LocalizedNode> map = new TreeMap<>();
|
|
||||||
|
|
||||||
for(LocalizedNode item : list) {
|
|
||||||
map.put(item.getKey(), item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package de.marhali.easyi18n.util;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies sorting to {@link Properties} files.
|
|
||||||
* @author marhali
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class SortedProperties extends Properties {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Object> keySet() {
|
|
||||||
return Collections.unmodifiableSet(new TreeSet<>(super.keySet()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Map.Entry<Object, Object>> entrySet() {
|
|
||||||
TreeMap<Object, Object> sorted = new TreeMap<>();
|
|
||||||
|
|
||||||
for(Object key : super.keySet()) {
|
|
||||||
sorted.put(key, get(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sorted.entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized Enumeration<Object> keys() {
|
|
||||||
return Collections.enumeration(new TreeSet<>(super.keySet()));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user