Skip to content

Commit 5410c7d

Browse files
authored
Merge pull request wso2#10087 from wso2/sync-pr-10073-to-next
[Sync][master -> next][wso2#10073]: [Master] Enabling browser auto detect language
2 parents 4c60008 + bc51e7a commit 5410c7d

3 files changed

Lines changed: 150 additions & 34 deletions

File tree

.changeset/early-ways-cry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wso2is/identity-apps-core": patch
3+
---
4+
5+
Enabling browser auto detect custom language

identity-apps-core/apps/authentication-portal/src/main/webapp/includes/localize.jsp

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<%@ page import="org.wso2.carbon.identity.application.authentication.endpoint.util.EncodedControl" %>
2121
<%@ page import="java.nio.charset.StandardCharsets" %>
2222
<%@ page import="java.util.*" %>
23+
<%@ page import="java.io.FileReader" %>
24+
<%@ page import="java.io.BufferedReader" %>
2325
<%@ page import="org.json.JSONObject" %>
2426
<%@ page import="java.util.Calendar" %>
2527
<%@ page import="org.apache.commons.lang.StringUtils" %>
@@ -99,6 +101,8 @@
99101
Locale userLocale = browserLocale;
100102
String localeFromCookie = null;
101103
String BUNDLE = "org.wso2.carbon.identity.application.authentication.endpoint.i18n.Resources";
104+
String SUPPORTED_LANGUAGES_ATTR = "supportedLanguages";
105+
String LANGUAGE_SUPPORTED_COUNTRIES_ATTR = "languageSupportedCountries";
102106
103107
// List of screen names for retrieving text branding customizations.
104108
List<String> screenNames = new ArrayList<>();
@@ -107,23 +111,59 @@
107111
// Map to store default supported language codes.
108112
// TODO: Use this map to generate the `language-switcher.jsp`.
109113
Map<String, String> supportedLanguages = new HashMap<>();
110-
supportedLanguages.put("en", "US");
111-
supportedLanguages.put("fr", "FR");
112-
supportedLanguages.put("es", "ES");
113-
supportedLanguages.put("pt", "PT");
114-
supportedLanguages.put("de", "DE");
115-
supportedLanguages.put("zh", "CN");
116-
supportedLanguages.put("ja", "JP");
117114
118115
List<String> languageSupportedCountries = new ArrayList<>();
119-
languageSupportedCountries.add("US");
120-
languageSupportedCountries.add("FR");
121-
languageSupportedCountries.add("ES");
122-
languageSupportedCountries.add("PT");
123-
languageSupportedCountries.add("DE");
124-
languageSupportedCountries.add("CN");
125-
languageSupportedCountries.add("JP");
126-
languageSupportedCountries.add("BR");
116+
117+
// Dynamically load supported languages from languageOptions.properties
118+
// Use request scope to cache the parsed language options
119+
Map<String, String> cachedSupportedLanguages = (Map<String, String>) request.getAttribute(SUPPORTED_LANGUAGES_ATTR);
120+
List<String> cachedLanguageSupportedCountries = (List<String>) request.getAttribute(LANGUAGE_SUPPORTED_COUNTRIES_ATTR);
121+
122+
if (cachedSupportedLanguages != null && cachedLanguageSupportedCountries != null) {
123+
supportedLanguages = cachedSupportedLanguages;
124+
languageSupportedCountries = cachedLanguageSupportedCountries;
125+
} else {
126+
// Specify the file path
127+
String filePath = application.getRealPath("/") + "/WEB-INF/classes/LanguageOptions.properties";
128+
129+
// Use a BufferedReader to read the file content
130+
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) {
131+
String line;
132+
while ((line = bufferedReader.readLine()) != null) {
133+
// Ignore comments and empty lines
134+
if (!line.trim().startsWith("#") && !line.trim().isEmpty()) {
135+
// Split the line into key and value using '=' as the delimiter
136+
String[] keyValue = line.split("=", 2);
137+
if (keyValue.length < 2) {
138+
continue; // Skip malformed lines
139+
}
140+
// Split the key further using '.' as the delimiter
141+
String[] parts = keyValue[0].split("\\.");
142+
if (parts.length == 0) {
143+
continue;
144+
}
145+
String languageCode = parts[parts.length - 1];
146+
// Split the value further using ',' as the delimiter
147+
String[] values = keyValue[1].split(",");
148+
if (values.length < 2) {
149+
continue; // Skip lines without proper country,displayName format
150+
}
151+
String country = values[0];
152+
// displayName is available in values[1] if needed in the future
153+
// Add the values to the list.
154+
supportedLanguages.put(languageCode, country);
155+
if (!languageSupportedCountries.contains(country)) {
156+
languageSupportedCountries.add(country);
157+
}
158+
}
159+
}
160+
161+
request.setAttribute(SUPPORTED_LANGUAGES_ATTR, supportedLanguages);
162+
request.setAttribute(LANGUAGE_SUPPORTED_COUNTRIES_ATTR, languageSupportedCountries);
163+
} catch (Exception e) {
164+
throw e;
165+
}
166+
}
127167
128168
// Check cookie for the user selected language first
129169
Cookie[] cookies = request.getCookies();
@@ -203,6 +243,14 @@
203243
userLocale = new Locale(browserLocale.getLanguage(), countryCode);
204244
} else if (StringUtils.isNotBlank(fallbackCountryCode)){
205245
userLocale = new Locale(browserLocale.getLanguage(), fallbackCountryCode);
246+
} else if (StringUtils.isNotBlank(browserLocale.getLanguage())){
247+
for (String key : supportedLanguages.keySet()) {
248+
if (key.startsWith(browserLocale.getLanguage() + "_")) {
249+
String[] parts = key.split("_");
250+
userLocale = new Locale(parts[0], parts[1]);
251+
break;
252+
}
253+
}
206254
} else {
207255
userLocale = new Locale("en","US");
208256
}
@@ -274,6 +322,14 @@
274322
userLocale = new Locale(browserLocale.getLanguage(), countryCode);
275323
} else if (StringUtils.isNotBlank(fallbackCountryCode)){
276324
userLocale = new Locale(browserLocale.getLanguage(), fallbackCountryCode);
325+
} else if (StringUtils.isNotBlank(browserLocale.getLanguage())){
326+
for (String key : supportedLanguages.keySet()) {
327+
if (key.startsWith(browserLocale.getLanguage() + "_")) {
328+
String[] parts = key.split("_");
329+
userLocale = new Locale(parts[0], parts[1]);
330+
break;
331+
}
332+
}
277333
} else {
278334
userLocale = new Locale("en","US");
279335
}

