diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2934414..fbd8650 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,12 +3,21 @@
# easy-i18n Changelog
## [Unreleased]
+### Added
+- Support for IntelliJ Platform version 2022.3
+- Regex support for translation file patterns
+
+### Changed
+- Reload function internally consolidated
+
+### Fixed
+- Parsing for .properties files
## [4.2.4]
-### Changed
-- Improved exception handling on syntax errors
+### Changed
+- Improved exception handling on syntax errors
-### Fixed
+### Fixed
- Some settings are not retained on IDE restarts
## [4.2.3]
diff --git a/gradle.properties b/gradle.properties
index 0ce983e..d171033 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,12 +4,12 @@
pluginGroup = de.marhali.easyi18n
pluginName = easy-i18n
# SemVer format -> https://semver.org
-pluginVersion = 4.2.4
+pluginVersion = 4.3.0
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 203
-pluginUntilBuild = 222.*
+pluginUntilBuild = 223
# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IU
diff --git a/src/main/java/de/marhali/easyi18n/DataStore.java b/src/main/java/de/marhali/easyi18n/DataStore.java
index b335c88..db0bf31 100644
--- a/src/main/java/de/marhali/easyi18n/DataStore.java
+++ b/src/main/java/de/marhali/easyi18n/DataStore.java
@@ -49,9 +49,6 @@ public class DataStore {
*/
public void loadFromPersistenceLayer(@NotNull Consumer successResult) {
ProjectSettings settings = ProjectSettingsService.get(project).getState();
-
- ApplicationManager.getApplication().saveAll(); // Save opened files (required if new locales were added)
-
ApplicationManager.getApplication().runReadAction(() -> {
try {
this.data = new IOHandler(project, settings).read();
diff --git a/src/main/java/de/marhali/easyi18n/InstanceManager.java b/src/main/java/de/marhali/easyi18n/InstanceManager.java
index 829c60a..8eddfae 100644
--- a/src/main/java/de/marhali/easyi18n/InstanceManager.java
+++ b/src/main/java/de/marhali/easyi18n/InstanceManager.java
@@ -72,6 +72,7 @@ public class InstanceManager {
* Fetches data from persistence layer and notifies all endpoints via {@link DataBus}.
*/
public void reload() {
+ ApplicationManager.getApplication().saveAll(); // Save opened files (required if new locales were added)
store.loadFromPersistenceLayer((success) ->
bus.propagate().onUpdateData(store.getData()));
}
diff --git a/src/main/java/de/marhali/easyi18n/io/folder/FolderStrategy.java b/src/main/java/de/marhali/easyi18n/io/folder/FolderStrategy.java
index d9161fa..149be8a 100644
--- a/src/main/java/de/marhali/easyi18n/io/folder/FolderStrategy.java
+++ b/src/main/java/de/marhali/easyi18n/io/folder/FolderStrategy.java
@@ -7,8 +7,8 @@ import de.marhali.easyi18n.io.parser.ParserStrategyType;
import de.marhali.easyi18n.model.TranslationData;
import de.marhali.easyi18n.model.TranslationFile;
import de.marhali.easyi18n.settings.ProjectSettings;
+import de.marhali.easyi18n.util.WildcardRegexMatcher;
-import org.apache.commons.io.FilenameUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -51,7 +51,8 @@ public abstract class FolderStrategy {
* @return true if file matches and should be processed
*/
protected boolean isFileRelevant(@NotNull VirtualFile file) {
- return !file.isDirectory() && FilenameUtils.wildcardMatch(file.getName(), this.settings.getFilePattern());
+ return !file.isDirectory()
+ && WildcardRegexMatcher.matchWildcardRegex(file.getName(), settings.getFilePattern());
}
/**
diff --git a/src/main/java/de/marhali/easyi18n/io/parser/json5/Json5ParserStrategy.java b/src/main/java/de/marhali/easyi18n/io/parser/json5/Json5ParserStrategy.java
index 1baf0ec..70d9224 100644
--- a/src/main/java/de/marhali/easyi18n/io/parser/json5/Json5ParserStrategy.java
+++ b/src/main/java/de/marhali/easyi18n/io/parser/json5/Json5ParserStrategy.java
@@ -26,7 +26,7 @@ import java.util.Objects;
public class Json5ParserStrategy extends ParserStrategy {
private static final Json5 JSON5 = Json5.builder(builder ->
- builder.allowInvalidSurrogate().trailingComma().indentFactor(4).build());
+ builder.allowInvalidSurrogate().trailingComma().indentFactor(2).build());
public Json5ParserStrategy(@NotNull ProjectSettings settings) {
super(settings);
diff --git a/src/main/java/de/marhali/easyi18n/io/parser/properties/PropertiesParserStrategy.java b/src/main/java/de/marhali/easyi18n/io/parser/properties/PropertiesParserStrategy.java
index 936dbf8..007c788 100644
--- a/src/main/java/de/marhali/easyi18n/io/parser/properties/PropertiesParserStrategy.java
+++ b/src/main/java/de/marhali/easyi18n/io/parser/properties/PropertiesParserStrategy.java
@@ -47,9 +47,7 @@ public class PropertiesParserStrategy extends ParserStrategy {
throw new SyntaxException(ex.getMessage(), file);
}
- if(!input.isEmpty()) {
- PropertiesMapper.read(file.getLocale(), input, targetData, converter);
- }
+ PropertiesMapper.read(file.getLocale(), input, targetData, converter);
}
}
diff --git a/src/main/java/de/marhali/easyi18n/service/FileChangeListener.java b/src/main/java/de/marhali/easyi18n/service/FileChangeListener.java
index 00ed6e2..88ce083 100644
--- a/src/main/java/de/marhali/easyi18n/service/FileChangeListener.java
+++ b/src/main/java/de/marhali/easyi18n/service/FileChangeListener.java
@@ -54,10 +54,7 @@ public class FileChangeListener implements AsyncFileListener {
events.forEach((e) -> {
if(e.getPath().contains(localesPath)) { // Perform reload
logger.debug("Detected file change. Reloading instance...");
- InstanceManager manager = InstanceManager.get(project);
- manager.store().loadFromPersistenceLayer((success) -> {
- manager.bus().propagate().onUpdateData(manager.store().getData());
- });
+ InstanceManager.get(project).reload();
}
});
}
diff --git a/src/main/java/de/marhali/easyi18n/settings/ProjectSettingsService.java b/src/main/java/de/marhali/easyi18n/settings/ProjectSettingsService.java
index 1cc0538..3363ec5 100644
--- a/src/main/java/de/marhali/easyi18n/settings/ProjectSettingsService.java
+++ b/src/main/java/de/marhali/easyi18n/settings/ProjectSettingsService.java
@@ -31,7 +31,7 @@ public class ProjectSettingsService implements PersistentStateComponent {});
+
+ // Save the cached translation data to a temporary output directory
+ ProjectSettingsState out = new ProjectSettingsState(settings);
+ out.setLocalesDirectory(tempPath.toString());
+ ProjectSettingsService.get(getProject()).setState(out);
+
+ InstanceManager.get(getProject()).store().saveToPersistenceLayer(success -> {});
+
+ // Compare file structure and contents
+ IOFileFilter fileFilter = TrueFileFilter.INSTANCE;
+
+ File originalDirectory = new File(Objects.requireNonNull(settings.getLocalesDirectory()));
+ File[] originalFiles = FileUtils.listFiles(originalDirectory, fileFilter, fileFilter).toArray(new File[0]);
+
+ File outputDirectory = tempPath.toFile();
+ File[] outputFiles = FileUtils.listFiles(outputDirectory, fileFilter, fileFilter).toArray(new File[0]);
+
+ Arrays.sort(originalFiles);
+ Arrays.sort(outputFiles);
+
+ assertEquals(originalFiles.length, outputFiles.length);
+
+ for(int i = 0; i < originalFiles.length; i++) {
+ File originalFile = originalFiles[i];
+ File outputFile = outputFiles[i];
+
+ // Replace originalFile with os-dependent line-separators
+ assertEquals(FileUtils.readFileToString(originalFile, CHARSET).replace("\n", System.lineSeparator()),
+ FileUtils.readFileToString(outputFile, CHARSET));
+ }
+ }
+}
diff --git a/src/test/java/de/marhali/easyi18n/e2e/TestSettingsState.java b/src/test/java/de/marhali/easyi18n/e2e/TestSettingsState.java
new file mode 100644
index 0000000..50b403b
--- /dev/null
+++ b/src/test/java/de/marhali/easyi18n/e2e/TestSettingsState.java
@@ -0,0 +1,51 @@
+package de.marhali.easyi18n.e2e;
+
+import de.marhali.easyi18n.io.folder.FolderStrategyType;
+import de.marhali.easyi18n.io.parser.ParserStrategyType;
+import de.marhali.easyi18n.settings.presets.DefaultPreset;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Settings base for end-to-end tests.
+ * @author marhali
+ */
+public class TestSettingsState extends DefaultPreset {
+
+ private final String localesDirectory;
+ private final FolderStrategyType folderStrategy;
+ private final ParserStrategyType parserStrategy;
+
+ public TestSettingsState(String localesDirectory, FolderStrategyType folderStrategy, ParserStrategyType parserStrategy) {
+ this.localesDirectory = localesDirectory;
+ this.folderStrategy = folderStrategy;
+ this.parserStrategy = parserStrategy;
+ }
+
+
+ @Override
+ public @Nullable String getLocalesDirectory() {
+ return localesDirectory;
+ }
+
+ @Override
+ public @NotNull FolderStrategyType getFolderStrategy() {
+ return folderStrategy;
+ }
+
+ @Override
+ public @NotNull ParserStrategyType getParserStrategy() {
+ return parserStrategy;
+ }
+
+ @Override
+ public @NotNull String getFilePattern() {
+ return "*.*";
+ }
+
+ @Override
+ public boolean isSorting() {
+ return false;
+ }
+}
diff --git a/src/test/java/de/marhali/easyi18n/e2e/single/SingleJson5Test.java b/src/test/java/de/marhali/easyi18n/e2e/single/SingleJson5Test.java
new file mode 100644
index 0000000..ff12ae9
--- /dev/null
+++ b/src/test/java/de/marhali/easyi18n/e2e/single/SingleJson5Test.java
@@ -0,0 +1,20 @@
+package de.marhali.easyi18n.e2e.single;
+
+import de.marhali.easyi18n.e2e.EndToEndTestCase;
+import de.marhali.easyi18n.e2e.TestSettingsState;
+import de.marhali.easyi18n.io.folder.FolderStrategyType;
+import de.marhali.easyi18n.io.parser.ParserStrategyType;
+
+/**
+ * @author marhali
+ * End-to-end tests for single directory json5 files.
+ */
+public class SingleJson5Test extends EndToEndTestCase {
+ public SingleJson5Test() {
+ super(new TestSettingsState(
+ "src/test/resources/single/json5",
+ FolderStrategyType.SINGLE,
+ ParserStrategyType.JSON5)
+ );
+ }
+}
diff --git a/src/test/java/de/marhali/easyi18n/e2e/single/SingleJsonTest.java b/src/test/java/de/marhali/easyi18n/e2e/single/SingleJsonTest.java
new file mode 100644
index 0000000..68f0826
--- /dev/null
+++ b/src/test/java/de/marhali/easyi18n/e2e/single/SingleJsonTest.java
@@ -0,0 +1,20 @@
+package de.marhali.easyi18n.e2e.single;
+
+import de.marhali.easyi18n.e2e.EndToEndTestCase;
+import de.marhali.easyi18n.e2e.TestSettingsState;
+import de.marhali.easyi18n.io.folder.FolderStrategyType;
+import de.marhali.easyi18n.io.parser.ParserStrategyType;
+
+/**
+ * End-to-end tests for single directory json files.
+ * @author marhali
+ */
+public class SingleJsonTest extends EndToEndTestCase {
+ public SingleJsonTest() {
+ super(new TestSettingsState(
+ "src/test/resources/single/json",
+ FolderStrategyType.SINGLE,
+ ParserStrategyType.JSON)
+ );
+ }
+}
diff --git a/src/test/java/de/marhali/easyi18n/e2e/single/SinglePropertiesTest.java b/src/test/java/de/marhali/easyi18n/e2e/single/SinglePropertiesTest.java
new file mode 100644
index 0000000..8420450
--- /dev/null
+++ b/src/test/java/de/marhali/easyi18n/e2e/single/SinglePropertiesTest.java
@@ -0,0 +1,20 @@
+package de.marhali.easyi18n.e2e.single;
+
+import de.marhali.easyi18n.e2e.EndToEndTestCase;
+import de.marhali.easyi18n.e2e.TestSettingsState;
+import de.marhali.easyi18n.io.folder.FolderStrategyType;
+import de.marhali.easyi18n.io.parser.ParserStrategyType;
+
+/**
+ * End-to-end tests for single directory .properties files.
+ * @author marhali
+ */
+public class SinglePropertiesTest extends EndToEndTestCase {
+ public SinglePropertiesTest() {
+ super(new TestSettingsState(
+ "src/test/resources/single/properties",
+ FolderStrategyType.SINGLE,
+ ParserStrategyType.PROPERTIES)
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/marhali/easyi18n/e2e/single/SingleYamlTest.java b/src/test/java/de/marhali/easyi18n/e2e/single/SingleYamlTest.java
new file mode 100644
index 0000000..da609b9
--- /dev/null
+++ b/src/test/java/de/marhali/easyi18n/e2e/single/SingleYamlTest.java
@@ -0,0 +1,20 @@
+package de.marhali.easyi18n.e2e.single;
+
+import de.marhali.easyi18n.e2e.EndToEndTestCase;
+import de.marhali.easyi18n.e2e.TestSettingsState;
+import de.marhali.easyi18n.io.folder.FolderStrategyType;
+import de.marhali.easyi18n.io.parser.ParserStrategyType;
+
+/**
+ * End-to-ends tests for single directory yaml files.
+ * @author marhali
+ */
+public class SingleYamlTest extends EndToEndTestCase {
+ public SingleYamlTest() {
+ super(new TestSettingsState(
+ "src/test/resources/single/yaml",
+ FolderStrategyType.SINGLE,
+ ParserStrategyType.YML)
+ );
+ }
+}
diff --git a/src/test/java/de/marhali/easyi18n/settings/ProjectSettingsServiceTest.java b/src/test/java/de/marhali/easyi18n/settings/ProjectSettingsServiceTest.java
index 94c774f..5ccc4f9 100644
--- a/src/test/java/de/marhali/easyi18n/settings/ProjectSettingsServiceTest.java
+++ b/src/test/java/de/marhali/easyi18n/settings/ProjectSettingsServiceTest.java
@@ -10,9 +10,16 @@ import de.marhali.easyi18n.settings.presets.DefaultPreset;
* @author marhali
*/
public class ProjectSettingsServiceTest extends BasePlatformTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ ProjectSettingsService.get(getProject()).setState(new ProjectSettingsState());
+ }
+
public void testSettingsDefaultPreset() {
ProjectSettingsState state = ProjectSettingsService.get(getProject()).getState();
- assertEquals(state, new ProjectSettingsState(new DefaultPreset()));
+ assertEquals(new ProjectSettingsState(new DefaultPreset()), state);
}
public void testPersistenceState() {
diff --git a/src/test/resources/single/json/de.json b/src/test/resources/single/json/de.json
new file mode 100644
index 0000000..145065b
--- /dev/null
+++ b/src/test/resources/single/json/de.json
@@ -0,0 +1,11 @@
+{
+ "title": "Titel",
+ "number": 187,
+ "object": {
+ "title": "Titel"
+ },
+ "array": [
+ "element1",
+ "element2"
+ ]
+}
\ No newline at end of file
diff --git a/src/test/resources/single/json/en.json b/src/test/resources/single/json/en.json
new file mode 100644
index 0000000..b274e3a
--- /dev/null
+++ b/src/test/resources/single/json/en.json
@@ -0,0 +1,11 @@
+{
+ "title": "Title",
+ "number": -187,
+ "object": {
+ "title": "Title"
+ },
+ "array": [
+ "item1",
+ "item2"
+ ]
+}
\ No newline at end of file
diff --git a/src/test/resources/single/json5/de.json5 b/src/test/resources/single/json5/de.json5
new file mode 100644
index 0000000..2f722ae
--- /dev/null
+++ b/src/test/resources/single/json5/de.json5
@@ -0,0 +1,12 @@
+{
+ "title": "Titel",
+ "number": 187,
+ "hex": 0x187,
+ "object": {
+ "title": "Titel",
+ },
+ "array": [
+ "element1",
+ "element2",
+ ],
+}
\ No newline at end of file
diff --git a/src/test/resources/single/json5/en.json5 b/src/test/resources/single/json5/en.json5
new file mode 100644
index 0000000..3161f98
--- /dev/null
+++ b/src/test/resources/single/json5/en.json5
@@ -0,0 +1,12 @@
+{
+ "title": "Title",
+ "number": -187,
+ "hex": -0x187,
+ "object": {
+ "title": "Title",
+ },
+ "array": [
+ "item1",
+ "item2",
+ ],
+}
\ No newline at end of file
diff --git a/src/test/resources/single/properties/de.properties b/src/test/resources/single/properties/de.properties
new file mode 100644
index 0000000..da7cba4
--- /dev/null
+++ b/src/test/resources/single/properties/de.properties
@@ -0,0 +1,2 @@
+breakLine=eins\nzwei
+title=Titel
diff --git a/src/test/resources/single/properties/en.properties b/src/test/resources/single/properties/en.properties
new file mode 100644
index 0000000..f9b8eca
--- /dev/null
+++ b/src/test/resources/single/properties/en.properties
@@ -0,0 +1,2 @@
+breakLine=first\nsecond
+title=Title
diff --git a/src/test/resources/single/yaml/de.yaml b/src/test/resources/single/yaml/de.yaml
new file mode 100644
index 0000000..5e7a01e
--- /dev/null
+++ b/src/test/resources/single/yaml/de.yaml
@@ -0,0 +1,3 @@
+title: Titel
+nested:
+ title: Titel
diff --git a/src/test/resources/single/yaml/en.yaml b/src/test/resources/single/yaml/en.yaml
new file mode 100644
index 0000000..f9e21b7
--- /dev/null
+++ b/src/test/resources/single/yaml/en.yaml
@@ -0,0 +1,3 @@
+title: Title
+nested:
+ title: Title