mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Replace RTL_LANGUAGE_CODE implementation to Bidi
Fixes #33833. Signed-off-by: akbarhusainpatel <apatel@intermiles.com> Signed-off-by: Alexander Schwartz <aschwart@redhat.com> Co-authored-by: akbarhusainpatel <apatel@intermiles.com> Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
parent
4036357b1d
commit
4965f40994
@ -21,10 +21,11 @@ import org.keycloak.models.RealmModel;
|
||||
|
||||
import jakarta.ws.rs.core.UriBuilder;
|
||||
|
||||
import java.text.Bidi;
|
||||
import java.text.Collator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -32,18 +33,16 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class LocaleBean {
|
||||
|
||||
private static final Set<String> RTL_LANGUAGE_CODES =
|
||||
Set.of("ar", "dv", "fa", "ha", "he", "iw", "ji", "ps", "sd", "ug", "ur", "yi");
|
||||
|
||||
private String current;
|
||||
private String currentLanguageTag;
|
||||
private boolean rtl; // right-to-left language
|
||||
private List<Locale> supported;
|
||||
private final String current;
|
||||
private final String currentLanguageTag;
|
||||
private final boolean rtl; // right-to-left language
|
||||
private final List<Locale> supported;
|
||||
private static final ConcurrentHashMap<java.util.Locale, Boolean> bidiMap = new ConcurrentHashMap<>();
|
||||
|
||||
public LocaleBean(RealmModel realm, java.util.Locale current, UriBuilder uriBuilder, Properties messages) {
|
||||
this.currentLanguageTag = current.toLanguageTag();
|
||||
this.current = messages.getProperty("locale_" + this.currentLanguageTag, this.currentLanguageTag);
|
||||
this.rtl = RTL_LANGUAGE_CODES.contains(current.getLanguage());
|
||||
this.rtl = isLeftToRight(current);
|
||||
|
||||
Collator collator = Collator.getInstance(current);
|
||||
collator.setStrength(Collator.PRIMARY); // ignore case and accents
|
||||
@ -58,6 +57,18 @@ public class LocaleBean {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected static boolean isLeftToRight(java.util.Locale current) {
|
||||
// Some languages that are RTL have an English name in Java locales, like 'dv' aka Divehi as stated in
|
||||
// https://github.com/keycloak/keycloak/issues/33833#issuecomment-2446965307.
|
||||
// Still, this solution seems to be good enough for now. Any exceptions would be added when those translations arise.
|
||||
// Adding the ICU library was discarded at the time to avoid an additional dependency and due to its special license.
|
||||
// This might be reconsidered in the future if there are more scenarios.
|
||||
//
|
||||
// As the most likely alternative, a translation could in the future define RTL, its language name, and then this can be used instead.
|
||||
|
||||
return bidiMap.computeIfAbsent(current, l -> new Bidi(l.getLanguage(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT).isLeftToRight());
|
||||
}
|
||||
|
||||
public String getCurrent() {
|
||||
return current;
|
||||
}
|
||||
@ -79,9 +90,9 @@ public class LocaleBean {
|
||||
|
||||
public static class Locale {
|
||||
|
||||
private String languageTag;
|
||||
private String label;
|
||||
private String url;
|
||||
private final String languageTag;
|
||||
private final String label;
|
||||
private final String url;
|
||||
|
||||
public Locale(String languageTag, String label, String url) {
|
||||
this.languageTag = languageTag;
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2025 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.theme.beans;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public class LocaleBeanTest {
|
||||
|
||||
private static final Set<String> RTL_LANGUAGE_CODES =
|
||||
Set.of("ar", "dv", "fa", "ha", "he", "iw", "ji", "ps", "sd", "ug", "ur", "yi");
|
||||
|
||||
private static final Set<String> LTR_LANGUAGE_CODES =
|
||||
Set.of("en", "de");
|
||||
|
||||
@Test
|
||||
public void verifyRtl() {
|
||||
for (String rtlLanguageCode : RTL_LANGUAGE_CODES) {
|
||||
MatcherAssert.assertThat(LocaleBean.isLeftToRight(Locale.forLanguageTag(rtlLanguageCode)), Matchers.is(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyLtr() {
|
||||
for (String rtlLanguageCode : LTR_LANGUAGE_CODES) {
|
||||
MatcherAssert.assertThat(LocaleBean.isLeftToRight(Locale.forLanguageTag(rtlLanguageCode)), Matchers.is(true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user