Permalink
Cannot retrieve contributors at this time
278 lines (202 sloc)
6.79 KB
| package net.krazyweb.starmodmanager.data; | |
| import java.io.File; | |
| import java.io.UnsupportedEncodingException; | |
| import java.net.MalformedURLException; | |
| import java.net.URL; | |
| import java.net.URLClassLoader; | |
| import java.nio.file.Paths; | |
| import java.util.ArrayList; | |
| import java.util.Collections; | |
| import java.util.HashSet; | |
| import java.util.List; | |
| import java.util.Locale; | |
| import java.util.MissingResourceException; | |
| import java.util.ResourceBundle; | |
| import java.util.Set; | |
| import javafx.concurrent.Task; | |
| import javafx.concurrent.WorkerStateEvent; | |
| import javafx.event.EventHandler; | |
| import org.apache.logging.log4j.LogManager; | |
| import org.apache.logging.log4j.Logger; | |
| import org.apache.logging.log4j.message.ParameterizedMessage; | |
| import com.ibm.icu.text.MessageFormat; | |
| public class Localizer implements LocalizerModelInterface, Observer { | |
| private static final Logger log = LogManager.getLogger(Localizer.class); | |
| private static boolean overrideLanguage = false; | |
| private static String languageFile = ""; | |
| private static String languageLocale = ""; | |
| private List<Language> languages; | |
| private Locale locale; | |
| private ResourceBundle bundle; | |
| private SettingsModelInterface settings; | |
| private SettingsModelFactory settingsFactory; | |
| private Set<Observer> observers; | |
| protected Localizer(final SettingsModelFactory settingsFactory) { | |
| observers = new HashSet<>(); | |
| this.settingsFactory = settingsFactory; | |
| } | |
| @Override | |
| public Task<Void> getInitializerTask() { | |
| settings = settingsFactory.getInstance(); | |
| settings.addObserver(this); | |
| Task<Void> task = new Task<Void>() { | |
| @Override | |
| protected Void call() throws Exception { | |
| this.updateMessage("Loading Localizer"); | |
| this.updateProgress(0.0, 1.0); | |
| setLocale(settings.getPropertyString("locale")); | |
| languages = new ArrayList<>(); | |
| Collections.addAll(languages, | |
| new Language("en-US", "English"), | |
| new Language("de-DE", "Deutsch") | |
| //new Language("fl-SB", "Floran") | |
| ); | |
| Collections.sort(languages); | |
| this.updateProgress(1.0, 1.0); | |
| return null; | |
| } | |
| }; | |
| task.setOnSucceeded(new EventHandler<WorkerStateEvent>() { | |
| @Override | |
| public void handle(final WorkerStateEvent event) { | |
| notifyObservers("localizerloaded"); | |
| } | |
| }); | |
| return task; | |
| } | |
| @Override | |
| public String getMessage(final String key, final boolean suppressLogging) { | |
| String output = ""; | |
| try { | |
| output = bundle.getString(key.toLowerCase()); | |
| } catch (final NullPointerException e) { | |
| if (!suppressLogging) { | |
| log.warn("Localization key is null."); | |
| } | |
| return "Localization key is null."; | |
| } catch (final MissingResourceException e) { | |
| if (!suppressLogging) { | |
| log.warn("Key '{}' not found.", key); | |
| } | |
| return "Key '" + key + "' not found."; | |
| } catch (final ClassCastException e) { | |
| if (!suppressLogging) { | |
| log.warn("Value found for key '{}' is not a String.", key); | |
| } | |
| return "Value found for key '" + key + "' is not a String."; | |
| } | |
| String formatted = "CHAR ENCODING ERROR"; | |
| try { | |
| formatted = new String(output.getBytes("ISO-8859-1"), "UTF-8"); | |
| } catch (final UnsupportedEncodingException e) { | |
| if (!suppressLogging) { | |
| log.error(new ParameterizedMessage("Could not encode '{}' to UTF-8.", output), e); | |
| } | |
| } | |
| if (!suppressLogging) { | |
| log.debug("String '{}' converted to '{}'.", output, formatted); | |
| } | |
| return formatted; | |
| } | |
| @Override | |
| public String getMessage(final String key) { | |
| return getMessage(key, false); | |
| } | |
| @Override | |
| public String formatMessage(final boolean suppressLogging, final String key, final Object... messageArguments) { | |
| MessageFormat formatter = null; | |
| try { | |
| formatter = new MessageFormat(bundle.getString(key.toLowerCase()), locale); | |
| } catch (final IllegalArgumentException | MissingResourceException e) { | |
| if (!suppressLogging) { | |
| log.error(new ParameterizedMessage("Could not parse pattern for '{}'", key.toLowerCase()), e); | |
| } | |
| } | |
| if (formatter == null) { | |
| return "INVALID PROPERTY: " + key; | |
| } | |
| formatter.setLocale(locale); | |
| String formatted = "CHAR ENCODING ERROR"; | |
| try { | |
| formatted = new String(formatter.format(messageArguments).getBytes("ISO-8859-1"), "UTF-8"); | |
| } catch (final UnsupportedEncodingException e) { | |
| if (!suppressLogging) { | |
| log.error(new ParameterizedMessage("Could not encode '{}' to UTF-8.", formatter.format(messageArguments)), e); | |
| } | |
| } | |
| if (!suppressLogging) { | |
| log.debug("String '{}' encoded to '{}'.", formatter.format(messageArguments), formatted); | |
| } | |
| return formatted; | |
| } | |
| @Override | |
| public String formatMessage(final String key, final Object... messageArguments) { | |
| return formatMessage(false, key, messageArguments); | |
| } | |
| @Override | |
| public List<Language> getLanguages() { | |
| return new ArrayList<>(languages); | |
| } | |
| @Override | |
| public Language getCurrentLanguage() { | |
| String loc = settings.getPropertyString("locale"); | |
| for (Language l : languages) { | |
| if (l.getLocale().equals(loc)) { | |
| return l; | |
| } | |
| } | |
| return null; | |
| } | |
| private void setLocale(final String loc) { | |
| if (overrideLanguage) { | |
| log.debug("Language Overridden!"); | |
| try { | |
| File file = Paths.get(languageFile).toAbsolutePath().getParent().toFile(); | |
| URL[] urls = {file.toURI().toURL()}; | |
| ClassLoader loader = new URLClassLoader(urls); | |
| log.debug("{}", file); | |
| String[] splitLocale = languageLocale.split("-"); | |
| locale = new Locale(splitLocale[0], splitLocale[1]); | |
| bundle = ResourceBundle.getBundle("strings", locale, loader); | |
| notifyObservers("localechanged"); | |
| } catch (final MalformedURLException e) { | |
| log.error("Could not load provided language file '{}'", languageFile); | |
| } | |
| } else { | |
| String[] splitLocale = loc.split("-"); | |
| Locale oldLocale = locale; | |
| locale = new Locale(splitLocale[0], splitLocale[1]); | |
| //Don't reload the language if nothing changed | |
| if (oldLocale == null || !oldLocale.equals(locale)) { | |
| bundle = ResourceBundle.getBundle("strings", locale); | |
| log.debug("Locale set to: {}", locale); | |
| notifyObservers("localechanged"); | |
| } | |
| } | |
| } | |
| public static void overrideLanguage(final String file, final String locale) { | |
| overrideLanguage = true; | |
| languageFile = file; | |
| languageLocale = locale; | |
| } | |
| @Override | |
| public void update(final Observable observable, final Object message) { | |
| if (observable instanceof Settings && message.equals("propertychanged:locale")) { | |
| log.debug("Locale changed message received."); | |
| setLocale(settings.getPropertyString("locale")); | |
| } | |
| } | |
| @Override | |
| public void addObserver(final Observer observer) { | |
| observers.add(observer); | |
| } | |
| @Override | |
| public void removeObserver(final Observer observer) { | |
| observers.remove(observer); | |
| } | |
| private final void notifyObservers(final String message) { | |
| for (final Observer o : observers) { | |
| o.update(this, (Object) message); | |
| } | |
| } | |
| } |