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