KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > HTTPClient > CIHashtable


1 /*
2  * @(#)CIHashtable.java 0.3-2 18/06/1999
3  *
4  * This file is part of the HTTPClient package
5  * Copyright (C) 1996-1999 Ronald Tschalär
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307, USA
21  *
22  * For questions, suggestions, bug-reports, enhancement-requests etc.
23  * I may be contacted at:
24  *
25  * ronald@innovation.ch
26  *
27  */

28
29 package HTTPClient;
30
31
32 import java.util.Hashtable;
33 import java.util.Enumeration;
34
35 /**
36  * This class implements a Hashtable with case-insensitive Strings as keys.
37  *
38  * @version 0.3-2 18/06/1999
39  * @author Ronald Tschalär
40  */

41
42 class CIHashtable extends Hashtable
43 {
44     // Constructors
45

46     /**
47      * Create a new CIHashtable with the specified initial capacity and the
48      * specified load factor.
49      *
50      * @param intialCapacity the initial number of buckets
51      * @param loadFactor a number between 0.0 and 1.0
52      * @see java.util.Hashtable(int, float)
53      */

54     public CIHashtable(int initialCapacity, float loadFactor)
55     {
56     super(initialCapacity, loadFactor);
57     }
58
59
60     /**
61      * Create a new CIHashtable with the specified initial capacity.
62      *
63      * @param intialCapacity the initial number of buckets
64      * @see java.util.Hashtable(int)
65      */

66     public CIHashtable(int initialCapacity)
67     {
68     super(initialCapacity);
69     }
70
71
72     /**
73      * Create a new CIHashtable with a default initial capacity.
74      *
75      * @see java.util.Hashtable()
76      */

77     public CIHashtable()
78     {
79     super();
80     }
81
82
83     // Methods
84

85     /**
86      * Retrieves the object associated with the specified key. The key lookup
87      * is case-insensitive.
88      *
89      * @param key the key
90      * @return the object associated with the key, or null if none found.
91      * @see java.util.Hashtable.get(Object)
92      */

93     public Object get(String key)
94     {
95     return super.get(new CIString(key));
96     }
97
98
99     /**
100      * Stores the specified object with the specified key.
101      *
102      * @param key the key
103      * @param value the object to be associated with the key
104      * @return the object previously associated with the key, or null if
105      * there was none.
106      * @see java.util.Hashtable.put(Object, Object)
107      */

108     public Object put(String key, Object value)
109     {
110     return super.put(new CIString(key), value);
111     }
112
113
114     /**
115      * Looks whether any object is associated with the specified key. The
116      * key lookup is case insensitive.
117      *
118      * @param key the key
119      * @return true is there is an object associated with key, false otherwise
120      * @see java.util.Hashtable.containsKey(Object)
121      */

122     public boolean containsKey(String key)
123     {
124     return super.contains(new CIString(key));
125     }
126
127
128     /**
129      * Removes the object associated with this key from the Hashtable. The
130      * key lookup is case insensitive.
131      *
132      * @param key the key
133      * @return the object associated with this key, or null if there was none.
134      * @see java.util.Hashtable.remove(Object)
135      */

136     public Object remove(String key)
137     {
138     return super.remove(new CIString(key));
139     }
140
141
142     /**
143      * Returns an enumeration of all the keys in the Hashtable.
144      *
145      * @return the requested Enumerator
146      * @see java.util.Hashtable.keys(Object)
147      */

148     public Enumeration keys()
149     {
150     return new CIHashtableEnumeration(super.keys());
151     }
152 }
153
154
155 /**
156  * A simple enumerator which delegates everything to the real enumerator.
157  * If a CIString element is returned, then the string it represents is
158  * returned instead.
159  */

160 final class CIHashtableEnumeration implements Enumeration
161 {
162     Enumeration HTEnum;
163
164     public CIHashtableEnumeration(Enumeration enum)
165     {
166     HTEnum = enum;
167     }
168
169     public boolean hasMoreElements()
170     {
171     return HTEnum.hasMoreElements();
172     }
173
174     public Object nextElement()
175     {
176     Object tmp = HTEnum.nextElement();
177     if (tmp instanceof CIString)
178         return ((CIString) tmp).getString();
179
180     return tmp;
181     }
182 }
183
184
185 /**
186  * This class' raison d'etre is that I want to use a Hashtable using
187  * Strings as keys and I want the lookup be case insensitive, but I
188  * also want to be able retrieve the keys with original case (otherwise
189  * I could just use toLowerCase() in the get() and put()). Since the
190  * class String is final we create a new class that holds the string
191  * and overrides the methods hashCode() and equals().
192  */

193 final class CIString
194 {
195     /** the string */
196     private String string;
197
198     /** the hash code */
199     private int hash;
200
201
202     /** the constructor */
203     public CIString(String string)
204     {
205     this.string = string;
206     this.hash = calcHashCode(string);
207     }
208
209     /** return the original string */
210     public final String getString()
211     {
212     return string;
213     }
214
215     /** the hash code was precomputed */
216     public int hashCode()
217     {
218     return hash;
219     }
220
221
222     /**
223      * We smash case before calculation so that the hash code is
224      * "case insensitive". This is based on code snarfed from
225      * java.lang.String.hashCode().
226      */

227     private static final int calcHashCode(String str)
228     {
229     int hash = 0;
230     char llc[] = lc;
231     int len = str.length();
232
233     for (int idx= 0; idx<len; idx++)
234         hash = 31*hash + llc[str.charAt(idx)];
235
236     return hash;
237     }
238
239
240     /**
241      * Uses the case insensitive comparison.
242      */

243     public boolean equals(Object obj)
244     {
245     if (obj != null)
246     {
247         if (obj instanceof CIString)
248         return string.equalsIgnoreCase(((CIString) obj).string);
249
250         if (obj instanceof String)
251         return string.equalsIgnoreCase((String) obj);
252     }
253
254     return false;
255     }
256
257     /**
258      * Just return the internal string.
259      */

260     public String toString()
261     {
262     return string;
263     }
264
265
266     private static final char[] lc = new char[256];
267
268     static
269     {
270     // just ISO-8859-1
271
for (char idx=0; idx<256; idx++)
272         lc[idx] = Character.toLowerCase(idx);
273     }
274 }
275
276
Popular Tags