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