Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 /*
     27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
     28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
     29  *
     30  * The original version of this source code and documentation
     31  * is copyrighted and owned by Taligent, Inc., a wholly-owned
     32  * subsidiary of IBM. These materials are provided under terms
     33  * of a License Agreement between Taligent and Sun. This technology
     34  * is protected by multiple US and International patents.
     35  *
     36  * This notice and attribution to Taligent may not be removed.
     37  * Taligent is a registered trademark of Taligent, Inc.
     38  *
     39  */
     40 
     41 package java.util;
     42 
     43 import sun.util.ResourceBundleEnumeration;
     44 
     45 /**
     46  * <code>ListResourceBundle</code> is an abstract subclass of
     47  * <code>ResourceBundle</code> that manages resources for a locale
     48  * in a convenient and easy to use list. See <code>ResourceBundle</code> for
     49  * more information about resource bundles in general.
     50  *
     51  * <P>
     52  * Subclasses must override <code>getContents</code> and provide an array,
     53  * where each item in the array is a pair of objects.
     54  * The first element of each pair is the key, which must be a
     55  * <code>String</code>, and the second element is the value associated with
     56  * that key.
     57  *
     58  * <p>
     59  * The following <a name="sample">example</a> shows two members of a resource
     60  * bundle family with the base name "MyResources".
     61  * "MyResources" is the default member of the bundle family, and
     62  * "MyResources_fr" is the French member.
     63  * These members are based on <code>ListResourceBundle</code>
     64  * (a related <a href="PropertyResourceBundle.html#sample">example</a> shows
     65  * how you can add a bundle to this family that's based on a properties file).
     66  * The keys in this example are of the form "s1" etc. The actual
     67  * keys are entirely up to your choice, so long as they are the same as
     68  * the keys you use in your program to retrieve the objects from the bundle.
     69  * Keys are case-sensitive.
     70  * <blockquote>
     71  * <pre>
     72  *
     73  * public class MyResources extends ListResourceBundle {
     74  *     protected Object[][] getContents() {
     75  *         return new Object[][] {
     76  *         // LOCALIZE THIS
     77  *             {"s1", "The disk \"{1}\" contains {0}."},  // MessageFormat pattern
     78  *             {"s2", "1"},                               // location of {0} in pattern
     79  *             {"s3", "My Disk"},                         // sample disk name
     80  *             {"s4", "no files"},                        // first ChoiceFormat choice
     81  *             {"s5", "one file"},                        // second ChoiceFormat choice
     82  *             {"s6", "{0,number} files"},                // third ChoiceFormat choice
     83  *             {"s7", "3 Mar 96"},                        // sample date
     84  *             {"s8", new Dimension(1,5)}                 // real object, not just string
     85  *         // END OF MATERIAL TO LOCALIZE
     86  *         };
     87  *     }
     88  * }
     89  *
     90  * public class MyResources_fr extends ListResourceBundle {
     91  *     protected Object[][] getContents() {
     92  *         return new Object[][] {
     93  *         // LOCALIZE THIS
     94  *             {"s1", "Le disque \"{1}\" {0}."},          // MessageFormat pattern
     95  *             {"s2", "1"},                               // location of {0} in pattern
     96  *             {"s3", "Mon disque"},                      // sample disk name
     97  *             {"s4", "ne contient pas de fichiers"},     // first ChoiceFormat choice
     98  *             {"s5", "contient un fichier"},             // second ChoiceFormat choice
     99  *             {"s6", "contient {0,number} fichiers"},    // third ChoiceFormat choice
    100  *             {"s7", "3 mars 1996"},                     // sample date
    101  *             {"s8", new Dimension(1,3)}                 // real object, not just string
    102  *         // END OF MATERIAL TO LOCALIZE
    103  *         };
    104  *     }
    105  * }
    106  * </pre>
    107  * </blockquote>
    108  *
    109  * <p>
    110  * The implementation of a {@code ListResourceBundle} subclass must be thread-safe
    111  * if it's simultaneously used by multiple threads. The default implementations
    112  * of the methods in this class are thread-safe.
    113  *
    114  * @see ResourceBundle
    115  * @see PropertyResourceBundle
    116  * @since JDK1.1
    117  */
    118 public abstract class ListResourceBundle extends ResourceBundle {
    119     /**
    120      * Sole constructor.  (For invocation by subclass constructors, typically
    121      * implicit.)
    122      */
    123     public ListResourceBundle() {
    124     }
    125 
    126     // Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification.
    127     public final Object handleGetObject(String key) {
    128         // lazily load the lookup hashtable.
    129         if (lookup == null) {
    130             loadLookup();
    131         }
    132         if (key == null) {
    133             throw new NullPointerException();
    134         }
    135         return lookup.get(key); // this class ignores locales
    136     }
    137 
    138     /**
    139      * Returns an <code>Enumeration</code> of the keys contained in
    140      * this <code>ResourceBundle</code> and its parent bundles.
    141      *
    142      * @return an <code>Enumeration</code> of the keys contained in
    143      *         this <code>ResourceBundle</code> and its parent bundles.
    144      * @see #keySet()
    145      */
    146     public Enumeration<String> getKeys() {
    147         // lazily load the lookup hashtable.
    148         if (lookup == null) {
    149             loadLookup();
    150         }
    151 
    152         ResourceBundle parent = this.parent;
    153         return new ResourceBundleEnumeration(lookup.keySet(),
    154                 (parent != null) ? parent.getKeys() : null);
    155     }
    156 
    157     /**
    158      * Returns a <code>Set</code> of the keys contained
    159      * <em>only</em> in this <code>ResourceBundle</code>.
    160      *
    161      * @return a <code>Set</code> of the keys contained only in this
    162      *         <code>ResourceBundle</code>
    163      * @since 1.6
    164      * @see #keySet()
    165      */
    166     protected Set<String> handleKeySet() {
    167         if (lookup == null) {
    168             loadLookup();
    169         }
    170         return lookup.keySet();
    171     }
    172 
    173     /**
    174      * Returns an array in which each item is a pair of objects in an
    175      * <code>Object</code> array. The first element of each pair is
    176      * the key, which must be a <code>String</code>, and the second
    177      * element is the value associated with that key.  See the class
    178      * description for details.
    179      *
    180      * @return an array of an <code>Object</code> array representing a
    181      * key-value pair.
    182      */
    183     abstract protected Object[][] getContents();
    184 
    185     // ==================privates====================
    186 
    187     /**
    188      * We lazily load the lookup hashtable.  This function does the
    189      * loading.
    190      */
    191     private synchronized void loadLookup() {
    192         if (lookup != null)
    193             return;
    194 
    195         Object[][] contents = getContents();
    196         HashMap<String,Object> temp = new HashMap<>(contents.length);
    197         for (int i = 0; i < contents.length; ++i) {
    198             // key must be non-null String, value must be non-null
    199             String key = (String) contents[i][0];
    200             Object value = contents[i][1];
    201             if (key == null || value == null) {
    202                 throw new NullPointerException();
    203             }
    204             temp.put(key, value);
    205         }
    206         lookup = temp;
    207     }
    208 
    209     // Android-changed: Fix unsafe publication http://b/31467561
    210     // Fixed in OpenJDK 9: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/29ecac30ecae
    211     // was: private Map<String,Object> lookup = null;
    212     private volatile Map<String,Object> lookup = null;
    213 }
    214