/* * StringMap.java * * Brazil project web application toolkit, * export version: 2.3 * Copyright (c) 1999-2009 Sun Microsystems, Inc. * * Sun Public License Notice * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is included as the file "license.terms", * and also available at http://www.sun.com/ * * The Original Code is from: * Brazil project web application toolkit release 2.3. * The Initial Developer of the Original Code is: cstevens. * Portions created by cstevens are Copyright (C) Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): cstevens, suhler. * * Version: 2.8 * Created by cstevens on 99/09/15 * Last modified by suhler on 09/04/22 11:59:01 * * Version Histories: * * 2.8 09/04/22-11:59:01 (suhler) * add toString() option to specify item delimiter * * 2.7 08/03/04-11:08:11 (suhler) * javadoc fixes * * 2.6 08/03/04-10:57:51 (suhler) * StringMap.java * * 2.5 07/01/14-15:12:01 (suhler) * add get(key, dflt) * * 2.4 05/05/26-08:59:24 (suhler) * add append() to combite 2 string maps * * 2.3 04/11/30-15:19:45 (suhler) * fixed sccs version string * * 2.2 04/04/28-15:55:32 (suhler) * doc format fixes * * 2.1 02/10/01-16:36:58 (suhler) * version change * * 1.11 00/03/29-16:46:29 (cstevens) * * 1.10 99/11/16-14:47:27 (cstevens) * Rename "getValue" to "get" to make it more compatible with Dictionary * naming scheme. * * 1.9 99/10/19-19:00:19 (cstevens) * toString crashed if nothing in stringMap. * * 1.8 99/10/14-12:57:39 (cstevens) * Documentation for StringMap.toString. * * 1.7 99/10/07-13:02:35 (cstevens) * javadoc lint. * * 1.6 99/10/04-17:16:38 (cstevens) * tostring * * 1.5 99/10/04-16:13:39 (cstevens) * Merged changes between child workspace "/home/cstevens/ws/brazil/naws" and * parent workspace "/export/ws/brazil/naws". * * 1.3.1.1 99/10/04-16:03:18 (cstevens) * Documentation for LexML and StringMap. * * 1.4 99/10/01-11:21:00 (suhler) * added toString() * * 1.3 99/09/15-15:56:38 (cstevens) * bug * * 1.2 99/09/15-14:51:43 (cstevens) * lines ended with CRLF. * * 1.2 99/09/15-14:31:03 (Codemgr) * SunPro Code Manager data about conflicts, renames, etc... * Name history : 1 0 util/StringMap.java * * 1.1 99/09/15-14:31:02 (cstevens) * date and time created 99/09/15 14:31:02 by cstevens * */ package sunlabs.brazil.util; import java.util.Dictionary; import java.util.Enumeration; import java.util.Vector; /** * The StringMap class is a substitute for the Hashtable. * The StringMap has the following properties: * * @author Colin Stevens (colin.stevens@sun.com) * @version 2.8 */ public class StringMap extends Dictionary { Vector keys; Vector values; /** * Creates an empty StringMap. */ public StringMap() { keys = new Vector(); values = new Vector(); } /** * Returns the number of elements in this StringMap. Every occurrence of * keys that appear multiple times is counted. * * @return The number of elements in this StringMap. * * @see #keys * * implements Dictionary#size */ public int size() { return keys.size(); } /** * Tests if there are any elements in this StringMap. * * @return Returns true if there are no elements, * false otherwise. * * implements Dictionary#isEmpty */ public boolean isEmpty() { return keys.isEmpty(); } /** * Returns an enumeration of the keys in this StringMap. The elements * of the enumeration are strings. *

* The same key may appear multiple times in the enumeration, not * necessarily consecutively. Since get always returns * the value associated with the first occurrence of a given key, a * StringMap cannot be enumerated in the same fashion as a Hashtable. * Instead, the caller should use: *

     * Enumeration keys = map.keys();
     * Enumeration values = map.elements();
     * while (keys.hasMoreElements()) {
     *     String key = (String) keys.nextElement();
     *     String value = (String) values.nextElement();
     * }
     * 
* or: *
     * for (int i = 0; i < map.size(); i++) {
     *     String key = map.getKey(i);
     *     String value = map.get(i);
     * }
     * 
* * @return An enumeration of the keys. * * @see #elements * @see #size * @see #getKey * @see #get * * implements Dictionary#keys */ public Enumeration keys() { return keys.elements(); } /** * Returns an enumeration of the values in this StringMap. The elements * of the enumeration are strings. * * @return An enumeration of the values. * * @see #keys * * implements Dictionary#elements */ public Enumeration elements() { return values.elements(); } /** * Returns the key at the specified index. The index ranges from * 0 to size() - 1. *

* This method can be used to iterate over all the keys in this * StringMap in the order in which they were inserted, subject to any * intervening deletions. * * @param index * The index of the key. * * @return The key at the specified index. * * @throws IndexOutOfBoundsException * if the index is out of the allowed range. */ public String getKey(int index) throws IndexOutOfBoundsException { return (String) keys.elementAt(index); } /** * Returns the value at the specified index. The index ranges from * 0 to size() - 1. *

* This method can be used to iterate over all the values in this * StringMap in the order in which they were inserted, subject to any * intervening deletions. * * @param index * The index of the key. * * @return The value at the specified index. * * @throws IndexOutOfBoundsException * if the index is out of the allowed range. */ public String get(int index) throws IndexOutOfBoundsException { return (String) values.elementAt(index); } /** * Returns the value that the specified case-insensitive key maps to * in this StringMap. *

* The same key may appear multiple times in the enumeration; this * method always returns the value associated with the first * occurrence of the specified key. In order to get all the values, * it is necessary to iterate over the entire StringMap to retrieve * all the values associated with a given key. * * @param key * A key in this StringMap. May not be null. * * @return The value to which the specified key is mapped, or * null if the key is not in the StringMap. * * @see #keys */ public String get(String key) { return get(key, null); } /** * Returns the value that the specified case-insensitive key maps to * in this StringMap. * @param key * A key in this StringMap. May not be null. * @param dflt * A default value if the entry for key is not found. * * @return The value to which the specified key is mapped, or * dflt if the key is not in the StringMap. */ public String get(String key, String dflt) { int i = indexOf(key); if (i >= 0) { return (String) values.elementAt(i); } else { return dflt; } } /** * Performs the same job as get(String). It exists so * this class can extend the Dictionary class. * * @param key * Must be a String. * * @return A String value. * * @throws ClassCastException * if the key is not a String. * * @see #get(String) * * implements Dictionary#get */ public Object get(Object key) { return get((String) key); } /** * Maps the key at the given index to the specified value in this * StringMap. The index ranges from 0 to * size() - 1. * * @param index * The index of the key. * * @param The value at the specified index. * * @throws IndexOutOfBoundsException * if the index is out of the allowed range. */ public void put(int index, String value) { values.setElementAt(value, index); } /** * Maps the given case-insensitive key to the specified value in this * StringMap. *

* The value can be retrieved by calling get with a * key that is case-insensitive equal to the given key. *

* If this StringMap already contained a mapping for the given key, * the old value is forgotten and the new specified value is used. * The case of the prior key is retained in that case. Otherwise * the case of the new key is used. * * @param key * The new key. May not be null. * * @param value * The new value. May be null. */ public void put(String key, String value) { int i = indexOf(key); if (i < 0) { keys.addElement(key); values.addElement(value); } else { values.setElementAt(value, i); } } /** * Performs the same job as put(String, String). It exists * so this class can extend the Dictionary class. * * @param key * Must be a String. * * @param value * Must be a String. * * @return The previous value to which key was mapped, * or null if the the key did not map to any * value. * * @throws ClassCastException * if the key or value is not a * String. * * @see #put(String, String) * * implements Dictionary#put */ public Object put(Object key, Object value) { String skey = (String) key; String svalue = (String) value; Object prior; int i = indexOf(skey); if (i < 0) { prior = null; keys.addElement(skey); values.addElement(svalue); } else { prior = values.elementAt(i); values.setElementAt(svalue, i); } return prior; } /** * Maps the given case-insensitive key to the specified value in this * StringMap. *

* The new mapping is added to this StringMap even if the given key * already has a mapping. In this way it is possible to create a key * that maps to two or more values. *

* Since the same key may appear multiple times in this StringMap, it * is necessary to iterate over the entire StringMap to retrieve all * values associated with a given key. * * @param key * The new key. May not be null. * * @param value * The new value. May be null. * * @see #put(String, String) * @see #keys */ public void add(String key, String value) { keys.addElement(key); values.addElement(value); } /** * Removes the given case-insensitive key and its corresponding value * from this StringMap. This method does nothing if the key is not in * this StringMap. *

* The same key may appear in multiple times in this StringMap; this * method only removes the first occurrence of the key. * * @param key * The key that needs to be removed. Must not be * null. */ public void remove(String key) { int i = indexOf(key); if (i >= 0) { remove(i); } } public void remove(int i) { keys.removeElementAt(i); values.removeElementAt(i); } /** * Performs the same job as remove(String). It exists so * this class can extend the Dictionary class. * * @param key * Must be a String. * * @return The string value to which the key had been mapped, or * null if the key did not have a mapping. * * @throws ClassCastException * if the key is not a String. * * implements Dictionary#remove */ public Object remove(Object key) { int i = indexOf((String) key); if (i >= 0) { Object prior = values.elementAt(i); remove(i); return prior; } return null; } /** * Removes all the keys and values from this StringMap. */ public void clear() { keys.setSize(0); values.setSize(0); } private int indexOf(String key) { int length = keys.size(); for (int i = 0; i < length; i++) { String got = (String) keys.elementAt(i); if (key.equalsIgnoreCase(got)) { return i; } } return -1; } /** * Append another Stringmap onto this one. * @param other the map to append to this one * @param noReplace should existing values be replaced? */ public void append(StringMap other, boolean noReplace) { int size = (other != null) ? other.size() : 0; for (int i = 0; i < size; i++) { if (noReplace) { add(other.getKey(i), other.get(i)); } else { put(other.getKey(i), other.get(i)); } } } /** * Returns a string representation of this StringMap in the * form of a set of entries, enclosed in braces and separated by the * characters ", ". Each entry is rendered as the key, an equals sign * "=", and the associated value. * * @return The string representation of this StringMap. */ public String toString() { return toString(", "); } /** * Returns a string representation of this StringMap in the * form of a set of entries, enclosed in braces and separated by the * supplied argument string. * Each entry is rendered as the key, an equals sign * "=", and the associated value. * * @return The string representation of this StringMap. */ public String toString(String sep) { StringBuffer sb = new StringBuffer(); sb.append('{'); int length = keys.size(); for (int i = 0; i < length; i++) { sb.append(getKey(i)); sb.append('='); sb.append(get(i)); sb.append(sep); } if (sb.length() > 1) { sb.setLength(sb.length() - sep.length()); } sb.append('}'); return sb.toString(); } }