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.HashMap;
067 import java.util.HashSet;
068 import java.util.List;
069 import java.util.Locale;
070 import java.util.Map;
071 import java.util.ResourceBundle;
072 import java.util.Set;
073 import java.util.concurrent.ConcurrentHashMap;
074 import java.util.regex.Matcher;
075 import java.util.regex.Pattern;
076
077 import javax.portlet.PortletConfig;
078 import javax.portlet.PortletRequest;
079
080 import javax.servlet.http.Cookie;
081 import javax.servlet.http.HttpServletRequest;
082 import javax.servlet.http.HttpServletResponse;
083
084
106 @DoPrivileged
107 public class LanguageImpl implements Language, Serializable {
108
109 public void afterPropertiesSet() {
110 ServiceDependencyManager serviceDependencyManager =
111 new ServiceDependencyManager();
112
113 serviceDependencyManager.addServiceDependencyListener(
114 new ServiceDependencyListener() {
115
116 @Override
117 public void dependenciesFulfilled() {
118 Registry registry = RegistryUtil.getRegistry();
119
120 MultiVMPool multiVMPool = registry.getService(
121 MultiVMPool.class);
122
123 _portalCache =
124 (PortalCache<Long, Serializable>)
125 multiVMPool.getPortalCache(
126 LanguageImpl.class.getName());
127
128 PortalCacheMapSynchronizeUtil.synchronize(
129 _portalCache, _companyLocalesBags,
130 new Synchronizer<Long, Serializable>() {
131
132 @Override
133 public void onSynchronize(
134 Map<? extends Long, ? extends Serializable> map,
135 Long key, Serializable value, int timeToLive) {
136
137 _companyLocalesBags.remove(key);
138 }
139
140 });
141 }
142
143 @Override
144 public void destroy() {
145 }
146
147 }
148 );
149
150 serviceDependencyManager.registerDependencies(MultiVMPool.class);
151 }
152
153
178 @Override
179 public String format(
180 HttpServletRequest request, String pattern, LanguageWrapper argument) {
181
182 return format(request, pattern, new LanguageWrapper[] {argument}, true);
183 }
184
185
211 @Override
212 public String format(
213 HttpServletRequest request, String pattern, LanguageWrapper argument,
214 boolean translateArguments) {
215
216 return format(
217 request, pattern, new LanguageWrapper[] {argument},
218 translateArguments);
219 }
220
221
246 @Override
247 public String format(
248 HttpServletRequest request, String pattern,
249 LanguageWrapper[] arguments) {
250
251 return format(request, pattern, arguments, true);
252 }
253
254
279 @Override
280 public String format(
281 HttpServletRequest request, String pattern, LanguageWrapper[] arguments,
282 boolean translateArguments) {
283
284 if (PropsValues.TRANSLATIONS_DISABLED) {
285 return pattern;
286 }
287
288 String value = null;
289
290 try {
291 pattern = get(request, pattern);
292
293 if (ArrayUtil.isNotEmpty(arguments)) {
294 pattern = _escapePattern(pattern);
295
296 Object[] formattedArguments = new Object[arguments.length];
297
298 for (int i = 0; i < arguments.length; i++) {
299 if (translateArguments) {
300 formattedArguments[i] =
301 arguments[i].getBefore() +
302 get(request, arguments[i].getText()) +
303 arguments[i].getAfter();
304 }
305 else {
306 formattedArguments[i] =
307 arguments[i].getBefore() + arguments[i].getText() +
308 arguments[i].getAfter();
309 }
310 }
311
312 MessageFormat messageFormat = decorateMessageFormat(
313 request, pattern, formattedArguments);
314
315 value = messageFormat.format(formattedArguments);
316 }
317 else {
318 value = pattern;
319 }
320 }
321 catch (Exception e) {
322 if (_log.isWarnEnabled()) {
323 _log.warn(e, e);
324 }
325 }
326
327 return value;
328 }
329
330
355 @Override
356 public String format(
357 HttpServletRequest request, String pattern, Object argument) {
358
359 return format(request, pattern, new Object[] {argument}, true);
360 }
361
362
388 @Override
389 public String format(
390 HttpServletRequest request, String pattern, Object argument,
391 boolean translateArguments) {
392
393 return format(
394 request, pattern, new Object[] {argument}, translateArguments);
395 }
396
397
422 @Override
423 public String format(
424 HttpServletRequest request, String pattern, Object[] arguments) {
425
426 return format(request, pattern, arguments, true);
427 }
428
429
454 @Override
455 public String format(
456 HttpServletRequest request, String pattern, Object[] arguments,
457 boolean translateArguments) {
458
459 if (PropsValues.TRANSLATIONS_DISABLED) {
460 return pattern;
461 }
462
463 String value = null;
464
465 try {
466 pattern = get(request, pattern);
467
468 if (ArrayUtil.isNotEmpty(arguments)) {
469 pattern = _escapePattern(pattern);
470
471 Object[] formattedArguments = new Object[arguments.length];
472
473 for (int i = 0; i < arguments.length; i++) {
474 if (translateArguments) {
475 formattedArguments[i] = get(
476 request, arguments[i].toString());
477 }
478 else {
479 formattedArguments[i] = arguments[i];
480 }
481 }
482
483 MessageFormat messageFormat = decorateMessageFormat(
484 request, pattern, formattedArguments);
485
486 value = messageFormat.format(formattedArguments);
487 }
488 else {
489 value = pattern;
490 }
491 }
492 catch (Exception e) {
493 if (_log.isWarnEnabled()) {
494 _log.warn(e, e);
495 }
496 }
497
498 return value;
499 }
500
501
524 @Override
525 public String format(
526 Locale locale, String pattern, List<Object> arguments) {
527
528 return format(locale, pattern, arguments.toArray(), true);
529 }
530
531
554 @Override
555 public String format(Locale locale, String pattern, Object argument) {
556 return format(locale, pattern, new Object[] {argument}, true);
557 }
558
559
583 @Override
584 public String format(
585 Locale locale, String pattern, Object argument,
586 boolean translateArguments) {
587
588 return format(
589 locale, pattern, new Object[] {argument}, translateArguments);
590 }
591
592
615 @Override
616 public String format(Locale locale, String pattern, Object[] arguments) {
617 return format(locale, pattern, arguments, true);
618 }
619
620
644 @Override
645 public String format(
646 Locale locale, String pattern, Object[] arguments,
647 boolean translateArguments) {
648
649 if (PropsValues.TRANSLATIONS_DISABLED) {
650 return pattern;
651 }
652
653 String value = null;
654
655 try {
656 pattern = get(locale, pattern);
657
658 if (ArrayUtil.isNotEmpty(arguments)) {
659 pattern = _escapePattern(pattern);
660
661 Object[] formattedArguments = new Object[arguments.length];
662
663 for (int i = 0; i < arguments.length; i++) {
664 if (translateArguments) {
665 formattedArguments[i] = get(
666 locale, arguments[i].toString());
667 }
668 else {
669 formattedArguments[i] = arguments[i];
670 }
671 }
672
673 MessageFormat messageFormat = decorateMessageFormat(
674 locale, pattern, formattedArguments);
675
676 value = messageFormat.format(formattedArguments);
677 }
678 else {
679 value = pattern;
680 }
681 }
682 catch (Exception e) {
683 if (_log.isWarnEnabled()) {
684 _log.warn(e, e);
685 }
686 }
687
688 return value;
689 }
690
691
710 @Override
711 public String format(
712 ResourceBundle resourceBundle, String pattern, Object argument) {
713
714 return format(resourceBundle, pattern, new Object[] {argument}, true);
715 }
716
717
737 @Override
738 public String format(
739 ResourceBundle resourceBundle, String pattern, Object argument,
740 boolean translateArguments) {
741
742 return format(
743 resourceBundle, pattern, new Object[] {argument},
744 translateArguments);
745 }
746
747
766 @Override
767 public String format(
768 ResourceBundle resourceBundle, String pattern, Object[] arguments) {
769
770 return format(resourceBundle, pattern, arguments, true);
771 }
772
773
793 @Override
794 public String format(
795 ResourceBundle resourceBundle, String pattern, Object[] arguments,
796 boolean translateArguments) {
797
798 if (PropsValues.TRANSLATIONS_DISABLED) {
799 return pattern;
800 }
801
802 String value = null;
803
804 try {
805 pattern = get(resourceBundle, pattern);
806
807 if (ArrayUtil.isNotEmpty(arguments)) {
808 pattern = _escapePattern(pattern);
809
810 Object[] formattedArguments = new Object[arguments.length];
811
812 for (int i = 0; i < arguments.length; i++) {
813 if (translateArguments) {
814 formattedArguments[i] = get(
815 resourceBundle, arguments[i].toString());
816 }
817 else {
818 formattedArguments[i] = arguments[i];
819 }
820 }
821
822 MessageFormat messageFormat = decorateMessageFormat(
823 resourceBundle.getLocale(), pattern, formattedArguments);
824
825 value = messageFormat.format(formattedArguments);
826 }
827 else {
828 value = pattern;
829 }
830 }
831 catch (Exception e) {
832 if (_log.isWarnEnabled()) {
833 _log.warn(e, e);
834 }
835 }
836
837 return value;
838 }
839
840
851 @Override
852 public String get(
853 HttpServletRequest request, ResourceBundle resourceBundle, String key) {
854
855 return get(request, resourceBundle, key, key);
856 }
857
858 @Override
859 public String get(
860 HttpServletRequest request, ResourceBundle resourceBundle, String key,
861 String defaultValue) {
862
863 String value = _get(resourceBundle, key);
864
865 if (value != null) {
866 return value;
867 }
868
869 return get(request, key, defaultValue);
870 }
871
872 @Override
873 public String get(HttpServletRequest request, String key) {
874 return get(request, key, key);
875 }
876
877
889 @Override
890 public String get(
891 HttpServletRequest request, String key, String defaultValue) {
892
893 if ((request == null) || (key == null)) {
894 return defaultValue;
895 }
896
897 PortletConfig portletConfig = (PortletConfig)request.getAttribute(
898 JavaConstants.JAVAX_PORTLET_CONFIG);
899
900 Locale locale = _getLocale(request);
901
902 if (portletConfig == null) {
903 return get(locale, key, defaultValue);
904 }
905
906 ResourceBundle resourceBundle = portletConfig.getResourceBundle(locale);
907
908 if (resourceBundle.containsKey(key)) {
909 return _get(resourceBundle, key);
910 }
911
912 return get(locale, key, defaultValue);
913 }
914
915
922 @Override
923 public String get(Locale locale, String key) {
924 return get(locale, key, key);
925 }
926
927
937 @Override
938 public String get(Locale locale, String key, String defaultValue) {
939 if (PropsValues.TRANSLATIONS_DISABLED) {
940 return key;
941 }
942
943 if ((locale == null) || (key == null)) {
944 return defaultValue;
945 }
946
947 String value = LanguageResources.getMessage(locale, key);
948
949 if (value != null) {
950 return LanguageResources.fixValue(value);
951 }
952
953 if (value == null) {
954 if ((key.length() > 0) &&
955 (key.charAt(key.length() - 1) == CharPool.CLOSE_BRACKET)) {
956
957 int pos = key.lastIndexOf(CharPool.OPEN_BRACKET);
958
959 if (pos != -1) {
960 key = key.substring(0, pos);
961
962 return get(locale, key, defaultValue);
963 }
964 }
965 }
966
967 return defaultValue;
968 }
969
970
977 @Override
978 public String get(ResourceBundle resourceBundle, String key) {
979 return get(resourceBundle, key, key);
980 }
981
982
992 @Override
993 public String get(
994 ResourceBundle resourceBundle, String key, String defaultValue) {
995
996 String value = _get(resourceBundle, key);
997
998 if (value != null) {
999 return value;
1000 }
1001
1002 return defaultValue;
1003 }
1004
1005
1012 @Override
1013 public Set<Locale> getAvailableLocales() {
1014 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1015
1016 return companyLocalesBag.getAvailableLocales();
1017 }
1018
1019 @Override
1020 public Set<Locale> getAvailableLocales(long groupId) {
1021 if (groupId <= 0) {
1022 return getAvailableLocales();
1023 }
1024
1025 try {
1026 if (isInheritLocales(groupId)) {
1027 return getAvailableLocales();
1028 }
1029 }
1030 catch (Exception e) {
1031 }
1032
1033 Map<String, Locale> groupLanguageIdLocalesMap =
1034 _getGroupLanguageIdLocalesMap(groupId);
1035
1036 return new HashSet<>(groupLanguageIdLocalesMap.values());
1037 }
1038
1039 @Override
1040 public String getBCP47LanguageId(HttpServletRequest request) {
1041 Locale locale = PortalUtil.getLocale(request);
1042
1043 return getBCP47LanguageId(locale);
1044 }
1045
1046 @Override
1047 public String getBCP47LanguageId(Locale locale) {
1048 return LocaleUtil.toBCP47LanguageId(locale);
1049 }
1050
1051 @Override
1052 public String getBCP47LanguageId(PortletRequest portletRequest) {
1053 Locale locale = PortalUtil.getLocale(portletRequest);
1054
1055 return getBCP47LanguageId(locale);
1056 }
1057
1058
1066 @Override
1067 public String getLanguageId(HttpServletRequest request) {
1068 String languageId = ParamUtil.getString(request, "languageId");
1069
1070 if (Validator.isNotNull(languageId)) {
1071 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1072
1073 if (companyLocalesBag.containsLanguageCode(languageId) ||
1074 companyLocalesBag.containsLanguageId(languageId)) {
1075
1076 return languageId;
1077 }
1078 }
1079
1080 Locale locale = PortalUtil.getLocale(request);
1081
1082 return getLanguageId(locale);
1083 }
1084
1085
1093 @Override
1094 public String getLanguageId(Locale locale) {
1095 return LocaleUtil.toLanguageId(locale);
1096 }
1097
1098
1107 @Override
1108 public String getLanguageId(PortletRequest portletRequest) {
1109 HttpServletRequest request = PortalUtil.getHttpServletRequest(
1110 portletRequest);
1111
1112 return getLanguageId(request);
1113 }
1114
1115 @Override
1116 public Locale getLocale(long groupId, String languageCode) {
1117 Map<String, Locale> groupLanguageCodeLocalesMap =
1118 _getGroupLanguageCodeLocalesMap(groupId);
1119
1120 return groupLanguageCodeLocalesMap.get(languageCode);
1121 }
1122
1123
1130 @Override
1131 public Locale getLocale(String languageCode) {
1132 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1133
1134 return companyLocalesBag.getByLanguageCode(languageCode);
1135 }
1136
1137 public ResourceBundleLoader getPortalResourceBundleLoader() {
1138 return LanguageResources.RESOURCE_BUNDLE_LOADER;
1139 }
1140
1141 @Override
1142 public Set<Locale> getSupportedLocales() {
1143 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1144
1145 return companyLocalesBag._supportedLocalesSet;
1146 }
1147
1148
1177 @Override
1178 public String getTimeDescription(
1179 HttpServletRequest request, long milliseconds) {
1180
1181 return getTimeDescription(request, milliseconds, false);
1182 }
1183
1184
1228 @Override
1229 public String getTimeDescription(
1230 HttpServletRequest request, long milliseconds, boolean approximate) {
1231
1232 String description = Time.getDescription(milliseconds, approximate);
1233
1234 String value = null;
1235
1236 try {
1237 int pos = description.indexOf(CharPool.SPACE);
1238
1239 String x = description.substring(0, pos);
1240
1241 value = x.concat(StringPool.SPACE).concat(
1242 get(
1243 request,
1244 StringUtil.toLowerCase(
1245 description.substring(pos + 1, description.length()))));
1246 }
1247 catch (Exception e) {
1248 if (_log.isWarnEnabled()) {
1249 _log.warn(e, e);
1250 }
1251 }
1252
1253 return value;
1254 }
1255
1256
1285 @Override
1286 public String getTimeDescription(
1287 HttpServletRequest request, Long milliseconds) {
1288
1289 return getTimeDescription(request, milliseconds.longValue());
1290 }
1291
1292
1321 @Override
1322 public String getTimeDescription(Locale locale, long milliseconds) {
1323 return getTimeDescription(locale, milliseconds, false);
1324 }
1325
1326
1370 @Override
1371 public String getTimeDescription(
1372 Locale locale, long milliseconds, boolean approximate) {
1373
1374 String description = Time.getDescription(milliseconds, approximate);
1375
1376 String value = null;
1377
1378 try {
1379 int pos = description.indexOf(CharPool.SPACE);
1380
1381 String x = description.substring(0, pos);
1382
1383 value = x.concat(StringPool.SPACE).concat(
1384 get(
1385 locale,
1386 StringUtil.toLowerCase(
1387 description.substring(pos + 1, description.length()))));
1388 }
1389 catch (Exception e) {
1390 if (_log.isWarnEnabled()) {
1391 _log.warn(e, e);
1392 }
1393 }
1394
1395 return value;
1396 }
1397
1398
1427 @Override
1428 public String getTimeDescription(Locale locale, Long milliseconds) {
1429 return getTimeDescription(locale, milliseconds.longValue());
1430 }
1431
1432 @Override
1433 public void init() {
1434 _companyLocalesBags.clear();
1435 }
1436
1437
1447 @Override
1448 public boolean isAvailableLanguageCode(String languageCode) {
1449 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1450
1451 return companyLocalesBag.containsLanguageCode(languageCode);
1452 }
1453
1454
1463 @Override
1464 public boolean isAvailableLocale(Locale locale) {
1465 if (locale == null) {
1466 return false;
1467 }
1468
1469 return isAvailableLocale(LocaleUtil.toLanguageId(locale));
1470 }
1471
1472
1481 @Override
1482 public boolean isAvailableLocale(long groupId, Locale locale) {
1483 if (locale == null) {
1484 return false;
1485 }
1486
1487 return isAvailableLocale(groupId, LocaleUtil.toLanguageId(locale));
1488 }
1489
1490
1499 @Override
1500 public boolean isAvailableLocale(long groupId, String languageId) {
1501 if (groupId <= 0) {
1502 return isAvailableLocale(languageId);
1503 }
1504
1505 try {
1506 if (isInheritLocales(groupId)) {
1507 return isAvailableLocale(languageId);
1508 }
1509 }
1510 catch (Exception e) {
1511 }
1512
1513 Map<String, Locale> groupLanguageIdLocalesMap =
1514 _getGroupLanguageIdLocalesMap(groupId);
1515
1516 return groupLanguageIdLocalesMap.containsKey(languageId);
1517 }
1518
1519
1527 @Override
1528 public boolean isAvailableLocale(String languageId) {
1529 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1530
1531 return companyLocalesBag.containsLanguageId(languageId);
1532 }
1533
1534
1542 @Override
1543 public boolean isBetaLocale(Locale locale) {
1544 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1545
1546 return companyLocalesBag.isBetaLocale(locale);
1547 }
1548
1549 @Override
1550 public boolean isDuplicateLanguageCode(String languageCode) {
1551 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
1552
1553 return companyLocalesBag.isDuplicateLanguageCode(languageCode);
1554 }
1555
1556 @Override
1557 public boolean isInheritLocales(long groupId) throws PortalException {
1558 Group group = GroupLocalServiceUtil.getGroup(groupId);
1559
1560 if (group.isStagingGroup()) {
1561 group = group.getLiveGroup();
1562 }
1563
1564 if (!group.isSite() || group.isCompany()) {
1565 return true;
1566 }
1567
1568 return GetterUtil.getBoolean(
1569 group.getTypeSettingsProperty(
1570 GroupConstants.TYPE_SETTINGS_KEY_INHERIT_LOCALES),
1571 true);
1572 }
1573
1574 @Override
1575 public String process(
1576 ResourceBundle resourceBundle, Locale locale, String content) {
1577
1578 StringBundler sb = new StringBundler();
1579
1580 Matcher matcher = _pattern.matcher(content);
1581
1582 int x = 0;
1583
1584 while (matcher.find()) {
1585 int y = matcher.start(0);
1586
1587 String key = matcher.group(1);
1588
1589 sb.append(content.substring(x, y));
1590 sb.append(StringPool.APOSTROPHE);
1591
1592 String value = get(resourceBundle, key);
1593
1594 sb.append(HtmlUtil.escapeJS(value));
1595 sb.append(StringPool.APOSTROPHE);
1596
1597 x = matcher.end(0);
1598 }
1599
1600 sb.append(content.substring(x));
1601
1602 return sb.toString();
1603 }
1604
1605 @Override
1606 public void resetAvailableGroupLocales(long groupId) {
1607 _resetAvailableGroupLocales(groupId);
1608 }
1609
1610 @Override
1611 public void resetAvailableLocales(long companyId) {
1612 _resetAvailableLocales(companyId);
1613 }
1614
1615 @Override
1616 public void updateCookie(
1617 HttpServletRequest request, HttpServletResponse response,
1618 Locale locale) {
1619
1620 String languageId = LocaleUtil.toLanguageId(locale);
1621
1622 Cookie languageIdCookie = new Cookie(
1623 CookieKeys.GUEST_LANGUAGE_ID, languageId);
1624
1625 languageIdCookie.setPath(StringPool.SLASH);
1626 languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
1627
1628 CookieKeys.addCookie(request, response, languageIdCookie);
1629 }
1630
1631 protected MessageFormat decorateMessageFormat(
1632 HttpServletRequest request, String pattern,
1633 Object[] formattedArguments) {
1634
1635 Locale locale = _getLocale(request);
1636
1637 return decorateMessageFormat(locale, pattern, formattedArguments);
1638 }
1639
1640 protected MessageFormat decorateMessageFormat(
1641 Locale locale, String pattern, Object[] formattedArguments) {
1642
1643 if (locale == null) {
1644 locale = LocaleUtil.getDefault();
1645 }
1646
1647 MessageFormat messageFormat = new MessageFormat(pattern, locale);
1648
1649 for (int i = 0; i < formattedArguments.length; i++) {
1650 Object formattedArgument = formattedArguments[i];
1651
1652 if (formattedArgument instanceof Number) {
1653 messageFormat.setFormat(i, NumberFormat.getInstance(locale));
1654 }
1655 }
1656
1657 return messageFormat;
1658 }
1659
1660 private static CompanyLocalesBag _getCompanyLocalesBag() {
1661 Long companyId = CompanyThreadLocal.getCompanyId();
1662
1663 CompanyLocalesBag companyLocalesBag = _companyLocalesBags.get(
1664 companyId);
1665
1666 if (companyLocalesBag == null) {
1667 companyLocalesBag = new CompanyLocalesBag(companyId);
1668
1669 _companyLocalesBags.put(companyId, companyLocalesBag);
1670 }
1671
1672 return companyLocalesBag;
1673 }
1674
1675 private ObjectValuePair<Map<String, Locale>, Map<String, Locale>>
1676 _createGroupLocales(long groupId) {
1677
1678 String[] languageIds = PropsValues.LOCALES_ENABLED;
1679
1680 try {
1681 Group group = GroupLocalServiceUtil.getGroup(groupId);
1682
1683 UnicodeProperties typeSettingsProperties =
1684 group.getTypeSettingsProperties();
1685
1686 languageIds = StringUtil.split(
1687 typeSettingsProperties.getProperty(PropsKeys.LOCALES));
1688 }
1689 catch (Exception e) {
1690 }
1691
1692 Map<String, Locale> groupLanguageCodeLocalesMap = new HashMap<>();
1693 Map<String, Locale> groupLanguageIdLocalesMap = new HashMap<>();
1694
1695 for (String languageId : languageIds) {
1696 Locale locale = LocaleUtil.fromLanguageId(languageId, false);
1697
1698 String languageCode = languageId;
1699
1700 int pos = languageId.indexOf(CharPool.UNDERLINE);
1701
1702 if (pos > 0) {
1703 languageCode = languageId.substring(0, pos);
1704 }
1705
1706 if (!groupLanguageCodeLocalesMap.containsKey(languageCode)) {
1707 groupLanguageCodeLocalesMap.put(languageCode, locale);
1708 }
1709
1710 groupLanguageIdLocalesMap.put(languageId, locale);
1711 }
1712
1713 _groupLanguageCodeLocalesMapMap.put(
1714 groupId, groupLanguageCodeLocalesMap);
1715 _groupLanguageIdLocalesMap.put(groupId, groupLanguageIdLocalesMap);
1716
1717 return new ObjectValuePair<>(
1718 groupLanguageCodeLocalesMap, groupLanguageIdLocalesMap);
1719 }
1720
1721 private String _escapePattern(String pattern) {
1722 return StringUtil.replace(
1723 pattern, StringPool.APOSTROPHE, StringPool.DOUBLE_APOSTROPHE);
1724 }
1725
1726 private String _get(ResourceBundle resourceBundle, String key) {
1727 if (PropsValues.TRANSLATIONS_DISABLED) {
1728 return key;
1729 }
1730
1731 if ((resourceBundle == null) || (key == null)) {
1732 return null;
1733 }
1734
1735 String value = ResourceBundleUtil.getString(resourceBundle, key);
1736
1737 if (value != null) {
1738 return LanguageResources.fixValue(value);
1739 }
1740
1741 if ((key.length() > 0) &&
1742 (key.charAt(key.length() - 1) == CharPool.CLOSE_BRACKET)) {
1743
1744 int pos = key.lastIndexOf(CharPool.OPEN_BRACKET);
1745
1746 if (pos != -1) {
1747 key = key.substring(0, pos);
1748
1749 return _get(resourceBundle, key);
1750 }
1751 }
1752
1753 return null;
1754 }
1755
1756 private Map<String, Locale> _getGroupLanguageCodeLocalesMap(long groupId) {
1757 Map<String, Locale> groupLanguageCodeLocalesMap =
1758 _groupLanguageCodeLocalesMapMap.get(groupId);
1759
1760 if (groupLanguageCodeLocalesMap == null) {
1761 ObjectValuePair<Map<String, Locale>, Map<String, Locale>>
1762 objectValuePair = _createGroupLocales(groupId);
1763
1764 groupLanguageCodeLocalesMap = objectValuePair.getKey();
1765 }
1766
1767 return groupLanguageCodeLocalesMap;
1768 }
1769
1770 private Map<String, Locale> _getGroupLanguageIdLocalesMap(long groupId) {
1771 Map<String, Locale> groupLanguageIdLocalesMap =
1772 _groupLanguageIdLocalesMap.get(groupId);
1773
1774 if (groupLanguageIdLocalesMap == null) {
1775 ObjectValuePair<Map<String, Locale>, Map<String, Locale>>
1776 objectValuePair = _createGroupLocales(groupId);
1777
1778 groupLanguageIdLocalesMap = objectValuePair.getValue();
1779 }
1780
1781 return groupLanguageIdLocalesMap;
1782 }
1783
1784 private Locale _getLocale(HttpServletRequest request) {
1785 Locale locale = null;
1786
1787 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
1788 WebKeys.THEME_DISPLAY);
1789
1790 if (themeDisplay != null) {
1791 locale = themeDisplay.getLocale();
1792 }
1793 else {
1794 locale = request.getLocale();
1795
1796 if (!isAvailableLocale(locale)) {
1797 locale = LocaleUtil.getDefault();
1798 }
1799 }
1800
1801 return locale;
1802 }
1803
1804 private void _resetAvailableGroupLocales(long groupId) {
1805 _groupLanguageCodeLocalesMapMap.remove(groupId);
1806 _groupLanguageIdLocalesMap.remove(groupId);
1807 }
1808
1809 private void _resetAvailableLocales(long companyId) {
1810 _portalCache.remove(companyId);
1811 }
1812
1813 private static final Log _log = LogFactoryUtil.getLog(LanguageImpl.class);
1814
1815 private static final Map<Long, CompanyLocalesBag> _companyLocalesBags =
1816 new ConcurrentHashMap<>();
1817 private static final Pattern _pattern = Pattern.compile(
1818 "Liferay\\.Language\\.get\\([\"']([^)]+)[\"']\\)");
1819 private static PortalCache<Long, Serializable> _portalCache;
1820
1821 private final Map<Long, Map<String, Locale>>
1822 _groupLanguageCodeLocalesMapMap = new ConcurrentHashMap<>();
1823 private final Map<Long, Map<String, Locale>> _groupLanguageIdLocalesMap =
1824 new ConcurrentHashMap<>();
1825
1826 private static class CompanyLocalesBag implements Serializable {
1827
1828 public boolean containsLanguageCode(String languageCode) {
1829 return _languageCodeLocalesMap.containsKey(languageCode);
1830 }
1831
1832 public boolean containsLanguageId(String languageId) {
1833 return _languageIdLocalesMap.containsKey(languageId);
1834 }
1835
1836 public Set<Locale> getAvailableLocales() {
1837 return new HashSet<>(_languageIdLocalesMap.values());
1838 }
1839
1840 public Locale getByLanguageCode(String languageCode) {
1841 return _languageCodeLocalesMap.get(languageCode);
1842 }
1843
1844 public boolean isBetaLocale(Locale locale) {
1845 return _localesBetaSet.contains(locale);
1846 }
1847
1848 public boolean isDuplicateLanguageCode(String languageCode) {
1849 return _duplicateLanguageCodes.contains(languageCode);
1850 }
1851
1852 private CompanyLocalesBag(long companyId) {
1853 String[] languageIds = PropsValues.LOCALES;
1854
1855 if (companyId != CompanyConstants.SYSTEM) {
1856 try {
1857 languageIds = PrefsPropsUtil.getStringArray(
1858 companyId, PropsKeys.LOCALES, StringPool.COMMA,
1859 PropsValues.LOCALES_ENABLED);
1860 }
1861 catch (SystemException se) {
1862 languageIds = PropsValues.LOCALES_ENABLED;
1863 }
1864 }
1865
1866 for (String languageId : languageIds) {
1867 Locale locale = LocaleUtil.fromLanguageId(languageId, false);
1868
1869 String languageCode = languageId;
1870
1871 int pos = languageId.indexOf(CharPool.UNDERLINE);
1872
1873 if (pos > 0) {
1874 languageCode = languageId.substring(0, pos);
1875 }
1876
1877 if (_languageCodeLocalesMap.containsKey(languageCode)) {
1878 _duplicateLanguageCodes.add(languageCode);
1879 }
1880 else {
1881 _languageCodeLocalesMap.put(languageCode, locale);
1882 }
1883
1884 _languageIdLocalesMap.put(languageId, locale);
1885 }
1886
1887 for (String languageId : PropsValues.LOCALES_BETA) {
1888 _localesBetaSet.add(
1889 LocaleUtil.fromLanguageId(languageId, false));
1890 }
1891
1892 _supportedLocalesSet = new HashSet<>(
1893 _languageIdLocalesMap.values());
1894
1895 _supportedLocalesSet.removeAll(_localesBetaSet);
1896 }
1897
1898 private final Set<String> _duplicateLanguageCodes = new HashSet<>();
1899 private final Map<String, Locale> _languageCodeLocalesMap =
1900 new HashMap<>();
1901 private final Map<String, Locale> _languageIdLocalesMap =
1902 new HashMap<>();
1903 private final Set<Locale> _localesBetaSet = new HashSet<>();
1904 private final Set<Locale> _supportedLocalesSet;
1905
1906 }
1907
1908 }