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