001
014
015 package com.liferay.portal.util;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
019 import com.liferay.portal.kernel.json.JSONObject;
020 import com.liferay.portal.kernel.language.LanguageUtil;
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.settings.LocalizedValuesMap;
025 import com.liferay.portal.kernel.settings.Settings;
026 import com.liferay.portal.kernel.util.ArrayUtil;
027 import com.liferay.portal.kernel.util.ClassLoaderUtil;
028 import com.liferay.portal.kernel.util.LocaleUtil;
029 import com.liferay.portal.kernel.util.Localization;
030 import com.liferay.portal.kernel.util.ParamUtil;
031 import com.liferay.portal.kernel.util.PrefsParamUtil;
032 import com.liferay.portal.kernel.util.ResourceBundleUtil;
033 import com.liferay.portal.kernel.util.StringBundler;
034 import com.liferay.portal.kernel.util.StringPool;
035 import com.liferay.portal.kernel.util.StringUtil;
036 import com.liferay.portal.kernel.util.Tuple;
037 import com.liferay.portal.kernel.util.Validator;
038 import com.liferay.portal.kernel.xml.Document;
039 import com.liferay.portal.kernel.xml.Element;
040 import com.liferay.portal.language.LanguageResources;
041 import com.liferay.portal.security.xml.SecureXMLFactoryProviderUtil;
042 import com.liferay.util.ContentUtil;
043
044 import java.util.HashMap;
045 import java.util.Locale;
046 import java.util.Map;
047 import java.util.ResourceBundle;
048 import java.util.Set;
049
050 import javax.portlet.PortletPreferences;
051 import javax.portlet.PortletRequest;
052
053 import javax.servlet.http.HttpServletRequest;
054
055 import javax.xml.stream.XMLInputFactory;
056 import javax.xml.stream.XMLOutputFactory;
057 import javax.xml.stream.XMLStreamConstants;
058 import javax.xml.stream.XMLStreamException;
059 import javax.xml.stream.XMLStreamReader;
060 import javax.xml.stream.XMLStreamWriter;
061
062 import org.apache.commons.collections.map.ReferenceMap;
063
064
072 @DoPrivileged
073 public class LocalizationImpl implements Localization {
074
075 @Override
076 public Object deserialize(JSONObject jsonObject) {
077 Map<Locale, String> map = new HashMap<>();
078
079 for (Locale locale : LanguageUtil.getAvailableLocales()) {
080 String languageId = LocaleUtil.toLanguageId(locale);
081
082 String value = jsonObject.getString(languageId);
083
084 if (Validator.isNotNull(value)) {
085 map.put(locale, value);
086 }
087 }
088
089 return map;
090 }
091
092 @Override
093 public String[] getAvailableLanguageIds(Document document) {
094 String attributeValue = _getRootAttributeValue(
095 document, _AVAILABLE_LOCALES, StringPool.BLANK);
096
097 return StringUtil.split(attributeValue);
098 }
099
100 @Override
101 public String[] getAvailableLanguageIds(String xml) {
102 String attributeValue = _getRootAttributeValue(
103 xml, _AVAILABLE_LOCALES, StringPool.BLANK);
104
105 return StringUtil.split(attributeValue);
106 }
107
108 @Override
109 public Locale getDefaultImportLocale(
110 String className, long classPK, Locale contentDefaultLocale,
111 Locale[] contentAvailableLocales) {
112
113 if (LanguageUtil.isAvailableLocale(contentDefaultLocale)) {
114 return contentDefaultLocale;
115 }
116
117 Locale defaultLocale = LocaleUtil.getSiteDefault();
118
119 if (ArrayUtil.contains(contentAvailableLocales, defaultLocale)) {
120 return defaultLocale;
121 }
122
123 for (Locale contentAvailableLocale : contentAvailableLocales) {
124 if (LanguageUtil.isAvailableLocale(contentAvailableLocale)) {
125 return contentAvailableLocale;
126 }
127 }
128
129 if (_log.isWarnEnabled()) {
130 StringBundler sb = new StringBundler(9);
131
132 sb.append("Language ");
133 sb.append(LocaleUtil.toLanguageId(contentDefaultLocale));
134 sb.append(" is missing for ");
135 sb.append(className);
136 sb.append(" with primary key ");
137 sb.append(classPK);
138 sb.append(". Setting default language to ");
139 sb.append(LocaleUtil.toLanguageId(defaultLocale));
140 sb.append(".");
141
142 _log.warn(sb.toString());
143 }
144
145 return defaultLocale;
146 }
147
148 @Override
149 public String getDefaultLanguageId(Document document) {
150 return getDefaultLanguageId(document, LocaleUtil.getSiteDefault());
151 }
152
153 @Override
154 public String getDefaultLanguageId(
155 Document document, Locale defaultLocale) {
156
157 String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
158
159 return _getRootAttributeValue(
160 document, _DEFAULT_LOCALE, defaultLanguageId);
161 }
162
163 @Override
164 public String getDefaultLanguageId(String xml) {
165 return getDefaultLanguageId(xml, LocaleUtil.getSiteDefault());
166 }
167
168 @Override
169 public String getDefaultLanguageId(String xml, Locale defaultLocale) {
170 String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
171
172 return _getRootAttributeValue(xml, _DEFAULT_LOCALE, defaultLanguageId);
173 }
174
175 @Override
176 public String getLocalization(String xml, String requestedLanguageId) {
177 return getLocalization(xml, requestedLanguageId, true);
178 }
179
180 @Override
181 public String getLocalization(
182 String xml, String requestedLanguageId, boolean useDefault) {
183
184 return getLocalization(
185 xml, requestedLanguageId, useDefault, StringPool.BLANK);
186 }
187
188 @Override
189 public String getLocalization(
190 String xml, String requestedLanguageId, boolean useDefault,
191 String defaultValue) {
192
193 String systemDefaultLanguageId = LocaleUtil.toLanguageId(
194 LocaleUtil.getSiteDefault());
195
196 if (!Validator.isXml(xml)) {
197 if (useDefault ||
198 requestedLanguageId.equals(systemDefaultLanguageId)) {
199
200 return xml;
201 }
202 else {
203 return defaultValue;
204 }
205 }
206
207 String value = _getCachedValue(xml, requestedLanguageId, useDefault);
208
209 if (value != null) {
210 return value;
211 }
212
213 String priorityLanguageId = null;
214
215 Locale requestedLocale = LocaleUtil.fromLanguageId(requestedLanguageId);
216
217 if (useDefault &&
218 LanguageUtil.isDuplicateLanguageCode(
219 requestedLocale.getLanguage())) {
220
221 Locale priorityLocale = LanguageUtil.getLocale(
222 requestedLocale.getLanguage());
223
224 if (!requestedLanguageId.equals(priorityLanguageId)) {
225 priorityLanguageId = LocaleUtil.toLanguageId(priorityLocale);
226 }
227 }
228
229 XMLStreamReader xmlStreamReader = null;
230
231 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
232
233 ClassLoader contextClassLoader =
234 ClassLoaderUtil.getContextClassLoader();
235
236 try {
237 if (contextClassLoader != portalClassLoader) {
238 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
239 }
240
241 XMLInputFactory xmlInputFactory =
242 SecureXMLFactoryProviderUtil.newXMLInputFactory();
243
244 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
245 new UnsyncStringReader(xml));
246
247 String defaultLanguageId = StringPool.BLANK;
248
249
250
251 if (xmlStreamReader.hasNext()) {
252 xmlStreamReader.nextTag();
253
254 defaultLanguageId = xmlStreamReader.getAttributeValue(
255 null, _DEFAULT_LOCALE);
256
257 if (Validator.isNull(defaultLanguageId)) {
258 defaultLanguageId = systemDefaultLanguageId;
259 }
260 }
261
262
263
264 String priorityValue = null;
265 String defaultLocalizationValue = null;
266
267 while (xmlStreamReader.hasNext()) {
268 int event = xmlStreamReader.next();
269
270 if (event == XMLStreamConstants.START_ELEMENT) {
271 String languageId = xmlStreamReader.getAttributeValue(
272 null, _LANGUAGE_ID);
273
274 if (Validator.isNull(languageId)) {
275 languageId = defaultLanguageId;
276 }
277
278 if (languageId.equals(defaultLanguageId) ||
279 languageId.equals(priorityLanguageId) ||
280 languageId.equals(requestedLanguageId)) {
281
282 String text = xmlStreamReader.getElementText();
283
284 if (languageId.equals(defaultLanguageId)) {
285 defaultLocalizationValue = text;
286 }
287
288 if (languageId.equals(priorityLanguageId)) {
289 priorityValue = text;
290 }
291
292 if (languageId.equals(requestedLanguageId)) {
293 value = text;
294 }
295
296 if (Validator.isNotNull(value)) {
297 break;
298 }
299 }
300 }
301 else if (event == XMLStreamConstants.END_DOCUMENT) {
302 break;
303 }
304 }
305
306 if (useDefault && Validator.isNotNull(priorityLanguageId) &&
307 Validator.isNull(value) && Validator.isNotNull(priorityValue)) {
308
309 value = priorityValue;
310 }
311
312 if (useDefault && Validator.isNull(value)) {
313 value = defaultLocalizationValue;
314 }
315
316 if (Validator.isNull(value)) {
317 value = defaultValue;
318 }
319 }
320 catch (Exception e) {
321 if (_log.isWarnEnabled()) {
322 _log.warn(e, e);
323 }
324 }
325 finally {
326 if (contextClassLoader != portalClassLoader) {
327 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
328 }
329
330 if (xmlStreamReader != null) {
331 try {
332 xmlStreamReader.close();
333 }
334 catch (Exception e) {
335 }
336 }
337 }
338
339 _setCachedValue(xml, requestedLanguageId, useDefault, value);
340
341 return value;
342 }
343
344 @Override
345 public Map<Locale, String> getLocalizationMap(
346 HttpServletRequest request, String parameter) {
347
348 Map<Locale, String> map = new HashMap<>();
349
350 for (Locale locale : LanguageUtil.getAvailableLocales()) {
351 String localizedParameter = getLocalizedName(
352 parameter, LocaleUtil.toLanguageId(locale));
353
354 map.put(locale, ParamUtil.getString(request, localizedParameter));
355 }
356
357 return map;
358 }
359
360 @Override
361 public Map<Locale, String> getLocalizationMap(
362 PortletPreferences preferences, String preferenceName) {
363
364 return getLocalizationMap(preferences, preferenceName, null);
365 }
366
367 @Override
368 public Map<Locale, String> getLocalizationMap(
369 PortletPreferences preferences, String preferenceName,
370 String propertyName) {
371
372 String defaultPropertyValue = null;
373
374 if (propertyName != null) {
375 defaultPropertyValue = PropsUtil.get(propertyName);
376 }
377
378 return getLocalizationMap(
379 preferences, preferenceName, propertyName, defaultPropertyValue,
380 getClass().getClassLoader());
381 }
382
383 @Override
384 public Map<Locale, String> getLocalizationMap(
385 PortletPreferences preferences, String preferenceName,
386 String propertyName, String defaultPropertyValue,
387 ClassLoader classLoader) {
388
389 Map<Locale, String> map = new HashMap<>();
390
391 for (Locale locale : LanguageUtil.getAvailableLocales()) {
392 String localizedPreference = getLocalizedName(
393 preferenceName, LocaleUtil.toLanguageId(locale));
394
395 map.put(
396 locale,
397 preferences.getValue(localizedPreference, StringPool.BLANK));
398 }
399
400 if (Validator.isNull(propertyName)) {
401 return map;
402 }
403
404 Locale defaultLocale = LocaleUtil.getSiteDefault();
405
406 String defaultValue = map.get(defaultLocale);
407
408 if (Validator.isNotNull(defaultValue)) {
409 return map;
410 }
411
412 map.put(
413 defaultLocale, ContentUtil.get(classLoader, defaultPropertyValue));
414
415 return map;
416 }
417
418 @Override
419 public Map<Locale, String> getLocalizationMap(
420 PortletRequest portletRequest, String parameter) {
421
422 return getLocalizationMap(
423 portletRequest, parameter, new HashMap<Locale, String>());
424 }
425
426 @Override
427 public Map<Locale, String> getLocalizationMap(
428 PortletRequest portletRequest, String parameter,
429 Map<Locale, String> defaultValues) {
430
431 Map<Locale, String> map = new HashMap<>();
432
433 for (Locale locale : LanguageUtil.getAvailableLocales()) {
434 String localizedParameter = getLocalizedName(
435 parameter, LocaleUtil.toLanguageId(locale));
436
437 map.put(
438 locale,
439 ParamUtil.getString(
440 portletRequest, localizedParameter,
441 defaultValues.get(locale)));
442 }
443
444 return map;
445 }
446
447 @Override
448 public Map<Locale, String> getLocalizationMap(String xml) {
449 return getLocalizationMap(xml, false);
450 }
451
452 @Override
453 public Map<Locale, String> getLocalizationMap(
454 String xml, boolean useDefault) {
455
456 Map<Locale, String> map = new HashMap<>();
457
458 for (Locale locale : LanguageUtil.getAvailableLocales()) {
459 String languageId = LocaleUtil.toLanguageId(locale);
460
461 String value = getLocalization(xml, languageId, useDefault);
462
463 if (Validator.isNotNull(value)) {
464 map.put(locale, value);
465 }
466 }
467
468 return map;
469 }
470
471 @Override
472 public Map<Locale, String> getLocalizationMap(
473 String bundleName, ClassLoader classLoader, String key,
474 boolean includeBetaLocales) {
475
476 if (key == null) {
477 return null;
478 }
479
480 Map<Locale, String> map = new HashMap<>();
481
482 Locale defaultLocale = LocaleUtil.getSiteDefault();
483
484 String defaultValue = _getLocalization(
485 bundleName, defaultLocale, classLoader, key, key);
486
487 map.put(defaultLocale, defaultValue);
488
489 Set<Locale> locales = null;
490
491 if (includeBetaLocales) {
492 locales = LanguageUtil.getAvailableLocales();
493 }
494 else {
495 locales = LanguageUtil.getSupportedLocales();
496 }
497
498 for (Locale locale : locales) {
499 if (locale.equals(defaultLocale)) {
500 continue;
501 }
502
503 String value = _getLocalization(
504 bundleName, locale, classLoader, key, null);
505
506 if (Validator.isNotNull(value) && !value.equals(defaultValue)) {
507 map.put(locale, value);
508 }
509 }
510
511 return map;
512 }
513
514 @Override
515 public Map<Locale, String> getLocalizationMap(
516 String[] languageIds, String[] values) {
517
518 Map<Locale, String> map = new HashMap<>();
519
520 for (int i = 0; i < values.length; i++) {
521 Locale locale = LocaleUtil.fromLanguageId(languageIds[i]);
522
523 map.put(locale, values[i]);
524 }
525
526 return map;
527 }
528
529 @Override
530 public String getLocalizationXmlFromPreferences(
531 PortletPreferences preferences, PortletRequest portletRequest,
532 String parameter) {
533
534 return getLocalizationXmlFromPreferences(
535 preferences, portletRequest, parameter, null, null);
536 }
537
538 @Override
539 public String getLocalizationXmlFromPreferences(
540 PortletPreferences preferences, PortletRequest portletRequest,
541 String parameter, String defaultValue) {
542
543 return getLocalizationXmlFromPreferences(
544 preferences, portletRequest, parameter, defaultValue, null);
545 }
546
547 @Override
548 public String getLocalizationXmlFromPreferences(
549 PortletPreferences preferences, PortletRequest portletRequest,
550 String parameter, String prefix, String defaultValue) {
551
552 String xml = null;
553
554 Locale defaultLocale = LocaleUtil.getSiteDefault();
555 String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
556
557 for (Locale locale : LanguageUtil.getAvailableLocales()) {
558 String languageId = LocaleUtil.toLanguageId(locale);
559
560 String localizedKey = getLocalizedName(parameter, languageId);
561
562 String prefixedLocalizedKey = localizedKey;
563
564 if (Validator.isNotNull(prefix)) {
565 prefixedLocalizedKey = prefix + "--" + localizedKey + "--";
566 }
567
568 String value = ParamUtil.getString(
569 portletRequest, prefixedLocalizedKey,
570 preferences.getValue(localizedKey, null));
571
572 if (value != null) {
573 xml = updateLocalization(xml, parameter, value, languageId);
574 }
575 }
576
577 if (getLocalization(xml, defaultLanguageId, true, null) == null) {
578 String oldValue = PrefsParamUtil.getString(
579 preferences, portletRequest, parameter, defaultValue);
580
581 if (Validator.isNotNull(oldValue)) {
582 xml = updateLocalization(xml, parameter, oldValue);
583 }
584 }
585
586 return xml;
587 }
588
589 @Override
590 public String getLocalizedName(String name, String languageId) {
591 return name.concat(StringPool.UNDERLINE).concat(languageId);
592 }
593
594
597 @Deprecated
598 @Override
599 public Map<Locale, String> getLocalizedParameter(
600 PortletRequest portletRequest, String parameter) {
601
602 return getLocalizationMap(portletRequest, parameter);
603 }
604
605 @Override
606 public Map<Locale, String> getMap(LocalizedValuesMap localizedValuesMap) {
607 Map<Locale, String> map = localizedValuesMap.getValues();
608
609 Locale locale = LocaleUtil.getDefault();
610
611 if (map.get(locale) == null) {
612 map.put(locale, localizedValuesMap.getDefaultValue());
613 }
614
615 return map;
616 }
617
618
621 @Deprecated
622 @Override
623 public String getPreferencesKey(String key, String languageId) {
624 String defaultLanguageId = LocaleUtil.toLanguageId(
625 LocaleUtil.getSiteDefault());
626
627 if (!languageId.equals(defaultLanguageId)) {
628 key = getLocalizedName(key, languageId);
629 }
630
631 return key;
632 }
633
634 @Override
635 public String getPreferencesValue(
636 PortletPreferences preferences, String key, String languageId) {
637
638 return getPreferencesValue(preferences, key, languageId, true);
639 }
640
641 @Override
642 public String getPreferencesValue(
643 PortletPreferences preferences, String key, String languageId,
644 boolean useDefault) {
645
646 String localizedKey = getLocalizedName(key, languageId);
647
648 String value = preferences.getValue(localizedKey, StringPool.BLANK);
649
650 if (useDefault && Validator.isNull(value)) {
651 value = preferences.getValue(
652 _getDefaultLocalizedName(key), StringPool.BLANK);
653
654 if (Validator.isNull(value)) {
655 value = preferences.getValue(key, StringPool.BLANK);
656 }
657 }
658
659 return value;
660 }
661
662 @Override
663 public String[] getPreferencesValues(
664 PortletPreferences preferences, String key, String languageId) {
665
666 return getPreferencesValues(preferences, key, languageId, true);
667 }
668
669 @Override
670 public String[] getPreferencesValues(
671 PortletPreferences preferences, String key, String languageId,
672 boolean useDefault) {
673
674 String localizedKey = getLocalizedName(key, languageId);
675
676 String[] values = preferences.getValues(localizedKey, new String[0]);
677
678 if (useDefault && ArrayUtil.isEmpty(values)) {
679 values = preferences.getValues(
680 _getDefaultLocalizedName(key), new String[0]);
681
682 if (ArrayUtil.isEmpty(values)) {
683 values = preferences.getValues(key, new String[0]);
684 }
685 }
686
687 return values;
688 }
689
690 @Override
691 public String getSettingsValue(
692 Settings settings, String key, String languageId) {
693
694 return getSettingsValue(settings, key, languageId, true);
695 }
696
697 @Override
698 public String getSettingsValue(
699 Settings settings, String key, String languageId, boolean useDefault) {
700
701 String localizedKey = getLocalizedName(key, languageId);
702
703 String value = settings.getValue(localizedKey, StringPool.BLANK);
704
705 if (useDefault && Validator.isNull(value)) {
706 value = settings.getValue(
707 _getDefaultLocalizedName(key), StringPool.BLANK);
708
709 if (Validator.isNull(value)) {
710 value = settings.getValue(key, StringPool.BLANK);
711 }
712 }
713
714 return value;
715 }
716
717 @Override
718 public String[] getSettingsValues(
719 Settings settings, String key, String languageId) {
720
721 return getSettingsValues(settings, key, languageId, true);
722 }
723
724 @Override
725 public String[] getSettingsValues(
726 Settings settings, String key, String languageId, boolean useDefault) {
727
728 String localizedKey = getLocalizedName(key, languageId);
729
730 String[] values = settings.getValues(localizedKey, new String[0]);
731
732 if (useDefault && ArrayUtil.isEmpty(values)) {
733 values = settings.getValues(
734 _getDefaultLocalizedName(key), new String[0]);
735
736 if (ArrayUtil.isEmpty(values)) {
737 values = settings.getValues(key, new String[0]);
738 }
739 }
740
741 return values;
742 }
743
744 @Override
745 public String getXml(LocalizedValuesMap localizedValuesMap, String key) {
746 XMLStreamWriter xmlStreamWriter = null;
747
748 try {
749 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
750
751 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
752
753 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
754 unsyncStringWriter);
755
756 xmlStreamWriter.writeStartDocument();
757
758 xmlStreamWriter.writeStartElement("root");
759
760 Set<Locale> availableLocales = LanguageUtil.getAvailableLocales();
761
762 xmlStreamWriter.writeAttribute(
763 "available-locales", StringUtil.merge(availableLocales));
764
765 Locale defaultLocale = LocaleUtil.getSiteDefault();
766
767 xmlStreamWriter.writeAttribute(
768 "default-locale", defaultLocale.toString());
769
770 for (Locale locale : availableLocales) {
771 String value = localizedValuesMap.get(locale);
772
773 if (value != null) {
774 xmlStreamWriter.writeStartElement(key);
775
776 xmlStreamWriter.writeAttribute(
777 "language-id", locale.toString());
778
779 xmlStreamWriter.writeCharacters(value);
780
781 xmlStreamWriter.writeEndElement();
782 }
783 }
784
785 xmlStreamWriter.writeEndElement();
786
787 xmlStreamWriter.writeEndDocument();
788
789 return unsyncStringWriter.toString();
790 }
791 catch (XMLStreamException xmlse) {
792 throw new RuntimeException(xmlse);
793 }
794 finally {
795 _close(xmlStreamWriter);
796 }
797 }
798
799 @Override
800 public String removeLocalization(
801 String xml, String key, String requestedLanguageId) {
802
803 return removeLocalization(xml, key, requestedLanguageId, false);
804 }
805
806 @Override
807 public String removeLocalization(
808 String xml, String key, String requestedLanguageId, boolean cdata) {
809
810 return removeLocalization(xml, key, requestedLanguageId, cdata, true);
811 }
812
813 @Override
814 public String removeLocalization(
815 String xml, String key, String requestedLanguageId, boolean cdata,
816 boolean localized) {
817
818 if (Validator.isNull(xml)) {
819 return StringPool.BLANK;
820 }
821
822 if (!Validator.isXml(xml)) {
823 return xml;
824 }
825
826 xml = _sanitizeXML(xml);
827
828 String systemDefaultLanguageId = LocaleUtil.toLanguageId(
829 LocaleUtil.getSiteDefault());
830
831 XMLStreamReader xmlStreamReader = null;
832 XMLStreamWriter xmlStreamWriter = null;
833
834 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
835
836 ClassLoader contextClassLoader =
837 ClassLoaderUtil.getContextClassLoader();
838
839 try {
840 if (contextClassLoader != portalClassLoader) {
841 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
842 }
843
844 XMLInputFactory xmlInputFactory =
845 SecureXMLFactoryProviderUtil.newXMLInputFactory();
846
847 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
848 new UnsyncStringReader(xml));
849
850 String availableLocales = StringPool.BLANK;
851 String defaultLanguageId = StringPool.BLANK;
852
853
854
855 if (xmlStreamReader.hasNext()) {
856 xmlStreamReader.nextTag();
857
858 availableLocales = xmlStreamReader.getAttributeValue(
859 null, _AVAILABLE_LOCALES);
860 defaultLanguageId = xmlStreamReader.getAttributeValue(
861 null, _DEFAULT_LOCALE);
862
863 if (Validator.isNull(defaultLanguageId)) {
864 defaultLanguageId = systemDefaultLanguageId;
865 }
866 }
867
868 if ((availableLocales != null) &&
869 availableLocales.contains(requestedLanguageId)) {
870
871 availableLocales = StringUtil.removeFromList(
872 availableLocales, requestedLanguageId);
873
874 UnsyncStringWriter unsyncStringWriter =
875 new UnsyncStringWriter();
876
877 XMLOutputFactory xmlOutputFactory =
878 XMLOutputFactory.newInstance();
879
880 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
881 unsyncStringWriter);
882
883 xmlStreamWriter.writeStartDocument();
884 xmlStreamWriter.writeStartElement(_ROOT);
885
886 if (localized) {
887 xmlStreamWriter.writeAttribute(
888 _AVAILABLE_LOCALES, availableLocales);
889 xmlStreamWriter.writeAttribute(
890 _DEFAULT_LOCALE, defaultLanguageId);
891 }
892
893 _copyNonExempt(
894 xmlStreamReader, xmlStreamWriter, requestedLanguageId,
895 defaultLanguageId, cdata);
896
897 xmlStreamWriter.writeEndElement();
898 xmlStreamWriter.writeEndDocument();
899
900 xmlStreamWriter.close();
901 xmlStreamWriter = null;
902
903 xml = unsyncStringWriter.toString();
904 }
905 }
906 catch (Exception e) {
907 if (_log.isWarnEnabled()) {
908 _log.warn(e, e);
909 }
910 }
911 finally {
912 if (contextClassLoader != portalClassLoader) {
913 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
914 }
915
916 if (xmlStreamReader != null) {
917 try {
918 xmlStreamReader.close();
919 }
920 catch (Exception e) {
921 }
922 }
923
924 if (xmlStreamWriter != null) {
925 try {
926 xmlStreamWriter.close();
927 }
928 catch (Exception e) {
929 }
930 }
931 }
932
933 return xml;
934 }
935
936 @Override
937 public void setLocalizedPreferencesValues(
938 PortletRequest portletRequest, PortletPreferences preferences,
939 String parameter)
940 throws Exception {
941
942 Map<Locale, String> map = getLocalizationMap(portletRequest, parameter);
943
944 for (Map.Entry<Locale, String> entry : map.entrySet()) {
945 String languageId = LocaleUtil.toLanguageId(entry.getKey());
946 String value = entry.getValue();
947
948 setPreferencesValue(preferences, parameter, languageId, value);
949 }
950 }
951
952 @Override
953 public void setPreferencesValue(
954 PortletPreferences preferences, String key, String languageId,
955 String value)
956 throws Exception {
957
958 preferences.setValue(getLocalizedName(key, languageId), value);
959 }
960
961 @Override
962 public void setPreferencesValues(
963 PortletPreferences preferences, String key, String languageId,
964 String[] values)
965 throws Exception {
966
967 preferences.setValues(getLocalizedName(key, languageId), values);
968 }
969
970 @Override
971 public String updateLocalization(
972 Map<Locale, String> localizationMap, String xml, String key,
973 String defaultLanguageId) {
974
975 for (Locale locale : LanguageUtil.getAvailableLocales()) {
976 String value = localizationMap.get(locale);
977
978 String languageId = LocaleUtil.toLanguageId(locale);
979
980 if (Validator.isNotNull(value)) {
981 xml = updateLocalization(
982 xml, key, value, languageId, defaultLanguageId);
983 }
984 else {
985 xml = removeLocalization(xml, key, languageId);
986 }
987 }
988
989 return xml;
990 }
991
992 @Override
993 public String updateLocalization(String xml, String key, String value) {
994 String defaultLanguageId = LocaleUtil.toLanguageId(
995 LocaleUtil.getSiteDefault());
996
997 return updateLocalization(
998 xml, key, value, defaultLanguageId, defaultLanguageId);
999 }
1000
1001 @Override
1002 public String updateLocalization(
1003 String xml, String key, String value, String requestedLanguageId) {
1004
1005 String defaultLanguageId = LocaleUtil.toLanguageId(
1006 LocaleUtil.getSiteDefault());
1007
1008 return updateLocalization(
1009 xml, key, value, requestedLanguageId, defaultLanguageId);
1010 }
1011
1012 @Override
1013 public String updateLocalization(
1014 String xml, String key, String value, String requestedLanguageId,
1015 String defaultLanguageId) {
1016
1017 return updateLocalization(
1018 xml, key, value, requestedLanguageId, defaultLanguageId, false);
1019 }
1020
1021 @Override
1022 public String updateLocalization(
1023 String xml, String key, String value, String requestedLanguageId,
1024 String defaultLanguageId, boolean cdata) {
1025
1026 return updateLocalization(
1027 xml, key, value, requestedLanguageId, defaultLanguageId, cdata,
1028 true);
1029 }
1030
1031 @Override
1032 public String updateLocalization(
1033 String xml, String key, String value, String requestedLanguageId,
1034 String defaultLanguageId, boolean cdata, boolean localized) {
1035
1036 xml = _sanitizeXML(xml);
1037
1038 XMLStreamReader xmlStreamReader = null;
1039 XMLStreamWriter xmlStreamWriter = null;
1040
1041 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
1042
1043 ClassLoader contextClassLoader =
1044 ClassLoaderUtil.getContextClassLoader();
1045
1046 try {
1047 if (contextClassLoader != portalClassLoader) {
1048 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
1049 }
1050
1051 XMLInputFactory xmlInputFactory =
1052 SecureXMLFactoryProviderUtil.newXMLInputFactory();
1053
1054 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
1055 new UnsyncStringReader(xml));
1056
1057 String availableLocales = StringPool.BLANK;
1058
1059
1060
1061 if (xmlStreamReader.hasNext()) {
1062 xmlStreamReader.nextTag();
1063
1064 availableLocales = xmlStreamReader.getAttributeValue(
1065 null, _AVAILABLE_LOCALES);
1066
1067 if (Validator.isNull(availableLocales)) {
1068 availableLocales = defaultLanguageId;
1069 }
1070
1071 if (!availableLocales.contains(requestedLanguageId)) {
1072 availableLocales = StringUtil.add(
1073 availableLocales, requestedLanguageId,
1074 StringPool.COMMA);
1075 }
1076 }
1077
1078 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
1079
1080 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
1081
1082 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
1083 unsyncStringWriter);
1084
1085 xmlStreamWriter.writeStartDocument();
1086 xmlStreamWriter.writeStartElement(_ROOT);
1087
1088 if (localized) {
1089 xmlStreamWriter.writeAttribute(
1090 _AVAILABLE_LOCALES, availableLocales);
1091 xmlStreamWriter.writeAttribute(
1092 _DEFAULT_LOCALE, defaultLanguageId);
1093 }
1094
1095 _copyNonExempt(
1096 xmlStreamReader, xmlStreamWriter, requestedLanguageId,
1097 defaultLanguageId, cdata);
1098
1099 xmlStreamWriter.writeStartElement(key);
1100
1101 if (localized) {
1102 xmlStreamWriter.writeAttribute(
1103 _LANGUAGE_ID, requestedLanguageId);
1104 }
1105
1106 if (cdata) {
1107 xmlStreamWriter.writeCData(value);
1108 }
1109 else {
1110 xmlStreamWriter.writeCharacters(value);
1111 }
1112
1113 xmlStreamWriter.writeEndElement();
1114 xmlStreamWriter.writeEndElement();
1115 xmlStreamWriter.writeEndDocument();
1116
1117 xmlStreamWriter.close();
1118 xmlStreamWriter = null;
1119
1120 xml = unsyncStringWriter.toString();
1121 }
1122 catch (Exception e) {
1123 if (_log.isWarnEnabled()) {
1124 _log.warn(e, e);
1125 }
1126 }
1127 finally {
1128 if (contextClassLoader != portalClassLoader) {
1129 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
1130 }
1131
1132 if (xmlStreamReader != null) {
1133 try {
1134 xmlStreamReader.close();
1135 }
1136 catch (Exception e) {
1137 }
1138 }
1139
1140 if (xmlStreamWriter != null) {
1141 try {
1142 xmlStreamWriter.close();
1143 }
1144 catch (Exception e) {
1145 }
1146 }
1147 }
1148
1149 return xml;
1150 }
1151
1152 private void _close(XMLStreamWriter xmlStreamWriter) {
1153 if (xmlStreamWriter != null) {
1154 try {
1155 xmlStreamWriter.close();
1156 }
1157 catch (XMLStreamException xmlse) {
1158 }
1159 }
1160 }
1161
1162 private void _copyNonExempt(
1163 XMLStreamReader xmlStreamReader, XMLStreamWriter xmlStreamWriter,
1164 String exemptLanguageId, String defaultLanguageId, boolean cdata)
1165 throws XMLStreamException {
1166
1167 while (xmlStreamReader.hasNext()) {
1168 int event = xmlStreamReader.next();
1169
1170 if (event == XMLStreamConstants.START_ELEMENT) {
1171 String languageId = xmlStreamReader.getAttributeValue(
1172 null, _LANGUAGE_ID);
1173
1174 if (Validator.isNull(languageId)) {
1175 languageId = defaultLanguageId;
1176 }
1177
1178 if (!languageId.equals(exemptLanguageId)) {
1179 xmlStreamWriter.writeStartElement(
1180 xmlStreamReader.getLocalName());
1181 xmlStreamWriter.writeAttribute(_LANGUAGE_ID, languageId);
1182
1183 String text = xmlStreamReader.getElementText();
1184
1185 if (cdata) {
1186 xmlStreamWriter.writeCData(text);
1187 }
1188 else {
1189 xmlStreamWriter.writeCharacters(text);
1190 }
1191
1192 xmlStreamWriter.writeEndElement();
1193 }
1194 }
1195 else if (event == XMLStreamConstants.END_DOCUMENT) {
1196 break;
1197 }
1198 }
1199 }
1200
1201 private String _getCachedValue(
1202 String xml, String requestedLanguageId, boolean useDefault) {
1203
1204 String value = null;
1205
1206 Map<Tuple, String> valueMap = _cache.get(xml);
1207
1208 if (valueMap != null) {
1209 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
1210
1211 value = valueMap.get(subkey);
1212 }
1213
1214 return value;
1215 }
1216
1217 private String _getDefaultLocalizedName(String name) {
1218 String defaultLanguageId = LocaleUtil.toLanguageId(
1219 LocaleUtil.getSiteDefault());
1220
1221 return getLocalizedName(name, defaultLanguageId);
1222 }
1223
1224 private String _getLocalization(
1225 String bundleName, Locale locale, ClassLoader classLoader, String key,
1226 String defaultValue) {
1227
1228 ResourceBundle resourceBundle = ResourceBundleUtil.getBundle(
1229 bundleName, locale, classLoader);
1230
1231 String value = null;
1232
1233 if (resourceBundle.containsKey(key)) {
1234 try {
1235 value = ResourceBundleUtil.getString(resourceBundle, key);
1236
1237 value = new String(
1238 value.getBytes(StringPool.ISO_8859_1), StringPool.UTF8);
1239 }
1240 catch (Exception e) {
1241 }
1242 }
1243
1244 if (Validator.isNotNull(value)) {
1245 value = LanguageResources.fixValue(value);
1246 }
1247 else {
1248 value = LanguageUtil.get(locale, key, defaultValue);
1249 }
1250
1251 return value;
1252 }
1253
1254 private String _getRootAttributeValue(
1255 Document document, String name, String defaultValue) {
1256
1257 Element rootElement = document.getRootElement();
1258
1259 return rootElement.attributeValue(name, defaultValue);
1260 }
1261
1262 private String _getRootAttributeValue(
1263 String xml, String name, String defaultValue) {
1264
1265 String value = null;
1266
1267 XMLStreamReader xmlStreamReader = null;
1268
1269 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
1270
1271 ClassLoader contextClassLoader =
1272 ClassLoaderUtil.getContextClassLoader();
1273
1274 try {
1275 if (contextClassLoader != portalClassLoader) {
1276 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
1277 }
1278
1279 XMLInputFactory xmlInputFactory =
1280 SecureXMLFactoryProviderUtil.newXMLInputFactory();
1281
1282 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
1283 new UnsyncStringReader(xml));
1284
1285 if (xmlStreamReader.hasNext()) {
1286 xmlStreamReader.nextTag();
1287
1288 value = xmlStreamReader.getAttributeValue(null, name);
1289 }
1290 }
1291 catch (Exception e) {
1292 if (_log.isWarnEnabled()) {
1293 _log.warn(e, e);
1294 }
1295 }
1296 finally {
1297 if (contextClassLoader != portalClassLoader) {
1298 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
1299 }
1300
1301 if (xmlStreamReader != null) {
1302 try {
1303 xmlStreamReader.close();
1304 }
1305 catch (Exception e) {
1306 }
1307 }
1308 }
1309
1310 if (Validator.isNull(value)) {
1311 value = defaultValue;
1312 }
1313
1314 return value;
1315 }
1316
1317 private String _sanitizeXML(String xml) {
1318 if (Validator.isNull(xml) || !xml.contains("<root")) {
1319 xml = _EMPTY_ROOT_NODE;
1320 }
1321
1322 return xml;
1323 }
1324
1325 private void _setCachedValue(
1326 String xml, String requestedLanguageId, boolean useDefault,
1327 String value) {
1328
1329 if (Validator.isNotNull(xml) && !xml.equals(_EMPTY_ROOT_NODE)) {
1330 synchronized (_cache) {
1331 Map<Tuple, String> map = _cache.get(xml);
1332
1333 if (map == null) {
1334 map = new HashMap<>();
1335 }
1336
1337 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
1338
1339 map.put(subkey, value);
1340
1341 _cache.put(xml, map);
1342 }
1343 }
1344 }
1345
1346 private static final String _AVAILABLE_LOCALES = "available-locales";
1347
1348 private static final String _DEFAULT_LOCALE = "default-locale";
1349
1350 private static final String _EMPTY_ROOT_NODE = "<root />";
1351
1352 private static final String _LANGUAGE_ID = "language-id";
1353
1354 private static final String _ROOT = "root";
1355
1356 private static final Log _log = LogFactoryUtil.getLog(
1357 LocalizationImpl.class);
1358
1359 private final Map<String, Map<Tuple, String>> _cache = new ReferenceMap(
1360 ReferenceMap.SOFT, ReferenceMap.HARD);
1361
1362 }