diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ViewLabelsServlet.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ViewLabelsServlet.java index f68db8d56..69286eb50 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ViewLabelsServlet.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ViewLabelsServlet.java @@ -170,7 +170,7 @@ public class ViewLabelsServlet extends FreemarkerHttpServlet{ Locale currentLocale) throws FileNotFoundException { HashMap map = new HashMap(); //Replacing the underscore with a hyphen because that is what is represented in the actual literals - map.put("code", locale.toString().replace("_", "-")); + map.put("code", locale.toLanguageTag().replace("_", "-")); map.put("label", locale.getDisplayName(currentLocale)); return map; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java index 3f7e912bb..3e03abcf7 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java @@ -464,7 +464,7 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen Locale currentLocale) throws FileNotFoundException { HashMap map = new HashMap(); //Replacing the underscore with a hyphen because that is what is represented in the actual literals - map.put("code", locale.toString().replace("_", "-")); + map.put("code", locale.toLanguageTag().replace("_", "-")); map.put("label", locale.getDisplayName(currentLocale)); return map; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java index 93c86ad9d..ea88a0d28 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java @@ -284,7 +284,7 @@ public class CachingResponseFilter implements Filter { StringBuilder buffer = new StringBuilder("\"").append(rawEtag); for (Locale locale : locales) { - buffer.append(locale.toString()); + buffer.append(locale.toLanguageTag()); } buffer.append("\""); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java index aa013c965..ba47e443f 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java @@ -88,7 +88,7 @@ public class LocaleSelectionController extends HttpServlet { if (!selectables.contains(locale)) { log.warn("User selected a locale '" + locale + "' that was not in the list: " + selectables); - } else if (!LocaleUtils.isAvailableLocale(locale)) { + } else if (!LocaleUtils.isAvailableLocale(locale.stripExtensions())) { log.warn("User selected an unrecognized locale: '" + locale + "'"); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionDataGetter.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionDataGetter.java index 17fa89fed..bb040d43e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionDataGetter.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionDataGetter.java @@ -3,12 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.i18n.selection; import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,7 +31,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter; * { [a map for each Locale] * code = [the code for the Locale, e.g. "en_US"] * label = [the alt text for the Locale, e.g. "Spanish (Spain)"] - * imageUrl = [the URL of the image that represents the Locale] + * country = [the country for the Locale, e.g. "United States"] + * institution = [the abbreviation for institution, e.g. "UQAM"] * selected = [true, if this locale is currently selected] * } * } @@ -50,6 +46,8 @@ public class LocaleSelectionDataGetter implements DataGetter { private final VitroRequest vreq; + private static final char PRIVATE_USE_SUBTAG = 'x'; + public LocaleSelectionDataGetter(VitroRequest vreq) { this.vreq = vreq; } @@ -73,10 +71,23 @@ public class LocaleSelectionDataGetter implements DataGetter { private List> buildLocalesList(List selectables) { Locale currentLocale = SelectedLocale.getCurrentLocale(vreq); + // The next couple of lines check whether there are locales in the list with the same root. + // If yes, the institution abbreviation (private tag) will be displayed in UI. + // For instance, if there are fr_CA_x_uqam and fr_CA in a VIVO instance runtime.properties, + // the institutional abbreviation (UQAM) will be displayed next to locale name + // in the dropdown menu for selection of a UI language. + boolean includeAbbreviation = false; + Set setOfLocalesBase = new HashSet<>(); + for(final Locale locale: selectables) { + setOfLocalesBase.add(locale.stripExtensions().toLanguageTag()); + } + if (setOfLocalesBase.size() < selectables.size()) { + includeAbbreviation = true; + } List> list = new ArrayList<>(); for (Locale locale : selectables) { try { - list.add(buildLocaleMap(locale, currentLocale)); + list.add(buildLocaleMap(locale, currentLocale, includeAbbreviation)); } catch (FileNotFoundException e) { log.warn("Can't show the Locale selector for '" + locale + "': " + e); @@ -86,12 +97,15 @@ public class LocaleSelectionDataGetter implements DataGetter { } private Map buildLocaleMap(Locale locale, - Locale currentLocale) throws FileNotFoundException { + Locale currentLocale, boolean includeAbbreviation) throws FileNotFoundException { Map map = new HashMap<>(); map.put("code", locale.toLanguageTag().replace('-','_')); map.put("label", locale.getDisplayLanguage(locale)); map.put("country", locale.getDisplayCountry(locale)); + if (includeAbbreviation) { + map.put("institution", Optional.ofNullable(locale.getExtension(LocaleSelectionDataGetter.PRIVATE_USE_SUBTAG)).orElse("").toUpperCase()); + } map.put("selected", currentLocale.equals(locale)); return map; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionSetup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionSetup.java index 98ff8b02f..2884cfaa9 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionSetup.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionSetup.java @@ -154,7 +154,7 @@ public class LocaleSelectionSetup implements ServletContextListener { Locale locale = LocaleUtility.languageStringToLocale(localeString); if (!"es_GO".equals(localeString) && // No complaint about bogus locale - !LocaleUtils.isAvailableLocale(locale)) { + !LocaleUtils.isAvailableLocale(locale.stripExtensions())) { ssWarning("'" + locale + "' is not a recognized locale."); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java index c7f5fcfe0..7be5b7816 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java @@ -33,7 +33,7 @@ public class LanguageFilteringUtils { * (as in RDF language specifiers). */ public static String localeToLanguage(Locale locale) { - return locale.toString().replace(UNDERSCORE, HYPHEN); + return locale.toLanguageTag().replace(UNDERSCORE, HYPHEN); } /** @@ -69,7 +69,7 @@ public class LanguageFilteringUtils { List langs = new ArrayList<>(); while (locales.hasMoreElements()) { Locale locale = (Locale) locales.nextElement(); - langs.add(locale.toString().replace(UNDERSCORE, HYPHEN)); + langs.add(locale.toLanguageTag().replace(UNDERSCORE, HYPHEN)); } if (!langs.contains(DEFAULT_LANG_STRING)) { langs.add(DEFAULT_LANG_STRING); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFFilesLoader.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFFilesLoader.java index c8535c76f..f912c15b7 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFFilesLoader.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/servlet/setup/RDFFilesLoader.java @@ -136,7 +136,19 @@ public class RDFFilesLoader { // Which locales are enabled in runtime.properties? List locales = SelectedLocale.getSelectableLocales(ctx); for (Locale locale : locales) { - enabledLocales.add(locale.toLanguageTag().replace('-', '_')); + String localeString = locale.toLanguageTag().replace('-', '_'); + if (! enabledLocales.contains(localeString)) { + enabledLocales.add(localeString); + } + // If a locale with fr_CA_x_uqam is used, the locale fr_CA should be also enabled for loading. + // Private tags (lang_CountryCode_x_InstitutionAbbreviation) are inteded to be just extension, + // therefore the basic locale (lang_CountryCode) should be loaded as well. + if(locale.hasExtensions()){ + localeString = locale.stripExtensions().toLanguageTag().replace('-', '_'); + if (! enabledLocales.contains(localeString)) { + enabledLocales.add(localeString); + } + } } // If no languages were enabled in runtime.properties, add a fallback as the default diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/LocaleUtility.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/LocaleUtility.java index efbe51288..2c4e2a789 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/LocaleUtility.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/LocaleUtility.java @@ -10,10 +10,17 @@ public final class LocaleUtility { public static Locale languageStringToLocale(String localeString){ String[] parsedLoc = localeString.trim().split("_", -1); - //regex pattern for locale tag with script specified - Locale locale = localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}") ? - new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).build() : - LocaleUtils.toLocale(localeString); + Locale locale = null; + if (localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}_x_[a-z]{1,}")) { //regex pattern for locale tag with script and private-use subtag, e.g. sr_Latn_RS_x_uns + locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).setExtension('x', parsedLoc[4]).build(); + } else if (localeString.matches("^[a-z]{1,3}_[A-Za-z]{2}_x_[a-z]{1,}")) { //regex pattern for locale tag with script and private-use subtag, e.g. fr_CA_x_uqam + locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[1]).setExtension('x', parsedLoc[3]).build(); + } else if (localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}")) { //regex pattern for locale tag with script specified, e.g. sr_Latn_RS + locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).build(); + } else { // other, just languge, e.g. es, or language + region, e.g. en_US, pt_BR, ru_RU, etc. + locale = LocaleUtils.toLocale(localeString); + } + String localeLang = locale.toLanguageTag(); return locale; } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/searchengine/SearchQueryUtils.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/searchengine/SearchQueryUtils.java index ae99b6044..d1c5c471d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/searchengine/SearchQueryUtils.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/utils/searchengine/SearchQueryUtils.java @@ -209,11 +209,11 @@ public class SearchQueryUtils { } public static String getSortFieldNameForLocale(Locale locale) { - return locale.toString().replace('_', '-') + VitroSearchTermNames.LABEL_SORT_SUFFIX; + return locale.toLanguageTag().replace('_', '-') + VitroSearchTermNames.LABEL_SORT_SUFFIX; } public static String getLabelFieldNameForLocale(Locale locale) { - return locale.toString().replace('_', '-') + VitroSearchTermNames.LABEL_DISPLAY_SUFFIX; + return locale.toLanguageTag().replace('_', '-') + VitroSearchTermNames.LABEL_DISPLAY_SUFFIX; } public static SearchQuery getRandomQuery(List vclassUris, int page, int pageSize){ diff --git a/webapp/src/main/webapp/templates/freemarker/page/partials/languageSelector.ftl b/webapp/src/main/webapp/templates/freemarker/page/partials/languageSelector.ftl index 9bb4b9047..794f2e34f 100644 --- a/webapp/src/main/webapp/templates/freemarker/page/partials/languageSelector.ftl +++ b/webapp/src/main/webapp/templates/freemarker/page/partials/languageSelector.ftl @@ -6,7 +6,7 @@ <#list selectLocale.locales as locale>
  • status="selected"> - ${locale.label?capitalize}<#if locale.country?has_content> (${locale.country}) + ${locale.label?capitalize}<#if locale.country?has_content> (${locale.country})<#if locale.institution?has_content> - ${locale.institution}
  • @@ -21,6 +21,7 @@ * -- code * -- label (tooltip displayed in original locale, not current locale) * -- country (displayed in original locale, not current locale) + * -- institution (abbreviation) * -- selected (boolean) -->