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