diff --git a/src/main/java/de/marhali/easyi18n/ionext/parser/ParserStrategy.java b/src/main/java/de/marhali/easyi18n/ionext/parser/ParserStrategy.java new file mode 100644 index 0000000..82b2f9b --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/ionext/parser/ParserStrategy.java @@ -0,0 +1,75 @@ +package de.marhali.easyi18n.ionext.parser; + +import de.marhali.easyi18n.model.*; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.Objects; + +/** + * Represents a parser for a specific file format. + * @author marhali + */ +public abstract class ParserStrategy { + + protected final @NotNull SettingsState settings; + + public ParserStrategy(@NotNull SettingsState settings) { + this.settings = settings; + } + + /** + * Reads the translation file into the translation data object (consider namespace and locale) + * @param file File to read from + * @param data Target translation data to save the parsed data + */ + public abstract void read(@NotNull TranslationFile file, @NotNull TranslationData data) throws IOException; + + /** + * Writes the relevant data to the translation file (consider namespace and locale) + * @param data Translation data cache + * @param file Target translation file + */ + public abstract void write(@NotNull TranslationData data, @NotNull TranslationFile file) throws IOException; + + /** + * Determines translation node to use for parsing + * @param file Translation file to parse + * @param data Translations + * @return TranslationNode to use + */ + protected @NotNull TranslationNode getOrCreateTargetNode( + @NotNull TranslationFile file, @NotNull TranslationData data) { + + TranslationNode targetNode = data.getRootNode(); + + if(file.getNamespace() != null) { + String moduleName = file.getNamespace(); + TranslationNode moduleNode = data.getNode(KeyPath.of(moduleName)); + + if(moduleNode == null) { + moduleNode = new TranslationNode(this.settings.isSortKeys()); + data.getRootNode().setChildren(moduleName, moduleNode); + } + } + + return targetNode; + } + + /** + * Determines translation node to use for writing + * @param data Translations + * @param file Translation file to update + * @return TranslationNode to use + */ + protected @NotNull TranslationNode getTargetNode(@NotNull TranslationData data, @NotNull TranslationFile file) { + TranslationNode targetNode = data.getRootNode(); + + if(file.getNamespace() != null) { + targetNode = data.getNode(KeyPath.of(file.getNamespace())); + } + + return Objects.requireNonNull(targetNode); + } +} diff --git a/src/main/java/de/marhali/easyi18n/ionext/parser/json/JsonParserStrategy.java b/src/main/java/de/marhali/easyi18n/ionext/parser/json/JsonParserStrategy.java new file mode 100644 index 0000000..4c244f0 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/ionext/parser/json/JsonParserStrategy.java @@ -0,0 +1,54 @@ +package de.marhali.easyi18n.ionext.parser.json; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.intellij.openapi.vfs.VirtualFile; + +import de.marhali.easyi18n.io.json.JsonMapper; +import de.marhali.easyi18n.ionext.parser.ParserStrategy; +import de.marhali.easyi18n.model.*; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Objects; + +/** + * Json file format parser strategy. + * @author marhali + */ +public class JsonParserStrategy extends ParserStrategy { + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); + + public JsonParserStrategy(@NotNull SettingsState settings) { + super(settings); + } + + @Override + public void read(@NotNull TranslationFile file, @NotNull TranslationData data) throws IOException { + data.addLocale(file.getLocale()); + + VirtualFile vf = file.getVirtualFile(); + TranslationNode targetNode = super.getOrCreateTargetNode(file, data); + + try(Reader reader = new InputStreamReader(vf.getInputStream(), vf.getCharset())) { + JsonObject input = GSON.fromJson(reader, JsonObject.class); + JsonMapper.read(file.getLocale(), input, targetNode); + } + } + + @Override + public void write(@NotNull TranslationData data, @NotNull TranslationFile file) throws IOException { + TranslationNode targetNode = super.getTargetNode(data, file); + + JsonObject output = new JsonObject(); + JsonMapper.write(file.getLocale(), output, Objects.requireNonNull(targetNode)); + + VirtualFile vf = file.getVirtualFile(); + vf.setBinaryContent(GSON.toJson(output).getBytes(vf.getCharset())); + } +} diff --git a/src/main/java/de/marhali/easyi18n/ionext/parser/properties/PropertiesParserStrategy.java b/src/main/java/de/marhali/easyi18n/ionext/parser/properties/PropertiesParserStrategy.java new file mode 100644 index 0000000..5dbed68 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/ionext/parser/properties/PropertiesParserStrategy.java @@ -0,0 +1,60 @@ +package de.marhali.easyi18n.ionext.parser.properties; + +import com.intellij.openapi.vfs.VirtualFile; + +import de.marhali.easyi18n.io.properties.PropertiesMapper; +import de.marhali.easyi18n.io.properties.SortableProperties; +import de.marhali.easyi18n.ionext.parser.ParserStrategy; +import de.marhali.easyi18n.model.SettingsState; +import de.marhali.easyi18n.model.TranslationData; +import de.marhali.easyi18n.model.TranslationFile; +import de.marhali.easyi18n.model.TranslationNode; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; + +/** + * Properties file format parser strategy. + * @author marhali + */ +public class PropertiesParserStrategy extends ParserStrategy { + + public PropertiesParserStrategy(@NotNull SettingsState settings) { + super(settings); + } + + @Override + public void read(@NotNull TranslationFile file, @NotNull TranslationData data) throws IOException { + data.addLocale(file.getLocale()); + + VirtualFile vf = file.getVirtualFile(); + TranslationNode targetNode = super.getOrCreateTargetNode(file, data); + TranslationData targetData = new TranslationData(data.getLocales(), targetNode); + + try(Reader reader = new InputStreamReader(vf.getInputStream(), vf.getCharset())) { + SortableProperties input = new SortableProperties(this.settings.isSortKeys()); + input.load(reader); + PropertiesMapper.read(file.getLocale(), input, targetData); + } + } + + @Override + public void write(@NotNull TranslationData data, @NotNull TranslationFile file) throws IOException { + TranslationNode targetNode = super.getTargetNode(data, file); + TranslationData targetData = new TranslationData(data.getLocales(), targetNode); + + SortableProperties output = new SortableProperties(this.settings.isSortKeys()); + PropertiesMapper.write(file.getLocale(), output, targetData); + + try(StringWriter writer = new StringWriter()) { + output.store(writer, null); + + VirtualFile vf = file.getVirtualFile(); + vf.setBinaryContent(writer.toString().getBytes(vf.getCharset())); + } + } +} diff --git a/src/main/java/de/marhali/easyi18n/ionext/parser/yaml/YamlParserStrategy.java b/src/main/java/de/marhali/easyi18n/ionext/parser/yaml/YamlParserStrategy.java new file mode 100644 index 0000000..d8c7e97 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/ionext/parser/yaml/YamlParserStrategy.java @@ -0,0 +1,53 @@ +package de.marhali.easyi18n.ionext.parser.yaml; + +import com.intellij.openapi.vfs.VirtualFile; + +import de.marhali.easyi18n.io.yaml.YamlMapper; +import de.marhali.easyi18n.ionext.parser.ParserStrategy; +import de.marhali.easyi18n.model.SettingsState; +import de.marhali.easyi18n.model.TranslationData; +import de.marhali.easyi18n.model.TranslationFile; +import de.marhali.easyi18n.model.TranslationNode; + +import org.jetbrains.annotations.NotNull; +import thito.nodeflow.config.MapSection; +import thito.nodeflow.config.Section; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * Yaml / YML file format parser strategy. + * @author marhali + */ +public class YamlParserStrategy extends ParserStrategy { + + public YamlParserStrategy(@NotNull SettingsState settings) { + super(settings); + } + + @Override + public void read(@NotNull TranslationFile file, @NotNull TranslationData data) throws IOException { + data.addLocale(file.getLocale()); + + VirtualFile vf = file.getVirtualFile(); + TranslationNode targetNode = super.getOrCreateTargetNode(file, data); + + try(Reader reader = new InputStreamReader(vf.getInputStream(), vf.getCharset())) { + Section input = Section.parseToMap(reader); + YamlMapper.read(file.getLocale(), input, targetNode); + } + } + + @Override + public void write(@NotNull TranslationData data, @NotNull TranslationFile file) throws IOException { + TranslationNode targetNode = super.getTargetNode(data, file); + + Section output = new MapSection(); + YamlMapper.write(file.getLocale(), output, targetNode); + + VirtualFile vf = file.getVirtualFile(); + vf.setBinaryContent(Section.toString(output).getBytes(vf.getCharset())); + } +}