001
014
015 package com.liferay.portal.language;
016
017 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
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.security.pacl.DoPrivileged;
028 import com.liferay.portal.kernel.util.ArrayUtil;
029 import com.liferay.portal.kernel.util.CharPool;
030 import com.liferay.portal.kernel.util.CookieKeys;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.HtmlUtil;
033 import com.liferay.portal.kernel.util.JavaConstants;
034 import com.liferay.portal.kernel.util.LocaleUtil;
035 import com.liferay.portal.kernel.util.ObjectValuePair;
036 import com.liferay.portal.kernel.util.ParamUtil;
037 import com.liferay.portal.kernel.util.PropsKeys;
038 import com.liferay.portal.kernel.util.ResourceBundleUtil;
039 import com.liferay.portal.kernel.util.StringBundler;
040 import com.liferay.portal.kernel.util.StringPool;
041 import com.liferay.portal.kernel.util.StringUtil;
042 import com.liferay.portal.kernel.util.Time;
043 import com.liferay.portal.kernel.util.UnicodeProperties;
044 import com.liferay.portal.kernel.util.Validator;
045 import com.liferay.portal.model.CompanyConstants;
046 import com.liferay.portal.model.Group;
047 import com.liferay.portal.model.GroupConstants;
048 import com.liferay.portal.security.auth.CompanyThreadLocal;
049 import com.liferay.portal.service.GroupLocalServiceUtil;
050 import com.liferay.portal.theme.ThemeDisplay;
051 import com.liferay.portal.util.PortalUtil;
052 import com.liferay.portal.util.PrefsPropsUtil;
053 import com.liferay.portal.util.PropsValues;
054 import com.liferay.portal.util.WebKeys;
055
056 import java.io.Serializable;
057
058 import java.text.MessageFormat;
059
060 import java.util.HashMap;
061 import java.util.HashSet;
062 import java.util.List;
063 import java.util.Locale;
064 import java.util.Map;
065 import java.util.ResourceBundle;
066 import java.util.Set;
067 import java.util.concurrent.ConcurrentHashMap;
068 import java.util.regex.Matcher;
069 import java.util.regex.Pattern;
070
071 import javax.portlet.PortletConfig;
072 import javax.portlet.PortletRequest;
073
074 import javax.servlet.http.Cookie;
075 import javax.servlet.http.HttpServletRequest;
076 import javax.servlet.http.HttpServletResponse;
077
078
083 @DoPrivileged
084 public class LanguageImpl implements Language, Serializable {
085
086 @Override
087 public String format(
088 HttpServletRequest request, String pattern, LanguageWrapper argument) {
089
090 return format(request, pattern, new LanguageWrapper[] {argument}, true);
091 }
092
093 @Override
094 public String format(
095 HttpServletRequest request, String pattern, LanguageWrapper argument,
096 boolean translateArguments) {
097
098 return format(
099 request, pattern, new LanguageWrapper[] {argument},
100 translateArguments);
101 }
102
103 @Override
104 public String format(
105 HttpServletRequest request, String pattern,
106 LanguageWrapper[] arguments) {
107
108 return format(request, pattern, arguments, true);
109 }
110
111 @Override
112 public String format(
113 HttpServletRequest request, String pattern, LanguageWrapper[] arguments,
114 boolean translateArguments) {
115
116 if (PropsValues.TRANSLATIONS_DISABLED) {
117 return pattern;
118 }
119
120 String value = null;
121
122 try {
123 pattern = get(request, pattern);
124
125 if (ArrayUtil.isNotEmpty(arguments)) {
126 pattern = _escapePattern(pattern);
127
128 Object[] formattedArguments = new Object[arguments.length];
129
130 for (int i = 0; i < arguments.length; i++) {
131 if (translateArguments) {
132 formattedArguments[i] =
133 arguments[i].getBefore() +
134 get(request, arguments[i].getText()) +
135 arguments[i].getAfter();
136 }
137 else {
138 formattedArguments[i] =
139 arguments[i].getBefore() +
140 arguments[i].getText() +
141 arguments[i].getAfter();
142 }
143 }
144
145 value = MessageFormat.format(pattern, formattedArguments);
146 }
147 else {
148 value = pattern;
149 }
150 }
151 catch (Exception e) {
152 if (_log.isWarnEnabled()) {
153 _log.warn(e, e);
154 }
155 }
156
157 return value;
158 }
159
160 @Override
161 public String format(
162 HttpServletRequest request, String pattern, Object argument) {
163
164 return format(request, pattern, new Object[] {argument}, true);
165 }
166
167 @Override
168 public String format(
169 HttpServletRequest request, String pattern, Object argument,
170 boolean translateArguments) {
171
172 return format(
173 request, pattern, new Object[] {argument}, translateArguments);
174 }
175
176 @Override
177 public String format(
178 HttpServletRequest request, String pattern, Object[] arguments) {
179
180 return format(request, pattern, arguments, true);
181 }
182
183 @Override
184 public String format(
185 HttpServletRequest request, String pattern, Object[] arguments,
186 boolean translateArguments) {
187
188 if (PropsValues.TRANSLATIONS_DISABLED) {
189 return pattern;
190 }
191
192 String value = null;
193
194 try {
195 pattern = get(request, pattern);
196
197 if (ArrayUtil.isNotEmpty(arguments)) {
198 pattern = _escapePattern(pattern);
199
200 Object[] formattedArguments = new Object[arguments.length];
201
202 for (int i = 0; i < arguments.length; i++) {
203 if (translateArguments) {
204 formattedArguments[i] = get(
205 request, arguments[i].toString());
206 }
207 else {
208 formattedArguments[i] = arguments[i];
209 }
210 }
211
212 value = MessageFormat.format(pattern, formattedArguments);
213 }
214 else {
215 value = pattern;
216 }
217 }
218 catch (Exception e) {
219 if (_log.isWarnEnabled()) {
220 _log.warn(e, e);
221 }
222 }
223
224 return value;
225 }
226
227 @Override
228 public String format(
229 Locale locale, String pattern, List<Object> arguments) {
230
231 return format(locale, pattern, arguments.toArray(), true);
232 }
233
234 @Override
235 public String format(Locale locale, String pattern, Object argument) {
236 return format(locale, pattern, new Object[] {argument}, true);
237 }
238
239 @Override
240 public String format(
241 Locale locale, String pattern, Object argument,
242 boolean translateArguments) {
243
244 return format(
245 locale, pattern, new Object[] {argument}, translateArguments);
246 }
247
248 @Override
249 public String format(Locale locale, String pattern, Object[] arguments) {
250 return format(locale, pattern, arguments, true);
251 }
252
253 @Override
254 public String format(
255 Locale locale, String pattern, Object[] arguments,
256 boolean translateArguments) {
257
258 if (PropsValues.TRANSLATIONS_DISABLED) {
259 return pattern;
260 }
261
262 String value = null;
263
264 try {
265 pattern = get(locale, pattern);
266
267 if (ArrayUtil.isNotEmpty(arguments)) {
268 pattern = _escapePattern(pattern);
269
270 Object[] formattedArguments = new Object[arguments.length];
271
272 for (int i = 0; i < arguments.length; i++) {
273 if (translateArguments) {
274 formattedArguments[i] = get(
275 locale, arguments[i].toString());
276 }
277 else {
278 formattedArguments[i] = arguments[i];
279 }
280 }
281
282 value = MessageFormat.format(pattern, formattedArguments);
283 }
284 else {
285 value = pattern;
286 }
287 }
288 catch (Exception e) {
289 if (_log.isWarnEnabled()) {
290 _log.warn(e, e);
291 }
292 }
293
294 return value;
295 }
296
297 @Override
298 public String format(
299 ResourceBundle resourceBundle, String pattern, Object argument) {
300
301 return format(resourceBundle, pattern, new Object[] {argument}, true);
302 }
303
304 @Override
305 public String format(
306 ResourceBundle resourceBundle, String pattern, Object argument,
307 boolean translateArguments) {
308
309 return format(
310 resourceBundle, pattern, new Object[] {argument},
311 translateArguments);
312 }
313
314 @Override
315 public String format(
316 ResourceBundle resourceBundle, String pattern, Object[] arguments) {
317
318 return format(resourceBundle, pattern, arguments, true);
319 }
320
321 @Override
322 public String format(
323 ResourceBundle resourceBundle, String pattern, Object[] arguments,
324 boolean translateArguments) {
325
326 if (PropsValues.TRANSLATIONS_DISABLED) {
327 return pattern;
328 }
329
330 String value = null;
331
332 try {
333 pattern = get(resourceBundle, pattern);
334
335 if (ArrayUtil.isNotEmpty(arguments)) {
336 pattern = _escapePattern(pattern);
337
338 Object[] formattedArguments = new Object[arguments.length];
339
340 for (int i = 0; i < arguments.length; i++) {
341 if (translateArguments) {
342 formattedArguments[i] = get(
343 resourceBundle, arguments[i].toString());
344 }
345 else {
346 formattedArguments[i] = arguments[i];
347 }
348 }
349
350 value = MessageFormat.format(pattern, formattedArguments);
351 }
352 else {
353 value = pattern;
354 }
355 }
356 catch (Exception e) {
357 if (_log.isWarnEnabled()) {
358 _log.warn(e, e);
359 }
360 }
361
362 return value;
363 }
364
365 @Override
366 public String get(
367 HttpServletRequest request, ResourceBundle resourceBundle, String key) {
368
369 return get(request, resourceBundle, key, key);
370 }
371
372 @Override
373 public String get(
374 HttpServletRequest request, ResourceBundle resourceBundle, String key,
375 String defaultValue) {
376
377 String value = _get(resourceBundle, key);
378
379 if (value != null) {
380 return value;
381 }
382
383 return get(request, key, defaultValue);
384 }
385
386 @Override
387 public String get(HttpServletRequest request, String key) {
388 return get(request, key, key);
389 }
390
391 @Override
392 public String get(
393 HttpServletRequest request, String key, String defaultValue) {
394
395 if ((request == null) || (key == null)) {
396 return defaultValue;
397 }
398
399 PortletConfig portletConfig = (PortletConfig)request.getAttribute(
400 JavaConstants.JAVAX_PORTLET_CONFIG);
401
402 Locale locale = _getLocale(request);
403
404 if (portletConfig == null) {
405 return get(locale, key, defaultValue);
406 }
407
408 ResourceBundle resourceBundle = portletConfig.getResourceBundle(locale);
409
410 if (resourceBundle.containsKey(key)) {
411 return _get(resourceBundle, key);
412 }
413
414 return get(locale, key, defaultValue);
415 }
416
417 @Override
418 public String get(Locale locale, String key) {
419 return get(locale, key, key);
420 }
421
422 @Override
423 public String get(Locale locale, String key, String defaultValue) {
424 if (PropsValues.TRANSLATIONS_DISABLED) {
425 return key;
426 }
427
428 if ((locale == null) || (key == null)) {
429 return defaultValue;
430 }
431
432 String value = LanguageResources.getMessage(locale, key);
433
434 if (value != null) {
435 return LanguageResources.fixValue(value);
436 }
437
438 if (value == null) {
439 if ((key.length() > 0) &&
440 (key.charAt(key.length() - 1) == CharPool.CLOSE_BRACKET)) {
441
442 int pos = key.lastIndexOf(CharPool.OPEN_BRACKET);
443
444 if (pos != -1) {
445 key = key.substring(0, pos);
446
447 return get(locale, key, defaultValue);
448 }
449 }
450 }
451
452 return defaultValue;
453 }
454
455 @Override
456 public String get(ResourceBundle resourceBundle, String key) {
457 return get(resourceBundle, key, key);
458 }
459
460 @Override
461 public String get(
462 ResourceBundle resourceBundle, String key, String defaultValue) {
463
464 String value = _get(resourceBundle, key);
465
466 if (value != null) {
467 return value;
468 }
469
470 return defaultValue;
471 }
472
473 @Override
474 public Set<Locale> getAvailableLocales() {
475 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
476
477 return companyLocalesBag.getAvailableLocales();
478 }
479
480 @Override
481 public Set<Locale> getAvailableLocales(long groupId) {
482 if (groupId <= 0) {
483 return getAvailableLocales();
484 }
485
486 try {
487 if (isInheritLocales(groupId)) {
488 return getAvailableLocales();
489 }
490 }
491 catch (Exception e) {
492 }
493
494 Map<String, Locale> groupLanguageIdLocalesMap =
495 _getGroupLanguageIdLocalesMap(groupId);
496
497 return new HashSet<>(groupLanguageIdLocalesMap.values());
498 }
499
500 @Override
501 public String getBCP47LanguageId(HttpServletRequest request) {
502 Locale locale = PortalUtil.getLocale(request);
503
504 return getBCP47LanguageId(locale);
505 }
506
507 @Override
508 public String getBCP47LanguageId(Locale locale) {
509 return LocaleUtil.toBCP47LanguageId(locale);
510 }
511
512 @Override
513 public String getBCP47LanguageId(PortletRequest portletRequest) {
514 Locale locale = PortalUtil.getLocale(portletRequest);
515
516 return getBCP47LanguageId(locale);
517 }
518
519 @Override
520 public String getLanguageId(HttpServletRequest request) {
521 String languageId = ParamUtil.getString(request, "languageId");
522
523 if (Validator.isNotNull(languageId)) {
524 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
525
526 if (companyLocalesBag.containsLanguageCode(languageId) ||
527 companyLocalesBag.containsLanguageId(languageId)) {
528
529 return languageId;
530 }
531 }
532
533 Locale locale = PortalUtil.getLocale(request);
534
535 return getLanguageId(locale);
536 }
537
538 @Override
539 public String getLanguageId(Locale locale) {
540 return LocaleUtil.toLanguageId(locale);
541 }
542
543 @Override
544 public String getLanguageId(PortletRequest portletRequest) {
545 HttpServletRequest request = PortalUtil.getHttpServletRequest(
546 portletRequest);
547
548 return getLanguageId(request);
549 }
550
551 @Override
552 public Locale getLocale(long groupId, String languageCode) {
553 Map<String, Locale> groupLanguageCodeLocalesMap =
554 _getGroupLanguageCodeLocalesMap(groupId);
555
556 return groupLanguageCodeLocalesMap.get(languageCode);
557 }
558
559 @Override
560 public Locale getLocale(String languageCode) {
561 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
562
563 return companyLocalesBag.getByLanguageCode(languageCode);
564 }
565
566 @Override
567 public Set<Locale> getSupportedLocales() {
568 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
569
570 return companyLocalesBag._supportedLocalesSet;
571 }
572
573 @Override
574 public String getTimeDescription(
575 HttpServletRequest request, long milliseconds) {
576
577 return getTimeDescription(request, milliseconds, false);
578 }
579
580 @Override
581 public String getTimeDescription(
582 HttpServletRequest request, long milliseconds, boolean approximate) {
583
584 String description = Time.getDescription(milliseconds, approximate);
585
586 String value = null;
587
588 try {
589 int pos = description.indexOf(CharPool.SPACE);
590
591 String x = description.substring(0, pos);
592
593 value = x.concat(StringPool.SPACE).concat(
594 get(
595 request,
596 StringUtil.toLowerCase(
597 description.substring(pos + 1, description.length()))));
598 }
599 catch (Exception e) {
600 if (_log.isWarnEnabled()) {
601 _log.warn(e, e);
602 }
603 }
604
605 return value;
606 }
607
608 @Override
609 public String getTimeDescription(
610 HttpServletRequest request, Long milliseconds) {
611
612 return getTimeDescription(request, milliseconds.longValue());
613 }
614
615 @Override
616 public String getTimeDescription(Locale locale, long milliseconds) {
617 return getTimeDescription(locale, milliseconds, false);
618 }
619
620 @Override
621 public String getTimeDescription(
622 Locale locale, long milliseconds, boolean approximate) {
623
624 String description = Time.getDescription(milliseconds, approximate);
625
626 String value = null;
627
628 try {
629 int pos = description.indexOf(CharPool.SPACE);
630
631 String x = description.substring(0, pos);
632
633 value = x.concat(StringPool.SPACE).concat(
634 get(
635 locale,
636 StringUtil.toLowerCase(
637 description.substring(pos + 1, description.length()))));
638 }
639 catch (Exception e) {
640 if (_log.isWarnEnabled()) {
641 _log.warn(e, e);
642 }
643 }
644
645 return value;
646 }
647
648 @Override
649 public String getTimeDescription(Locale locale, Long milliseconds) {
650 return getTimeDescription(locale, milliseconds.longValue());
651 }
652
653 @Override
654 public void init() {
655 _companyLocalesBags.clear();
656 }
657
658 @Override
659 public boolean isAvailableLanguageCode(String languageCode) {
660 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
661
662 return companyLocalesBag.containsLanguageCode(languageCode);
663 }
664
665 @Override
666 public boolean isAvailableLocale(Locale locale) {
667 return isAvailableLocale(LocaleUtil.toLanguageId(locale));
668 }
669
670 @Override
671 public boolean isAvailableLocale(long groupId, Locale locale) {
672 return isAvailableLocale(groupId, LocaleUtil.toLanguageId(locale));
673 }
674
675 @Override
676 public boolean isAvailableLocale(long groupId, String languageId) {
677 if (groupId <= 0) {
678 return isAvailableLocale(languageId);
679 }
680
681 try {
682 if (isInheritLocales(groupId)) {
683 return isAvailableLocale(languageId);
684 }
685 }
686 catch (Exception e) {
687 }
688
689 Map<String, Locale> groupLanguageIdLocalesMap =
690 _getGroupLanguageIdLocalesMap(groupId);
691
692 return groupLanguageIdLocalesMap.containsKey(languageId);
693 }
694
695 @Override
696 public boolean isAvailableLocale(String languageId) {
697 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
698
699 return companyLocalesBag.containsLanguageId(languageId);
700 }
701
702 @Override
703 public boolean isBetaLocale(Locale locale) {
704 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
705
706 return companyLocalesBag.isBetaLocale(locale);
707 }
708
709 @Override
710 public boolean isDuplicateLanguageCode(String languageCode) {
711 CompanyLocalesBag companyLocalesBag = _getCompanyLocalesBag();
712
713 return companyLocalesBag.isDuplicateLanguageCode(languageCode);
714 }
715
716 @Override
717 public boolean isInheritLocales(long groupId) throws PortalException {
718 Group group = GroupLocalServiceUtil.getGroup(groupId);
719
720 if (group.isStagingGroup()) {
721 group = group.getLiveGroup();
722 }
723
724 if (!group.isSite() || group.isCompany()) {
725 return true;
726 }
727
728 return GetterUtil.getBoolean(
729 group.getTypeSettingsProperty(
730 GroupConstants.TYPE_SETTINGS_KEY_INHERIT_LOCALES),
731 true);
732 }
733
734 @Override
735 public String process(
736 ResourceBundle resourceBundle, Locale locale, String content) {
737
738 StringBundler sb = new StringBundler();
739
740 Matcher matcher = _pattern.matcher(content);
741
742 int x = 0;
743
744 while (matcher.find()) {
745 int y = matcher.start(0);
746
747 String key = matcher.group(1);
748
749 sb.append(content.substring(x, y));
750 sb.append(StringPool.APOSTROPHE);
751
752 String value = get(resourceBundle, key);
753
754 sb.append(HtmlUtil.escapeJS(value));
755 sb.append(StringPool.APOSTROPHE);
756
757 x = matcher.end(0);
758 }
759
760 sb.append(content.substring(x));
761
762 return sb.toString();
763 }
764
765 @Override
766 public void resetAvailableGroupLocales(long groupId) {
767 _resetAvailableGroupLocales(groupId);
768 }
769
770 @Override
771 public void resetAvailableLocales(long companyId) {
772 _resetAvailableLocales(companyId);
773 }
774
775 @Override
776 public void updateCookie(
777 HttpServletRequest request, HttpServletResponse response,
778 Locale locale) {
779
780 String languageId = LocaleUtil.toLanguageId(locale);
781
782 Cookie languageIdCookie = new Cookie(
783 CookieKeys.GUEST_LANGUAGE_ID, languageId);
784
785 languageIdCookie.setPath(StringPool.SLASH);
786 languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
787
788 CookieKeys.addCookie(request, response, languageIdCookie);
789 }
790
791 private static CompanyLocalesBag _getCompanyLocalesBag() {
792 Long companyId = CompanyThreadLocal.getCompanyId();
793
794 CompanyLocalesBag companyLocalesBag = _companyLocalesBags.get(
795 companyId);
796
797 if (companyLocalesBag == null) {
798 companyLocalesBag = new CompanyLocalesBag(companyId);
799
800 _companyLocalesBags.put(companyId, companyLocalesBag);
801 }
802
803 return companyLocalesBag;
804 }
805
806 private ObjectValuePair<Map<String, Locale>, Map<String, Locale>>
807 _createGroupLocales(long groupId) {
808
809 String[] languageIds = PropsValues.LOCALES_ENABLED;
810
811 try {
812 Group group = GroupLocalServiceUtil.getGroup(groupId);
813
814 UnicodeProperties typeSettingsProperties =
815 group.getTypeSettingsProperties();
816
817 languageIds = StringUtil.split(
818 typeSettingsProperties.getProperty(PropsKeys.LOCALES));
819 }
820 catch (Exception e) {
821 }
822
823 Map<String, Locale> groupLanguageCodeLocalesMap = new HashMap<>();
824 Map<String, Locale> groupLanguageIdLocalesMap = new HashMap<>();
825
826 for (String languageId : languageIds) {
827 Locale locale = LocaleUtil.fromLanguageId(languageId, false);
828
829 String languageCode = languageId;
830
831 int pos = languageId.indexOf(CharPool.UNDERLINE);
832
833 if (pos > 0) {
834 languageCode = languageId.substring(0, pos);
835 }
836
837 if (!groupLanguageCodeLocalesMap.containsKey(languageCode)) {
838 groupLanguageCodeLocalesMap.put(languageCode, locale);
839 }
840
841 groupLanguageIdLocalesMap.put(languageId, locale);
842 }
843
844 _groupLanguageCodeLocalesMapMap.put(
845 groupId, groupLanguageCodeLocalesMap);
846 _groupLanguageIdLocalesMap.put(groupId, groupLanguageIdLocalesMap);
847
848 return new ObjectValuePair<>(
849 groupLanguageCodeLocalesMap, groupLanguageIdLocalesMap);
850 }
851
852 private String _escapePattern(String pattern) {
853 return StringUtil.replace(
854 pattern, StringPool.APOSTROPHE, StringPool.DOUBLE_APOSTROPHE);
855 }
856
857 private String _get(ResourceBundle resourceBundle, String key) {
858 if (PropsValues.TRANSLATIONS_DISABLED) {
859 return key;
860 }
861
862 if ((resourceBundle == null) || (key == null)) {
863 return null;
864 }
865
866 String value = ResourceBundleUtil.getString(resourceBundle, key);
867
868 if (value != null) {
869 return LanguageResources.fixValue(value);
870 }
871
872 if ((key.length() > 0) &&
873 (key.charAt(key.length() - 1) == CharPool.CLOSE_BRACKET)) {
874
875 int pos = key.lastIndexOf(CharPool.OPEN_BRACKET);
876
877 if (pos != -1) {
878 key = key.substring(0, pos);
879
880 return _get(resourceBundle, key);
881 }
882 }
883
884 return null;
885 }
886
887 private Map<String, Locale> _getGroupLanguageCodeLocalesMap(long groupId) {
888 Map<String, Locale> groupLanguageCodeLocalesMap =
889 _groupLanguageCodeLocalesMapMap.get(groupId);
890
891 if (groupLanguageCodeLocalesMap == null) {
892 ObjectValuePair<Map<String, Locale>, Map<String, Locale>>
893 objectValuePair = _createGroupLocales(groupId);
894
895 groupLanguageCodeLocalesMap = objectValuePair.getKey();
896 }
897
898 return groupLanguageCodeLocalesMap;
899 }
900
901 private Map<String, Locale> _getGroupLanguageIdLocalesMap(long groupId) {
902 Map<String, Locale> groupLanguageIdLocalesMap =
903 _groupLanguageIdLocalesMap.get(groupId);
904
905 if (groupLanguageIdLocalesMap == null) {
906 ObjectValuePair<Map<String, Locale>, Map<String, Locale>>
907 objectValuePair = _createGroupLocales(groupId);
908
909 groupLanguageIdLocalesMap = objectValuePair.getValue();
910 }
911
912 return groupLanguageIdLocalesMap;
913 }
914
915 private Locale _getLocale(HttpServletRequest request) {
916 Locale locale = null;
917
918 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
919 WebKeys.THEME_DISPLAY);
920
921 if (themeDisplay != null) {
922 locale = themeDisplay.getLocale();
923 }
924 else {
925 locale = request.getLocale();
926
927 if (!isAvailableLocale(locale)) {
928 locale = LocaleUtil.getDefault();
929 }
930 }
931
932 return locale;
933 }
934
935 private void _resetAvailableGroupLocales(long groupId) {
936 _groupLanguageCodeLocalesMapMap.remove(groupId);
937 _groupLanguageIdLocalesMap.remove(groupId);
938 }
939
940 private void _resetAvailableLocales(long companyId) {
941 _portalCache.remove(companyId);
942 }
943
944 private static final Log _log = LogFactoryUtil.getLog(LanguageImpl.class);
945
946 private static final Map<Long, CompanyLocalesBag> _companyLocalesBags =
947 new ConcurrentHashMap<>();
948 private static final Pattern _pattern = Pattern.compile(
949 "Liferay\\.Language\\.get\\([\"']([^)]+)[\"']\\)");
950 private static final PortalCache<Long, Serializable> _portalCache =
951 MultiVMPoolUtil.getCache(LanguageImpl.class.getName());
952
953 static {
954 PortalCacheMapSynchronizeUtil.<Long, Serializable>synchronize(
955 _portalCache, _companyLocalesBags,
956 new Synchronizer<Long, Serializable>() {
957
958 @Override
959 public void onSynchronize(
960 Map<? extends Long, ? extends Serializable> map, Long key,
961 Serializable value, int timeToLive) {
962
963 _companyLocalesBags.remove(key);
964 }
965
966 });
967 }
968
969 private final Map<Long, Map<String, Locale>>
970 _groupLanguageCodeLocalesMapMap = new ConcurrentHashMap<>();
971 private final Map<Long, Map<String, Locale>> _groupLanguageIdLocalesMap =
972 new ConcurrentHashMap<>();
973
974 private static class CompanyLocalesBag implements Serializable {
975
976 public boolean containsLanguageCode(String languageCode) {
977 return _languageCodeLocalesMap.containsKey(languageCode);
978 }
979
980 public boolean containsLanguageId(String languageId) {
981 return _languageIdLocalesMap.containsKey(languageId);
982 }
983
984 public Set<Locale> getAvailableLocales() {
985 return new HashSet<>(_languageIdLocalesMap.values());
986 }
987
988 public Locale getByLanguageCode(String languageCode) {
989 return _languageCodeLocalesMap.get(languageCode);
990 }
991
992 public boolean isBetaLocale(Locale locale) {
993 return _localesBetaSet.contains(locale);
994 }
995
996 public boolean isDuplicateLanguageCode(String languageCode) {
997 return _duplicateLanguageCodes.contains(languageCode);
998 }
999
1000 private CompanyLocalesBag(long companyId) {
1001 String[] languageIds = PropsValues.LOCALES;
1002
1003 if (companyId != CompanyConstants.SYSTEM) {
1004 try {
1005 languageIds = PrefsPropsUtil.getStringArray(
1006 companyId, PropsKeys.LOCALES, StringPool.COMMA,
1007 PropsValues.LOCALES_ENABLED);
1008 }
1009 catch (SystemException se) {
1010 languageIds = PropsValues.LOCALES_ENABLED;
1011 }
1012 }
1013
1014 for (String languageId : languageIds) {
1015 Locale locale = LocaleUtil.fromLanguageId(languageId, false);
1016
1017 String languageCode = languageId;
1018
1019 int pos = languageId.indexOf(CharPool.UNDERLINE);
1020
1021 if (pos > 0) {
1022 languageCode = languageId.substring(0, pos);
1023 }
1024
1025 if (_languageCodeLocalesMap.containsKey(languageCode)) {
1026 _duplicateLanguageCodes.add(languageCode);
1027 }
1028 else {
1029 _languageCodeLocalesMap.put(languageCode, locale);
1030 }
1031
1032 _languageIdLocalesMap.put(languageId, locale);
1033 }
1034
1035 for (String languageId : PropsValues.LOCALES_BETA) {
1036 _localesBetaSet.add(
1037 LocaleUtil.fromLanguageId(languageId, false));
1038 }
1039
1040 _supportedLocalesSet = new HashSet<>(
1041 _languageIdLocalesMap.values());
1042
1043 _supportedLocalesSet.removeAll(_localesBetaSet);
1044 }
1045
1046 private final Set<String> _duplicateLanguageCodes = new HashSet<>();
1047 private final Map<String, Locale> _languageCodeLocalesMap =
1048 new HashMap<>();
1049 private final Map<String, Locale> _languageIdLocalesMap =
1050 new HashMap<>();
1051 private final Set<Locale> _localesBetaSet = new HashSet<>();
1052 private final Set<Locale> _supportedLocalesSet;
1053
1054 }
1055
1056 }