scolebourne    2003/10/28 16:06:25

  Modified:    collections/src/java/org/apache/commons/collections
                        AbstractDualBidiMap.java BidiMap.java
               collections/src/test/org/apache/commons/collections
                        AbstractTestBidiMap.java
               collections build.xml
  Added:       collections/src/java/org/apache/commons/collections
                        MapIterator.java
  Log:
  Add MapIterator to BidiMap
  
  Revision  Changes    Path
  1.4       +66 -2     
jakarta-commons/collections/src/java/org/apache/commons/collections/AbstractDualBidiMap.java
  
  Index: AbstractDualBidiMap.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/AbstractDualBidiMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractDualBidiMap.java  10 Oct 2003 21:09:49 -0000      1.3
  +++ AbstractDualBidiMap.java  29 Oct 2003 00:06:25 -0000      1.4
  @@ -214,6 +214,10 @@
   
       // BidiMap
       //-----------------------------------------------------------------------
  +    public MapIterator mapIterator() {
  +        return new BidiMapIterator(this);
  +    }
  +    
       public Object getKey(Object value) {
           return maps[1].get(value);
       }
  @@ -435,6 +439,66 @@
           
           public Object setValue(Object value) {
               final Object oldValue = super.setValue(value);
  +
  +            // Gets old key and pairs with new value
  +            final Object inverseKey = map.maps[1].remove(oldValue);
  +            map.maps[1].put(value, inverseKey);
  +
  +            return oldValue;
  +        }
  +    }
  +    
  +    /**
  +     * Inner class MapIterator.
  +     */
  +    protected static class BidiMapIterator extends AbstractIteratorDecorator 
