001/*
002 *     Copyright 2021 Siroshun09
003 *
004 *     Licensed under the Apache License, Version 2.0 (the "License");
005 *     you may not use this file except in compliance with the License.
006 *     You may obtain a copy of the License at
007 *
008 *         http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *     Unless required by applicable law or agreed to in writing, software
011 *     distributed under the License is distributed on an "AS IS" BASIS,
012 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *     See the License for the specific language governing permissions and
014 *     limitations under the License.
015 */
016
017package com.github.siroshun09.mcmessage.translation;
018
019import com.github.siroshun09.configapi.common.FileConfiguration;
020import com.github.siroshun09.configapi.common.util.FileUtils;
021import com.github.siroshun09.mcmessage.loader.MessageLoader;
022import net.kyori.adventure.key.Key;
023import net.kyori.adventure.translation.GlobalTranslator;
024import net.kyori.adventure.translation.TranslationRegistry;
025import org.jetbrains.annotations.NotNull;
026import org.jetbrains.annotations.Unmodifiable;
027
028import java.io.IOException;
029import java.nio.file.Files;
030import java.nio.file.Path;
031import java.util.HashSet;
032import java.util.Locale;
033import java.util.Optional;
034import java.util.Set;
035import java.util.stream.Collectors;
036
037public abstract class AbstractTranslationLoader implements TranslationLoader {
038
039    private final Path directory;
040    private final Key registryKey;
041    private final Locale defaultLocale;
042    private final String fileExtension;
043    private final Set<Locale> loadedLocales = new HashSet<>();
044
045    private TranslationRegistry registry;
046
047    protected AbstractTranslationLoader(@NotNull Path directory, @NotNull Key registryKey,
048                                        @NotNull Locale defaultLocale) {
049        this(directory, registryKey, defaultLocale, ".yml");
050    }
051
052    protected AbstractTranslationLoader(@NotNull Path directory, @NotNull Key registryKey,
053                                        @NotNull Locale defaultLocale, @NotNull String fileExtension) {
054        this.directory = directory;
055        this.registryKey = registryKey;
056        this.defaultLocale = defaultLocale;
057        this.fileExtension = fileExtension;
058    }
059
060    @Override
061    public void load() throws IOException {
062        registry = TranslationRegistry.create(registryKey);
063        registry.defaultLocale(defaultLocale);
064
065        FileUtils.createDirectoriesIfNotExists(directory);
066
067        saveDefaultIfNotExists();
068
069        loadDefault();
070        loadCustom();
071
072        GlobalTranslator.get().addSource(registry);
073    }
074
075    @Override
076    public void reload() throws IOException {
077        if (registry != null) {
078            GlobalTranslator.get().removeSource(registry);
079        }
080
081        load();
082    }
083
084    @Override
085    public @NotNull @Unmodifiable Set<Locale> getLoadedLocales() {
086        return Set.copyOf(loadedLocales);
087    }
088
089    @Override
090    public @NotNull Path getDirectory() {
091        return directory;
092    }
093
094    @Override
095    public @NotNull Key getRegistryKey() {
096        return registryKey;
097    }
098
099    @Override
100    public @NotNull Locale getDefaultLocale() {
101        return defaultLocale;
102    }
103
104    @Override
105    public @NotNull String getFileExtension() {
106        return fileExtension;
107    }
108
109    protected abstract void saveDefaultIfNotExists() throws IOException;
110
111    protected abstract @NotNull FileConfiguration createFileConfiguration(@NotNull Path path);
112
113    private void loadDefault() throws IOException {
114        var defaultFileName = defaultLocale + fileExtension;
115        var defaultFile = directory.resolve(defaultFileName);
116
117        loadFile(defaultFile);
118    }
119
120    private void loadCustom() throws IOException {
121        try (var files = Files.list(directory)) {
122            var languageFiles = files.filter(Files::isRegularFile)
123                    .filter(p -> !p.toString().endsWith(defaultLocale + fileExtension))
124                    .collect(Collectors.toUnmodifiableSet());
125
126            for (var file : languageFiles) {
127                loadFile(file);
128            }
129        }
130    }
131
132    private void loadFile(@NotNull Path path) throws IOException {
133        var file = createFileConfiguration(path);
134        var loader = MessageLoader.fromFileConfiguration(file);
135
136        loader.load();
137        loader.registerToRegistry(registry);
138
139        Optional.ofNullable(loader.getLocale()).ifPresent(loadedLocales::add);
140    }
141}