You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/11/17 19:47:57 UTC

svn commit: r718321 - in /harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/util/ test/api/common/org/apache/harmony/luni/tests/java/util/

Author: tellison
Date: Mon Nov 17 10:47:57 2008
New Revision: 718321

URL: http://svn.apache.org/viewvc?rev=718321&view=rev
Log:
Apply patch for HARMONY-6017 ([classlib] [luni] (Iterator) Hashtable.keys() throws ClassCastException)

Modified:
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Hashtable.java
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/HashtableTest.java
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Hashtable.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Hashtable.java?rev=718321&r1=718320&r2=718321&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Hashtable.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Hashtable.java Mon Nov 17 10:47:57 2008
@@ -67,6 +67,21 @@
         }
     };
 
+    private static final Iterator<?> EMPTY_ITERATOR = new Iterator<Object>() {
+
+        public boolean hasNext() {
+            return false;
+        }
+
+        public Object next() {
+            throw new NoSuchElementException();
+        }
+
+        public void remove() {
+            throw new IllegalStateException();
+        }
+    };
+
     private static <K, V> Entry<K, V> newEntry(K key, V value, int hash) {
         return new Entry<K, V>(key, value);
     }
@@ -115,16 +130,16 @@
         }
     }
 
-    private final class HashIterator<E> implements Iterator<E> {
-        private int position, expectedModCount;
+    private class HashIterator<E> implements Iterator<E> {
+        int position, expectedModCount;
 
-        private final MapEntry.Type<E, K, V> type;
+        final MapEntry.Type<E, K, V> type;
 
-        private Entry<K, V> lastEntry;
+        Entry<K, V> lastEntry;
 
-        private int lastPosition;
+        int lastPosition;
 
-        private boolean canRemove = false;
+        boolean canRemove = false;
 
         HashIterator(MapEntry.Type<E, K, V> value) {
             type = value;
@@ -212,42 +227,6 @@
         }
     }
 
-    private final class HashEnumerator<E> implements Enumeration<E> {
-        boolean key;
-
-        int start;
-
-        Entry<K, V> entry;
-
-        HashEnumerator(boolean isKey) {
-            key = isKey;
-            start = lastSlot + 1;
-        }
-
-        public boolean hasMoreElements() {
-            if (entry != null) {
-                return true;
-            }
-            while (start > firstSlot) {
-                if (elementData[--start] != null) {
-                    entry = elementData[start];
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @SuppressWarnings("unchecked")
-        public E nextElement() {
-            if (hasMoreElements()) {
-                Object result = key ? entry.key : entry.value;
-                entry = entry.next;
-                return (E) result;
-            }
-            throw new NoSuchElementException();
-        }
-    }
-
     /**
      * Constructs a new Hashtable using the default capacity and load factor.
      */
@@ -426,7 +405,11 @@
         if (elementCount == 0) {
             return (Enumeration<V>) EMPTY_ENUMERATION;
         }
-        return new HashEnumerator<V>(false);
+        return new HashEnumIterator<V>(new MapEntry.Type<V, K, V>() {
+            public V get(MapEntry<K, V> entry) {
+                return entry.value;
+            }
+        }, true);
     }
 
     /**
@@ -605,7 +588,11 @@
         if (elementCount == 0) {
             return (Enumeration<K>) EMPTY_ENUMERATION;
         }
-        return new HashEnumerator<K>(true);
+        return new HashEnumIterator<K>(new MapEntry.Type<K, K, V>() {
+            public K get(MapEntry<K, V> entry) {
+                return entry.key;
+            }
+        }, true);
     }
 
     /**
@@ -643,7 +630,10 @@
 
             @Override
             public Iterator<K> iterator() {
-                return new HashIterator<K>(new MapEntry.Type<K, K, V>() {
+                if (this.size() == 0) {
+                    return (Iterator<K>) EMPTY_ITERATOR;
+                }
+                return new HashEnumIterator<K>(new MapEntry.Type<K, K, V>() {
                     public K get(MapEntry<K, V> entry) {
                         return entry.key;
                     }
@@ -652,6 +642,84 @@
         }, this);
     }
 
+    class HashEnumIterator<E> extends HashIterator<E> implements Enumeration<E> {
+
+        private boolean isEnumeration = false;
+
+        int start;
+
+        Entry<K, V> entry;
+
+        HashEnumIterator(MapEntry.Type<E, K, V> value) {
+            super(value);
+        }
+
+        HashEnumIterator(MapEntry.Type<E, K, V> value, boolean isEnumeration) {
+            super(value);
+            this.isEnumeration = isEnumeration;
+            start = lastSlot + 1;
+        }
+
+        public boolean hasMoreElements() {
+            if (isEnumeration) {
+                if (entry != null) {
+                    return true;
+                }
+                while (start > firstSlot) {
+                    if (elementData[--start] != null) {
+                        entry = elementData[start];
+                        return true;
+                    }
+                }
+                return false;
+            }
+            // iterator
+            return super.hasNext();
+        }
+
+        public boolean hasNext() {
+            if (isEnumeration) {
+                return hasMoreElements();
+            }
+            // iterator
+            return super.hasNext();
+        }
+
+        public E next() {
+            if (isEnumeration) {
+                if (expectedModCount == modCount) {
+                    return nextElement();
+                } else {
+                    throw new ConcurrentModificationException();
+                }
+            }
+            // iterator
+            return super.next();
+        }
+
+        @SuppressWarnings("unchecked")
+        public E nextElement() {
+            if (isEnumeration) {
+                if (hasMoreElements()) {
+                    Object result = type.get(entry);
+                    entry = entry.next;
+                    return (E) result;
+                }
+                throw new NoSuchElementException();
+            }
+            // iterator
+            return super.next();
+        }
+
+        public void remove() {
+            if (isEnumeration) {
+                throw new UnsupportedOperationException();
+            } else {
+                super.remove();
+            }
+        }
+    }
+
     /**
      * Associate the specified value with the specified key in this Hashtable.
      * If the key already exists, the old value is replaced. The key and value

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/HashtableTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/HashtableTest.java?rev=718321&r1=718320&r2=718321&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/HashtableTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/HashtableTest.java Mon Nov 17 10:47:57 2008
@@ -192,6 +192,16 @@
 		}
 
 		assertEquals("All keys not retrieved", 10, ht10.size());
+
+        // cast Enumeration to Iterator
+        Iterator iterator = (Iterator) elms;
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
 	}
 
 	/**
@@ -359,8 +369,18 @@
 		}
 
 		assertEquals("All keys not retrieved", 10, ht10.size());
-	}
 
+        // cast Enumeration to Iterator
+        Iterator iterator = (Iterator) keys;
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+	}
+	
 	/**
 	 * @tests java.util.Hashtable#keys()
 	 */
@@ -429,6 +449,10 @@
 		assertEquals("Wrong size 2", 1, map2.size());
 		assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
 				next));
+
+        // cast Iterator to Enumeration
+        Enumeration enumeration = (Enumeration) s.iterator();
+        assertTrue(enumeration.hasMoreElements());
 	}
 
 	/**
@@ -654,6 +678,150 @@
         }
         assertFalse(hashtable.containsKey("my.nonexistent.prop"));
     }
+    
+    /**
+     * @tests java.util.Hashtable#elements()
+     * @tests java.util.Hashtable#keys()
+     * @tests java.util.Hashtable#keySet()
+     */
+    public void test_keys_elements_keySet_Exceptions() {
+        Hashtable hashTable = new Hashtable();
+        String key = "key";
+        String value = "value";
+        hashTable.put(key, value);
+
+        Iterator iterator = (Iterator) hashTable.keys();
+        assertTrue(iterator.hasNext());
+        try {
+            iterator.remove();
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // Expected
+        }
+        iterator.next();
+        try {
+            iterator.remove();
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // Expected
+        }
+        assertFalse(iterator.hasNext());
+
+        iterator = (Iterator) hashTable.elements();
+        assertTrue(iterator.hasNext());
+        try {
+            iterator.remove();
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // Expected
+        }
+        iterator.next();
+        try {
+            iterator.remove();
+            fail("should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // Expected
+        }
+        assertFalse(iterator.hasNext());
+
+        iterator = hashTable.keySet().iterator();
+        assertTrue(iterator.hasNext());
+        try {
+            iterator.remove();
+            fail("should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+            // Expected
+        }
+        iterator.next();
+        iterator.remove();
+        assertFalse(iterator.hasNext());
+
+        hashTable.clear();
+        for (int i = 0; i < 10; i++) {
+            hashTable.put(key + i, value + i);
+        }
+
+        // cast Enumeration to Iterator
+        Enumeration enumeration = hashTable.keys();
+        iterator = (Iterator) enumeration;
+        assertTrue(enumeration.hasMoreElements());
+        assertTrue(iterator.hasNext());
+        for (int i = 0; i < 10; i++) {
+            if (i % 2 == 0) {
+                enumeration.nextElement();
+            } else {
+                iterator.next();
+            }
+        }
+        assertFalse(enumeration.hasMoreElements());
+        assertFalse(iterator.hasNext());
+        try {
+            enumeration.nextElement();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // cast Enumeration to Iterator
+        enumeration = hashTable.elements();
+        iterator = (Iterator) enumeration;
+        assertTrue(enumeration.hasMoreElements());
+        assertTrue(iterator.hasNext());
+        for (int i = 0; i < 10; i++) {
+            if (i % 2 == 0) {
+                enumeration.nextElement();
+            } else {
+                iterator.next();
+            }
+        }
+        assertFalse(enumeration.hasMoreElements());
+        assertFalse(iterator.hasNext());
+        try {
+            enumeration.nextElement();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+
+        // cast Iterator to Enumeration
+        enumeration = (Enumeration) hashTable.keySet().iterator();
+        iterator = (Iterator) enumeration;
+        assertTrue(enumeration.hasMoreElements());
+        assertTrue(iterator.hasNext());
+        for (int i = 0; i < 10; i++) {
+            if (i % 2 == 0) {
+                enumeration.nextElement();
+            } else {
+                iterator.next();
+            }
+        }
+        assertFalse(enumeration.hasMoreElements());
+        assertFalse(iterator.hasNext());
+        try {
+            enumeration.nextElement();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
+    }
 
 	protected Hashtable hashtableClone(Hashtable s) {
 		return (Hashtable) s.clone();

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java?rev=718321&r1=718320&r2=718321&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java Mon Nov 17 10:47:57 2008
@@ -24,6 +24,8 @@
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 import java.util.Properties;
 
 import tests.support.resource.Support_Resources;
@@ -252,6 +254,16 @@
             assertTrue("Incorrect names returned", p.equals("test.prop")
                     || p.equals("bogus.prop"));
         }
+
+        // cast Enumeration to Iterator
+        Iterator iterator = (Iterator) names;
+        assertFalse(iterator.hasNext());
+        try {
+            iterator.next();
+            fail("should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Expected
+        }
     }
 
     /**