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