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