remove legacy components

This commit is contained in:
marhali 2021-11-06 23:18:35 +01:00
parent 1afdac9006
commit cdd7188769
9 changed files with 0 additions and 809 deletions

View File

@ -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);
}

View File

@ -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);
}
});
}
}

View File

@ -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);
}
});
}
}

View File

@ -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);
});
}
}

View File

@ -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);
}
});
}
}

View File

@ -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) {}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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()));
}
}