211 lines
8.0 KiB
Java
211 lines
8.0 KiB
Java
![]() |
/*
|
||
|
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||
|
*
|
||
|
* This code is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License version 2 only, as
|
||
|
* published by the Free Software Foundation. Oracle designates this
|
||
|
* particular file as subject to the "Classpath" exception as provided
|
||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||
|
*
|
||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||
|
* accompanied this code).
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License version
|
||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
*
|
||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||
|
* or visit www.oracle.com if you need additional information or have any
|
||
|
* questions.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
|
||
|
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
|
||
|
*
|
||
|
* The original version of this source code and documentation
|
||
|
* is copyrighted and owned by Taligent, Inc., a wholly-owned
|
||
|
* subsidiary of IBM. These materials are provided under terms
|
||
|
* of a License Agreement between Taligent and Sun. This technology
|
||
|
* is protected by multiple US and International patents.
|
||
|
*
|
||
|
* This notice and attribution to Taligent may not be removed.
|
||
|
* Taligent is a registered trademark of Taligent, Inc.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
package java.util;
|
||
|
|
||
|
import sun.util.ResourceBundleEnumeration;
|
||
|
|
||
|
/**
|
||
|
* {@code ListResourceBundle} is an abstract subclass of
|
||
|
* {@code ResourceBundle} that manages resources for a locale
|
||
|
* in a convenient and easy to use list. See {@code ResourceBundle} for
|
||
|
* more information about resource bundles in general.
|
||
|
*
|
||
|
* <P>
|
||
|
* Subclasses must override {@code getContents} and provide an array,
|
||
|
* where each item in the array is a pair of objects.
|
||
|
* The first element of each pair is the key, which must be a
|
||
|
* {@code String}, and the second element is the value associated with
|
||
|
* that key.
|
||
|
*
|
||
|
* <p>
|
||
|
* The following <a id="sample">example</a> shows two members of a resource
|
||
|
* bundle family with the base name "MyResources".
|
||
|
* "MyResources" is the default member of the bundle family, and
|
||
|
* "MyResources_fr" is the French member.
|
||
|
* These members are based on {@code ListResourceBundle}
|
||
|
* (a related <a href="PropertyResourceBundle.html#sample">example</a> shows
|
||
|
* how you can add a bundle to this family that's based on a properties file).
|
||
|
* The keys in this example are of the form "s1" etc. The actual
|
||
|
* keys are entirely up to your choice, so long as they are the same as
|
||
|
* the keys you use in your program to retrieve the objects from the bundle.
|
||
|
* Keys are case-sensitive.
|
||
|
* <blockquote>
|
||
|
* <pre>
|
||
|
*
|
||
|
* public class MyResources extends ListResourceBundle {
|
||
|
* protected Object[][] getContents() {
|
||
|
* return new Object[][] {
|
||
|
* // LOCALIZE THIS
|
||
|
* {"s1", "The disk \"{1}\" contains {0}."}, // MessageFormat pattern
|
||
|
* {"s2", "1"}, // location of {0} in pattern
|
||
|
* {"s3", "My Disk"}, // sample disk name
|
||
|
* {"s4", "no files"}, // first ChoiceFormat choice
|
||
|
* {"s5", "one file"}, // second ChoiceFormat choice
|
||
|
* {"s6", "{0,number} files"}, // third ChoiceFormat choice
|
||
|
* {"s7", "3 Mar 96"}, // sample date
|
||
|
* {"s8", new Dimension(1,5)} // real object, not just string
|
||
|
* // END OF MATERIAL TO LOCALIZE
|
||
|
* };
|
||
|
* }
|
||
|
* }
|
||
|
*
|
||
|
* public class MyResources_fr extends ListResourceBundle {
|
||
|
* protected Object[][] getContents() {
|
||
|
* return new Object[][] {
|
||
|
* // LOCALIZE THIS
|
||
|
* {"s1", "Le disque \"{1}\" {0}."}, // MessageFormat pattern
|
||
|
* {"s2", "1"}, // location of {0} in pattern
|
||
|
* {"s3", "Mon disque"}, // sample disk name
|
||
|
* {"s4", "ne contient pas de fichiers"}, // first ChoiceFormat choice
|
||
|
* {"s5", "contient un fichier"}, // second ChoiceFormat choice
|
||
|
* {"s6", "contient {0,number} fichiers"}, // third ChoiceFormat choice
|
||
|
* {"s7", "3 mars 1996"}, // sample date
|
||
|
* {"s8", new Dimension(1,3)} // real object, not just string
|
||
|
* // END OF MATERIAL TO LOCALIZE
|
||
|
* };
|
||
|
* }
|
||
|
* }
|
||
|
* </pre>
|
||
|
* </blockquote>
|
||
|
*
|
||
|
* <p>
|
||
|
* The implementation of a {@code ListResourceBundle} subclass must be thread-safe
|
||
|
* if it's simultaneously used by multiple threads. The default implementations
|
||
|
* of the methods in this class are thread-safe.
|
||
|
*
|
||
|
* @see ResourceBundle
|
||
|
* @see PropertyResourceBundle
|
||
|
* @since 1.1
|
||
|
*/
|
||
|
public abstract class ListResourceBundle extends ResourceBundle {
|
||
|
/**
|
||
|
* Sole constructor. (For invocation by subclass constructors, typically
|
||
|
* implicit.)
|
||
|
*/
|
||
|
public ListResourceBundle() {
|
||
|
}
|
||
|
|
||
|
// Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification.
|
||
|
public final Object handleGetObject(String key) {
|
||
|
// lazily load the lookup hashtable.
|
||
|
if (lookup == null) {
|
||
|
loadLookup();
|
||
|
}
|
||
|
if (key == null) {
|
||
|
throw new NullPointerException();
|
||
|
}
|
||
|
return lookup.get(key); // this class ignores locales
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an {@code Enumeration} of the keys contained in
|
||
|
* this {@code ResourceBundle} and its parent bundles.
|
||
|
*
|
||
|
* @return an {@code Enumeration} of the keys contained in
|
||
|
* this {@code ResourceBundle} and its parent bundles.
|
||
|
* @see #keySet()
|
||
|
*/
|
||
|
public Enumeration<String> getKeys() {
|
||
|
// lazily load the lookup hashtable.
|
||
|
if (lookup == null) {
|
||
|
loadLookup();
|
||
|
}
|
||
|
|
||
|
ResourceBundle parent = this.parent;
|
||
|
return new ResourceBundleEnumeration(lookup.keySet(),
|
||
|
(parent != null) ? parent.getKeys() : null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a {@code Set} of the keys contained
|
||
|
* <em>only</em> in this {@code ResourceBundle}.
|
||
|
*
|
||
|
* @return a {@code Set} of the keys contained only in this
|
||
|
* {@code ResourceBundle}
|
||
|
* @since 1.6
|
||
|
* @see #keySet()
|
||
|
*/
|
||
|
protected Set<String> handleKeySet() {
|
||
|
if (lookup == null) {
|
||
|
loadLookup();
|
||
|
}
|
||
|
return lookup.keySet();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns an array in which each item is a pair of objects in an
|
||
|
* {@code Object} array. The first element of each pair is
|
||
|
* the key, which must be a {@code String}, and the second
|
||
|
* element is the value associated with that key. See the class
|
||
|
* description for details.
|
||
|
*
|
||
|
* @return an array of an {@code Object} array representing a
|
||
|
* key-value pair.
|
||
|
*/
|
||
|
protected abstract Object[][] getContents();
|
||
|
|
||
|
// ==================privates====================
|
||
|
|
||
|
/**
|
||
|
* We lazily load the lookup hashtable. This function does the
|
||
|
* loading.
|
||
|
*/
|
||
|
private synchronized void loadLookup() {
|
||
|
if (lookup != null)
|
||
|
return;
|
||
|
|
||
|
Object[][] contents = getContents();
|
||
|
HashMap<String,Object> temp = new HashMap<>(contents.length);
|
||
|
for (Object[] content : contents) {
|
||
|
// key must be non-null String, value must be non-null
|
||
|
String key = (String) content[0];
|
||
|
Object value = content[1];
|
||
|
if (key == null || value == null) {
|
||
|
throw new NullPointerException();
|
||
|
}
|
||
|
temp.put(key, value);
|
||
|
}
|
||
|
lookup = temp;
|
||
|
}
|
||
|
|
||
|
private volatile Map<String,Object> lookup;
|
||
|
}
|