View Javadoc
1 package org.apache.turbine.util; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.util.Collection; 58 import java.util.Hashtable; 59 import java.util.Iterator; 60 import java.util.LinkedList; 61 import java.util.Map; 62 import java.util.Set; 63 64 /*** 65 * A {@link java.util.Hashtable} whose keys are sequenced. The 66 * sequencing of the keys allow easy access to the values in the order 67 * which they were added in. This class is thread safe. 68 * <p> 69 * Implementing the List interface is not possible due to a instance 70 * method name clash. Java does not support method renaming. 71 * <p> 72 * A slightly more complex implementation and interface could involve 73 * the use of a list of <code>Map.Entry</code> objects. 74 * 75 * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> 76 * @version $Id: SequencedHashtable.java,v 1.4 2001/05/20 02:38:52 dlr Exp $ 77 */ 78 public class SequencedHashtable extends Hashtable 79 { 80 /*** 81 * Indicator for an unknown index. 82 */ 83 private static final int UKNOWN_INDEX = -1; 84 85 /*** 86 * The sequence used to keep track of the hash keys. Younger objects are 87 * kept towards the end of the list. Does not allow duplicates. 88 */ 89 private LinkedList keySequence; 90 91 /*** 92 * Creates a new instance with default storage. 93 */ 94 public SequencedHashtable () 95 { 96 keySequence = new LinkedList(); 97 } 98 99 /*** 100 * Creates a new instance with the specified storage. 101 * 102 * @param size The storage to allocate up front. 103 */ 104 public SequencedHashtable (int size) 105 { 106 super(size); 107 keySequence = new LinkedList(); 108 } 109 110 /*** 111 * Clears all elements. 112 */ 113 public synchronized void clear () 114 { 115 super.clear(); 116 keySequence.clear(); 117 } 118 119 /*** 120 * Creates a shallow copy of this object, preserving the internal 121 * structure by copying only references. The keys, values, and 122 * sequence are not <code>clone()</code>'d. 123 * 124 * @return A clone of this instance. 125 */ 126 public synchronized Object clone () 127 { 128 SequencedHashtable seqHash = (SequencedHashtable) super.clone(); 129 seqHash.keySequence = (LinkedList) keySequence.clone(); 130 return seqHash; 131 } 132 133 /*** 134 * Returns the key at the specified index. 135 */ 136 public Object get (int index) 137 { 138 return keySequence.get(index); 139 } 140 141 /*** 142 * Returns the value at the specified index. 143 */ 144 public Object getValue (int index) 145 { 146 return get(get(index)); 147 } 148 149 /*** 150 * Returns the index of the specified key. 151 */ 152 public int indexOf (Object key) 153 { 154 return keySequence.indexOf(key); 155 } 156 157 /*** 158 * Returns a key iterator. 159 */ 160 public Iterator iterator () 161 { 162 return keySequence.iterator(); 163 } 164 165 /*** 166 * Returns the last index of the specified key. 167 */ 168 public int lastIndexOf (Object key) 169 { 170 return keySequence.lastIndexOf(key); 171 } 172 173 /*** 174 * Stores the provided key/value pair. Freshens the sequence of existing 175 * elements. 176 * 177 * @param key The key to the provided value. 178 * @param value The value to store. 179 * @return The previous value for the specified key, or 180 * <code>null</code> if none. 181 */ 182 public synchronized Object put (Object key, Object value) 183 { 184 Object prevValue = super.put(key, value); 185 freshenSequence(key, prevValue); 186 return prevValue; 187 } 188 189 /*** 190 * Freshens the sequence of the element <code>value</code> if 191 * <code>value</code> is not <code>null</code>. 192 * 193 * @param key The key whose sequence to freshen. 194 * @param value The value whose existance to check before removing the old 195 * key sequence. 196 */ 197 protected void freshenSequence(Object key, Object value) 198 { 199 if (value != null) 200 { 201 // Freshening existing element's sequence. 202 keySequence.remove(key); 203 } 204 keySequence.add(key); 205 } 206 207 /*** 208 * Stores the provided key/value pairs. 209 * 210 * @param t The key/value pairs to store. 211 */ 212 public synchronized void putAll (Map t) 213 { 214 Set set = t.entrySet(); 215 for (Iterator iter = set.iterator(); iter.hasNext(); ) 216 { 217 Map.Entry e = (Map.Entry)iter.next(); 218 put(e.getKey(), e.getValue()); 219 } 220 } 221 222 /*** 223 * Removes the element at the specified index. 224 * 225 * @param index The index of the object to remove. 226 * @return The previous value coressponding the <code>key</code>, or 227 * <code>null</code> if none existed. 228 */ 229 public Object remove (int index) 230 { 231 return remove(index, null); 232 } 233 234 /*** 235 * Removes the element with the specified key. 236 * 237 * @param key The <code>Map</code> key of the object to remove. 238 * @return The previous value coressponding the <code>key</code>, or 239 * <code>null</code> if none existed. 240 */ 241 public Object remove (Object key) 242 { 243 return remove(UKNOWN_INDEX, key); 244 } 245 246 /*** 247 * Removes the element with the specified key or index. 248 * 249 * @param index The index of the object to remove, or 250 * <code>UKNOWN_INDEX</code> if not known. 251 * @param key The <code>Map</code> key of the object to remove. 252 * @return The previous value coressponding the <code>key</code>, or 253 * <code>null</code> if none existed. 254 */ 255 private final synchronized Object remove (int index, Object key) 256 { 257 if (index == UKNOWN_INDEX) index = indexOf(key); 258 if (key == null) key = get(index); 259 if (index != UKNOWN_INDEX) keySequence.remove(index); 260 return super.remove(key); 261 } 262 263 /*** 264 * Slightly cheaper implementation of <code>values()</code> method. 265 */ 266 public Collection values () 267 { 268 return keySequence; 269 } 270 }

This page was automatically generated by Maven