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