Author: bodewig
Date: Tue Nov 30 16:39:53 2010
New Revision: 1040627

URL: http://svn.apache.org/viewvc?rev=1040627&view=rev
Log:
A Hashtable subclass that works like a LinkedHashMap.  Will be useful for PR 
50297

Added:
    ant/core/trunk/src/main/org/apache/tools/ant/util/LinkedHashtable.java   
(with props)
    
ant/core/trunk/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
   (with props)

Added: ant/core/trunk/src/main/org/apache/tools/ant/util/LinkedHashtable.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/LinkedHashtable.java?rev=1040627&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/util/LinkedHashtable.java 
(added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/util/LinkedHashtable.java Tue 
Nov 30 16:39:53 2010
@@ -0,0 +1,130 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Subclass of Hashtable that wraps a LinkedHashMap to provide
+ * predictable iteration order.
+ *
+ * <p>This is not a general purpose class but has been written because
+ * the protected members of {...@link org.apache.tools.ant.taskdefs.Copy
+ * Copy} prohibited later revisions from using a more predictable
+ * collection.</p>
+ *
+ * <p>Methods are synchronized to keep Hashtable's contract.</p>
+ *
+ * @since Ant 1.8.2
+ */
+public class LinkedHashtable extends Hashtable {
+    private final LinkedHashMap map;
+
+    public LinkedHashtable() {
+        map = new LinkedHashMap();
+    }
+
+    public LinkedHashtable(int initialCapacity) {
+        map = new LinkedHashMap(initialCapacity);
+    }
+
+    public LinkedHashtable(int initialCapacity, float loadFactor) {
+        map = new LinkedHashMap(initialCapacity, loadFactor);
+    }
+
+    public LinkedHashtable(Map m) {
+        map = new LinkedHashMap(m);
+    }
+
+    public synchronized void clear() {
+        map.clear();
+    }
+
+    public boolean contains(Object value) {
+        return containsKey(value);
+    }
+
+    public synchronized boolean containsKey(Object value) {
+        return map.containsKey(value);
+    }
+
+    public synchronized boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    public Enumeration elements() {
+        return CollectionUtils.asEnumeration(values().iterator());
+    }
+
+    public synchronized Set entrySet() {
+        return map.entrySet();
+    }
+
+    public synchronized boolean equals(Object o) {
+        return map.equals(o);
+    }
+
+    public synchronized Object get(Object k) {
+        return map.get(k);
+    }
+
+    public synchronized int hashCode() {
+        return map.hashCode();
+    }
+
+    public synchronized boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    public Enumeration keys() {
+        return CollectionUtils.asEnumeration(keySet().iterator());
+    }
+
+    public synchronized Set keySet() {
+        return map.keySet();
+    }
+
+    public synchronized Object put(Object k, Object v) {
+        return map.put(k, v);
+    }
+
+    public synchronized void putAll(Map m) {
+        map.putAll(m);
+    }
+
+    public synchronized Object remove(Object k) {
+        return map.remove(k);
+    }
+
+    public synchronized int size() {
+        return map.size();
+    }
+
+    public synchronized String toString() {
+        return map.toString();
+    }
+
+    public synchronized Collection values() {
+        return map.values();
+    }
+}

Propchange: 
ant/core/trunk/src/main/org/apache/tools/ant/util/LinkedHashtable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java?rev=1040627&view=auto
==============================================================================
--- 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
 (added)
+++ 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
 Tue Nov 30 16:39:53 2010
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import junit.framework.TestCase;
+
+public class LinkedHashtableTest extends TestCase {
+
+    private static final Object K1 = new Object();
+    private static final Object K2 = new Object();
+    private static final Object V1 = new Object();
+    private static final Object V2 = new Object();
+    private Hashtable h = new LinkedHashtable();
+
+    public void testClear() {
+        h.put(K1, V1);
+        h.clear();
+        assertTrue(h.isEmpty());
+    }
+
+    public void testClone() {
+        h.put(K1, V1);
+        Hashtable h2 = (Hashtable) h.clone();
+        assertTrue(h2 instanceof LinkedHashtable);
+        assertTrue(h2.containsKey(K1));
+    }
+
+    public void testContainsAndPut() {
+        h.put(K1, V1);
+        assertTrue(h.contains(K1));
+        assertTrue(h.containsKey(K1));
+        assertTrue(h.containsValue(V1));
+        assertFalse(h.containsKey(K2));
+    }
+
+    public void testGet() {
+        assertNull(h.get(K1));
+        h.put(K1, V1);
+        assertSame(V1, h.get(K1));
+    }
+
+    public void testIsEmpty() {
+        assertTrue(h.isEmpty());
+        h.put(K1, V1);
+        assertFalse(h.isEmpty());
+    }
+
+    public void testPutReturnValue() {
+        assertNull(h.put(K1, V1));
+        assertSame(V1, h.put(K1, V2));
+    }
+
+    public void testPutAll() {
+        LinkedHashtable h2 = new LinkedHashtable();
+        h.put(K1, V1);
+        h2.putAll(h);
+        assertTrue(h2.containsKey(K1));
+    }
+
+    public void testRemove() {
+        h.put(K1, V1);
+        assertSame(V1, h.remove(K1));
+        assertTrue(h.isEmpty());
+        assertNull(h.remove(K1));
+    }
+
+    public void testSize() {
+        assertEquals(0, h.size());
+        h.put(K1, V1);
+        assertEquals(1, h.size());
+    }
+
+    public void testKeys() {
+        multiSetup();
+        assertKeys(CollectionUtils.asIterator(h.keys()));
+    }
+
+    public void testKeySet() {
+        multiSetup();
+        assertKeys(h.keySet().iterator());
+    }
+
+    public void testElements() {
+        multiSetup();
+        assertValues(CollectionUtils.asIterator(h.elements()));
+    }
+
+    public void testValues() {
+        multiSetup();
+        assertValues(h.values().iterator());
+    }
+
+    public void testEntrySet() {
+        multiSetup();
+        Iterator i = h.entrySet().iterator();
+        assertTrue(i.hasNext());
+        Map.Entry e = (Map.Entry) i.next();
+        assertSame(K1, e.getKey());
+        assertSame(V1, e.getValue());
+        assertTrue(i.hasNext());
+        e = (Map.Entry) i.next();
+        assertSame(K2, e.getKey());
+        assertSame(V2, e.getValue());
+        assertFalse(i.hasNext());
+    }
+
+    private void multiSetup() {
+        h.put(K1, V1);
+        h.put(K2, V2);
+    }
+
+    private static void assertKeys(Iterator i) {
+        assertTrue(i.hasNext());
+        assertSame(K1, i.next());
+        assertTrue(i.hasNext());
+        assertSame(K2, i.next());
+        assertFalse(i.hasNext());
+    }
+
+    private static void assertValues(Iterator i) {
+        assertTrue(i.hasNext());
+        assertSame(V1, i.next());
+        assertTrue(i.hasNext());
+        assertSame(V2, i.next());
+        assertFalse(i.hasNext());
+    }
+}

Propchange: 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to