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