1. /*
  2. * @(#)ListResourceBundle.java 1.15 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * @(#)ListResourceBundle.java 1.15 01/11/29
  9. *
  10. * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  11. * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  12. *
  13. * Portions copyright (c) 1996-1998 Sun Microsystems, Inc.
  14. * All Rights Reserved.
  15. *
  16. * The original version of this source code and documentation
  17. * is copyrighted and owned by Taligent, Inc., a wholly-owned
  18. * subsidiary of IBM. These materials are provided under terms
  19. * of a License Agreement between Taligent and Sun. This technology
  20. * is protected by multiple US and International patents.
  21. *
  22. * This notice and attribution to Taligent may not be removed.
  23. * Taligent is a registered trademark of Taligent, Inc.
  24. *
  25. * Permission to use, copy, modify, and distribute this software
  26. * and its documentation for NON-COMMERCIAL purposes and without
  27. * fee is hereby granted provided that this copyright notice
  28. * appears in all copies. Please refer to the file "copyright.html"
  29. * for further important copyright and licensing information.
  30. *
  31. * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  32. * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  33. * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  34. * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  35. * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  36. * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  37. *
  38. */
  39. package java.util;
  40. import java.util.Hashtable;
  41. /**
  42. * <code>ListResourceBundle</code> is a abstract subclass of
  43. * <code>ResourceBundle</code> that manages resources for a locale
  44. * in a convenient and easy to use list. See <code>ResourceBundle</code> for
  45. * more information about resource bundles in general.
  46. *
  47. * <P>
  48. * Subclasses must override <code>getContents</code> and provide an array,
  49. * where each item in the array is a pair of objects.
  50. * The first element of each pair is a <code>String</code> key, and the second
  51. * is the value associated with that key. [Right now, there's no error-checking
  52. * code to enforce this, so you could specify key-value pairs that have
  53. * something other than a String as a key. But since the interfaces are defined
  54. * in terms of String, any value with a key that isn't a String will be
  55. * inaccessible.]
  56. *
  57. * <p>
  58. * In the following example, the keys are of the form "s1"... The actual
  59. * keys are entirely up to your choice, so long as they are the same as
  60. * the keys you use in your program to retrieve the objects from the bundle.
  61. * Keys are case-sensitive. <code>MyResource</code> is the default version
  62. * of the bundle family, and <code>MyResource_fr</code> is the french version:
  63. * <blockquote>
  64. * <pre>
  65. * //====================
  66. * class MyResource extends ListResourceBundle {
  67. * public Object[][] getContents() {
  68. * return contents;
  69. * }
  70. * static final Object[][] contents = {
  71. * // LOCALIZE THIS
  72. * {"s1", "3"}, // starting value in choice field
  73. * {"s2", "MyDisk"}, // starting value in string field
  74. * {"s3", "3 Mar 96"}, // starting value in date field
  75. * {"s4", "The disk '{1}' contained {0} on {2}."}, // initial pattern
  76. * {"s5", "0"}, // first choice number
  77. * {"s6", "no files"}, // first choice value
  78. * {"s7", "1"}, // second choice number
  79. * {"s8", "one file"}, // second choice value
  80. * {"s9", "2"}, // third choice number
  81. * {"s10", "{0}|3 files"}, // third choice value
  82. * {"s11", "format threw an exception: {0}"}, // generic exception message
  83. * {"s12", "ERROR"}, // what to show in field in case of error
  84. * {"s14", "Result"}, // label for formatted stuff
  85. * {"s13", "Dialog"}, // standard font
  86. * {"s15", "Pattern"}, // label for standard pattern
  87. * {"s16", new Dimension(1,5)} // real object, not just string
  88. * // END OF MATERIAL TO LOCALIZE
  89. * };
  90. * }
  91. * //====================
  92. * class MyResource_fr extends ListResourceBundle {
  93. * public Object[][] getContents() {
  94. * return contents;
  95. }
  96. * static final Object[][] contents = {
  97. * // LOCALIZE THIS
  98. * {"s1", "3"}, // starting value in choice field
  99. * {"s2", "MonDisk"}, // starting value in string field
  100. * {"s3", "3 Mar 96"}, // starting value in date field
  101. * {"s4", "Le disk '{1}' a {0} a {2}."}, // initial pattern
  102. * {"s5", "0"}, // first choice number
  103. * {"s6", "pas de files"}, // first choice value
  104. * {"s7", "1"}, // second choice number
  105. * {"s8", "une file"}, // second choice value
  106. * {"s9", "2"}, // third choice number
  107. * {"s10", "{0}|3 files"}, // third choice value
  108. * {"s11", "Le format a jete une exception: {0}"}, // generic exception message
  109. * {"s12", "ERROR"}, // what to show in field in case of error
  110. * {"s14", "Resulte"}, // label for formatted stuff
  111. * {"s13", "Dialogue"}, // standard font
  112. * {"s15", "Pattern"}, // label for standard pattern
  113. * {"s16", new Dimension(1,3)} // real object, not just string
  114. * // END OF MATERIAL TO LOCALIZE
  115. * };
  116. * }
  117. * </pre>
  118. * </blockquote>
  119. * @see ResourceBundle
  120. * @see PropertyResourceBundle
  121. */
  122. public abstract class ListResourceBundle extends ResourceBundle {
  123. /**
  124. * Sole constructor. (For invocation by subclass constructors, typically
  125. * implicit.)
  126. */
  127. public ListResourceBundle() {
  128. }
  129. /**
  130. * Override of ResourceBundle, same semantics
  131. */
  132. public final Object handleGetObject(String key) {
  133. // lazily load the lookup hashtable.
  134. if (lookup == null) {
  135. loadLookup();
  136. }
  137. return lookup.get(key); // this class ignores locales
  138. }
  139. /**
  140. * Implementation of ResourceBundle.getKeys.
  141. */
  142. public Enumeration getKeys() {
  143. // lazily load the lookup hashtable.
  144. if (lookup == null) {
  145. loadLookup();
  146. }
  147. Enumeration result = null;
  148. if (parent != null) {
  149. final Enumeration myKeys = lookup.keys();
  150. final Enumeration parentKeys = parent.getKeys();
  151. result = new Enumeration() {
  152. public boolean hasMoreElements() {
  153. if (temp == null)
  154. nextElement();
  155. return temp != null;
  156. }
  157. public Object nextElement() {
  158. Object returnVal = temp;
  159. if (myKeys.hasMoreElements())
  160. temp = myKeys.nextElement();
  161. else {
  162. temp = null;
  163. while (temp == null && parentKeys.hasMoreElements()) {
  164. temp = parentKeys.nextElement();
  165. if (lookup.containsKey(temp))
  166. temp = null;
  167. }
  168. }
  169. return returnVal;
  170. }
  171. Object temp = null;
  172. };
  173. } else {
  174. result = lookup.keys();
  175. }
  176. return result;
  177. }
  178. /**
  179. * See class description.
  180. */
  181. abstract protected Object[][] getContents();
  182. // ==================privates====================
  183. /**
  184. * We lazily load the lookup hashtable. This function does the
  185. * loading.
  186. */
  187. private synchronized void loadLookup() {
  188. if (lookup != null)
  189. return;
  190. Object[][] contents = getContents();
  191. Hashtable temp = new Hashtable(contents.length);
  192. for (int i = 0; i < contents.length; ++i) {
  193. temp.put(contents[i][0],contents[i][1]);
  194. }
  195. lookup = temp;
  196. }
  197. private Hashtable lookup = null;
  198. }