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