Hi Jonathan!

Funnily enough, I spotted that too on Thursday / Friday and I think its now
fixed it in CVS.

You can browse the code from CVS here:-

http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/dom4j/dom4j/src/java/org/dom4
j/tree/
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/dom4j/dom4j/src/java/org/dom4
j/tree/FilterIterator.java?rev=1.3&content-type=text/vnd.viewcvs-markup


I think we both patched FilterIterator along the same lines (kinda spooky
that we both did it around the same time!).

I went the whole hog and implemented the NoSuchElementException throwing if
you call next() when there are no more elements - so I think we have a fully
supported FilterIterator now.

I also added your JUnit test case to CVS and added you as a contributor.
These changes should all show up in todays build and the current CVS image
appears to pass all JUnit tests with flying colours.

Many thanks for your work Jonathan!

James
----- Original Message -----
From: "Jonathan Doughty" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, August 06, 2001 3:52 AM
Subject: [dom4j-dev] Re: Incorrect implementation of hasNext in
FilterIterator


> Thinking about it a bit more, I realized that my patch only half fixed
> the bug: even in my previous patch there is still the presumption that
> one _must_ call hasNext() to advance to the next element in the
> iteration.  That shouldn't be the case: next() itself should so what's
> necessary, there should not be a requirement to call hasNext().q
>
> Below is a second patch, against the original, that hopefully addresses
> all the requirements of being a true Iterator.  Well, almost.  It
> appears that true Iterators throw a NoSuchElementException when one
> attempts to do an extra next; FilterIterator as presently implemented
> just sets the returned object to null.  I decided not to add that more
> correct behavior for fear of breaking code that doesn't expect it.
> Perhaps that should be added to, however, since ...
>
> Unfortunately my patch seems to cause a lot of failures in other test
> cases in the dom4j test suite.  Perhaps there is more dependence on the
> original, non-standard Iterator behavior than I realized; and fixing
> those is a bit beyond my capability/familiarity with dom4j.
>
> Here is my new diff:
>
> diff -u FilterIterator.java.orig FilterIterator.java
> --- FilterIterator.java.orig    Mon Jul 30 14:30:30 2001
> +++ FilterIterator.java    Sun Aug  5 22:25:43 2001
> @@ -26,24 +26,32 @@
>          this.proxy = proxy;
>      }
>
> -
> -    public boolean hasNext() {
> +    private void advanceToNext() {
>          if ( proxy == null ) {
> -            return false;
> +            return;
>          }
>          while (proxy.hasNext()) {
>              next = proxy.next();
> -            if ( matches(next) ) {
> -                return true;
> +            if ( next == null || matches(next) ) {
> +                return;
>              }
>          }
>          proxy = null;
> -        next = null;
> -        return false;
> +    }
> +
> +    public boolean hasNext() {
> +        if (next == null)
> +            advanceToNext();
> +
> +        return next != null;
>      }
>
>      public Object next() {
> -        return next;
> +        if (next == null)
> +            advanceToNext();
> +        Object toReturn = next;
> +        next = null;
> +        return toReturn;
>      }
>
>      public void remove() {
>
>
> And here, for what it is worth, is a TestIterator set of test cases that
> passes the way I expect for my version and fails the way I expect for
> the original.  You are welcome to add it to dom4j test set if you
> choose.  Thanks again for dom4j.
>
> /*
>  * $Id$
>  */
>
> package org.dom4j;
>
> import java.util.Iterator;
> import java.util.List;
>
> import junit.framework.*;
> import junit.textui.TestRunner;
>
> /** A test harness to test the Iterator API in DOM4J
>   *
>   * @author <a href="mailto:jdoughty@[EMAIL PROTECTED]";>Jonathan
> Doughty</a>
>   * @version $Revision: 1.01 $
>   */
> public class TestIterator extends AbstractTestCase {
>
>     public static void main( String[] args ) {
>         TestRunner.run( suite() );
>     }
>
>     public static Test suite() {
>         return new TestSuite( TestIterator.class );
>     }
>
>     public TestIterator(String name) {
>         super(name);
>     }
>
>     protected Document iterDocument;
>     private static final int NUMELE = 10;
>
>     protected void setUp() throws Exception {
>         iterDocument = createDocument();
>
>         Element root = iterDocument.addElement( "root" );
>
>         for (int i = 0; i < NUMELE; i++) {
>             root.addElement( "iterator test")
>                 .addAttribute( "instance", Integer.toString(i));
>         }
>     }
>
>     // Test case(s)
>
>
//-------------------------------------------------------------------------
>
>     public void testElementCount() throws Exception {
>         Element root = iterDocument.getRootElement();
>         assertTrue( "Has root element", root != null );
>
>         List elements = root.elements( "iterator test" );
>         int elementSize = elements.size();
>         assertTrue( "Root has " + elementSize + " children",
>                     elements != null && elementSize == NUMELE );
>
>     }
>
>     public void testPlainIteration() throws Exception {
>         Element root = iterDocument.getRootElement();
>         List elements = root.elements( "iterator test" );
>         Iterator iter = root.elementIterator( "iterator test" );
>         int elementSize = elements.size();
>
>         int count = 0;
>         for (; iter.hasNext();) {
>             Element e = (Element) iter.next();
>             assertTrue("instance " + e.attribute("instance").getValue() +
>                        " equals "+ count,
>                        e.attribute("instance").getValue().equals(
>                            Integer.toString(count)));
>             count++;
>         }
>
>         assertTrue( elementSize + " elements iterated", count ==
> elementSize );
>
>     }
>
>     public void testSkipAlternates() throws Exception {
>         Element root = iterDocument.getRootElement();
>         List elements = root.elements( "iterator test" );
>         Iterator iter = root.elementIterator( "iterator test" );
>         int elementSize = elements.size();
>         int count = 0;
>         for (; iter.hasNext();) {
>             Element e = (Element) iter.next();
>             assertTrue("instance " + e.attribute("instance").getValue() +
>                        " equals "+ count*2,
>                        e.attribute("instance").getValue().equals(
>                            Integer.toString(count*2)));
>             iter.next();
>             count++;
>         }
>         assertTrue( (elementSize/2) + " alternate elements iterated",
>                     count == (elementSize/2) );
>
>     }
>
>     public void testNoHasNext() throws Exception {
>         Element root = iterDocument.getRootElement();
>         List elements = root.elements( "iterator test" );
>         Iterator iter = root.elementIterator( "iterator test" );
>         int elementSize = elements.size();
>         int count = 0;
>         Element e = null;
>         for (; count < elementSize; ) {
>             e = (Element) iter.next();
>             assertTrue("instance " + e.attribute("instance").getValue() +
>                        " equals "+ count,
>                        e.attribute("instance").getValue().equals(
>                            Integer.toString(count)));
>             System.out.println("instance " +
>                                e.attribute("instance").getValue() +
>                                " equals "+ count);
>             count++;
>         }
>         try {
>             e = (Element) iter.next();
>             if (e != null) {
>                 // Real Iterators wouldn't get here
>                 assertTrue( "no more elements,value instead is " +
>                             e.attribute("instance").getValue(), e ==
null);
>             }
>         }
>         catch (Exception exp) {
>             assertTrue( "Real iterators throw NoSuchElementException",
>                         exp instanceof java.util.NoSuchElementException);
>         }
>     }
>
>     public void testExtraHasNexts() throws Exception {
>         Element root = iterDocument.getRootElement();
>         List elements = root.elements( "iterator test" );
>         Iterator iter = root.elementIterator( "iterator test" );
>         int elementSize = elements.size();
>         int count = 0;
>         for (; iter.hasNext();) {
>             Element e = (Element) iter.next();
>             assertTrue("instance " + e.attribute("instance").getValue() +
>                        " equals "+ count,
>                        e.attribute("instance").getValue().equals(
>                            Integer.toString(count)));
>             iter.hasNext();
>             count++;
>         }
>         assertTrue( elementSize + " elements iterated with extra
hasNexts",
>                     count == elementSize );
>     }
> }
>
>
>
> _______________________________________________
> dom4j-dev mailing list
> [EMAIL PROTECTED]
> http://lists.sourceforge.net/lists/listinfo/dom4j-dev
>


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


_______________________________________________
dom4j-dev mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/dom4j-dev

Reply via email to