Merge pull request #4958 from iilei/missing_accept_language_country_code_fallback
Fix Locale Negotiation for omitted Country Code
This commit is contained in:
commit
d63040283f
3 changed files with 102 additions and 21 deletions
|
@ -134,27 +134,7 @@ public class LocaleHelper {
|
|||
}
|
||||
|
||||
private static Locale findLocale(Set<String> supportedLocales, String... localeStrings) {
|
||||
for (String localeString : localeStrings) {
|
||||
if (localeString != null) {
|
||||
Locale result = null;
|
||||
Locale search = Locale.forLanguageTag(localeString);
|
||||
for (String languageTag : supportedLocales) {
|
||||
Locale locale = Locale.forLanguageTag(languageTag);
|
||||
if (locale.getLanguage().equals(search.getLanguage())) {
|
||||
if (locale.getCountry().equals("") && result == null) {
|
||||
result = locale;
|
||||
}
|
||||
if (locale.getCountry().equals(search.getCountry())) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return new LocaleNegotiator(supportedLocales).invoke(localeStrings);
|
||||
}
|
||||
|
||||
private static void updateUsersLocale(UserModel user, String locale) {
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.services.util;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
class LocaleNegotiator {
|
||||
private Set<String> supportedLocales;
|
||||
|
||||
LocaleNegotiator(Set<String> supportedLocales) {
|
||||
this.supportedLocales = supportedLocales;
|
||||
}
|
||||
|
||||
Locale invoke(String... localeStrings) {
|
||||
for (String localeString : localeStrings) {
|
||||
if (localeString != null) {
|
||||
Locale result = null;
|
||||
Locale search = Locale.forLanguageTag(localeString);
|
||||
for (String languageTag : supportedLocales) {
|
||||
Locale locale = Locale.forLanguageTag(languageTag);
|
||||
if (locale.getLanguage().equals(search.getLanguage())) {
|
||||
if (search.getCountry().equals("") ^ locale.getCountry().equals("") && result == null) {
|
||||
result = locale;
|
||||
}
|
||||
if (locale.getCountry().equals(search.getCountry())) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.keycloak.services.util;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
public class LocaleNegotiatorTest {
|
||||
|
||||
private LocaleNegotiator localeNegotiator;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Set<String> supportedLocales = new HashSet<>();
|
||||
supportedLocales.add("de");
|
||||
supportedLocales.add("de-AT");
|
||||
supportedLocales.add("de-CH");
|
||||
supportedLocales.add("de-DE");
|
||||
supportedLocales.add("pt-BR");
|
||||
localeNegotiator = new LocaleNegotiator(supportedLocales);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMatchWithoutCountryCode() {
|
||||
Locale actualLocale = localeNegotiator.invoke("de");
|
||||
Assert.assertEquals(Locale.GERMAN, actualLocale);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMatchWithPriorityCountryCode() {
|
||||
Locale actualLocale = localeNegotiator.invoke("de-CH", "de");
|
||||
Assert.assertEquals(new Locale("de", "CH"), actualLocale);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMatchWithPriorityNoCountryCode() {
|
||||
Locale actualLocale = localeNegotiator.invoke("de", "de-CH");
|
||||
Assert.assertEquals(new Locale("de"), actualLocale);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMatchOmittedCountryCodeWithBestFit() {
|
||||
Locale actualLocale = localeNegotiator.invoke("pt", "es-ES");
|
||||
Assert.assertEquals(new Locale("pt", "BR"), actualLocale);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue