Refactored localization

This commit is contained in:
Евгений Смирнов 2020-08-28 22:19:58 +03:00
parent 5fcccf05ca
commit 280ffba4c0
3 changed files with 123 additions and 135 deletions

View File

@ -2,5 +2,5 @@ package ru.windcorp.progressia.client.localization;
@FunctionalInterface @FunctionalInterface
public interface LocaleListener { public interface LocaleListener {
void onLocaleChanged(String newLanguage); void onLocaleChanged(String newLanguage);
} }

View File

@ -3,74 +3,65 @@ package ru.windcorp.progressia.client.localization;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.*; import java.util.*;
public class Localizer { public class Localizer {
private static final Localizer instance = new Localizer("assets/languages/lang_list.txt"); private static final Localizer INSTANCE = new Localizer("assets/languages/");
private final Parser langParser; private String language;
private final String langFolder;
private String language; private Map<String, String> data;
private final String langFolder; private final Map<String, String> langList;
private Map<String, String> data; private final Collection<WeakReference<LocaleListener>> listeners =
private final Map<String, String> langList; Collections.synchronizedCollection(new LinkedList<>());
private final Collection<WeakReference<LocaleListener>> listeners = //lang list must be in the same folder as .lang files
Collections.synchronizedCollection(new LinkedList<>()); public Localizer(String langFolder) {
this.langFolder = langFolder;
this.langList = new Parser(langFolder + "lang_list.txt").parse();
}
//lang list must be in the same folder as .lang files public synchronized void setLanguage(String language) {
public Localizer(String langList) { if (langList.containsKey(language)) {
this.langFolder = langList.concat("/../"); this.language = language;
langParser = new Parser(langList); data = new Parser(langFolder + language + ".lang").parse();
this.langList = langParser.parse(); pokeListeners(language);
} } else {
throw new RuntimeException("Language not found: " + language);
}
}
public synchronized void setLanguage(String language) { public synchronized String getLanguage() {
if (langList.containsKey(language)) { return language;
this.language = language; }
langParser.setFilePath(langFolder + language + ".lang");
data = langParser.parse();
pokeListeners(language);
} else {
throw new RuntimeException("Language not found: " + language);
}
}
public synchronized String getLanguage() { public synchronized String getValue(String key) {
return language; return data.getOrDefault(key, key);
} }
public synchronized String getValue(String key) { private void pokeListeners(String newLanguage) {
try { synchronized (listeners) {
return data.getOrDefault(key, key); Iterator<WeakReference<LocaleListener>> iterator = listeners.iterator();
} catch (NullPointerException e) { while (iterator.hasNext()) {
e.printStackTrace(); LocaleListener listenerOrNull = iterator.next().get();
return key; if (listenerOrNull == null) {
} iterator.remove();
} } else {
listenerOrNull.onLocaleChanged(newLanguage);
}
}
}
}
private void pokeListeners(String newLanguage) { public static Localizer getInstance() {
synchronized (listeners) { return INSTANCE;
Iterator<WeakReference<LocaleListener>> iterator = listeners.iterator(); }
while (iterator.hasNext()) {
LocaleListener listenerOrNull = iterator.next().get();
if (listenerOrNull == null) {
iterator.remove();
} else {
listenerOrNull.onLocaleChanged(newLanguage);
}
}
}
}
public static Localizer getInstance() { public void addListener(LocaleListener listener) {
return instance; listeners.add(new WeakReference<>(listener));
} }
public void addListener(LocaleListener listener) { public void removeListener(LocaleListener listener) {
listeners.add(new WeakReference<>(listener)); listeners.removeIf(ref -> listener.equals(ref.get()));
} }
public void removeListener(LocaleListener listener) {
listeners.removeIf(ref -> listener.equals(ref.get()));
}
} }

View File

@ -4,91 +4,88 @@ import ru.windcorp.jputil.chars.EscapeException;
import ru.windcorp.jputil.chars.Escaper; import ru.windcorp.jputil.chars.Escaper;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.resource.ResourceManager;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Parser { public class Parser {
private String filePath;
static private final Escaper ESCAPER = new Escaper.EscaperBuilder()
.withChars("n", "\n").build();
public Parser(String filePath) { public Parser(String filePath) {
this.filePath = filePath; this.filePath = filePath;
} }
public void setFilePath(String filePath) { public void setFilePath(String filePath) {
this.filePath = filePath; this.filePath = filePath;
} }
public Map<String, String> parse() { public Map<String, String> parse() {
Map<String, String> parsedData = new HashMap<>(); Map<String, String> parsedData = new HashMap<>();
try (Reader rawData = ResourceManager try (Reader rawData = ResourceManager
.getResource(filePath) .getResource(filePath)
.getReader() .getReader()
) { ) {
int code; int code;
char c; char c;
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
while (true) { while (true) {
code = rawData.read(); code = rawData.read();
if (code == -1) { if (code == -1) {
break; break;
} }
c = (char)code; c = (char) code;
if (c == '#') { if (c == '#') {
while (c != '\n') { while (c != '\n') {
code = rawData.read(); code = rawData.read();
if (code == -1) { if (code == -1) {
break; break;
} }
c = (char)code; c = (char) code;
} }
} else if (c == ' ') { } else if (c == ' ') {
code = rawData.read(); code = rawData.read();
if (code == -1) { if (code == -1) {
break; break;
} }
c = (char) code; c = (char) code;
if (c == '=') { if (c == '=') {
String key = escaper.escape(stringBuilder.toString()); String key = ESCAPER.escape(stringBuilder.toString());
stringBuilder.setLength(0); stringBuilder.setLength(0);
rawData.read(); //skip a char rawData.read(); //skip a char
while (true) { while (true) {
code = rawData.read(); code = rawData.read();
if (code == -1) { if (code == -1) {
break; break;
} }
c = (char) code; c = (char) code;
if (code == '\n') { if (code == '\n') {
break; break;
} else { } else {
stringBuilder.append(c); stringBuilder.append(c);
} }
} }
parsedData.put(escaper.unescape(key), parsedData.put(ESCAPER.unescape(key),
escaper.unescape(stringBuilder.toString())); ESCAPER.unescape(stringBuilder.toString()));
stringBuilder.setLength(0); stringBuilder.setLength(0);
} }
} else if (c == '\n') { } else if (c == '\n') {
stringBuilder.setLength(0); stringBuilder.setLength(0);
} else { } else {
stringBuilder.append(c); stringBuilder.append(c);
} }
} }
} catch (IOException | EscapeException e) { } catch (IOException | EscapeException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return parsedData; return parsedData;
} }
public String getFilePath() { public String getFilePath() {
return filePath; return filePath;
} }
private String filePath;
static private final Escaper escaper = new Escaper.EscaperBuilder()
.withChars("n", "\n").build();
} }