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.getDefault();
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.getDefault());
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.getDefault());
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.getDefault());
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.getDefault();
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 String xml = StringPool.BLANK;
480
481 Locale[] locales = LanguageUtil.getAvailableLocales();
482 Locale defaultLocale = LocaleUtil.getDefault();
483 String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
484
485 for (Locale locale : locales) {
486 String languageId = LocaleUtil.toLanguageId(locale);
487
488 String localizedKey = getPreferencesKey(parameter, languageId);
489
490 String value = PrefsParamUtil.getString(
491 preferences, portletRequest, localizedKey);
492
493 if (Validator.isNotNull(value)) {
494 xml = updateLocalization(xml, parameter, value, languageId);
495 }
496 }
497
498 if (Validator.isNull(getLocalization(xml, defaultLanguageId))) {
499 String oldValue = PrefsParamUtil.getString(
500 preferences, portletRequest, parameter);
501
502 if (Validator.isNotNull(oldValue)) {
503 xml = updateLocalization(xml, parameter, oldValue);
504 }
505 }
506
507 return xml;
508 }
509
510 @Override
511 public Map<Locale, String> getLocalizedParameter(
512 PortletRequest portletRequest, String parameter) {
513
514 return getLocalizationMap(portletRequest, parameter);
515 }
516
517 @Override
518 public String getPreferencesKey(String key, String languageId) {
519 String defaultLanguageId = LocaleUtil.toLanguageId(
520 LocaleUtil.getDefault());
521
522 if (!languageId.equals(defaultLanguageId)) {
523 key += StringPool.UNDERLINE + languageId;
524 }
525
526 return key;
527 }
528
529 @Override
530 public String getPreferencesValue(
531 PortletPreferences preferences, String key, String languageId) {
532
533 return getPreferencesValue(preferences, key, languageId, true);
534 }
535
536 @Override
537 public String getPreferencesValue(
538 PortletPreferences preferences, String key, String languageId,
539 boolean useDefault) {
540
541 String localizedKey = getPreferencesKey(key, languageId);
542
543 String value = preferences.getValue(localizedKey, StringPool.BLANK);
544
545 if (useDefault && Validator.isNull(value)) {
546 value = preferences.getValue(key, StringPool.BLANK);
547 }
548
549 return value;
550 }
551
552 @Override
553 public String[] getPreferencesValues(
554 PortletPreferences preferences, String key, String languageId) {
555
556 return getPreferencesValues(preferences, key, languageId, true);
557 }
558
559 @Override
560 public String[] getPreferencesValues(
561 PortletPreferences preferences, String key, String languageId,
562 boolean useDefault) {
563
564 String localizedKey = getPreferencesKey(key, languageId);
565
566 String[] values = preferences.getValues(localizedKey, new String[0]);
567
568 if (useDefault && ArrayUtil.isEmpty(values)) {
569 values = preferences.getValues(key, new String[0]);
570 }
571
572 return values;
573 }
574
575 @Override
576 public String removeLocalization(
577 String xml, String key, String requestedLanguageId) {
578
579 return removeLocalization(xml, key, requestedLanguageId, false);
580 }
581
582 @Override
583 public String removeLocalization(
584 String xml, String key, String requestedLanguageId, boolean cdata) {
585
586 return removeLocalization(xml, key, requestedLanguageId, cdata, true);
587 }
588
589 @Override
590 public String removeLocalization(
591 String xml, String key, String requestedLanguageId, boolean cdata,
592 boolean localized) {
593
594 if (Validator.isNull(xml)) {
595 return StringPool.BLANK;
596 }
597
598 if (!Validator.isXml(xml)) {
599 return xml;
600 }
601
602 xml = _sanitizeXML(xml);
603
604 String systemDefaultLanguageId = LocaleUtil.toLanguageId(
605 LocaleUtil.getDefault());
606
607 XMLStreamReader xmlStreamReader = null;
608 XMLStreamWriter xmlStreamWriter = null;
609
610 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
611
612 ClassLoader contextClassLoader =
613 ClassLoaderUtil.getContextClassLoader();
614
615 try {
616 if (contextClassLoader != portalClassLoader) {
617 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
618 }
619
620 XMLInputFactory xmlInputFactory =
621 SecureXMLFactoryProviderUtil.newXMLInputFactory();
622
623 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
624 new UnsyncStringReader(xml));
625
626 String availableLocales = StringPool.BLANK;
627 String defaultLanguageId = StringPool.BLANK;
628
629
630
631 if (xmlStreamReader.hasNext()) {
632 xmlStreamReader.nextTag();
633
634 availableLocales = xmlStreamReader.getAttributeValue(
635 null, _AVAILABLE_LOCALES);
636 defaultLanguageId = xmlStreamReader.getAttributeValue(
637 null, _DEFAULT_LOCALE);
638
639 if (Validator.isNull(defaultLanguageId)) {
640 defaultLanguageId = systemDefaultLanguageId;
641 }
642 }
643
644 if ((availableLocales != null) &&
645 availableLocales.contains(requestedLanguageId)) {
646
647 availableLocales = StringUtil.remove(
648 availableLocales, requestedLanguageId, StringPool.COMMA);
649
650 UnsyncStringWriter unsyncStringWriter =
651 new UnsyncStringWriter();
652
653 XMLOutputFactory xmlOutputFactory =
654 XMLOutputFactory.newInstance();
655
656 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
657 unsyncStringWriter);
658
659 xmlStreamWriter.writeStartDocument();
660 xmlStreamWriter.writeStartElement(_ROOT);
661
662 if (localized) {
663 xmlStreamWriter.writeAttribute(
664 _AVAILABLE_LOCALES, availableLocales);
665 xmlStreamWriter.writeAttribute(
666 _DEFAULT_LOCALE, defaultLanguageId);
667 }
668
669 _copyNonExempt(
670 xmlStreamReader, xmlStreamWriter, requestedLanguageId,
671 defaultLanguageId, cdata);
672
673 xmlStreamWriter.writeEndElement();
674 xmlStreamWriter.writeEndDocument();
675
676 xmlStreamWriter.close();
677 xmlStreamWriter = null;
678
679 xml = unsyncStringWriter.toString();
680 }
681 }
682 catch (Exception e) {
683 if (_log.isWarnEnabled()) {
684 _log.warn(e, e);
685 }
686 }
687 finally {
688 if (contextClassLoader != portalClassLoader) {
689 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
690 }
691
692 if (xmlStreamReader != null) {
693 try {
694 xmlStreamReader.close();
695 }
696 catch (Exception e) {
697 }
698 }
699
700 if (xmlStreamWriter != null) {
701 try {
702 xmlStreamWriter.close();
703 }
704 catch (Exception e) {
705 }
706 }
707 }
708
709 return xml;
710 }
711
712 @Override
713 public void setLocalizedPreferencesValues(
714 PortletRequest portletRequest, PortletPreferences preferences,
715 String parameter)
716 throws Exception {
717
718 Map<Locale, String> map = getLocalizationMap(portletRequest, parameter);
719
720 for (Map.Entry<Locale, String> entry : map.entrySet()) {
721 String languageId = LocaleUtil.toLanguageId(entry.getKey());
722 String value = entry.getValue();
723
724 setPreferencesValue(preferences, parameter, languageId, value);
725 }
726 }
727
728 @Override
729 public void setPreferencesValue(
730 PortletPreferences preferences, String key, String languageId,
731 String value)
732 throws Exception {
733
734 preferences.setValue(getPreferencesKey(key, languageId), value);
735 }
736
737 @Override
738 public void setPreferencesValues(
739 PortletPreferences preferences, String key, String languageId,
740 String[] values)
741 throws Exception {
742
743 preferences.setValues(getPreferencesKey(key, languageId), values);
744 }
745
746 @Override
747 public String updateLocalization(
748 Map<Locale, String> localizationMap, String xml, String key,
749 String defaultLanguageId) {
750
751 Locale[] locales = LanguageUtil.getAvailableLocales();
752
753 for (Locale locale : locales) {
754 String value = localizationMap.get(locale);
755
756 String languageId = LocaleUtil.toLanguageId(locale);
757
758 if (Validator.isNotNull(value)) {
759 xml = updateLocalization(
760 xml, key, value, languageId, defaultLanguageId);
761 }
762 else {
763 xml = removeLocalization(xml, key, languageId);
764 }
765 }
766
767 return xml;
768 }
769
770 @Override
771 public String updateLocalization(String xml, String key, String value) {
772 String defaultLanguageId = LocaleUtil.toLanguageId(
773 LocaleUtil.getDefault());
774
775 return updateLocalization(
776 xml, key, value, defaultLanguageId, defaultLanguageId);
777 }
778
779 @Override
780 public String updateLocalization(
781 String xml, String key, String value, String requestedLanguageId) {
782
783 String defaultLanguageId = LocaleUtil.toLanguageId(
784 LocaleUtil.getDefault());
785
786 return updateLocalization(
787 xml, key, value, requestedLanguageId, defaultLanguageId);
788 }
789
790 @Override
791 public String updateLocalization(
792 String xml, String key, String value, String requestedLanguageId,
793 String defaultLanguageId) {
794
795 return updateLocalization(
796 xml, key, value, requestedLanguageId, defaultLanguageId, false);
797 }
798
799 @Override
800 public String updateLocalization(
801 String xml, String key, String value, String requestedLanguageId,
802 String defaultLanguageId, boolean cdata) {
803
804 return updateLocalization(
805 xml, key, value, requestedLanguageId, defaultLanguageId, cdata,
806 true);
807 }
808
809 @Override
810 public String updateLocalization(
811 String xml, String key, String value, String requestedLanguageId,
812 String defaultLanguageId, boolean cdata, boolean localized) {
813
814 xml = _sanitizeXML(xml);
815
816 XMLStreamReader xmlStreamReader = null;
817 XMLStreamWriter xmlStreamWriter = null;
818
819 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
820
821 ClassLoader contextClassLoader =
822 ClassLoaderUtil.getContextClassLoader();
823
824 try {
825 if (contextClassLoader != portalClassLoader) {
826 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
827 }
828
829 XMLInputFactory xmlInputFactory =
830 SecureXMLFactoryProviderUtil.newXMLInputFactory();
831
832 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
833 new UnsyncStringReader(xml));
834
835 String availableLocales = StringPool.BLANK;
836
837
838
839 if (xmlStreamReader.hasNext()) {
840 xmlStreamReader.nextTag();
841
842 availableLocales = xmlStreamReader.getAttributeValue(
843 null, _AVAILABLE_LOCALES);
844
845 if (Validator.isNull(availableLocales)) {
846 availableLocales = defaultLanguageId;
847 }
848
849 if (!availableLocales.contains(requestedLanguageId)) {
850 availableLocales = StringUtil.add(
851 availableLocales, requestedLanguageId,
852 StringPool.COMMA);
853 }
854 }
855
856 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
857
858 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
859
860 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
861 unsyncStringWriter);
862
863 xmlStreamWriter.writeStartDocument();
864 xmlStreamWriter.writeStartElement(_ROOT);
865
866 if (localized) {
867 xmlStreamWriter.writeAttribute(
868 _AVAILABLE_LOCALES, availableLocales);
869 xmlStreamWriter.writeAttribute(
870 _DEFAULT_LOCALE, defaultLanguageId);
871 }
872
873 _copyNonExempt(
874 xmlStreamReader, xmlStreamWriter, requestedLanguageId,
875 defaultLanguageId, cdata);
876
877 xmlStreamWriter.writeStartElement(key);
878
879 if (localized) {
880 xmlStreamWriter.writeAttribute(
881 _LANGUAGE_ID, requestedLanguageId);
882 }
883
884 if (cdata) {
885 xmlStreamWriter.writeCData(value);
886 }
887 else {
888 xmlStreamWriter.writeCharacters(value);
889 }
890
891 xmlStreamWriter.writeEndElement();
892 xmlStreamWriter.writeEndElement();
893 xmlStreamWriter.writeEndDocument();
894
895 xmlStreamWriter.close();
896 xmlStreamWriter = null;
897
898 xml = unsyncStringWriter.toString();
899 }
900 catch (Exception e) {
901 if (_log.isWarnEnabled()) {
902 _log.warn(e, e);
903 }
904 }
905 finally {
906 if (contextClassLoader != portalClassLoader) {
907 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
908 }
909
910 if (xmlStreamReader != null) {
911 try {
912 xmlStreamReader.close();
913 }
914 catch (Exception e) {
915 }
916 }
917
918 if (xmlStreamWriter != null) {
919 try {
920 xmlStreamWriter.close();
921 }
922 catch (Exception e) {
923 }
924 }
925 }
926
927 return xml;
928 }
929
930 private void _copyNonExempt(
931 XMLStreamReader xmlStreamReader, XMLStreamWriter xmlStreamWriter,
932 String exemptLanguageId, String defaultLanguageId, boolean cdata)
933 throws XMLStreamException {
934
935 while (xmlStreamReader.hasNext()) {
936 int event = xmlStreamReader.next();
937
938 if (event == XMLStreamConstants.START_ELEMENT) {
939 String languageId = xmlStreamReader.getAttributeValue(
940 null, _LANGUAGE_ID);
941
942 if (Validator.isNull(languageId)) {
943 languageId = defaultLanguageId;
944 }
945
946 if (!languageId.equals(exemptLanguageId)) {
947 xmlStreamWriter.writeStartElement(
948 xmlStreamReader.getLocalName());
949 xmlStreamWriter.writeAttribute(_LANGUAGE_ID, languageId);
950
951 while (xmlStreamReader.hasNext()) {
952 event = xmlStreamReader.next();
953
954 if ((event == XMLStreamConstants.CHARACTERS) ||
955 (event == XMLStreamConstants.CDATA)) {
956
957 String text = xmlStreamReader.getText();
958
959 if (cdata) {
960 xmlStreamWriter.writeCData(text);
961 }
962 else {
963 xmlStreamWriter.writeCharacters(
964 xmlStreamReader.getText());
965 }
966
967 break;
968 }
969 else if (event == XMLStreamConstants.END_ELEMENT) {
970 break;
971 }
972 }
973
974 xmlStreamWriter.writeEndElement();
975 }
976 }
977 else if (event == XMLStreamConstants.END_DOCUMENT) {
978 break;
979 }
980 }
981 }
982
983 private String _getCachedValue(
984 String xml, String requestedLanguageId, boolean useDefault) {
985
986 String value = null;
987
988 Map<Tuple, String> valueMap = _cache.get(xml);
989
990 if (valueMap != null) {
991 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
992
993 value = valueMap.get(subkey);
994 }
995
996 return value;
997 }
998
999 private String _getLocalization(
1000 String bundleName, Locale locale, ClassLoader classLoader, String key,
1001 String defaultValue) {
1002
1003 ResourceBundle resourceBundle = ResourceBundle.getBundle(
1004 bundleName, locale, classLoader);
1005
1006 String value = null;
1007
1008 try {
1009 value = resourceBundle.getString(key);
1010
1011 value = new String(
1012 value.getBytes(StringPool.ISO_8859_1), StringPool.UTF8);
1013 }
1014
1015 catch (Exception e) {
1016 }
1017
1018 if (Validator.isNotNull(value)) {
1019 value = LanguageResources.fixValue(value);
1020 }
1021 else {
1022 value = LanguageUtil.get(locale, key, defaultValue);
1023 }
1024
1025 return value;
1026 }
1027
1028 private String _getRootAttributeValue(
1029 Document document, String name, String defaultValue) {
1030
1031 Element rootElement = document.getRootElement();
1032
1033 return rootElement.attributeValue(name, defaultValue);
1034 }
1035
1036 private String _getRootAttributeValue(
1037 String xml, String name, String defaultValue) {
1038
1039 String value = null;
1040
1041 XMLStreamReader xmlStreamReader = null;
1042
1043 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
1044
1045 ClassLoader contextClassLoader =
1046 ClassLoaderUtil.getContextClassLoader();
1047
1048 try {
1049 if (contextClassLoader != portalClassLoader) {
1050 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
1051 }
1052
1053 XMLInputFactory xmlInputFactory =
1054 SecureXMLFactoryProviderUtil.newXMLInputFactory();
1055
1056 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
1057 new UnsyncStringReader(xml));
1058
1059 if (xmlStreamReader.hasNext()) {
1060 xmlStreamReader.nextTag();
1061
1062 value = xmlStreamReader.getAttributeValue(null, name);
1063 }
1064 }
1065 catch (Exception e) {
1066 if (_log.isWarnEnabled()) {
1067 _log.warn(e, e);
1068 }
1069 }
1070 finally {
1071 if (contextClassLoader != portalClassLoader) {
1072 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
1073 }
1074
1075 if (xmlStreamReader != null) {
1076 try {
1077 xmlStreamReader.close();
1078 }
1079 catch (Exception e) {
1080 }
1081 }
1082 }
1083
1084 if (Validator.isNull(value)) {
1085 value = defaultValue;
1086 }
1087
1088 return value;
1089 }
1090
1091 private String _sanitizeXML(String xml) {
1092 if (Validator.isNull(xml) || !xml.contains("<root")) {
1093 xml = _EMPTY_ROOT_NODE;
1094 }
1095
1096 return xml;
1097 }
1098
1099 private void _setCachedValue(
1100 String xml, String requestedLanguageId, boolean useDefault,
1101 String value) {
1102
1103 if (Validator.isNotNull(xml) && !xml.equals(_EMPTY_ROOT_NODE)) {
1104 synchronized (_cache) {
1105 Map<Tuple, String> map = _cache.get(xml);
1106
1107 if (map == null) {
1108 map = new HashMap<Tuple, String>();
1109 }
1110
1111 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
1112
1113 map.put(subkey, value);
1114
1115 _cache.put(xml, map);
1116 }
1117 }
1118 }
1119
1120 private static final String _AVAILABLE_LOCALES = "available-locales";
1121
1122 private static final String _DEFAULT_LOCALE = "default-locale";
1123
1124 private static final String _EMPTY_ROOT_NODE = "<root />";
1125
1126 private static final String _LANGUAGE_ID = "language-id";
1127
1128 private static final String _ROOT = "root";
1129
1130 private static Log _log = LogFactoryUtil.getLog(LocalizationImpl.class);
1131
1132 private Map<String, Map<Tuple, String>> _cache = new ReferenceMap(
1133 ReferenceMap.SOFT, ReferenceMap.HARD);
1134
1135 }