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.util.LocaleUtil;
024 import com.liferay.portal.kernel.util.Localization;
025 import com.liferay.portal.kernel.util.ParamUtil;
026 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
027 import com.liferay.portal.kernel.util.PrefsParamUtil;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.StringUtil;
030 import com.liferay.portal.kernel.util.Tuple;
031 import com.liferay.portal.kernel.util.Validator;
032
033 import java.util.HashMap;
034 import java.util.Locale;
035 import java.util.Map;
036
037 import javax.portlet.PortletPreferences;
038 import javax.portlet.PortletRequest;
039
040 import javax.xml.stream.XMLInputFactory;
041 import javax.xml.stream.XMLOutputFactory;
042 import javax.xml.stream.XMLStreamConstants;
043 import javax.xml.stream.XMLStreamException;
044 import javax.xml.stream.XMLStreamReader;
045 import javax.xml.stream.XMLStreamWriter;
046
047 import org.apache.commons.collections.map.ReferenceMap;
048
049
057 public class LocalizationImpl implements Localization {
058
059 public Object deserialize(JSONObject jsonObject) {
060 Locale[] locales = LanguageUtil.getAvailableLocales();
061
062 Map<Locale, String> map = new HashMap<Locale, String>();
063
064 for (Locale locale : locales) {
065 String languageId = LocaleUtil.toLanguageId(locale);
066
067 String value = jsonObject.getString(languageId);
068
069 if (Validator.isNotNull(value)) {
070 map.put(locale, value);
071 }
072 }
073
074 return map;
075 }
076
077 public String[] getAvailableLocales(String xml) {
078 String attributeValue = _getRootAttribute(
079 xml, _AVAILABLE_LOCALES, StringPool.BLANK);
080
081 return StringUtil.split(attributeValue);
082 }
083
084 public String getDefaultLocale(String xml) {
085 String defaultLanguageId = LocaleUtil.toLanguageId(
086 LocaleUtil.getDefault());
087
088 return _getRootAttribute(xml, _DEFAULT_LOCALE, defaultLanguageId);
089 }
090
091 public String getLocalization(String xml, String requestedLanguageId) {
092 return getLocalization(xml, requestedLanguageId, true);
093 }
094
095 public String getLocalization(
096 String xml, String requestedLanguageId, boolean useDefault) {
097
098 String value = _getCachedValue(xml, requestedLanguageId, useDefault);
099
100 if (value != null) {
101 return value;
102 }
103 else {
104 value = StringPool.BLANK;
105 }
106
107 String systemDefaultLanguageId = LocaleUtil.toLanguageId(
108 LocaleUtil.getDefault());
109
110 String priorityLanguageId = null;
111
112 Locale requestedLocale = LocaleUtil.fromLanguageId(requestedLanguageId);
113
114 if (useDefault && LanguageUtil.isDuplicateLanguageCode(
115 requestedLocale.getLanguage())) {
116
117 Locale priorityLocale = LanguageUtil.getLocale(
118 requestedLocale.getLanguage());
119
120 if (!requestedLanguageId.equals(priorityLanguageId)) {
121 priorityLanguageId = LocaleUtil.toLanguageId(priorityLocale);
122 }
123 }
124
125 if (!Validator.isXml(xml)) {
126 if (useDefault ||
127 requestedLanguageId.equals(systemDefaultLanguageId)) {
128
129 value = xml;
130 }
131
132 _setCachedValue(xml, requestedLanguageId, useDefault, value);
133
134 return value;
135 }
136
137 XMLStreamReader xmlStreamReader = null;
138
139 ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();
140
141 Thread currentThread = Thread.currentThread();
142
143 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
144
145 try {
146 if (contextClassLoader != portalClassLoader) {
147 currentThread.setContextClassLoader(portalClassLoader);
148 }
149
150 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
151
152 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
153 new UnsyncStringReader(xml));
154
155 String defaultLanguageId = StringPool.BLANK;
156
157
158
159 if (xmlStreamReader.hasNext()) {
160 xmlStreamReader.nextTag();
161
162 defaultLanguageId = xmlStreamReader.getAttributeValue(
163 null, _DEFAULT_LOCALE);
164
165 if (Validator.isNull(defaultLanguageId)) {
166 defaultLanguageId = systemDefaultLanguageId;
167 }
168 }
169
170
171
172 String defaultValue = StringPool.BLANK;
173 String priorityValue = StringPool.BLANK;
174
175 while (xmlStreamReader.hasNext()) {
176 int event = xmlStreamReader.next();
177
178 if (event == XMLStreamConstants.START_ELEMENT) {
179 String languageId = xmlStreamReader.getAttributeValue(
180 null, _LANGUAGE_ID);
181
182 if (Validator.isNull(languageId)) {
183 languageId = defaultLanguageId;
184 }
185
186 if (languageId.equals(defaultLanguageId) ||
187 languageId.equals(priorityLanguageId) ||
188 languageId.equals(requestedLanguageId)) {
189
190 while (xmlStreamReader.hasNext()) {
191 event = xmlStreamReader.next();
192
193 if (event == XMLStreamConstants.CHARACTERS ||
194 event == XMLStreamConstants.CDATA) {
195
196 String text = xmlStreamReader.getText();
197
198 if (languageId.equals(defaultLanguageId)) {
199 defaultValue = text;
200 }
201
202 if (languageId.equals(priorityLanguageId)) {
203 priorityValue = text;
204 }
205
206 if (languageId.equals(requestedLanguageId)) {
207 value = text;
208 }
209
210 break;
211 }
212 else if (event == XMLStreamConstants.END_ELEMENT) {
213 break;
214 }
215 }
216
217 if (Validator.isNotNull(value)) {
218 break;
219 }
220 }
221 }
222 else if (event == XMLStreamConstants.END_DOCUMENT) {
223 break;
224 }
225 }
226
227 if (useDefault && Validator.isNotNull(priorityLanguageId) &&
228 Validator.isNull(value) && Validator.isNotNull(priorityValue)) {
229
230 value = priorityValue;
231 }
232
233 if (useDefault && Validator.isNull(value)) {
234 value = defaultValue;
235 }
236 }
237 catch (Exception e) {
238 if (_log.isWarnEnabled()) {
239 _log.warn(e, e);
240 }
241 }
242 finally {
243 if (contextClassLoader != portalClassLoader) {
244 currentThread.setContextClassLoader(contextClassLoader);
245 }
246
247 if (xmlStreamReader != null) {
248 try {
249 xmlStreamReader.close();
250 }
251 catch (Exception e) {
252 }
253 }
254 }
255
256 _setCachedValue(xml, requestedLanguageId, useDefault, value);
257
258 return value;
259 }
260
261 public Map<Locale, String> getLocalizationMap(
262 PortletRequest portletRequest, String parameter) {
263
264 Locale[] locales = LanguageUtil.getAvailableLocales();
265
266 Map<Locale, String> map = new HashMap<Locale, String>();
267
268 for (Locale locale : locales) {
269 String languageId = LocaleUtil.toLanguageId(locale);
270
271 String localeParameter =
272 parameter + StringPool.UNDERLINE + languageId;
273
274 map.put(
275 locale, ParamUtil.getString(portletRequest, localeParameter));
276 }
277
278 return map;
279 }
280
281 public Map<Locale, String> getLocalizationMap(String xml) {
282 Locale[] locales = LanguageUtil.getAvailableLocales();
283
284 Map<Locale, String> map = new HashMap<Locale, String>();
285
286 for (Locale locale : locales) {
287 String languageId = LocaleUtil.toLanguageId(locale);
288
289 map.put(locale, getLocalization(xml, languageId));
290 }
291
292 return map;
293 }
294
295 public String getLocalizationXmlFromPreferences(
296 PortletPreferences preferences, PortletRequest portletRequest,
297 String parameter) {
298
299 String xml = StringPool.BLANK;
300
301 Locale[] locales = LanguageUtil.getAvailableLocales();
302 Locale defaultLocale = LocaleUtil.getDefault();
303 String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);
304
305 for (Locale locale : locales) {
306 String languageId = LocaleUtil.toLanguageId(locale);
307
308 String localParameter =
309 parameter + StringPool.UNDERLINE + languageId;
310
311 String value = PrefsParamUtil.getString(
312 preferences, portletRequest, localParameter);
313
314 if (Validator.isNotNull(value)) {
315 xml = updateLocalization(xml, parameter, value ,languageId);
316 }
317 }
318
319 if (Validator.isNull(getLocalization(xml, defaultLanguageId))) {
320 String oldValue = PrefsParamUtil.getString(
321 preferences, portletRequest, parameter);
322
323 if (Validator.isNotNull(oldValue)) {
324 xml = updateLocalization(xml, parameter, oldValue);
325 }
326 }
327
328 return xml;
329 }
330
331 public Map<Locale, String> getLocalizedParameter(
332 PortletRequest portletRequest, String parameter) {
333
334 return getLocalizationMap(portletRequest, parameter);
335 }
336
337 public String getPreferencesValue(
338 PortletPreferences preferences, String key, String languageId) {
339
340 return getPreferencesValue(preferences, key, languageId, true);
341 }
342
343 public String getPreferencesValue(
344 PortletPreferences preferences, String key, String languageId,
345 boolean useDefault) {
346
347 String localizedKey = _getPreferencesKey(key, languageId);
348
349 String value = preferences.getValue(localizedKey, StringPool.BLANK);
350
351 if (useDefault && Validator.isNull(value)) {
352 value = preferences.getValue(key, StringPool.BLANK);
353 }
354
355 return value;
356 }
357
358 public String[] getPreferencesValues(
359 PortletPreferences preferences, String key, String languageId) {
360
361 return getPreferencesValues(preferences, key, languageId, true);
362 }
363
364 public String[] getPreferencesValues(
365 PortletPreferences preferences, String key, String languageId,
366 boolean useDefault) {
367
368 String localizedKey = _getPreferencesKey(key, languageId);
369
370 String[] values = preferences.getValues(localizedKey, new String[0]);
371
372 if (useDefault && Validator.isNull(values)) {
373 values = preferences.getValues(key, new String[0]);
374 }
375
376 return values;
377 }
378
379 public String removeLocalization(
380 String xml, String key, String requestedLanguageId) {
381
382 return removeLocalization(xml, key, requestedLanguageId, false);
383 }
384
385 public String removeLocalization(
386 String xml, String key, String requestedLanguageId, boolean cdata) {
387
388 return removeLocalization(xml, key, requestedLanguageId, cdata, true);
389 }
390
391 public String removeLocalization(
392 String xml, String key, String requestedLanguageId, boolean cdata,
393 boolean localized) {
394
395 if (Validator.isNull(xml)) {
396 return StringPool.BLANK;
397 }
398
399 xml = _sanitizeXML(xml);
400
401 String systemDefaultLanguageId = LocaleUtil.toLanguageId(
402 LocaleUtil.getDefault());
403
404 XMLStreamReader xmlStreamReader = null;
405 XMLStreamWriter xmlStreamWriter = null;
406
407 ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();
408
409 Thread currentThread = Thread.currentThread();
410
411 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
412
413 try {
414 if (contextClassLoader != portalClassLoader) {
415 currentThread.setContextClassLoader(portalClassLoader);
416 }
417
418 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
419
420 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
421 new UnsyncStringReader(xml));
422
423 String availableLocales = StringPool.BLANK;
424 String defaultLanguageId = StringPool.BLANK;
425
426
427
428 if (xmlStreamReader.hasNext()) {
429 xmlStreamReader.nextTag();
430
431 availableLocales = xmlStreamReader.getAttributeValue(
432 null, _AVAILABLE_LOCALES);
433 defaultLanguageId = xmlStreamReader.getAttributeValue(
434 null, _DEFAULT_LOCALE);
435
436 if (Validator.isNull(defaultLanguageId)) {
437 defaultLanguageId = systemDefaultLanguageId;
438 }
439 }
440
441 if ((availableLocales != null) &&
442 (availableLocales.indexOf(requestedLanguageId) != -1)) {
443
444 availableLocales = StringUtil.remove(
445 availableLocales, requestedLanguageId, StringPool.COMMA);
446
447 UnsyncStringWriter unsyncStringWriter =
448 new UnsyncStringWriter();
449
450 XMLOutputFactory xmlOutputFactory =
451 XMLOutputFactory.newInstance();
452
453 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
454 unsyncStringWriter);
455
456 xmlStreamWriter.writeStartDocument();
457 xmlStreamWriter.writeStartElement(_ROOT);
458
459 if (localized) {
460 xmlStreamWriter.writeAttribute(
461 _AVAILABLE_LOCALES, availableLocales);
462 xmlStreamWriter.writeAttribute(
463 _DEFAULT_LOCALE, defaultLanguageId);
464 }
465
466 _copyNonExempt(
467 xmlStreamReader, xmlStreamWriter, requestedLanguageId,
468 defaultLanguageId, cdata);
469
470 xmlStreamWriter.writeEndElement();
471 xmlStreamWriter.writeEndDocument();
472
473 xmlStreamWriter.close();
474 xmlStreamWriter = null;
475
476 xml = unsyncStringWriter.toString();
477 }
478 }
479 catch (Exception e) {
480 if (_log.isWarnEnabled()) {
481 _log.warn(e, e);
482 }
483 }
484 finally {
485 if (contextClassLoader != portalClassLoader) {
486 currentThread.setContextClassLoader(contextClassLoader);
487 }
488
489 if (xmlStreamReader != null) {
490 try {
491 xmlStreamReader.close();
492 }
493 catch (Exception e) {
494 }
495 }
496
497 if (xmlStreamWriter != null) {
498 try {
499 xmlStreamWriter.close();
500 }
501 catch (Exception e) {
502 }
503 }
504 }
505
506 return xml;
507 }
508
509 public void setLocalizedPreferencesValues (
510 PortletRequest portletRequest, PortletPreferences preferences,
511 String parameter)
512 throws Exception {
513
514 Map<Locale, String> map = getLocalizationMap(
515 portletRequest, parameter);
516
517 for (Map.Entry<Locale, String> entry : map.entrySet()) {
518 String languageId = LocaleUtil.toLanguageId(entry.getKey());
519 String value = entry.getValue();
520
521 setPreferencesValue(preferences, parameter, languageId, value);
522 }
523 }
524
525 public void setPreferencesValue(
526 PortletPreferences preferences, String key, String languageId,
527 String value)
528 throws Exception {
529
530 preferences.setValue(_getPreferencesKey(key, languageId), value);
531 }
532
533 public void setPreferencesValues(
534 PortletPreferences preferences, String key, String languageId,
535 String[] values)
536 throws Exception {
537
538 preferences.setValues(_getPreferencesKey(key, languageId), values);
539 }
540
541 public String updateLocalization(String xml, String key, String value) {
542 String defaultLanguageId = LocaleUtil.toLanguageId(
543 LocaleUtil.getDefault());
544
545 return updateLocalization(
546 xml, key, value, defaultLanguageId, defaultLanguageId);
547 }
548
549 public String updateLocalization(
550 String xml, String key, String value, String requestedLanguageId) {
551
552 String defaultLanguageId = LocaleUtil.toLanguageId(
553 LocaleUtil.getDefault());
554
555 return updateLocalization(
556 xml, key, value, requestedLanguageId, defaultLanguageId);
557 }
558
559 public String updateLocalization(
560 String xml, String key, String value, String requestedLanguageId,
561 String defaultLanguageId) {
562
563 return updateLocalization(
564 xml, key, value, requestedLanguageId, defaultLanguageId, false);
565 }
566
567 public String updateLocalization(
568 String xml, String key, String value, String requestedLanguageId,
569 String defaultLanguageId, boolean cdata) {
570
571 return updateLocalization(
572 xml, key, value, requestedLanguageId, defaultLanguageId, cdata,
573 true);
574 }
575
576 public String updateLocalization(
577 String xml, String key, String value, String requestedLanguageId,
578 String defaultLanguageId, boolean cdata, boolean localized) {
579
580 xml = _sanitizeXML(xml);
581
582 XMLStreamReader xmlStreamReader = null;
583 XMLStreamWriter xmlStreamWriter = null;
584
585 ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();
586
587 Thread currentThread = Thread.currentThread();
588
589 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
590
591 try {
592 if (contextClassLoader != portalClassLoader) {
593 currentThread.setContextClassLoader(portalClassLoader);
594 }
595
596 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
597
598 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
599 new UnsyncStringReader(xml));
600
601 String availableLocales = StringPool.BLANK;
602
603
604
605 if (xmlStreamReader.hasNext()) {
606 xmlStreamReader.nextTag();
607
608 availableLocales = xmlStreamReader.getAttributeValue(
609 null, _AVAILABLE_LOCALES);
610
611 if (Validator.isNull(availableLocales)) {
612 availableLocales = defaultLanguageId;
613 }
614
615 if (availableLocales.indexOf(requestedLanguageId) == -1) {
616 availableLocales = StringUtil.add(
617 availableLocales, requestedLanguageId,
618 StringPool.COMMA);
619 }
620 }
621
622 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
623
624 XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
625
626 xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(
627 unsyncStringWriter);
628
629 xmlStreamWriter.writeStartDocument();
630 xmlStreamWriter.writeStartElement(_ROOT);
631
632 if (localized) {
633 xmlStreamWriter.writeAttribute(
634 _AVAILABLE_LOCALES, availableLocales);
635 xmlStreamWriter.writeAttribute(
636 _DEFAULT_LOCALE, defaultLanguageId);
637 }
638
639 _copyNonExempt(
640 xmlStreamReader, xmlStreamWriter, requestedLanguageId,
641 defaultLanguageId, cdata);
642
643 xmlStreamWriter.writeStartElement(key);
644
645 if (localized) {
646 xmlStreamWriter.writeAttribute(
647 _LANGUAGE_ID, requestedLanguageId);
648 }
649
650 if (cdata) {
651 xmlStreamWriter.writeCData(value);
652 }
653 else {
654 xmlStreamWriter.writeCharacters(value);
655 }
656
657 xmlStreamWriter.writeEndElement();
658 xmlStreamWriter.writeEndElement();
659 xmlStreamWriter.writeEndDocument();
660
661 xmlStreamWriter.close();
662 xmlStreamWriter = null;
663
664 xml = unsyncStringWriter.toString();
665 }
666 catch (Exception e) {
667 if (_log.isWarnEnabled()) {
668 _log.warn(e, e);
669 }
670 }
671 finally {
672 if (contextClassLoader != portalClassLoader) {
673 currentThread.setContextClassLoader(contextClassLoader);
674 }
675
676 if (xmlStreamReader != null) {
677 try {
678 xmlStreamReader.close();
679 }
680 catch (Exception e) {
681 }
682 }
683
684 if (xmlStreamWriter != null) {
685 try {
686 xmlStreamWriter.close();
687 }
688 catch (Exception e) {
689 }
690 }
691 }
692
693 return xml;
694 }
695
696 private void _copyNonExempt(
697 XMLStreamReader xmlStreamReader, XMLStreamWriter xmlStreamWriter,
698 String exemptLanguageId, String defaultLanguageId, boolean cdata)
699 throws XMLStreamException {
700
701 while (xmlStreamReader.hasNext()) {
702 int event = xmlStreamReader.next();
703
704 if (event == XMLStreamConstants.START_ELEMENT) {
705 String languageId = xmlStreamReader.getAttributeValue(
706 null, _LANGUAGE_ID);
707
708 if (Validator.isNull(languageId)) {
709 languageId = defaultLanguageId;
710 }
711
712 if (!languageId.equals(exemptLanguageId)) {
713 xmlStreamWriter.writeStartElement(
714 xmlStreamReader.getLocalName());
715 xmlStreamWriter.writeAttribute(_LANGUAGE_ID, languageId);
716
717 while (xmlStreamReader.hasNext()) {
718 event = xmlStreamReader.next();
719
720 if ((event == XMLStreamConstants.CHARACTERS) ||
721 (event == XMLStreamConstants.CDATA)) {
722
723 String text = xmlStreamReader.getText();
724
725 if (cdata) {
726 xmlStreamWriter.writeCData(text);
727 }
728 else {
729 xmlStreamWriter.writeCharacters(
730 xmlStreamReader.getText());
731 }
732
733 break;
734 }
735 else if (event == XMLStreamConstants.END_ELEMENT) {
736 break;
737 }
738 }
739
740 xmlStreamWriter.writeEndElement();
741 }
742 }
743 else if (event == XMLStreamConstants.END_DOCUMENT) {
744 break;
745 }
746 }
747 }
748
749 private String _getCachedValue(
750 String xml, String requestedLanguageId, boolean useDefault) {
751
752 String value = null;
753
754 Map<Tuple, String> valueMap = _cache.get(xml);
755
756 if (valueMap != null) {
757 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
758
759 value = valueMap.get(subkey);
760 }
761
762 return value;
763 }
764
765 private String _getPreferencesKey(String key, String languageId) {
766 String defaultLanguageId = LocaleUtil.toLanguageId(
767 LocaleUtil.getDefault());
768
769 if (!languageId.equals(defaultLanguageId)) {
770 key += StringPool.UNDERLINE + languageId;
771 }
772
773 return key;
774 }
775
776 private String _getRootAttribute(
777 String xml, String name, String defaultValue) {
778
779 String value = null;
780
781 XMLStreamReader xmlStreamReader = null;
782
783 ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();
784
785 Thread currentThread = Thread.currentThread();
786
787 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
788
789 try {
790 if (contextClassLoader != portalClassLoader) {
791 currentThread.setContextClassLoader(portalClassLoader);
792 }
793
794 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
795
796 xmlStreamReader = xmlInputFactory.createXMLStreamReader(
797 new UnsyncStringReader(xml));
798
799 if (xmlStreamReader.hasNext()) {
800 xmlStreamReader.nextTag();
801
802 value = xmlStreamReader.getAttributeValue(null, name);
803 }
804 }
805 catch (Exception e) {
806 if (_log.isWarnEnabled()) {
807 _log.warn(e, e);
808 }
809 }
810 finally {
811 if (contextClassLoader != portalClassLoader) {
812 currentThread.setContextClassLoader(contextClassLoader);
813 }
814
815 if (xmlStreamReader != null) {
816 try {
817 xmlStreamReader.close();
818 }
819 catch (Exception e) {
820 }
821 }
822 }
823
824 if (Validator.isNull(value)) {
825 value = defaultValue;
826 }
827
828 return value;
829 }
830
831 private String _sanitizeXML(String xml) {
832 if (Validator.isNull(xml) || (xml.indexOf("<root") == -1)) {
833 xml = _EMPTY_ROOT_NODE;
834 }
835
836 return xml;
837 }
838
839 private void _setCachedValue(
840 String xml, String requestedLanguageId, boolean useDefault,
841 String value) {
842
843 if (Validator.isNotNull(xml) && !xml.equals(_EMPTY_ROOT_NODE)) {
844 synchronized (_cache) {
845 Map<Tuple, String> map = _cache.get(xml);
846
847 if (map == null) {
848 map = new HashMap<Tuple, String>();
849 }
850
851 Tuple subkey = new Tuple(useDefault, requestedLanguageId);
852
853 map.put(subkey, value);
854
855 _cache.put(xml, map);
856 }
857 }
858 }
859
860 private static final String _AVAILABLE_LOCALES = "available-locales";
861
862 private static final String _DEFAULT_LOCALE = "default-locale";
863
864 private static final String _EMPTY_ROOT_NODE = "<root />";
865
866 private static final String _LANGUAGE_ID = "language-id";
867
868 private static final String _ROOT = "root";
869
870 private static Log _log = LogFactoryUtil.getLog(LocalizationImpl.class);
871
872 private Map<String, Map<Tuple, String>> _cache = new ReferenceMap(
873 ReferenceMap.SOFT, ReferenceMap.HARD);
874
875 }