2021-12-07 13:22:10 +01:00

119 lines
4.5 KiB
Java

package de.marhali.easyi18n;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.*;
import de.marhali.easyi18n.io.IOStrategy;
import de.marhali.easyi18n.io.json.JsonIOStrategy;
import de.marhali.easyi18n.io.json.ModularizedJsonIOStrategy;
import de.marhali.easyi18n.io.properties.PropertiesIOStrategy;
import de.marhali.easyi18n.io.yaml.YamlIOStrategy;
import de.marhali.easyi18n.model.SettingsState;
import de.marhali.easyi18n.model.TranslationData;
import de.marhali.easyi18n.service.FileChangeListener;
import de.marhali.easyi18n.service.SettingsService;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Consumer;
/**
* Responsible for loading, saving and updating translation files.
* Provides access to the cached translation data which is used in the whole project.
* @author marhali
*/
public class DataStore {
private static final Set<IOStrategy> STRATEGIES = new LinkedHashSet<>(Arrays.asList(
new JsonIOStrategy("json"), new ModularizedJsonIOStrategy("json"),
new JsonIOStrategy("arb"), new ModularizedJsonIOStrategy("arb"),
new YamlIOStrategy("yaml"), new YamlIOStrategy("yml"),
new PropertiesIOStrategy()
));
private final @NotNull Project project;
private final @NotNull FileChangeListener changeListener;
private @NotNull TranslationData data;
protected DataStore(@NotNull Project project) {
this.project = project;
this.data = new TranslationData(true, true); // Initialize with hard-coded configuration
this.changeListener = new FileChangeListener(project);
VirtualFileManager.getInstance().addAsyncFileListener(
this.changeListener, Disposer.newDisposable("EasyI18n"));
}
public @NotNull TranslationData getData() {
return data;
}
/**
* Loads the translation data into cache and overwrites any previous cached data.
* If the configuration does not fit an empty translation instance will be populated.
* @param successResult Consumer will inform if operation was successful
*/
public void loadFromPersistenceLayer(@NotNull Consumer<Boolean> successResult) {
SettingsState state = SettingsService.getInstance(this.project).getState();
String localesPath = state.getLocalesPath();
if(localesPath == null || localesPath.isEmpty()) { // Populate empty instance
this.data = new TranslationData(state.isSortKeys(), state.isNestedKeys());
return;
}
this.changeListener.updateLocalesPath(localesPath);
IOStrategy strategy = this.determineStrategy(state, localesPath);
strategy.read(this.project, localesPath, state, (data) -> {
this.data = data == null
? new TranslationData(state.isSortKeys(), state.isNestedKeys())
: data;
successResult.accept(data != null);
});
}
/**
* Saves the cached translation data to the underlying io system.
* @param successResult Consumer will inform if operation was successful
*/
public void saveToPersistenceLayer(@NotNull Consumer<Boolean> successResult) {
SettingsState state = SettingsService.getInstance(this.project).getState();
String localesPath = state.getLocalesPath();
if(localesPath == null || localesPath.isEmpty()) { // Cannot save without valid path
successResult.accept(false);
return;
}
IOStrategy strategy = this.determineStrategy(state, localesPath);
strategy.write(this.project, localesPath, state, this.data, successResult);
}
/**
* Chooses the right strategy for the opened project. An exception might be thrown on
* runtime if the project configuration (e.g. locale files does not fit in any strategy).
* @param state Plugin configuration
* @param localesPath Locales directory
* @return matching {@link IOStrategy}
*/
public @NotNull IOStrategy determineStrategy(@NotNull SettingsState state, @NotNull String localesPath) {
for(IOStrategy strategy : STRATEGIES) {
if(strategy.canUse(this.project, localesPath, state)) {
return strategy;
}
}
throw new IllegalArgumentException("Could not determine i18n strategy. " +
"At least one locale file must be defined. " +
"For examples please visit https://github.com/marhali/easy-i18n");
}
}