implements MapIterator {
  +        
  +        protected final AbstractDualBidiMap map;
  +        private Map.Entry last = null;
  +        private boolean canRemove = false;
  +        
  +        protected BidiMapIterator(AbstractDualBidiMap map) {
  +            super(map.maps[0].entrySet().iterator());
  +            this.map = map;
  +        }
  +        
  +        public Object next() {
  +            last = new MapEntry((Map.Entry) super.next(), map);
  +            canRemove = true;
  +            return last.getKey();
  +        }
  +        
  +        public void remove() {
  +            if (canRemove == false) {
  +                throw new IllegalStateException("Iterator remove() can only be 
called once after next()");
  +            }
  +            // store value as remove may change the entry in the decorator 
(eg.TreeMap)
  +            Object value = last.getValue();
  +            super.remove();
  +            map.maps[1].remove(value);
  +            last = null;
  +            canRemove = false;
  +        }
  +        
  +        public Object getKey() {
  +            if (last == null) {
  +                throw new IllegalStateException("Iterator getKey() can only be 
called after next() and before remove()");
  +            }
  +            return last.getKey();
  +        }
  +
  +        public Object getValue() {
  +            if (last == null) {
  +                throw new IllegalStateException("Iterator getValue() can only be 
called after next() and before remove()");
  +            }
  +            return last.getValue();
  +        }
  +        
  +        public Object setValue(Object value) {
  +            if (last == null) {
  +                throw new IllegalStateException("Iterator setValue() can only be 
called after next() and before remove()");
  +            }
  +            Object oldValue = last.setValue(value);
   
               // Gets old key and pairs with new value
               final Object inverseKey = map.maps[1].remove(oldValue);
  
  
  
  1.4       +20 -4     
jakarta-commons/collections/src/java/org/apache/commons/collections/BidiMap.java
  
  Index: BidiMap.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/BidiMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- BidiMap.java      6 Oct 2003 23:47:17 -0000       1.3
  +++ BidiMap.java      29 Oct 2003 00:06:25 -0000      1.4
  @@ -70,8 +70,6 @@
    * <p>
    * Implementations should allow a value to be looked up from a key and
    * a key to be looked up from a value with equal performance.
  - * It should be noted that the quickest way to implement the <code>values</code>
  - * method is usually to return <code>inverseBidiMap().keySet()</code>.
    * 
    * @see org.apache.commons.collections.DualHashBidiMap
    * @since Commons Collections 3.0
  @@ -80,6 +78,24 @@
    * @author Stephen Colebourne
    */
   public interface BidiMap extends Map {
  +    
  +    /**
  +     * Obtains a <code>MapIterator</code> over the map.
  +     * <p>
  +     * A map iterator is an efficient way of iterating over maps.
  +     * It does not require that the map is stored using Map Entry objects
  +     * which can increase performance.
  +     * <pre>
  +     * BidiMap map = new DualHashBidiMap();
  +     * MapIterator it = map.mapIterator();
  +     * Object key = it.next();
  +     * Object value = it.getValue();
  +     * it.setValue("newValue");
  +     * </pre>
  +     * 
  +     * @return a map iterator
  +     */
  +    MapIterator mapIterator();
       
       /**
        * Puts the key-value pair into the map, replacing any previous pair.
  
  
  
  1.1                  
jakarta-commons/collections/src/java/org/apache/commons/collections/MapIterator.java
  
  Index: MapIterator.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/MapIterator.java,v
 1.1 2003/10/29 00:06:25 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 [EMAIL PROTECTED]
   *
   * 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;
  
  import java.util.Iterator;
  
  /**
   * Defines an iterator that operates over a <code>Map</code>.
   * <p>
   * This iterator is a special version designed for maps. It is much more
   * efficient to use this rather than an entry set iterator where the option
   * is available. A map that provides this interface may not hold the data
   * internally using Map Entry objects, thus this interface can avoid lots
   * of object creation.
   * <p>
   * In use, this iterator iterates through the keys in the map. After each
   * call to <code>next()</code>, the <code>getValue()</code> method provides
   * direct access to the value. The value can also be set using
   * <code>setValue()</code>.
   *  
   * @since Commons Collections 3.0
   * @version $Revision: 1.1 $ $Date: 2003/10/29 00:06:25 $
   *
   * @author Stephen Colebourne
   */
  public interface MapIterator extends Iterator {
      
      /**
       * Checks to see if there are more entries still to be iterated.
       *
       * @return <code>true</code> if the iterator has more elements
       */
      boolean hasNext();
  
      /**
       * Gets the next <em>key</em> from the <code>Map</code>.
       *
       * @return the next key in the iteration
       * @throws NoSuchElementException if the iteration is finished
       */
      Object next();
  
      //-----------------------------------------------------------------------
      /**
       * Gets the current key, which is the key returned by the last call
       * to <code>next()</code>.
       *
       * @return the current key
       * @throws IllegalStateException if <code>next()</code> has not yet been called
       */
      Object getKey();
  
      /**
       * Gets the current value, which is the value associated with the last key
       * returned by <code>next()</code>.
       *
       * @return the current value
       * @throws IllegalStateException if <code>next()</code> has not yet been called
       */
      Object getValue();
  
      //-----------------------------------------------------------------------
      /**
       * Removes the last returned key from the underlying <code>Map</code> (optional 
operation).
       * <p>
       * This method can be called once per call to <code>next()</code>.
       *
       * @throws UnsupportedOperationException if remove is not supported by the map
       * @throws IllegalStateException if <code>next()</code> has not yet been called
       * @throws IllegalStateException if <code>remove()</code> has already been called
       *  since the last call to <code>next()</code>
       */
      void remove();
      
      /**
       * Sets the value associated with the current key.
       *
       * @param value  the new value
       * @return the previous value
       * @throws IllegalStateException if <code>next()</code> has not yet been called
       * @throws IllegalStateException if <code>remove()</code> has been called since 
the
       *  last call to <code>next()</code>
       */
      Object setValue(Object value);
  
  }
  
  
  
  1.2       +109 -3    
jakarta-commons/collections/src/test/org/apache/commons/collections/AbstractTestBidiMap.java
  
  Index: AbstractTestBidiMap.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/AbstractTestBidiMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractTestBidiMap.java  10 Oct 2003 21:11:39 -0000      1.1
  +++ AbstractTestBidiMap.java  29 Oct 2003 00:06:25 -0000      1.2
  @@ -59,9 +59,10 @@
   
   import java.util.HashMap;
   import java.util.Map;
  +import java.util.NoSuchElementException;
   
   /**
  - * JUnit tests.
  + * Abstract test class for [EMAIL PROTECTED] BidiMap} methods and contracts.
    * 
    * @version $Revision$ $Date$
    * 
  @@ -375,4 +376,109 @@
   
       }
       
  +    //-----------------------------------------------------------------------
  +    public void testBidiMapIteratorEmpty() {
  +        resetEmpty();
  +        BidiMap bidi = (BidiMap) map;
  +        MapIterator it = bidi.mapIterator();
  +        assertEquals(false, it.hasNext());
  +        try {
  +            it.next();
  +        } catch (NoSuchElementException ex) {}
  +        try {
  +            it.getKey();
  +        } catch (IllegalStateException ex) {
  +        }
  +        try {
  +            it.getValue();
  +        } catch (IllegalStateException ex) {
  +        }
  +        try {
  +            it.remove();
  +        } catch (UnsupportedOperationException ex) {
  +        } catch (IllegalStateException ex) {
  +        }
  +        try {
  +            it.setValue(null);
  +        } catch (UnsupportedOperationException ex) {
  +        } catch (IllegalStateException ex) {
  +        }
  +        verify();
  +    }
  +
  +    //-----------------------------------------------------------------------
  +    public void testBidiMapIteratorFull() {
  +        resetFull();
  +        BidiMap bidi = (BidiMap) map;
  +        MapIterator it = bidi.mapIterator();
  +        
  +        assertEquals(true, it.hasNext());
  +        while (it.hasNext()) {
  +            Object key = it.next();
  +            assertSame(key, it.getKey());
  +        
  +            Object value = it.getValue();
  +            assertSame(bidi.get(key), value);
  +        }
  +        verify();
  +    }
  +
  +    //-----------------------------------------------------------------------
  +    public void testBidiMapIteratorRemove() {
  +        resetFull();
  +        BidiMap bidi = (BidiMap) map;
  +        MapIterator it = bidi.mapIterator();
  +        assertEquals(true, it.hasNext());
  +        Object key = it.next();
  +        
  +        if (isRemoveSupported() == false) {
  +            try {
  +                it.remove();
  +            } catch (UnsupportedOperationException ex) {
  +            }
  +            return;
  +        }
  +        
  +        it.remove();
  +        confirmed.remove(key);
  +        assertEquals(false, bidi.containsKey(key));
  +        verify();
  +        
  +        try {
  +            it.remove();  // second remove fails
  +        } catch (IllegalStateException ex) {
  +        }
  +        verify();
  +    }
  +
  +    //-----------------------------------------------------------------------
  +    public void testBidiMapIteratorSet() {
  +        resetFull();
  +        BidiMap bidi = (BidiMap) map;
  +        MapIterator it = bidi.mapIterator();
  +        assertEquals(true, it.hasNext());
  +        Object key = it.next();
  +        
  +        if (isPutChangeSupported() == false) {
  +            try {
  +                it.setValue(getOtherValues()[0]);
  +            } catch (UnsupportedOperationException ex) {
  +            }
  +            return;
  +        }
  +        
  +        it.setValue(getOtherValues()[0]);
  +        confirmed.put(key, getOtherValues()[0]);
  +        assertEquals(getOtherValues()[0], bidi.get(key));
  +        verify();
  +        
  +        it.remove();
  +        confirmed.remove(key);
  +        try {
  +            it.setValue(getOtherValues()[0]);
  +        } catch (IllegalStateException ex) {
  +        }
  +        verify();
  +    }
  +
   }
  
  
  
  1.50      +2 -1      jakarta-commons/collections/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/collections/build.xml,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- build.xml 27 Oct 2003 23:08:21 -0000      1.49
  +++ build.xml 29 Oct 2003 00:06:25 -0000      1.50
  @@ -37,6 +37,7 @@
      <patternset id="patternset-testframework-source">
         <include name="**/Bag.java"/>
         <include name="**/BidiMap.java"/>
  +      <include name="**/MapIterator.java"/>
         <include name="**/SortedBag.java"/>
         <include name="**/AbstractTest*.java"/>
         <include name="**/BulkTest*.java"/>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to