io.ultreia.java4all.i18n.runtime.I18nLanguageProvider Maven / Gradle / Ivy
package io.ultreia.java4all.i18n.runtime;
/*-
* #%L
* I18n :: Runtime
* %%
* Copyright (C) 2018 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import io.ultreia.java4all.i18n.I18n;
import io.ultreia.java4all.i18n.spi.I18nApplicationDefinition;
import io.ultreia.java4all.i18n.spi.I18nResourceInitializationException;
import io.ultreia.java4all.i18n.spi.I18nTemplateDefinition;
import io.ultreia.java4all.i18n.spi.I18nTranslationSetDefinition;
import io.ultreia.java4all.i18n.spi.io.I18nTemplateClassPathReader;
import io.ultreia.java4all.i18n.spi.io.I18nTemplateDirectoryReader;
import io.ultreia.java4all.i18n.spi.io.I18nTemplateReader;
import io.ultreia.java4all.i18n.spi.io.I18nTranslationSetClassPathReader;
import io.ultreia.java4all.i18n.spi.io.I18nTranslationSetDirectoryReader;
import io.ultreia.java4all.i18n.spi.io.I18nTranslationSetReader;
import io.ultreia.java4all.util.SortedProperties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
* Created by tchemit on 05/11/2018.
*
* @author Tony Chemit - [email protected]
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class I18nLanguageProvider {
private static final Logger log = LogManager.getLogger(I18nLanguageProvider.class);
private final Map languages;
private final I18nTranslationSetReader translationsReader;
private final I18nTemplateReader templatesReader;
/** le language actuellement utilise */
private I18nLanguage language;
/** la locale par defaut a utiliser. */
private Locale defaultLocale;
private I18nConfiguration configuration;
private I18nApplicationDefinition applicationDefinition;
private I18nLanguageProvider(Locale defaultLocale, I18nTranslationSetReader translationsReader, I18nTemplateReader templatesReader) {
this.defaultLocale = defaultLocale == null ? Locale.getDefault() : defaultLocale;
this.translationsReader = translationsReader;
this.templatesReader = templatesReader;
this.languages = new LinkedHashMap<>();
}
public static I18nLanguageProvider forClassPath(Locale defaultLocale,
I18nConfiguration configuration,
I18nApplicationDefinition locales) throws I18nResourceInitializationException {
ClassLoader classLoader = configuration.getClassLoader();
return new I18nLanguageProvider(
defaultLocale,
new I18nTranslationSetClassPathReader(classLoader, true),
new I18nTemplateClassPathReader(classLoader, true)
).load(configuration, locales);
}
public static I18nLanguageProvider forDirectory(Locale defaultLocale,
I18nConfiguration configuration,
Path directory,
I18nApplicationDefinition locales) throws I18nResourceInitializationException {
return new I18nLanguageProvider(
defaultLocale,
new I18nTranslationSetDirectoryReader(directory.resolve(I18nTranslationSetDefinition.PATH), false),
new I18nTemplateDirectoryReader(directory.resolve(I18nTemplateDefinition.PATH), false)
).load(configuration, locales);
}
protected I18nLanguageProvider load(I18nConfiguration configuration, I18nApplicationDefinition applicationDefinition) throws I18nResourceInitializationException {
this.configuration = Objects.requireNonNull(configuration);
this.applicationDefinition = applicationDefinition;
Charset encoding = configuration.getEncoding();
List locales = applicationDefinition.getLocales();
for (Locale locale : locales) {
List translationSetDefinitions = getTranslationSetDefinitions().stream().filter(f -> locale.equals(f.getLocale())).collect(Collectors.toList());
List dependenciesTranslationDefinitions = getDependenciesTranslationSetDefinitions().stream().filter(f -> locale.equals(f.getLocale())).collect(Collectors.toList());
Properties translations = new SortedProperties();
I18nTranslationSetDefinition translationSetDefinition;
if (translationSetDefinitions.isEmpty()) {
translationSetDefinition = new I18nTranslationSetDefinition(applicationDefinition.getPackageName(), applicationDefinition.getName(), locale);
I18nTranslationSetClassPathReader reader = new I18nTranslationSetClassPathReader(configuration.getClassLoader(), true);
for (I18nTranslationSetDefinition i18nTranslationSetDefinition : dependenciesTranslationDefinitions) {
Properties load = reader.read(i18nTranslationSetDefinition, encoding);
translations.putAll(load);
}
} else {
for (I18nTranslationSetDefinition i18nTranslationSetDefinition : translationSetDefinitions) {
Properties load = translationsReader.read(i18nTranslationSetDefinition, encoding);
translations.putAll(load);
}
translationSetDefinition = translationSetDefinitions.get(0);
}
List templateDefinitions = getTemplateDefinitions().stream().filter(f -> locale.equals(f.getLocale())).collect(Collectors.toList());
Map templates = new TreeMap<>();
for (I18nTemplateDefinition templateDefinition : templateDefinitions) {
templates.put(templateDefinition.getName(), templatesReader.read(templateDefinition, encoding));
}
languages.put(locale, new I18nLanguage(locale, configuration.isMissingKeyReturnNull(), translationSetDefinition, dependenciesTranslationDefinitions, templateDefinitions, translations, templates));
}
return this;
}
public Set getLocales() {
return languages.keySet();
}
public I18nLanguage getLanguage(Locale locale) {
I18nLanguage result = languages.get(locale);
if (result == null) {
result = new I18nLanguage(locale, configuration.isMissingKeyReturnNull(), new I18nTranslationSetDefinition(applicationDefinition.getPackageName(), applicationDefinition.getName(), locale),
Collections.emptyList(), Collections.emptyList(), new Properties(), Collections.emptyMap());
languages.put(locale, result);
}
return result;
}
public I18nConfiguration getConfiguration() {
return configuration;
}
public List getTranslationSetDefinitions() {
return applicationDefinition.getApplicationTranslationDefinitions();
}
public List getDependenciesTranslationSetDefinitions() {
return applicationDefinition.getDependenciesTranslationDefinitions();
}
public List getTemplateDefinitions() {
return applicationDefinition.getApplicationTemplateDefinitions();
}
/**
* Obtain the current language setted in the store.
*
* This language is used for all translations without locale information
* (says the method {@link I18n#t(String, Object...)}).
*
* @return the current language or {@code null} if none is defined
*/
public I18nLanguage getCurrentLanguage() {
return language;
}
/**
* Obtain the current locale setted in the store.
*
* This locale is coming from the current language and is used for all
* translations without locale information (says the method {@link I18n#t(String, Object...)}.
*
* @return the current locale or {@code null} if no current language is setted
*/
public Locale getCurrentLocale() {
return language == null ? null : language.getLocale();
}
/**
* Sets the current locale for the store.
*
* This will set the current language with this given locale.
*
* @param locale the new current locale
*/
public void setCurrentLocale(Locale locale) {
Locale currentLocale = getCurrentLocale();
if (locale.equals(currentLocale)) {
// nothing to do, already using this locale
return;
}
log.debug("locale: " + locale);
language = getLanguage(locale);
//TC-20090702 the selected language is the default locale, usefull for
// objects dealing with the default locale (swing widgets,...)
Locale.setDefault(locale);
}
/** @return the default locale of the store */
public Locale getDefaultLocale() {
return defaultLocale;
}
public boolean isEmpty() {
return languages.isEmpty();
}
public I18nApplicationDefinition getApplicationDefinition() {
return applicationDefinition;
}
}