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 String text = xmlStreamReader.getElementText();
961
962 if (cdata) {
963 xmlStreamWriter.writeCData(text);
964 }
965 else {
966 xmlStreamWriter.writeCharacters(text);
967 }
968
969 xmlStreamWriter.writeEndElement();
970 }
971 }
972 else if (event == XMLStreamConstants.END_DOCUMENT) {
973 break;
974 }
975 }
976 }
977
978 private String _getCachedValue(
979 String xml, String requestedLanguageId, boolean useDefault) {
980
981 String value = null;
982
983 Map<Tuple, String> valueMap = _cache.get(xml);
984
985 if (valueMap != null) {
986 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
987
988 value = valueMap.get(subkey);
989 }
990
991 return value;
992 }
993
994 private String _getLocalization(
995 String bundleName, Locale locale, ClassLoader classLoader, String key,
996 String defaultValue) {
997
998 ResourceBundle resourceBundle = ResourceBundle.getBundle(
999 bundleName, locale, classLoader);
1000
1001 String value = null;
1002
1003 try {
1004 value = resourceBundle.getString(key);
1005
1006 value = new String(
1007 value.getBytes(StringPool.ISO_8859_1), StringPool.UTF8);
1008 }
1009
1010 catch (Exception e) {
1011 }
1012
1013 if (Validator.isNotNull(value)) {
1014 value = LanguageResources.fixValue(value);
1015 }
1016 else {
1017 value = LanguageUtil.get(locale, key, defaultValue);
1018 }
1019
1020 return value;
1021 }
1022
1023 private String _getRootAttributeValue(
1024 Document document, String name, String defaultValue) {
1025
1026 Element rootElement = document.getRootElement();
1027
1028 return rootElement.attributeValue(name, defaultValue);
1029 }
1030
1031 private String _getRootAttributeValue(
1032 String xml, String name, String defaultValue) {
1033
1034 String value = null;
1035
1036 XMLStreamReader xmlStreamReader = null;
1037
1038 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
1039
1040 ClassLoader contextClassLoader =
1041 ClassLoaderUtil.getContextClassLoader();
1042
1043 try {
1044 if (contextClassLoader != portalClassLoader) {
1045 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
1046 }
1047
1048 XMLInputFactory xmlInputFactory =
1049 SecureXMLFactoryProviderUtil.newXMLInputFactory();
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 }