com.force.i18n.LanguageProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grammaticus Show documentation
Show all versions of grammaticus Show documentation
Localization Framework that allows grammatically correct renaming of nouns
/*
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
package com.force.i18n;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.google.common.collect.ImmutableList;
/**
* Interface for the provider of the "set" of HumanLanguage
*
* @author stamm
*/
public interface LanguageProvider {
/**
* @return the set of all languages supported by this provider
*/
List extends HumanLanguage> getAll();
/**
* @return the language that is the "base" for all labels. This assumes
* that the entire application is localized into a single language, and then
* translated into the others.
*
* If this language isn't "English", some things might not work.
*
* Note: This doesn't apply to "Renameable" things
*/
HumanLanguage getBaseLanguage();
/**
* @return the User Language associated directly with a locale (including country and variant)
* @param loc the locale to convert to a language
*/
HumanLanguage getLanguage(Locale loc);
/**
* @return the User Language associated directly with a locale (including country and variant)
* @param isoCode the isoCode to convert to a human language
*/
HumanLanguage getLanguage(String isoCode);
/**
* @return {@code true} if the given locale is a support user language locale
* @param loc the locale to test
*/
boolean isSupportedLanguageLocale(Locale loc);
/**
* @return the closest HumanLanguage to the given locale string, taking into account various factors
* @param localeString the java locale string
*/
HumanLanguage getLanguageForLocale(String localeString);
/**
* @return the closest HumanLanguage to the given locale, taking into account various factors
* @param loc the locale
*/
HumanLanguage getLanguageForLocale(Locale loc);
/**
* @return a map with an optimized implementation for the given map
* @param the human language type
* @param the type for the value of the map
*/
Map getNewMap();
/**
* @return the PluralRules for the given language, with the default implementation in
* DefaultLanguagePluralRulesImpl.
* @param language the language to test.
*/
default LanguagePluralRules getPluralRules(HumanLanguage language) {
return DefaultLanguagePluralRulesImpl.forLanguage(language);
}
/**
* Helper class for implementing LanguageProvider
*/
public static class Helper implements LanguageProvider {
// STATIC INITIALIZERS FOR MAGIC MAPS
private final HumanLanguage base;
private final List extends HumanLanguage> languages;
private final Map langByLoc;
private final Map langByString;
private final ConcurrentMap langByFuzzyLocale = new ConcurrentHashMap<>(128, .75f, 2);
public Helper(HumanLanguage base, List extends HumanLanguage> languages) {
if (base == null) throw new NullPointerException();
this.base = base;
this.languages = ImmutableList.copyOf(languages);
Map byLocale = new HashMap(128);
Map byString = new HashMap(128);
for (HumanLanguage language : languages) {
byLocale.put(language.getLocale(), language);
byString.put(language.getLocale().toString(), language);
if (language.getOverrideLanguage() != null) {
// Allow override codes directly. So getLanguage("iw") or ("he") work the same regardless of JDK
byString.put(language.getOverrideLanguage(), language);
}
}
langByLoc = Collections.unmodifiableMap(byLocale);
langByString = Collections.unmodifiableMap(byString);
langByFuzzyLocale.putAll(langByLoc);
// Add in aliases to magically help with fuzzy matches.
for (HumanLanguage language : languages) {
if (language.getOverrideLanguage() != null) {
// Handle any language overrides: note that this doesn't do anything for hebrew (since the locale gets mapped to "iw")
langByFuzzyLocale.put(new Locale(language.getOverrideLanguage()), language);
}
}
}
@Override
public List extends HumanLanguage> getAll() {
return languages;
}
@Override
public HumanLanguage getBaseLanguage() {
return base;
}
@Override
public HumanLanguage getLanguage(Locale loc) {
return langByLoc.get(loc);
}
@Override
public HumanLanguage getLanguage(String isoCode) {
return langByString.get(isoCode);
}
@Override
public boolean isSupportedLanguageLocale(Locale loc) {
return langByLoc.containsKey(loc);
}
/**
* Return the HumanLanguage for the specified locale string
*/
@Override
public HumanLanguage getLanguageForLocale(String localeString) {
Locale loc = LocaleUtils.get().getLocaleByIsoCode(localeString);
return getLanguageForLocale(loc);
}
/**
* Use
*/
@Override
public HumanLanguage getLanguageForLocale(Locale loc) {
if (loc == null) return null;
HumanLanguage result = langByFuzzyLocale.get(loc);
if (result != null) return result;
if (loc.getVariant() != null) {
Locale newLoc = new Locale(loc.getLanguage(), loc.getCountry());
result = getLanguage(newLoc);
}
if (result == null) {
Locale newLoc = new Locale(loc.getLanguage());
result = getLanguage(newLoc);
if (result == null) {
// See if there's another one that's close
for (HumanLanguage testLang : languages) {
if (testLang.getLocale().getLanguage().equals(loc.getLanguage())) {
result = testLang;
break;
}
}
}
}
// Use base as the default so we don't return null for real things
if (result == null) {
result = base;
}
langByFuzzyLocale.put(loc, result);
return result;
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" }) // Fake enum checks
public Map getNewMap() {
if (base instanceof Enum) {
return new EnumMap(base.getClass());
} else {
return new HashMap();
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy