001
014
015 package com.liferay.portal.language;
016
017 import com.liferay.portal.kernel.cache.MultiVMPool;
018 import com.liferay.portal.kernel.cache.PortalCache;
019 import com.liferay.portal.kernel.cache.PortalCacheMapSynchronizeUtil;
020 import com.liferay.portal.kernel.cache.PortalCacheMapSynchronizeUtil.Synchronizer;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.language.Language;
024 import com.liferay.portal.kernel.language.LanguageWrapper;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.model.CompanyConstants;
028 import com.liferay.portal.kernel.model.Group;
029 import com.liferay.portal.kernel.model.GroupConstants;
030 import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
031 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
032 import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
033 import com.liferay.portal.kernel.theme.ThemeDisplay;
034 import com.liferay.portal.kernel.util.ArrayUtil;
035 import com.liferay.portal.kernel.util.CharPool;
036 import com.liferay.portal.kernel.util.CookieKeys;
037 import com.liferay.portal.kernel.util.GetterUtil;
038 import com.liferay.portal.kernel.util.HtmlUtil;
039 import com.liferay.portal.kernel.util.JavaConstants;
040 import com.liferay.portal.kernel.util.LocaleUtil;
041 import com.liferay.portal.kernel.util.ObjectValuePair;
042 import com.liferay.portal.kernel.util.ParamUtil;
043 import com.liferay.portal.kernel.util.PortalUtil;
044 import com.liferay.portal.kernel.util.PropsKeys;
045 import com.liferay.portal.kernel.util.ResourceBundleLoader;
046 import com.liferay.portal.kernel.util.ResourceBundleUtil;
047 import com.liferay.portal.kernel.util.StringBundler;
048 import com.liferay.portal.kernel.util.StringPool;
049 import com.liferay.portal.kernel.util.StringUtil;
050 import com.liferay.portal.kernel.util.Time;
051 import com.liferay.portal.kernel.util.UnicodeProperties;
052 import com.liferay.portal.kernel.util.Validator;
053 import com.liferay.portal.kernel.util.WebKeys;
054 import com.liferay.portal.util.PrefsPropsUtil;
055 import com.liferay.portal.util.PropsValues;
056 import com.liferay.registry.Registry;
057 import com.liferay.registry.RegistryUtil;
058 import com.liferay.registry.dependency.ServiceDependencyListener;
059 import com.liferay.registry.dependency.ServiceDependencyManager;
060
061 import java.io.Serializable;
062
063 import java.text.MessageFormat;
064 import java.text.NumberFormat;
065
066 import java.util.Collections;
067 import java.util.HashMap;
068 import java.util.HashSet;
069 import java.util.List;
070 import java.util.Locale;
071 import java.util.Map;
072 import java.util.ResourceBundle;
073 import java.util.Set;
074 import java.util.concurrent.ConcurrentHashMap;
075 import java.util.regex.Matcher;
076 import java.util.regex.Pattern;
077
078 import javax.portlet.PortletConfig;
079 import javax.portlet.PortletRequest;
080
081 import javax.servlet.http.Cookie;
082 import javax.servlet.http.HttpServletRequest;
083 import javax.servlet.http.HttpServletResponse;
084
085
107 @DoPrivileged
108 public class LanguageImpl implements Language, Serializable {
109
110 public void afterPropertiesSet() {
111 ServiceDependencyManager serviceDependencyManager =
112 new ServiceDependencyManager();
113
114 serviceDependencyManager.addServiceDependencyListener(
115 new ServiceDependencyListener() {
116
117 @Override
118 public void dependenciesFulfilled() {
119 Registry registry = RegistryUtil.getRegistry();
120
121 MultiVMPool multiVMPool = registry.getService(
122 MultiVMPool.class);
123
124 _companyLocalesPortalCache =
125 (PortalCache<Long, Serializable>)
126 multiVMPool.getPortalCache(
127 _COMPANY_LOCALES_PORTAL_CACHE_NAME);
128
129 PortalCacheMapSynchronizeUtil.synchronize(
130 _companyLocalesPortalCache, _companyLocalesBags,
131 _removeSynchronizer);
132
133 _groupLocalesPortalCache =
134 (PortalCache<Long, Serializable>)
135 multiVMPool.getPortalCache(
136 _GROUP_LOCALES_PORTAL_CACHE_NAME);
137
138 PortalCacheMapSynchronizeUtil.synchronize(
139 _groupLocalesPortalCache,
140 _groupLanguageCodeLocalesMapMap, _removeSynchronizer);
141
142 PortalCacheMapSynchronizeUtil.synchronize(
143 _groupLocalesPortalCache, _groupLanguageIdLocalesMap,
144 _removeSynchronizer);
145 }
146
147 @Override
148 public void destroy() {
149 }
150
151 });
152
153 serviceDependencyManager.registerDependencies(MultiVMPool.class);
154 }
155
156
181 @Override
182 public String format(
183 HttpServletRequest request, String pattern, LanguageWrapper argument) {
184
185 return format(request, pattern, new LanguageWrapper[] {argument}, true);
186 }
187
188
214 @Override
215 public String format(
216 HttpServletRequest request, String pattern, LanguageWrapper argument,
217 boolean translateArguments) {
218
219 return format(
220 request, pattern, new LanguageWrapper[] {argument},
221 translateArguments);
222 }
223
224
249 @Override
250 public String format(
251 HttpServletRequest request, String pattern,
252 LanguageWrapper[] arguments) {
253
254 return format(request, pattern, arguments, true);
255 }
256
257
282 @Override
283 public String format(
284 HttpServletRequest request, String pattern, LanguageWrapper[] arguments,
285 boolean translateArguments) {
286
287 if (PropsValues.TRANSLATIONS_DISABLED) {
288 return pattern;
289 }
290
291 String value = null;
292
293 try {
294 pattern = get(request, pattern);
295
296 if (ArrayUtil.isNotEmpty(arguments)) {
297 pattern = _escapePattern(pattern);
298
299 Object[] formattedArguments = new Object[arguments.length];
300
301 for (int i = 0; i < arguments.length; i++) {
302 if (translateArguments) {
303 formattedArguments[i] =
304 arguments[i].getBefore() +
305 get(request, arguments[i].getText()) +
306 arguments[i].getAfter();
307 }
308 else {
309 formattedArguments[i] =
310 arguments[i].getBefore() + arguments[i].getText() +
311 arguments[i].getAfter();
312 }
313 }
314
315 MessageFormat messageFormat = decorateMessageFormat(
316 request, pattern, formattedArguments);
317
318 value = messageFormat.format(formattedArguments);
319 }
320 else {
321 value = pattern;
322 }
323 }
324 catch (Exception e) {
325 if (_log.isWarnEnabled()) {
326 _log.warn(e, e);
327 }
328 }
329
330 return value;
331 }
332
333
358 @Override
359 public String format(
360 HttpServletRequest request, String pattern, Object argument) {
361
362 return format(request, pattern, new Object[] {argument}, true);
363 }
364
365
391 @Override
392 public String format(
393 HttpServletRequest request, String pattern, Object argument,
394 boolean translateArguments) {
395
396 return format(
397 request, pattern, new Object[] {argument}, translateArguments);
398 }
399
400
425 @Override
426 public String format(
427 HttpServletRequest request, String pattern, Object[] arguments) {
428
429 return format(request, pattern, arguments, true);
430 }
431
432
457 @Override
458 public String format(
459 HttpServletRequest request, String pattern, Object[] arguments,
460 boolean translateArguments) {
461
462 if (PropsValues.TRANSLATIONS_DISABLED) {
463 return pattern;
464 }
465
466 String value = null;
467
468 try {
469 pattern = get(request, pattern);
470
471 if (ArrayUtil.isNotEmpty(arguments)) {
472 pattern = _escapePattern(pattern);
473
474 Object[] formattedArguments = new Object[arguments.length];
475
476 for (int i = 0; i < arguments.length; i++) {
477 if (translateArguments) {
478 formattedArguments[i] = get(
479 request, arguments[i].toString());
480 }
481 else {
482 formattedArguments[i] = arguments[i];
483 }
484 }
485
486 MessageFormat messageFormat = decorateMessageFormat(
487 request, pattern, formattedArguments);
488
489 value = messageFormat.format(formattedArguments);
490 }
491 else {
492 value = pattern;
493 }
494 }
495 catch (Exception e) {
496 if (_log.isWarnEnabled()) {
497 _log.warn(e, e);
498 }
499 }
500
501 return value;
502 }
503
504
527 @Override
528 public String format(
529 Locale locale, String pattern, List<Object> arguments) {
530
531 return format(locale, pattern, arguments.toArray(), true);
532 }
533
534
557 @Override
558 public String format(Locale locale, String pattern, Object argument) {
559 return format(locale, pattern, new Object[] {argument}, true);
560 }
561
562
586 @Override
587 public String format(
588 Locale locale, String pattern, Object argument,
589 boolean translateArguments) {
590
591 return format(
592 locale, pattern, new Object[] {argument}, translateArguments);
593 }
594
595
618 @Override
619 public String format(Locale locale, String pattern, Object[] arguments) {
620 return format(locale, pattern, arguments, true);
621 }
622
623
647 @Override
648 public String format(
649 Locale locale, String pattern, Object[] arguments,
650 boolean translateArguments) {
651
652 if (PropsValues.TRANSLATIONS_DISABLED) {
653 return pattern;
654 }
655
656 String value = null;
657
658 try {
659 pattern = get(locale, pattern);
660
661 if (ArrayUtil.isNotEmpty(arguments)) {
662 pattern = _escapePattern(pattern);
663
664 Object[] formattedArguments = new Object[arguments.length];
665
666 for (int i = 0; i < arguments.length; i++) {
667 if (translateArguments) {
668 formattedArguments[i] = get(
669 locale, arguments[i].toString());
670 }
671 else {
672 formattedArguments[i] = arguments[i];
673 }
674 }
675
676 MessageFormat messageFormat = decorateMessageFormat(
677 locale, pattern, formattedArguments);
678
679 value = messageFormat.format(formattedArguments);
680 }
681 else {
682 value = pattern;
683 }
684 }
685 catch (Exception e) {
686 if (_log.isWarnEnabled()) {
687 _log.warn(e, e);
688 }
689 }
690
691 return value;
692 }
693
694
713 @Override
714 public String format(
715 ResourceBundle resourceBundle, String pattern, Object argument) {
716
717 return format(resourceBundle, pattern, new Object[] {argument}, true);
718 }
719
720
740 @Override
741 public String format(
742 ResourceBundle resourceBundle, String pattern, Object argument,
743 boolean translateArguments) {
744
745 return format(
746 resourceBundle, pattern, new Object[] {argument},
747 translateArguments);
748 }
749
750
769 @Override
770 public String format(
771 ResourceBundle resourceBundle, String pattern, Object[] arguments) {
772
773 return format(resourceBundle, pattern, arguments, true);
774 }
775
776
796 @Override
797 public String format(
798 ResourceBundle resourceBundle, String pattern, Object[] arguments,
799 boolean translateArguments) {
800
801 if (PropsValues.TRANSLATIONS_DISABLED) {
802 return pattern;
803 }
804
805 String value = null;
806
807 try {
808 pattern = get(resourceBundle, pattern);
809
810 if (ArrayUtil.isNotEmpty(arguments)) {
811 pattern = _escapePattern(pattern);
812
813 Object[] formattedArguments = new Object[arguments.length];
814
815 for (int i = 0; i < arguments.length; i++) {
816 if (translateArguments) {
817 formattedArguments[i] = get(
818 resourceBundle, arguments[i].toString());
819 }
820 else {
821 formattedArguments[i] = arguments[i];
822 }
823 }
824
825 MessageFormat messageFormat = decorateMessageFormat(
826 resourceBundle.getLocale(), pattern, formattedArguments);
827
828 value = messageFormat.format(formattedArguments);
829 }
830 else {
831 value = pattern;
832 }
833 }
834 catch (Exception e) {
835 if (_log.isWarnEnabled()) {
836 _log.warn(e, e);
837 }
838 }
839
840 return value;
841 }
842
843
854 @Override
855 public String get(
856 HttpServletRequest request, ResourceBundle resourceBundle, String key) {
857
858 return get(request, resourceBundle, key, key);
859 }
860
861 @Override
862 public String get(
863 HttpServletRequest request, ResourceBundle resourceBundle, String key,
864 String defaultValue) {
865
866 String value = _get(resourceBundle, key);
867
868 if (value != null) {
869 return value;
870 }
871
872 return get(request, key, defaultValue);
873 }
874
875 @Override
876 public String get(HttpServletRequest request, String key) {
877 return get(request, key, key);
878 }
879
880
892 @Override
893 public String get(
894 HttpServletRequest request, String key, String defaultValue) {
895
896 if ((request == null) || (key == null)) {
897 return defaultValue;
898 }
899
900 PortletConfig portletConfig = (PortletConfig)request.getAttribute(
901 JavaConstants.JAVAX_PORTLET_CONFIG);
902
903 Locale locale = _getLocale(request);
904
905 if (portletConfig == null) {
906 return get(locale, key, defaultValue);
907 }
908
909 ResourceBundle resourceBundle = portletConfig.getResourceBundle(locale);
910
911 if (resourceBundle.containsKey(key)) {
912 return _get(resourceBundle, key);
913 }
914
915 return get(locale, key, defaultValue);
916 }
917
918
925 @Override
926 public String get(Locale locale, String key) {
927 return get(locale, key, key);
928 }
929
930
940 @Override
941 public String get(Locale locale, String key, String defaultValue) {
942 if (PropsValues.TRANSLATIONS_DISABLED) {
943 return key;
944 }
945
946 if ((locale == null) || (key == null)) {
947 return defaultValue;
948 }
949
950 String value = LanguageResources.getMessage(locale, key);
951
952 if (value != null) {
953 return LanguageResources.fixValue(value);
954 }
955
956 if (value == null) {
957 if ((key.length() > 0) &&
958 (key.charAt(key.length() - 1) == CharPool.CLOSE_BRACKET)) {
959
960 int pos = key.lastIndexOf(CharPool.OPEN_BRACKET);
961
962 if (pos != -1) {
963 key = key.substring(0, pos);
964
965 return get(locale, key, defaultValue);
966 }
967 }
968 }
969
970 return defaultValue;
971 }
972
973
980 @Override
981 public String get(ResourceBundle resourceBundle, String key) {
982 return get(resourceBundle, key, key);
983 }
984
985
995 @Override
996 public String get(
997 ResourceBundle resourceBundle, String key, String defaultValue) {
998
999 String value = _get(resourceBundle, key);
1000
1001 if (value != null) {
1002 return value;
1003 }
1004
1005 return defaultValue;
1006 }
1007
1008
1015 @Override
1016 public Set<Locale> getAvailableLocales() {
1017 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1018
1019 return companyLocalesBag.getAvailableLocales();
1020 }
1021
1022 @Override
1023 public Set<Locale> getAvailableLocales(long groupId) {
1024 if (groupId <= 0) {
1025 return getAvailableLocales();
1026 }
1027
1028 try {
1029 if (isInheritLocales(groupId)) {
1030 return getAvailableLocales();
1031 }
1032 }
1033 catch (Exception e) {
1034 }
1035
1036 Map<String, Locale> groupLanguageIdLocalesMap =
1037 _getGroupLanguageIdLocalesMap(groupId);
1038
1039 return new HashSet<>(groupLanguageIdLocalesMap.values());
1040 }
1041
1042 @Override
1043 public String getBCP47LanguageId(HttpServletRequest request) {
1044 Locale locale = PortalUtil.getLocale(request);
1045
1046 return getBCP47LanguageId(locale);
1047 }
1048
1049 @Override
1050 public String getBCP47LanguageId(Locale locale) {
1051 return LocaleUtil.toBCP47LanguageId(locale);
1052 }
1053
1054 @Override
1055 public String getBCP47LanguageId(PortletRequest portletRequest) {
1056 Locale locale = PortalUtil.getLocale(portletRequest);
1057
1058 return getBCP47LanguageId(locale);
1059 }
1060
1061
1069 @Override
1070 public String getLanguageId(HttpServletRequest request) {
1071 String languageId = ParamUtil.getString(request, "languageId");
1072
1073 if (Validator.isNotNull(languageId)) {
1074 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1075
1076 if (companyLocalesBag.containsLanguageCode(languageId) ||
1077 companyLocalesBag.containsLanguageId(languageId)) {
1078
1079 return languageId;
1080 }
1081 }
1082
1083 Locale locale = PortalUtil.getLocale(request);
1084
1085 return getLanguageId(locale);
1086 }
1087
1088
1096 @Override
1097 public String getLanguageId(Locale locale) {
1098 return LocaleUtil.toLanguageId(locale);
1099 }
1100
1101
1110 @Override
1111 public String getLanguageId(PortletRequest portletRequest) {
1112 HttpServletRequest request = PortalUtil.getHttpServletRequest(
1113 portletRequest);
1114
1115 return getLanguageId(request);
1116 }
1117
1118 @Override
1119 public Locale getLocale(long groupId, String languageCode) {
1120 Map<String, Locale> groupLanguageCodeLocalesMap =
1121 _getGroupLanguageCodeLocalesMap(groupId);
1122
1123 return groupLanguageCodeLocalesMap.get(languageCode);
1124 }
1125
1126
1133 @Override
1134 public Locale getLocale(String languageCode) {
1135 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1136
1137 return companyLocalesBag.getByLanguageCode(languageCode);
1138 }
1139
1140 @Override
1141 public ResourceBundleLoader getPortalResourceBundleLoader() {
1142 return LanguageResources.RESOURCE_BUNDLE_LOADER;
1143 }
1144
1145 @Override
1146 public Set<Locale> getSupportedLocales() {
1147 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1148
1149 return companyLocalesBag._supportedLocalesSet;
1150 }
1151
1152
1181 @Override
1182 public String getTimeDescription(
1183 HttpServletRequest request, long milliseconds) {
1184
1185 return getTimeDescription(request, milliseconds, false);
1186 }
1187
1188
1232 @Override
1233 public String getTimeDescription(
1234 HttpServletRequest request, long milliseconds, boolean approximate) {
1235
1236 String description = Time.getDescription(milliseconds, approximate);
1237
1238 String value = null;
1239
1240 try {
1241 int pos = description.indexOf(CharPool.SPACE);
1242
1243 String x = description.substring(0, pos);
1244
1245 value = x.concat(StringPool.SPACE).concat(
1246 get(
1247 request,
1248 StringUtil.toLowerCase(
1249 description.substring(pos + 1, description.length()))));
1250 }
1251 catch (Exception e) {
1252 if (_log.isWarnEnabled()) {
1253 _log.warn(e, e);
1254 }
1255 }
1256
1257 return value;
1258 }
1259
1260
1289 @Override
1290 public String getTimeDescription(
1291 HttpServletRequest request, Long milliseconds) {
1292
1293 return getTimeDescription(request, milliseconds.longValue());
1294 }
1295
1296
1325 @Override
1326 public String getTimeDescription(Locale locale, long milliseconds) {
1327 return getTimeDescription(locale, milliseconds, false);
1328 }
1329
1330
1374 @Override
1375 public String getTimeDescription(
1376 Locale locale, long milliseconds, boolean approximate) {
1377
1378 String description = Time.getDescription(milliseconds, approximate);
1379
1380 String value = null;
1381
1382 try {
1383 int pos = description.indexOf(CharPool.SPACE);
1384
1385 String x = description.substring(0, pos);
1386
1387 value = x.concat(StringPool.SPACE).concat(
1388 get(
1389 locale,
1390 StringUtil.toLowerCase(
1391 description.substring(pos + 1, description.length()))));
1392 }
1393 catch (Exception e) {
1394 if (_log.isWarnEnabled()) {
1395 _log.warn(e, e);
1396 }
1397 }
1398
1399 return value;
1400 }
1401
1402
1431 @Override
1432 public String getTimeDescription(Locale locale, Long milliseconds) {
1433 return getTimeDescription(locale, milliseconds.longValue());
1434 }
1435
1436 @Override
1437 public void init() {
1438 _companyLocalesBags.clear();
1439 }
1440
1441
1451 @Override
1452 public boolean isAvailableLanguageCode(String languageCode) {
1453 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1454
1455 return companyLocalesBag.containsLanguageCode(languageCode);
1456 }
1457
1458
1467 @Override
1468 public boolean isAvailableLocale(Locale locale) {
1469 if (locale == null) {
1470 return false;
1471 }
1472
1473 return isAvailableLocale(LocaleUtil.toLanguageId(locale));
1474 }
1475
1476
1485 @Override
1486 public boolean isAvailableLocale(long groupId, Locale locale) {
1487 if (locale == null) {
1488 return false;
1489 }
1490
1491 return isAvailableLocale(groupId, LocaleUtil.toLanguageId(locale));
1492 }
1493
1494
1503 @Override
1504 public boolean isAvailableLocale(long groupId, String languageId) {
1505 if (groupId <= 0) {
1506 return isAvailableLocale(languageId);
1507 }
1508
1509 try {
1510 if (isInheritLocales(groupId)) {
1511 return isAvailableLocale(languageId);
1512 }
1513 }
1514 catch (Exception e) {
1515 }
1516
1517 Map<String, Locale> groupLanguageIdLocalesMap =
1518 _getGroupLanguageIdLocalesMap(groupId);
1519
1520 return groupLanguageIdLocalesMap.containsKey(languageId);
1521 }
1522
1523
1531 @Override
1532 public boolean isAvailableLocale(String languageId) {
1533 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1534
1535 return companyLocalesBag.containsLanguageId(languageId);
1536 }
1537
1538
1546 @Override
1547 public boolean isBetaLocale(Locale locale) {
1548 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1549
1550 return companyLocalesBag.isBetaLocale(locale);
1551 }
1552
1553 @Override
1554 public boolean isDuplicateLanguageCode(String languageCode) {
1555 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1556
1557 return companyLocalesBag.isDuplicateLanguageCode(languageCode);
1558 }
1559
1560 @Override
1561 public boolean isInheritLocales(long groupId) throws PortalException {
1562 Group group = GroupLocalServiceUtil.getGroup(groupId);
1563
1564 if (group.isStagingGroup()) {
1565 group = group.getLiveGroup();
1566 }
1567
1568 if (!group.isSite() || group.isCompany()) {
1569 return true;
1570 }
1571
1572 return GetterUtil.getBoolean(
1573 group.getTypeSettingsProperty(
1574 GroupConstants.TYPE_SETTINGS_KEY_INHERIT_LOCALES),
1575 true);
1576 }
1577
1578 @Override
1579 public String process(
1580 ResourceBundle resourceBundle, Locale locale, String content) {
1581
1582 StringBundler sb = new StringBundler();
1583
1584 Matcher matcher = _pattern.matcher(content);
1585
1586 int x = 0;
1587
1588 while (matcher.find()) {
1589 int y = matcher.start(0);
1590
1591 String key = matcher.group(1);
1592
1593 sb.append(content.substring(x, y));
1594 sb.append(StringPool.APOSTROPHE);
1595
1596 String value = get(resourceBundle, key);
1597
1598 sb.append(HtmlUtil.escapeJS(value));
1599 sb.append(StringPool.APOSTROPHE);
1600
1601 x = matcher.end(0);
1602 }
1603
1604 sb.append(content.substring(x));
1605
1606 return sb.toString();
1607 }
1608
1609 @Override
1610 public void resetAvailableGroupLocales(long groupId) {
1611 _resetAvailableGroupLocales(groupId);
1612 }
1613
1614 @Override
1615 public void resetAvailableLocales(long companyId) {
1616 _resetAvailableLocales(companyId);
1617 }
1618
1619 @Override
1620 public void updateCookie(
1621 HttpServletRequest request, HttpServletResponse response,
1622 Locale locale) {
1623
1624 String languageId = LocaleUtil.toLanguageId(locale);
1625
1626 Cookie languageIdCookie = new Cookie(
1627 CookieKeys.GUEST_LANGUAGE_ID, languageId);
1628
1629 languageIdCookie.setPath(StringPool.SLASH);
1630 languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
1631
1632 CookieKeys.addCookie(request, response, languageIdCookie);
1633 }
1634
1635 protected MessageFormat decorateMessageFormat(
1636 HttpServletRequest request, String pattern,
1637 Object[] formattedArguments) {
1638
1639 Locale locale = _getLocale(request);
1640
1641 return decorateMessageFormat(locale, pattern, formattedArguments);
1642 }
1643
1644 protected MessageFormat decorateMessageFormat(
1645 Locale locale, String pattern, Object[] formattedArguments) {
1646
1647 if (locale == null) {
1648 locale = LocaleUtil.getDefault();
1649 }
1650
1651 MessageFormat messageFormat = new MessageFormat(pattern, locale);
1652
1653 for (int i = 0; i < formattedArguments.length; i++) {
1654 Object formattedArgument = formattedArguments[i];
1655
1656 if (formattedArgument instanceof Number) {
1657 messageFormat.setFormat(i, NumberFormat.getInstance(locale));
1658 }
1659 }
1660
1661 return messageFormat;
1662 }
1663
1664 private static CompanyLocalesBag _getCompanyLocalesBag() {
1665 Long companyId = CompanyThreadLocal.getCompanyId();
1666
1667 CompanyLocalesBag companyLocalesBag = _companyLocalesBags.get(
1668 companyId);
1669
1670 if (companyLocalesBag == null) {
1671 companyLocalesBag = new CompanyLocalesBag(companyId);
1672
1673 _companyLocalesBags.put(companyId, companyLocalesBag);
1674 }
1675
1676 return companyLocalesBag;
1677 }
1678
1679 private ObjectValuePair<HashMap<String, Locale>, HashMap<String, Locale>>
1680 _createGroupLocales(long groupId) {
1681
1682 String[] languageIds = PropsValues.LOCALES_ENABLED;
1683
1684 try {
1685 Group group = GroupLocalServiceUtil.getGroup(groupId);
1686
1687 UnicodeProperties typeSettingsProperties =
1688 group.getTypeSettingsProperties();
1689
1690 languageIds = StringUtil.split(
1691 typeSettingsProperties.getProperty(PropsKeys.LOCALES));
1692 }
1693 catch (Exception e) {
1694 }
1695
1696 HashMap<String, Locale> groupLanguageCodeLocalesMap = new HashMap<>();
1697 HashMap<String, Locale> groupLanguageIdLocalesMap = new HashMap<>();
1698
1699 for (String languageId : languageIds) {
1700 Locale locale = LocaleUtil.fromLanguageId(languageId, false);
1701
1702 String languageCode = languageId;
1703
1704 int pos = languageId.indexOf(CharPool.UNDERLINE);
1705
1706 if (pos > 0) {
1707 languageCode = languageId.substring(0, pos);
1708 }
1709
1710 if (!groupLanguageCodeLocalesMap.containsKey(languageCode)) {
1711 groupLanguageCodeLocalesMap.put(languageCode, locale);
1712 }
1713
1714 groupLanguageIdLocalesMap.put(languageId, locale);
1715 }
1716
1717 _groupLanguageCodeLocalesMapMap.put(
1718 groupId, groupLanguageCodeLocalesMap);
1719 _groupLanguageIdLocalesMap.put(groupId, groupLanguageIdLocalesMap);
1720
1721 return new ObjectValuePair<>(
1722 groupLanguageCodeLocalesMap, groupLanguageIdLocalesMap);
1723 }
1724
1725 private String _escapePattern(String pattern) {
1726 return StringUtil.replace(
1727 pattern, CharPool.APOSTROPHE, StringPool.DOUBLE_APOSTROPHE);
1728 }
1729
1730 private String _get(ResourceBundle resourceBundle, String key) {
1731 if (PropsValues.TRANSLATIONS_DISABLED) {
1732 return key;
1733 }
1734
1735 if ((resourceBundle == null) || (key == null)) {
1736 return null;
1737 }
1738
1739 String value = ResourceBundleUtil.getString(resourceBundle, key);
1740
1741 if (value != null) {
1742 return LanguageResources.fixValue(value);
1743 }
1744
1745 if ((key.length() > 0) &&
1746 (key.charAt(key.length() - 1) == CharPool.CLOSE_BRACKET)) {
1747
1748 int pos = key.lastIndexOf(CharPool.OPEN_BRACKET);
1749
1750 if (pos != -1) {
1751 key = key.substring(0, pos);
1752
1753 return _get(resourceBundle, key);
1754 }
1755 }
1756
1757 return null;
1758 }
1759
1760 private Map<String, Locale> _getGroupLanguageCodeLocalesMap(long groupId) {
1761 Map<String, Locale> groupLanguageCodeLocalesMap =
1762 _groupLanguageCodeLocalesMapMap.get(groupId);
1763
1764 if (groupLanguageCodeLocalesMap == null) {
1765 ObjectValuePair<HashMap<String, Locale>, HashMap<String, Locale>>
1766 objectValuePair = _createGroupLocales(groupId);
1767
1768 groupLanguageCodeLocalesMap = objectValuePair.getKey();
1769 }
1770
1771 return groupLanguageCodeLocalesMap;
1772 }
1773
1774 private Map<String, Locale> _getGroupLanguageIdLocalesMap(long groupId) {
1775 Map<String, Locale> groupLanguageIdLocalesMap =
1776 _groupLanguageIdLocalesMap.get(groupId);
1777
1778 if (groupLanguageIdLocalesMap == null) {
1779 ObjectValuePair<HashMap<String, Locale>, HashMap<String, Locale>>
1780 objectValuePair = _createGroupLocales(groupId);
1781
1782 groupLanguageIdLocalesMap = objectValuePair.getValue();
1783 }
1784
1785 return groupLanguageIdLocalesMap;
1786 }
1787
1788 private Locale _getLocale(HttpServletRequest request) {
1789 Locale locale = null;
1790
1791 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
1792 WebKeys.THEME_DISPLAY);
1793
1794 if (themeDisplay != null) {
1795 locale = themeDisplay.getLocale();
1796 }
1797 else {
1798 locale = request.getLocale();
1799
1800 if (!isAvailableLocale(locale)) {
1801 locale = LocaleUtil.getDefault();
1802 }
1803 }
1804
1805 return locale;
1806 }
1807
1808 private void _resetAvailableGroupLocales(long groupId) {
1809 _groupLocalesPortalCache.remove(groupId);
1810 }
1811
1812 private void _resetAvailableLocales(long companyId) {
1813 _companyLocalesPortalCache.remove(companyId);
1814 }
1815
1816 private static final String _COMPANY_LOCALES_PORTAL_CACHE_NAME =
1817 LanguageImpl.class + "._companyLocalesPortalCache";
1818
1819 private static final String _GROUP_LOCALES_PORTAL_CACHE_NAME =
1820 LanguageImpl.class + "._groupLocalesPortalCache";
1821
1822 private static final Log _log = LogFactoryUtil.getLog(LanguageImpl.class);
1823
1824 private static final Map<Long, CompanyLocalesBag> _companyLocalesBags =
1825 new ConcurrentHashMap<>();
1826 private static PortalCache<Long, Serializable> _companyLocalesPortalCache;
1827 private static PortalCache<Long, Serializable> _groupLocalesPortalCache;
1828 private static final Pattern _pattern = Pattern.compile(
1829 "Liferay\\.Language\\.get\\([\"']([^)]+)[\"']\\)");
1830
1831 private static final Synchronizer<Long, Serializable> _removeSynchronizer =
1832 new Synchronizer<Long, Serializable>() {
1833
1834 @Override
1835 public void onSynchronize(
1836 Map<? extends Long, ? extends Serializable> map, Long key,
1837 Serializable value, int timeToLive) {
1838
1839 map.remove(key);
1840 }
1841
1842 };
1843
1844 private final Map<Long, HashMap<String, Locale>>
1845 _groupLanguageCodeLocalesMapMap = new ConcurrentHashMap<>();
1846 private final Map<Long, HashMap<String, Locale>>
1847 _groupLanguageIdLocalesMap = new ConcurrentHashMap<>();
1848
1849 private static class CompanyLocalesBag implements Serializable {
1850
1851 public boolean containsLanguageCode(String languageCode) {
1852 return _languageCodeLocalesMap.containsKey(languageCode);
1853 }
1854
1855 public boolean containsLanguageId(String languageId) {
1856 return _languageIdLocalesMap.containsKey(languageId);
1857 }
1858
1859 public Set<Locale> getAvailableLocales() {
1860 return _availableLocales;
1861 }
1862
1863 public Locale getByLanguageCode(String languageCode) {
1864 return _languageCodeLocalesMap.get(languageCode);
1865 }
1866
1867 public boolean isBetaLocale(Locale locale) {
1868 return _localesBetaSet.contains(locale);
1869 }
1870
1871 public boolean isDuplicateLanguageCode(String languageCode) {
1872 return _duplicateLanguageCodes.contains(languageCode);
1873 }
1874
1875 private CompanyLocalesBag(long companyId) {
1876 String[] languageIds = PropsValues.LOCALES;
1877
1878 if (companyId != CompanyConstants.SYSTEM) {
1879 try {
1880 languageIds = PrefsPropsUtil.getStringArray(
1881 companyId, PropsKeys.LOCALES, StringPool.COMMA,
1882 PropsValues.LOCALES_ENABLED);
1883 }
1884 catch (SystemException se) {
1885 languageIds = PropsValues.LOCALES_ENABLED;
1886 }
1887 }
1888
1889 for (String languageId : languageIds) {
1890 Locale locale = LocaleUtil.fromLanguageId(languageId, false);
1891
1892 String languageCode = languageId;
1893
1894 int pos = languageId.indexOf(CharPool.UNDERLINE);
1895
1896 if (pos > 0) {
1897 languageCode = languageId.substring(0, pos);
1898 }
1899
1900 if (_languageCodeLocalesMap.containsKey(languageCode)) {
1901 _duplicateLanguageCodes.add(languageCode);
1902 }
1903 else {
1904 _languageCodeLocalesMap.put(languageCode, locale);
1905 }
1906
1907 _languageIdLocalesMap.put(languageId, locale);
1908 }
1909
1910 for (String languageId : PropsValues.LOCALES_BETA) {
1911 _localesBetaSet.add(
1912 LocaleUtil.fromLanguageId(languageId, false));
1913 }
1914
1915 _availableLocales = Collections.unmodifiableSet(
1916 new HashSet<>(_languageIdLocalesMap.values()));
1917
1918 Set<Locale> supportedLocalesSet = new HashSet<>(
1919 _languageIdLocalesMap.values());
1920
1921 supportedLocalesSet.removeAll(_localesBetaSet);
1922
1923 _supportedLocalesSet = Collections.unmodifiableSet(
1924 supportedLocalesSet);
1925 }
1926
1927 private final Set<Locale> _availableLocales;
1928 private final Set<String> _duplicateLanguageCodes = new HashSet<>();
1929 private final Map<String, Locale> _languageCodeLocalesMap =
1930 new HashMap<>();
1931 private final Map<String, Locale> _languageIdLocalesMap =
1932 new HashMap<>();
1933 private final Set<Locale> _localesBetaSet = new HashSet<>();
1934 private final Set<Locale> _supportedLocalesSet;
1935
1936 }
1937
1938 }