package io.gitlab.jfronny.translater.transformer; import io.gitlab.jfronny.libjf.config.api.v2.ConfigHolder; import io.gitlab.jfronny.translater.Cfg; import io.gitlab.jfronny.translater.Translater; import net.fabricmc.loader.api.FabricLoader; import org.jetbrains.annotations.Nullable; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; public class CachingTransformer implements Transformer { private static final Path CACHE_FILE = FabricLoader.getInstance().getConfigDir().resolve(Translater.MOD_ID + ".cache"); private final @Nullable Properties defaultCache; private final Properties cache = new Properties(); private final Transformer transformer; @Override public String transform(String str) { if (str == null) return null; //Transform and cache if not present if (!cache.containsKey(str)) { if (defaultCache != null && defaultCache.containsKey(str)) return (String) defaultCache.get(str); String transformed = transformer.transform(str); if (transformed == null) { // The transformer failed return str; } cache.put(str, transformed); save(); } //Return cached result return (String) cache.get(str); } @Override public void transformMultiple(Stream strings, ResultConsumer results) { AtomicBoolean bl = new AtomicBoolean(false); transformer.transformMultiple(strings.filter(s -> { String translation = (String) cache.get(s); if (translation != null) { results.accept(s, translation); return false; } if (defaultCache != null) { translation = (String) defaultCache.get(s); if (translation != null) { results.accept(s, translation); return false; } } return true; }), (str, translation) -> { cache.put(str, translation); bl.set(true); }); if (bl.get()) save(); } public CachingTransformer(Transformer baseTransformer) { transformer = baseTransformer; if (Cfg.forceRegenerate) { Cfg.forceRegenerate = false; ConfigHolder.getInstance().getRegistered().get(Translater.MOD_ID).write(); } else { //Load cache if (Files.exists(CACHE_FILE) && Files.isRegularFile(CACHE_FILE)) { Translater.LOGGER.info("Loading cache"); try (InputStream inS = Files.newInputStream(CACHE_FILE)) { cache.load(inS); } catch (IOException e) { Translater.LOGGER.error("Could not load translater cache", e); } } } //Save default cache if parameters are default if (!Cfg.breakFully && Cfg.rounds == 5 && "en".equals(Cfg.targetLanguage) && !Cfg.forceRegenerate) { Translater.LOGGER.info("Initializing default cache"); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Properties p = new Properties(); try (InputStream inS = classLoader.getResourceAsStream("namecache.ini")) { if (inS == null) p = null; else p.load(inS); } catch (IOException e) { p = null; Translater.LOGGER.error("Could not initialize default translater cache", e); } defaultCache = p; } else defaultCache = null; save(); } private void save() { if (cache.isEmpty()) return; try (OutputStream outS = Files.newOutputStream(CACHE_FILE)) { cache.store(outS, "---Lang---"); } catch (IOException e) { Translater.LOGGER.error("Could not save translater cache"); } } }