You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2003/11/20 01:03:06 UTC

cvs commit: jakarta-commons/collections/src/test/org/apache/commons/collections/map TestListOrderedMap.java

scolebourne    2003/11/19 16:03:06

  Modified:    collections/src/test/org/apache/commons/collections/iterators
                        AbstractTestMapIterator.java
               collections/src/java/org/apache/commons/collections/map
                        ListOrderedMap.java
               collections/src/test/org/apache/commons/collections/map
                        TestListOrderedMap.java
  Added:       collections/src/test/org/apache/commons/collections/iterators
                        AbstractTestOrderedMapIterator.java
  Log:
  Make ListOrderedMap implement OrderedMap
  Improve associated tests
  
  Revision  Changes    Path
  1.5       +5 -2      jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/AbstractTestMapIterator.java
  
  Index: AbstractTestMapIterator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/AbstractTestMapIterator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractTestMapIterator.java	18 Nov 2003 22:37:14 -0000	1.4
  +++ AbstractTestMapIterator.java	20 Nov 2003 00:03:05 -0000	1.5
  @@ -261,6 +261,9 @@
           assertSame("Key must not change after setValue", key, it.getKey());
           assertSame("Value must be changed after setValue", newValue, it.getValue());
           assertSame("setValue must return old value", value, old);
  +        assertEquals("Map must contain key", true, map.containsKey(key));
  +        assertEquals("Map must not contain old value", false, map.containsValue(old));
  +        assertEquals("Map must contain old value", true, map.containsValue(newValue));
           verify();
           
           it.setValue(newValue);  // same value - should be OK
  
  
  
  1.1                  jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/AbstractTestOrderedMapIterator.java
  
  Index: AbstractTestOrderedMapIterator.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/iterators/AbstractTestOrderedMapIterator.java,v 1.1 2003/11/20 00:03:05 scolebourne Exp $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowledgement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgement may appear in the software itself,
   *    if and wherever such third-party acknowledgements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.collections.iterators;
  
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.NoSuchElementException;
  import java.util.Set;
  
  /**
   * Abstract class for testing the OrderedMapIterator interface.
   * <p>
   * This class provides a framework for testing an implementation of MapIterator.
   * Concrete subclasses must provide the list iterator to be tested.
   * They must also specify certain details of how the list iterator operates by
   * overriding the supportsXxx() methods if necessary.
   * 
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/11/20 00:03:05 $
   * 
   * @author Stephen Colebourne
   */
  public abstract class AbstractTestOrderedMapIterator extends AbstractTestMapIterator {
  
      /**
       * JUnit constructor.
       * 
       * @param testName  the test class name
       */
      public AbstractTestOrderedMapIterator(String testName) {
          super(testName);
      }
  
      //-----------------------------------------------------------------------
      /**
       * Test that the empty list iterator contract is correct.
       */
      public void testEmptyMapIterator() {
          if (supportsEmptyIterator() == false) {
              return;
          }
  
          super.testEmptyMapIterator();
          
          OrderedMapIterator it = (OrderedMapIterator) makeEmptyMapIterator();
          Map map = getMap();
          assertEquals(false, it.hasPrevious());
          try {
              it.previous();
              fail();
          } catch (NoSuchElementException ex) {}
      }
  
      //-----------------------------------------------------------------------
      /**
       * Test that the full list iterator contract is correct.
       */
      public void testFullMapIterator() {
          if (supportsFullIterator() == false) {
              return;
          }
  
          super.testFullMapIterator();
          
          OrderedMapIterator it = (OrderedMapIterator) makeFullMapIterator();
          Map map = getMap();
          
          assertEquals(true, it.hasNext());
          assertEquals(false, it.hasPrevious());
          Set set = new HashSet();
          while (it.hasNext()) {
              // getKey
              Object key = it.next();
              assertSame("it.next() should equals getKey()", key, it.getKey());
              assertTrue("Key must be in map",  map.containsKey(key));
              assertTrue("Key must be unique", set.add(key));
              
              // getValue
              Object value = it.getValue();
              assertSame("Value must be mapped to key", map.get(key), value);
              assertTrue("Value must be in map",  map.containsValue(value));
              assertSame("Value must be mapped to key", map.get(key), value);
  
              assertEquals(true, it.hasPrevious());
              
              verify();
          }
          while (it.hasPrevious()) {
              // getKey
              Object key = it.previous();
              assertSame("it.previous() should equals getKey()", key, it.getKey());
              assertTrue("Key must be in map",  map.containsKey(key));
              assertTrue("Key must be unique", set.remove(key));
              
              // getValue
              Object value = it.getValue();
              assertSame("Value must be mapped to key", map.get(key), value);
              assertTrue("Value must be in map",  map.containsValue(value));
              assertSame("Value must be mapped to key", map.get(key), value);
  
              assertEquals(true, it.hasNext());
              
              verify();
          }
      }
      
      //-----------------------------------------------------------------------
      /**
       * Test that the iterator order matches the keySet order.
       */
      public void testMapIteratorOrder() {
          if (supportsFullIterator() == false) {
              return;
          }
  
          OrderedMapIterator it = (OrderedMapIterator) makeFullMapIterator();
          Map map = getMap();
          
          assertEquals("keySet() not consistent", new ArrayList(map.keySet()), new ArrayList(map.keySet()));
          
          Iterator it2 = map.keySet().iterator();
          assertEquals(true, it.hasNext());
          assertEquals(true, it2.hasNext());
          List list = new ArrayList();
          while (it.hasNext()) {
              Object key = it.next();
              assertEquals(it2.next(), key);
              list.add(key);
          }
          while (it.hasPrevious()) {
              Object key = it.previous();
              assertEquals(list.get(list.size() - 1), key);
              list.remove(list.size() - 1);
          }
      }
      
  }
  
  
  
  1.2       +164 -17   jakarta-commons/collections/src/java/org/apache/commons/collections/map/ListOrderedMap.java
  
  Index: ListOrderedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/ListOrderedMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ListOrderedMap.java	16 Nov 2003 00:05:45 -0000	1.1
  +++ ListOrderedMap.java	20 Nov 2003 00:03:05 -0000	1.2
  @@ -63,12 +63,15 @@
   import java.util.Collection;
   import java.util.Iterator;
   import java.util.List;
  +import java.util.ListIterator;
   import java.util.Map;
  +import java.util.NoSuchElementException;
   import java.util.Set;
   
   import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
  -import org.apache.commons.collections.iterators.EntrySetMapIterator;
   import org.apache.commons.collections.iterators.MapIterator;
  +import org.apache.commons.collections.iterators.OrderedMapIterator;
  +import org.apache.commons.collections.iterators.ResettableIterator;
   import org.apache.commons.collections.pairs.AbstractMapEntry;
   
   /**
  @@ -76,6 +79,8 @@
    * <p>
    * The order will be used via the iterators and toArray methods on the views.
    * The order is also returned by the <code>MapIterator</code>.
  + * The <code>orderedMapIterator()</code> method accesses an iterator that can
  + * iterate both forwards and backwards through the map.
    * <p>
    * If an object is added to the Map for a second time, it will remain in the
    * original position in the iteration.
  @@ -86,7 +91,7 @@
    * @author Henri Yandell
    * @author Stephen Colebourne
    */
  -public class ListOrderedMap extends AbstractMapDecorator implements Map {
  +public class ListOrderedMap extends AbstractMapDecorator implements OrderedMap {
   
       /** Internal list to hold the sequence of objects */
       protected final List insertOrder = new ArrayList();
  @@ -115,6 +120,72 @@
           insertOrder.addAll(getMap().keySet());
       }
   
  +    // Implement OrderedMap
  +    //-----------------------------------------------------------------------
  +    public MapIterator mapIterator() {
  +        return orderedMapIterator();
  +    }
  +
  +    public OrderedMapIterator orderedMapIterator() {
  +        return new ListOrderedMapIterator(this);
  +    }
  +
  +    /**
  +     * Gets the first key in this map by insert order.
  +     *
  +     * @return the first key currently in this map
  +     * @throws NoSuchElementException if this map is empty
  +     */
  +    public Object firstKey() {
  +        if (size() == 0) {
  +            throw new NoSuchElementException("Map is empty");
  +        }
  +        return insertOrder.get(0);
  +    }
  +
  +    /**
  +     * Gets the last key in this map by insert order.
  +     *
  +     * @return the last key currently in this map
  +     * @throws NoSuchElementException if this map is empty
  +     */
  +    public Object lastKey() {
  +        if (size() == 0) {
  +            throw new NoSuchElementException("Map is empty");
  +        }
  +        return insertOrder.get(size() - 1);
  +    }
  +    
  +    /**
  +     * Gets the next key to the one specified using insert order.
  +     * This method performs a list search to find the key and is O(n).
  +     * 
  +     * @param key  the key to find previous for
  +     * @return the next key, null if no match or at start
  +     */
  +    public Object nextKey(Object key) {
  +        int index = insertOrder.indexOf(key);
  +        if (index >= 0 && index < size() - 1) {
  +            return insertOrder.get(index + 1);
  +        }
  +        return null;
  +    }
  +
  +    /**
  +     * Gets the previous key to the one specified using insert order.
  +     * This method performs a list search to find the key and is O(n).
  +     * 
  +     * @param key  the key to find previous for
  +     * @return the previous key, null if no match or at start
  +     */
  +    public Object previousKey(Object key) {
  +        int index = insertOrder.indexOf(key);
  +        if (index > 0) {
  +            return insertOrder.get(index - 1);
  +        }
  +        return null;
  +    }
  +
       //-----------------------------------------------------------------------
       public Object put(Object key, Object value) {
           if (getMap().containsKey(key)) {
  @@ -147,10 +218,6 @@
       }
   
       //-----------------------------------------------------------------------
  -    public MapIterator mapIterator() {
  -        return new EntrySetMapIterator(this);
  -    }
  -    
       public Set keySet() {
           return new KeySetView(this);
       }
  @@ -181,14 +248,14 @@
               Map.Entry entry = (Map.Entry) it.next();
               Object key = entry.getKey();
               Object value = entry.getValue();
  -            buf.append(key == this ? "(this Map)" : key);
  -            buf.append('=');
  -            buf.append(value == this ? "(this Map)" : value);
               if (first) {
                   first = false;
               } else {
                   buf.append(", ");
               }
  +            buf.append(key == this ? "(this Map)" : key);
  +            buf.append('=');
  +            buf.append(value == this ? "(this Map)" : value);
           }
           buf.append('}');
           return buf.toString();
  @@ -320,22 +387,23 @@
           }
           
           public Iterator iterator() {
  -            return new OrderedIterator(parent, insertOrder);
  +            return new ListOrderedIterator(parent, insertOrder);
           }
       }
       
  -    static class OrderedIterator extends AbstractIteratorDecorator {
  +    //-----------------------------------------------------------------------
  +    static class ListOrderedIterator extends AbstractIteratorDecorator {
           private final ListOrderedMap parent;
           private Object last = null;
           
  -        OrderedIterator(ListOrderedMap parent, List insertOrder) {
  +        ListOrderedIterator(ListOrderedMap parent, List insertOrder) {
               super(insertOrder.iterator());
               this.parent = parent;
           }
           
           public Object next() {
               last = super.next();
  -            return new OrderedMapEntry(parent, last);
  +            return new ListOrderedMapEntry(parent, last);
           }
   
           public void remove() {
  @@ -344,10 +412,11 @@
           }
       }
       
  -    static class OrderedMapEntry extends AbstractMapEntry {
  +    //-----------------------------------------------------------------------
  +    static class ListOrderedMapEntry extends AbstractMapEntry {
           private final ListOrderedMap parent;
           
  -        OrderedMapEntry(ListOrderedMap parent, Object key) {
  +        ListOrderedMapEntry(ListOrderedMap parent, Object key) {
               super(key, null);
               this.parent = parent;
           }
  @@ -361,4 +430,82 @@
           }
       }
   
  +    //-----------------------------------------------------------------------
  +    static class ListOrderedMapIterator implements OrderedMapIterator, ResettableIterator {
  +        private final ListOrderedMap parent;
  +        private ListIterator iterator;
  +        private Object last = null;
  +        private boolean readable = false;
  +        
  +        ListOrderedMapIterator(ListOrderedMap parent) {
  +            super();
  +            this.parent = parent;
  +            this.iterator = parent.insertOrder.listIterator();
  +        }
  +        
  +        public boolean hasNext() {
  +            return iterator.hasNext();
  +        }
  +        
  +        public Object next() {
  +            last = iterator.next();
  +            readable = true;
  +            return last;
  +        }
  +        
  +        public boolean hasPrevious() {
  +            return iterator.hasPrevious();
  +        }
  +        
  +        public Object previous() {
  +            last = iterator.previous();
  +            readable = true;
  +            return last;
  +        }
  +        
  +        public void remove() {
  +            if (readable == false) {
  +                throw new IllegalStateException("Iterator remove() can only be called after next() and before remove()");
  +            }
  +            iterator.remove();
  +            parent.map.remove(last);
  +            readable = false;
  +        }
  +        
  +        public Object getKey() {
  +            if (readable == false) {
  +                throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
  +            }
  +            return last;
  +        }
  +
  +        public Object getValue() {
  +            if (readable == false) {
  +                throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
  +            }
  +            return parent.get(last);
  +        }
  +        
  +        public Object setValue(Object value) {
  +            if (readable == false) {
  +                throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
  +            }
  +            return parent.map.put(last, value);
  +        }
  +        
  +        public void reset() {
  +            iterator = parent.insertOrder.listIterator();
  +            last = null;
  +            readable = false;
  +        }
  +        
  +        public String toString() {
  +            if (readable == true) {
  +                return "MapIterator[" + getKey() + "=" + getValue() + "]";
  +            } else {
  +                return "MapIterator[]";
  +            }
  +        }
  +    }
  +    
   }
  
  
  
  1.4       +8 -85     jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestListOrderedMap.java
  
  Index: TestListOrderedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestListOrderedMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestListOrderedMap.java	18 Nov 2003 22:37:17 -0000	1.3
  +++ TestListOrderedMap.java	20 Nov 2003 00:03:06 -0000	1.4
  @@ -67,7 +67,7 @@
   import junit.framework.Test;
   
   import org.apache.commons.collections.BulkTest;
  -import org.apache.commons.collections.iterators.AbstractTestMapIterator;
  +import org.apache.commons.collections.iterators.AbstractTestOrderedMapIterator;
   import org.apache.commons.collections.iterators.MapIterator;
   
   /**
  @@ -101,12 +101,13 @@
   
       //-----------------------------------------------------------------------
       public BulkTest bulkTestMapIterator() {
  -        return new TestOrderedMapIterator();
  +        return new TestListOrderedMapIterator();
       }
       
  -    public class TestOrderedMapIterator extends AbstractTestMapIterator {
  -        public TestOrderedMapIterator() {
  -            super("TestOrderedMapIterator");
  +    // TODO: Test mapIterator() and orderedMapIterator() separately
  +    public class TestListOrderedMapIterator extends AbstractTestOrderedMapIterator {
  +        public TestListOrderedMapIterator() {
  +            super("TestListOrderedMapIterator");
           }
           
           public boolean supportsRemove() {
  @@ -143,84 +144,6 @@
           }
       }
       
  -    //-----------------------------------------------------------------------
  -    public void testMapIteratorRemove() {
  -        resetFull();
  -        ListOrderedMap testMap = (ListOrderedMap) map;
  -        MapIterator it = testMap.mapIterator();
  -        assertEquals(true, it.hasNext());
  -        Object key = it.next();
  -        
  -        if (isRemoveSupported() == false) {
  -            try {
  -                it.remove();
  -                fail();
  -            } catch (UnsupportedOperationException ex) {
  -            }
  -            return;
  -        }
  -        
  -        it.remove();
  -        confirmed.remove(key);
  -        assertEquals(false, testMap.containsKey(key));
  -        verify();
  -        
  -        try {
  -            it.remove();  // second remove fails
  -        } catch (IllegalStateException ex) {
  -        }
  -        verify();
  -    }
  -
  -    //-----------------------------------------------------------------------
  -    public void testMapIteratorSet() {
  -        Object newValue1 = getOtherValues()[0];
  -        Object newValue2 = getOtherValues()[1];
  -        
  -        resetFull();
  -        ListOrderedMap testMap = (ListOrderedMap) map;
  -        MapIterator it = testMap.mapIterator();
  -        assertEquals(true, it.hasNext());
  -        Object key1 = it.next();
  -        
  -        if (isSetValueSupported() == false) {
  -            try {
  -                it.setValue(newValue1);
  -                fail();
  -            } catch (UnsupportedOperationException ex) {
  -            }
  -            return;
  -        }
  -        
  -        it.setValue(newValue1);
  -        confirmed.put(key1, newValue1);
  -        assertSame(key1, it.getKey());
  -        assertSame(newValue1, it.getValue());
  -        assertEquals(true, testMap.containsKey(key1));
  -        assertEquals(true, testMap.containsValue(newValue1));
  -        assertEquals(newValue1, testMap.get(key1));
  -        verify();
  -        
  -        it.setValue(newValue1);  // same value - should be OK
  -        confirmed.put(key1, newValue1);
  -        assertSame(key1, it.getKey());
  -        assertSame(newValue1, it.getValue());
  -        assertEquals(true, testMap.containsKey(key1));
  -        assertEquals(true, testMap.containsValue(newValue1));
  -        assertEquals(newValue1, testMap.get(key1));
  -        verify();
  -        
  -        Object key2 = it.next();
  -        it.setValue(newValue2);
  -        confirmed.put(key2, newValue2);
  -        assertSame(key2, it.getKey());
  -        assertSame(newValue2, it.getValue());
  -        assertEquals(true, testMap.containsKey(key2));
  -        assertEquals(true, testMap.containsValue(newValue2));
  -        assertEquals(newValue2, testMap.get(key2));
  -        verify();
  -    }
  -
       //-----------------------------------------------------------------------
       // Creates a known series of Objects, puts them in 
       // an OrderedMap and ensures that all three Collection 
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org