All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.ai.vaadin.translations.CompositeI18nProvider Maven / Gradle / Ivy

The newest version!
package fi.evolver.ai.vaadin.translations;

import java.io.Serial;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.vaadin.flow.i18n.I18NProvider;

@Component
public class CompositeI18nProvider implements I18NProvider {
	@Serial
	private static final long serialVersionUID = 1L;

	private static final Logger LOG = LoggerFactory.getLogger(CompositeI18nProvider.class);

	final Set providedLocales;
	private final List providers;

	@Value("${vaadin.provided-languages:}")
	private List providedLanguages;
	
	@Value("${vaadin.disable-all-translations:false}")
	private boolean disableTranslations;

	private static final int MAX_CACHE_ENTRIES = 512;
	private static final Map providerCache = Collections.synchronizedMap(
		new LinkedHashMap(MAX_CACHE_ENTRIES, 0.75f, true) {
		private static final long serialVersionUID = 1L;

		@Override
		public boolean removeEldestEntry(Map.Entry eldest) {
			return size() >= MAX_CACHE_ENTRIES;
		}
	});

	@Autowired
	public CompositeI18nProvider(List providers) {
		this.providers = providers;
		providedLocales = this.providers.stream().flatMap(p -> p.getProvidedLocales().stream()).collect(Collectors.toSet());
		LOG.debug("Initializing i18n with providers: {}",
				String.join(", ", providers.stream().map(l -> l.getClass().toString()).toList()));
	}

	@Override
	public List getProvidedLocales() {
		if (providedLanguages == null || providedLanguages.isEmpty())
			return providedLocales.stream().toList();
		return providedLocales.stream()
				.filter(x -> (x.equals(Locale.ROOT) && providedLanguages.contains("en")) || providedLanguages.contains(x.getLanguage()))
				.toList();
	}

	@Override
	public String getTranslation(String key, Locale locale, Object... params) {
		if (disableTranslations)
			return key;
		String value = getTranslationFromProviders(key, locale, params);
		if (params != null && params.length > 0)
			return new MessageFormat(value, locale).format(params);
		return value;
	}

	public String getTranslationFromProviders(String key, Locale locale, Object... params) {
		final String cacheKey = locale.toString() + ";" + key;
		TranslationProvider cachedProvider = providerCache.get(cacheKey);
		if (cachedProvider != null && cachedProvider.hasTranslation(key, locale))
			return cachedProvider.getTranslation(key, locale);
		LOG.trace("Getting translation for key \"{}\" and locale: {}", key, locale.toString());
		for (TranslationProvider provider : providers) {
			if (!providesLocale(provider, locale)) {
				LOG.trace("\tSkipping {} because it doesn't provide the requested locale", provider.getClass());
				continue;
			}
			if (provider.hasTranslation(key, locale)) {
				providerCache.put(cacheKey, provider);
				return provider.getTranslation(key, locale);
			}
			else
				LOG.trace("\tSkipping {} because it doesn't have the translation key", provider.getClass());
		}
		return key;
	}

	private static boolean providesLocale(TranslationProvider provider, Locale locale) {
		return provider.getProvidedLocales().contains(locale)
				|| provider.getProvidedLocales().contains(Locale.ROOT)
				|| provider.getProvidedLocales().stream()
						.anyMatch(l -> l.getLanguage().equals(locale.getLanguage()));
	}

	public static void clearCache() {
		providerCache.clear();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy