1. /*
  2. * @(#)ListResourceBundle.java 1.26 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  9. * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  10. *
  11. * The original version of this source code and documentation
  12. * is copyrighted and owned by Taligent, Inc., a wholly-owned
  13. * subsidiary of IBM. These materials are provided under terms
  14. * of a License Agreement between Taligent and Sun. This technology
  15. * is protected by multiple US and International patents.
  16. *
  17. * This notice and attribution to Taligent may not be removed.
  18. * Taligent is a registered trademark of Taligent, Inc.
  19. *
  20. */
  21. package java.util;
  22. /**
  23. * <code>ListResourceBundle</code> is an abstract subclass of
  24. * <code>ResourceBundle</code> that manages resources for a locale
  25. * in a convenient and easy to use list. See <code>ResourceBundle</code> for
  26. * more information about resource bundles in general.
  27. *
  28. * <P>
  29. * Subclasses must override <code>getContents</code> and provide an array,
  30. * where each item in the array is a pair of objects.
  31. * The first element of each pair is the key, which must be a
  32. * <code>String</code>, and the second element is the value associated with
  33. * that key.
  34. *
  35. * <p>
  36. * The following <a name="sample">example</a> shows two members of a resource
  37. * bundle family with the base name "MyResources".
  38. * "MyResources" is the default member of the bundle family, and
  39. * "MyResources_fr" is the French member.
  40. * These members are based on <code>ListResourceBundle</code>
  41. * (a related <a href="PropertyResourceBundle.html#sample">example</a> shows
  42. * how you can add a bundle to this family that's based on a properties file).
  43. * The keys in this example are of the form "s1" etc. The actual
  44. * keys are entirely up to your choice, so long as they are the same as
  45. * the keys you use in your program to retrieve the objects from the bundle.
  46. * Keys are case-sensitive.
  47. * <blockquote>
  48. * <pre>
  49. *
  50. * public class MyResources extends ListResourceBundle {
  51. * public Object[][] getContents() {
  52. * return contents;
  53. * }
  54. * static final Object[][] contents = {
  55. * // LOCALIZE THIS
  56. * {"s1", "The disk \"{1}\" contains {0}."}, // MessageFormat pattern
  57. * {"s2", "1"}, // location of {0} in pattern
  58. * {"s3", "My Disk"}, // sample disk name
  59. * {"s4", "no files"}, // first ChoiceFormat choice
  60. * {"s5", "one file"}, // second ChoiceFormat choice
  61. * {"s6", "{0,number} files"}, // third ChoiceFormat choice
  62. * {"s7", "3 Mar 96"}, // sample date
  63. * {"s8", new Dimension(1,5)} // real object, not just string
  64. * // END OF MATERIAL TO LOCALIZE
  65. * };
  66. * }
  67. *
  68. * public class MyResources_fr extends ListResourceBundle {
  69. * public Object[][] getContents() {
  70. * return contents;
  71. * }
  72. * static final Object[][] contents = {
  73. * // LOCALIZE THIS
  74. * {"s1", "Le disque \"{1}\" {0}."}, // MessageFormat pattern
  75. * {"s2", "1"}, // location of {0} in pattern
  76. * {"s3", "Mon disque"}, // sample disk name
  77. * {"s4", "ne contient pas de fichiers"}, // first ChoiceFormat choice
  78. * {"s5", "contient un fichier"}, // second ChoiceFormat choice
  79. * {"s6", "contient {0,number} fichiers"}, // third ChoiceFormat choice
  80. * {"s7", "3 mars 1996"}, // sample date
  81. * {"s8", new Dimension(1,3)} // real object, not just string
  82. * // END OF MATERIAL TO LOCALIZE
  83. * };
  84. * }
  85. * </pre>
  86. * </blockquote>
  87. * @see ResourceBundle
  88. * @see PropertyResourceBundle
  89. * @since JDK1.1
  90. */
  91. public abstract class ListResourceBundle extends ResourceBundle {
  92. /**
  93. * Sole constructor. (For invocation by subclass constructors, typically
  94. * implicit.)
  95. */
  96. public ListResourceBundle() {
  97. }
  98. // Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification.
  99. public final Object handleGetObject(String key) {
  100. // lazily load the lookup hashtable.
  101. if (lookup == null) {
  102. loadLookup();
  103. }
  104. if (key == null) {
  105. throw new NullPointerException();
  106. }
  107. return lookup.get(key); // this class ignores locales
  108. }
  109. /**
  110. * Implementation of ResourceBundle.getKeys.
  111. */
  112. public Enumeration<String> getKeys() {
  113. // lazily load the lookup hashtable.
  114. if (lookup == null) {
  115. loadLookup();
  116. }
  117. ResourceBundle parent = this.parent;
  118. return new ResourceBundleEnumeration(lookup.keySet(),
  119. (parent != null) ? parent.getKeys() : null);
  120. }
  121. /**
  122. * See class description.
  123. */
  124. abstract protected Object[][] getContents();
  125. // ==================privates====================
  126. /**
  127. * We lazily load the lookup hashtable. This function does the
  128. * loading.
  129. */
  130. private synchronized void loadLookup() {
  131. if (lookup != null)
  132. return;
  133. Object[][] contents = getContents();
  134. HashMap temp = new HashMap(contents.length);
  135. for (int i = 0; i < contents.length; ++i) {
  136. // key must be non-null String, value must be non-null
  137. String key = (String) contents[i][0];
  138. Object value = contents[i][1];
  139. if (key == null || value == null) {
  140. throw new NullPointerException();
  141. }
  142. temp.put(key, value);
  143. }
  144. lookup = temp;
  145. }
  146. private Map lookup = null;
  147. }