identity-apps-core/apps/recovery-portal/src/main/webapp/includes/localize.jsp

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<%@ page import="org.wso2.carbon.identity.application.authentication.endpoint.util.EncodedControl" %>
2121
<%@ page import="java.nio.charset.StandardCharsets" %>
2222
<%@ page import="java.util.*" %>
23+
<%@ page import="java.io.FileReader" %>
24+
<%@ page import="java.io.BufferedReader" %>
2325
<%@ page import="org.json.JSONObject" %>
2426
<%@ page import="java.util.Calendar" %>
2527
<%@ page import="org.apache.commons.lang.StringUtils" %>
@@ -101,6 +103,8 @@
101103
Locale userLocale = browserLocale;
102104
String localeFromCookie = null;
103105
String BUNDLE = "org.wso2.carbon.identity.mgt.recovery.endpoint.i18n.Resources";
106+
String SUPPORTED_LANGUAGES_ATTR = "supportedLanguages";
107+
String LANGUAGE_SUPPORTED_COUNTRIES_ATTR = "languageSupportedCountries";
104108
105109
// List of screen names for retrieving text branding customizations.
106110
List<String> screenNames = new ArrayList<>();
@@ -109,23 +113,58 @@
109113
// Map to store default supported language codes.
110114
// TODO: Use this map to generate the `language-switcher.jsp`.
111115
Map<String, String> supportedLanguages = new HashMap<>();
112-
supportedLanguages.put("en", "US");
113-
supportedLanguages.put("fr", "FR");
114-
supportedLanguages.put("es", "ES");
115-
supportedLanguages.put("pt", "PT");
116-
supportedLanguages.put("de", "DE");
117-
supportedLanguages.put("zh", "CN");
118-
supportedLanguages.put("ja", "JP");
119-
120116
List<String> languageSupportedCountries = new ArrayList<>();
121-
languageSupportedCountries.add("US");
122-
languageSupportedCountries.add("FR");
123-
languageSupportedCountries.add("ES");
124-
languageSupportedCountries.add("PT");
125-
languageSupportedCountries.add("DE");
126-
languageSupportedCountries.add("CN");
127-
languageSupportedCountries.add("JP");
128-
languageSupportedCountries.add("BR");
117+
118+
// Dynamically load supported languages from languageOptions.properties
119+
// Use application scope to cache the parsed language options
120+
Map<String, String> cachedSupportedLanguages = (Map<String, String>) request.getAttribute(SUPPORTED_LANGUAGES_ATTR);
121+
List<String> cachedLanguageSupportedCountries = (List<String>) request.getAttribute(LANGUAGE_SUPPORTED_COUNTRIES_ATTR);
122+
123+
if (cachedSupportedLanguages != null && cachedLanguageSupportedCountries != null) {
124+
supportedLanguages = cachedSupportedLanguages;
125+
languageSupportedCountries = cachedLanguageSupportedCountries;
126+
} else {
127+
// Specify the file path
128+
String filePath = application.getRealPath("/") + "/WEB-INF/classes/LanguageOptions.properties";
129+
130+
// Use a BufferedReader to read the file content
131+
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) {
132+
String line;
133+
while ((line = bufferedReader.readLine()) != null) {
134+
// Ignore comments and empty lines
135+
if (!line.trim().startsWith("#") && !line.trim().isEmpty()) {
136+
// Split the line into key and value using '=' as the delimiter
137+
String[] keyValue = line.split("=", 2);
138+
if (keyValue.length < 2) {
139+
continue; // Skip malformed lines
140+
}
141+
// Split the key further using '.' as the delimiter
142+
String[] parts = keyValue[0].split("\\.");
143+
if (parts.length == 0) {
144+
continue;
145+
}
146+
String languageCode = parts[parts.length - 1];
147+
// Split the value further using ',' as the delimiter
148+
String[] values = keyValue[1].split(",");
149+
if (values.length < 2) {
150+
continue; // Skip lines without proper country,displayName format
151+
}
152+
String country = values[0];
153+
// displayName is available in values[1] if needed in the future
154+
// Add the values to the list.
155+
supportedLanguages.put(languageCode, country);
156+
if (!languageSupportedCountries.contains(country)) {
157+
languageSupportedCountries.add(country);
158+
}
159+
}
160+
}
161+
162+
request.setAttribute(SUPPORTED_LANGUAGES_ATTR, supportedLanguages);
163+
request.setAttribute(LANGUAGE_SUPPORTED_COUNTRIES_ATTR, languageSupportedCountries);
164+
} catch (Exception e) {
165+
throw e;
166+
}
167+
}
129168
130169
// Check cookie for the user selected language first
131170
Cookie[] cookies = request.getCookies();
@@ -205,6 +244,14 @@
205244
userLocale = new Locale(browserLocale.getLanguage(), countryCode);
206245
} else if (StringUtils.isNotBlank(fallbackCountryCode)){
207246
userLocale = new Locale(browserLocale.getLanguage(), fallbackCountryCode);
247+
} else if (StringUtils.isNotBlank(browserLocale.getLanguage())){
248+
for (String key : supportedLanguages.keySet()) {
249+
if (key.startsWith(browserLocale.getLanguage() + "_")) {
250+
String[] parts = key.split("_");
251+
userLocale = new Locale(parts[0], parts[1]);
252+
break;
253+
}
254+
}
208255
} else {
209256
userLocale = new Locale("en","US");
210257
}
@@ -276,10 +323,18 @@
276323
userLocale = new Locale(browserLocale.getLanguage(), countryCode);
277324
} else if (StringUtils.isNotBlank(fallbackCountryCode)){
278325
userLocale = new Locale(browserLocale.getLanguage(), fallbackCountryCode);
326+
} else if (StringUtils.isNotBlank(browserLocale.getLanguage())){
327+
for (String key : supportedLanguages.keySet()) {
328+
if (key.startsWith(browserLocale.getLanguage() + "_")) {
329+
String[] parts = key.split("_");
330+
userLocale = new Locale(parts[0], parts[1]);
331+
break;
332+
}
333+
}
279334
} else {
280335
userLocale = new Locale("en","US");
281336
}
282-
}
337+
}
283338
}
284339
285340
ResourceBundle recoveryResourceBundle = ResourceBundle.getBundle(BUNDLE, userLocale, new
@@ -395,7 +450,7 @@
395450
}
396451
%>
397452
398-
<%!
453+
<%!
399454
private static final String LOCALE_CODE_KEY = "localeCode";
400455
private static final String FLAG_CODE_KEY = "flagCode";
401456
private static final String DISPLAY_NAME_KEY = "displayName";
@@ -415,7 +470,7 @@
415470
localeProperties.load(localeReader);
416471
for (String key : localeProperties.stringPropertyNames()) {
417472
String[] values = localeProperties.getProperty(key).split(",");
418-
473+
419474
// Validate the number of values
420475
if (values.length == 3) {
421476
String flagCode = values[0].trim();

0 commit comments

Comments
 (0)