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