Return-Path: Delivered-To: apmail-incubator-sling-commits-archive@locus.apache.org Received: (qmail 31423 invoked from network); 7 Feb 2008 09:29:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 7 Feb 2008 09:29:19 -0000 Received: (qmail 49431 invoked by uid 500); 7 Feb 2008 09:29:12 -0000 Delivered-To: apmail-incubator-sling-commits-archive@incubator.apache.org Received: (qmail 49393 invoked by uid 500); 7 Feb 2008 09:29:12 -0000 Mailing-List: contact sling-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sling-dev@incubator.apache.org Delivered-To: mailing list sling-commits@incubator.apache.org Received: (qmail 49384 invoked by uid 99); 7 Feb 2008 09:29:12 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Feb 2008 01:29:12 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Feb 2008 09:28:50 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 1E6DF1A983A; Thu, 7 Feb 2008 01:28:58 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r619319 - in /incubator/sling/trunk/jcr/resource/src: main/java/org/apache/sling/jcr/resource/internal/ main/java/org/apache/sling/jcr/resource/internal/helper/ test/java/org/apache/sling/jcr/resource/internal/ test/java/org/apache/sling/jc... Date: Thu, 07 Feb 2008 09:28:57 -0000 To: sling-commits@incubator.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080207092858.1E6DF1A983A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fmeschbe Date: Thu Feb 7 01:28:56 2008 New Revision: 619319 URL: http://svn.apache.org/viewvc?rev=619319&view=rev Log: SLING-230 ResourceResolver never considers the parent path after cutting off all dot-separated parts Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java?rev=619319&r1=619318&r2=619319&view=diff ============================================================================== --- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java (original) +++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java Thu Feb 7 01:28:56 2008 @@ -84,7 +84,7 @@ pathInfo = "/"; } - Resource result = resolve(pathInfo, request.getMethod()); + Resource result = resolve(pathInfo); if (result == null) { result = new NonExistingResource(pathInfo); @@ -99,9 +99,41 @@ */ public Resource resolve(String uri) throws SlingException { - // TODO for now use null as a method to make sure this goes up the path - // (see SLING-179) - return resolve(uri, null); + // decode the request URI (required as the servlet container does not + try { + uri = URLDecoder.decode(uri, "UTF-8"); + } catch (UnsupportedEncodingException uee) { + log.error("Cannot decode request URI using UTF-8", uee); + } catch (Exception e) { + log.error("Failed to decode request URI " + uri, e); + } + + // resolve virtual uri + String realUrl = factory.virtualToRealUri(uri); + if (realUrl != null) { + log.debug("resolve: Using real url '{}' for virtual url '{}'", + realUrl, uri); + uri = realUrl; + } + + try { + + // translate url to a mapped url structure + Resource result = urlToResource(uri); + return result; + + } catch (AccessControlException ace) { + // rethrow AccessControlExceptions to be handled + throw ace; + + } catch (SlingException se) { + // rethrow SlingException as it is declared + throw se; + + } catch (Throwable t) { + // wrap any other issue into a SlingException + throw new SlingException("Problem resolving " + uri, t); + } } @@ -251,55 +283,11 @@ // ---------- implementation helper ---------------------------------------- - /** - * @throws AccessControlException If an item would exist but is not readable - * to this manager's session. - */ - private Resource resolve(String uri, String httpMethod) - throws SlingException { - - // decode the request URI (required as the servlet container does not - try { - uri = URLDecoder.decode(uri, "UTF-8"); - } catch (UnsupportedEncodingException uee) { - log.error("Cannot decode request URI using UTF-8", uee); - } catch (Exception e) { - log.error("Failed to decode request URI " + uri, e); - } - - // resolve virtual uri - String realUrl = factory.virtualToRealUri(uri); - if (realUrl != null) { - log.debug("resolve: Using real url '{}' for virtual url '{}'", - realUrl, uri); - uri = realUrl; - } - - try { - - // translate url to a mapped url structure - Resource result = urlToResource(uri, httpMethod); - return result; - - } catch (AccessControlException ace) { - // rethrow AccessControlExceptions to be handled - throw ace; - - } catch (SlingException se) { - // rethrow SlingException as it is declared - throw se; - - } catch (Throwable t) { - // wrap any other issue into a SlingException - throw new SlingException("Problem resolving " + uri, t); - } - } - public Session getSession() { return rootProvider.getSession(); } - private Resource urlToResource(String uri, String httpMethod) + private Resource urlToResource(String uri) throws SlingException { Mapping[] mappings = factory.getMappings(); for (int i = 0; i < mappings.length; i++) { @@ -310,7 +298,7 @@ continue; } - Resource resource = scanPath(mappedUri, httpMethod); + Resource resource = scanPath(mappedUri); if (resource != null) { ResourceMetadata rm = resource.getResourceMetadata(); @@ -332,13 +320,12 @@ } - private Resource scanPath(String uriPath, String httpMethod) + private Resource scanPath(String uriPath) throws SlingException { Resource resource = null; String curPath = uriPath; try { - final ResourcePathIterator it = new ResourcePathIterator(uriPath, - httpMethod); + final ResourcePathIterator it = new ResourcePathIterator(uriPath); while (it.hasNext() && resource == null) { curPath = it.next(); resource = getResourceInternal(curPath); Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java?rev=619319&r1=619318&r2=619319&view=diff ============================================================================== --- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java (original) +++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java Thu Feb 7 01:28:56 2008 @@ -23,9 +23,7 @@ /** * Iterate over the the HTTP request path by creating shorter segments of that - * path using "." as a separator. If the request path is for a request method - * other than GET or HEAD, after checking the last dot, - * the parent path is also checked. + * path using "." as a separator. *

* For example, if path = /some/stuff.a4.html/xyz.ext the sequence is: *

    @@ -33,7 +31,6 @@ *
  1. /some/stuff.a4.html/xyz
  2. *
  3. /some/stuff.a4
  4. *
  5. /some/stuff
  6. - *
  7. /some (only if the request method is neither GET nor HEAD)
  8. *
*

* The root path (/) is never returned. @@ -43,10 +40,6 @@ // the next path to return, null if nothing more to return private String nextPath; - // true if the parent of nextPath is to be considered after cutting - // off at all dots, initialy true only for non-GET/HEAD requests - private boolean considerParent; - /** * Creates a new instance iterating over the given path * @@ -55,11 +48,7 @@ * @param httpMethod The HTTP request method causing this iterator to be * created. */ - public ResourcePathIterator(String path, String httpMethod) { - - // only consider a parent if not a GET or HEAD request - considerParent = !HttpConstants.METHOD_GET.equals(httpMethod) - && !HttpConstants.METHOD_HEAD.equals(httpMethod); + public ResourcePathIterator(String path) { // find last non-slash character int i = (path != null) ? path.length() - 1 : -1; @@ -92,28 +81,9 @@ final String result = nextPath; - // find last + // find next path int lastDot = nextPath.lastIndexOf('.'); - if (lastDot > 0) { - nextPath = nextPath.substring(0, lastDot); - } else if (lastDot == 0) { - // path started with a dot ?? - nextPath = null; - } else if (considerParent) { - // no dot any more, go up to parent for non-GET/HEAD - int lastSlash = nextPath.lastIndexOf('/'); - if (lastSlash > 0) { - nextPath = nextPath.substring(0, lastSlash); - } else { - // never consider "/" - nextPath = null; - } - - // prevent going further up the path by slashes - considerParent = false; - } else { - nextPath = null; - } + nextPath = (lastDot > 0) ? nextPath.substring(0, lastDot) : null; return result; } Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java?rev=619319&r1=619318&r2=619319&view=diff ============================================================================== --- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java (original) +++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java Thu Feb 7 01:28:56 2008 @@ -44,13 +44,15 @@ public class JcrResourceResolverTest extends RepositoryTestBase { private String rootPath; + private Node rootNode; + private ResourceResolver resResolver; protected void setUp() throws Exception { super.setUp(); getSession(); - + JcrResourceResolverFactoryImpl resFac = new JcrResourceResolverFactoryImpl(); Field repoField = resFac.getClass().getDeclaredField("repository"); @@ -104,7 +106,8 @@ public void testResolveResource() throws Exception { // existing resource - Resource res = resResolver.resolve(new ResourceResolverTestRequest(rootPath)); + Resource res = resResolver.resolve(new ResourceResolverTestRequest( + rootPath)); assertNotNull(res); assertEquals(rootPath, res.getPath()); assertEquals(rootNode.getPrimaryNodeType().getName(), @@ -113,16 +116,14 @@ assertNotNull(res.adaptTo(Node.class)); assertTrue(rootNode.isSame(res.adaptTo(Node.class))); - // missing resource below root should resolve root + // missing resource below root should resolve "missing resource" String path = rootPath + "/missing"; res = resResolver.resolve(new ResourceResolverTestRequest(path)); assertNotNull(res); - assertEquals(rootPath, res.getPath()); - assertEquals(rootNode.getPrimaryNodeType().getName(), - res.getResourceType()); + assertEquals(path, res.getPath()); + assertEquals(Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType()); - assertNotNull(res.adaptTo(Node.class)); - assertTrue(rootNode.isSame(res.adaptTo(Node.class))); + assertNull(res.adaptTo(Node.class)); // root with selectors/ext should resolve root path = rootPath + ".print.a4.html"; @@ -143,38 +144,43 @@ assertEquals(path, res.getPath()); assertEquals(Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType()); } - + public void testGetDoesNotGoUp() throws Exception { - + final String path = rootPath + "/nothing"; - - { - final Resource res = resResolver.resolve(new ResourceResolverTestRequest(path, "POST")); + + { + final Resource res = resResolver.resolve(new ResourceResolverTestRequest( + path, "POST")); assertNotNull(res); - assertEquals("POST request resolution goes up up the path to rootPath", rootPath, res.getPath()); - assertEquals(rootNode.getPrimaryNodeType().getName(), res.getResourceType()); + assertEquals("POST request resolution does not go up the path", + Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType()); } - - { - final Resource res = resResolver.resolve(new ResourceResolverTestRequest(path, "GET")); + + { + final Resource res = resResolver.resolve(new ResourceResolverTestRequest( + path, "GET")); assertNotNull(res); - assertEquals("GET request resolution does not go up the path", - Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType()); + assertEquals("GET request resolution does not go up the path", + Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType()); } } - + public void testGetRemovesExtensionInResolution() throws Exception { final String path = rootPath + ".whatever"; - final Resource res = resResolver.resolve(new ResourceResolverTestRequest(path, "GET")); + final Resource res = resResolver.resolve(new ResourceResolverTestRequest( + path, "GET")); assertNotNull(res); assertEquals(rootPath, res.getPath()); - assertEquals(rootNode.getPrimaryNodeType().getName(), res.getResourceType()); + assertEquals(rootNode.getPrimaryNodeType().getName(), + res.getResourceType()); } - - private static class ResourceResolverTestRequest implements HttpServletRequest { + private static class ResourceResolverTestRequest implements + HttpServletRequest { private final String pathInfo; + private final String method; ResourceResolverTestRequest(String pathInfo) { Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java?rev=619319&r1=619318&r2=619319&view=diff ============================================================================== --- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java (original) +++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java Thu Feb 7 01:28:56 2008 @@ -26,227 +26,124 @@ public class ResourcePathIteratorTest extends TestCase { public void testNull() { - ResourcePathIterator rpi = new ResourcePathIterator(null, "POST"); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + ResourcePathIterator rpi = new ResourcePathIterator(null); + assertFinished(rpi); } public void testEmpty() { - ResourcePathIterator rpi = new ResourcePathIterator("", "POST"); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + ResourcePathIterator rpi = new ResourcePathIterator(""); + assertFinished(rpi); } public void testRoot() { - ResourcePathIterator rpi = new ResourcePathIterator("/", "POST"); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + ResourcePathIterator rpi = new ResourcePathIterator("/"); + assertFinished(rpi); } public void testSlashed() { - ResourcePathIterator rpi = new ResourcePathIterator("/root/child", - "POST"); - assertEquals("/root/child", rpi.next()); - assertEquals("/root", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } - } - - public void testOtherMethods() { - final String[] methods = { "PUT", "WHATEVER.METHOD", null }; - for (String method : methods) { - ResourcePathIterator rpi = new ResourcePathIterator("/root/child", - method); - assertEquals("/root/child", rpi.next()); - assertEquals("/root", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } - } + ResourcePathIterator rpi = new ResourcePathIterator("/root/child"); + assertNext("/root/child", rpi); + assertFinished(rpi); } public void testSlashedTrailingSlash1() { - ResourcePathIterator rpi = new ResourcePathIterator("/root/child/", - "POST"); - assertEquals("/root/child", rpi.next()); - assertEquals("/root", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + ResourcePathIterator rpi = new ResourcePathIterator("/root/child/"); + assertNext("/root/child", rpi); + assertFinished(rpi); } public void testSlashedTrailingSlash2() { - ResourcePathIterator rpi = new ResourcePathIterator("/root/child//", - "POST"); - assertEquals("/root/child", rpi.next()); - assertEquals("/root", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + ResourcePathIterator rpi = new ResourcePathIterator("/root/child//"); + assertNext("/root/child", rpi); + assertFinished(rpi); } public void testDotted() { - ResourcePathIterator rpi = new ResourcePathIterator("/root.child", - "POST"); - assertEquals("/root.child", rpi.next()); - assertEquals("/root", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + ResourcePathIterator rpi = new ResourcePathIterator("/root.child"); + assertNext("/root.child", rpi); + assertNext("/root", rpi); + assertFinished(rpi); } - public void testMixedPost() { + public void testMixed() { ResourcePathIterator rpi = new ResourcePathIterator( - "/root/child.print.a4.html/with/suffix", "POST"); - assertEquals("/root/child.print.a4.html/with/suffix", rpi.next()); - assertEquals("/root/child.print.a4", rpi.next()); - assertEquals("/root/child.print", rpi.next()); - assertEquals("/root/child", rpi.next()); - assertEquals("/root", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } - } - - public void testMixedGet() { - ResourcePathIterator rpi = new ResourcePathIterator( - "/root/child.print.a4.html/with/suffix", "GET"); - assertEquals("/root/child.print.a4.html/with/suffix", rpi.next()); - assertEquals("/root/child.print.a4", rpi.next()); - assertEquals("/root/child.print", rpi.next()); - assertEquals("/root/child", rpi.next()); - assertFalse(rpi.hasNext()); - - try { - rpi.next(); - fail("Expected NoSuchElementException after end of iterator"); - } catch (NoSuchElementException nsee) { - // expected - } + "/root/child.print.a4.html/with/suffix"); + assertNext("/root/child.print.a4.html/with/suffix", rpi); + assertNext("/root/child.print.a4", rpi); + assertNext("/root/child.print", rpi); + assertNext("/root/child", rpi); + assertFinished(rpi); } public void testNoSeparators() { - final Iterator it = new ResourcePathIterator( - "MickeyMouseWasHere", "POST"); - assertTrue(it.hasNext()); - assertEquals("MickeyMouseWasHere", it.next()); - assertFalse("done iterating", it.hasNext()); + final Iterator rpi = new ResourcePathIterator( + "MickeyMouseWasHere"); + assertNext("MickeyMouseWasHere", rpi); + assertFinished(rpi); } public void testGetA() { - final Iterator it = new ResourcePathIterator( - "/some/stuff/more.a4.html", "GET"); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more.a4.html", it.next()); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more.a4", it.next()); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more", it.next()); - assertFalse("done iterating", it.hasNext()); + final Iterator rpi = new ResourcePathIterator( + "/some/stuff/more.a4.html"); + assertNext("/some/stuff/more.a4.html", rpi); + assertNext("/some/stuff/more.a4", rpi); + assertNext("/some/stuff/more", rpi); + assertFinished(rpi); } public void testGetB() { - final Iterator it = new ResourcePathIterator( - "/some/stuff/more.html", "GET"); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more.html", it.next()); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more", it.next()); - assertFalse("done iterating", it.hasNext()); + final Iterator rpi = new ResourcePathIterator( + "/some/stuff/more.html"); + assertNext("/some/stuff/more.html", rpi); + assertNext("/some/stuff/more", rpi); + assertFinished(rpi); } public void testHeadB() { - final Iterator it = new ResourcePathIterator( - "/some/stuff/more.html", "HEAD"); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more.html", it.next()); - assertTrue(it.hasNext()); - assertEquals("/some/stuff/more", it.next()); - assertFalse("done iterating", it.hasNext()); + final Iterator rpi = new ResourcePathIterator( + "/some/stuff/more.html"); + assertNext("/some/stuff/more.html", rpi); + assertNext("/some/stuff/more", rpi); + assertFinished(rpi); } public void testGetC() { - final Iterator it = new ResourcePathIterator( - "/some/stuff/more", "GET"); - assertEquals("/some/stuff/more", it.next()); - assertFalse("done iterating", it.hasNext()); + final Iterator it = new ResourcePathIterator("/some/stuff/more"); + assertNext("/some/stuff/more", it); + assertFinished(it); } public void testGetD() { final Iterator it = new ResourcePathIterator( - "/some/stuff.print/more.html", "GET"); - assertEquals("/some/stuff.print/more.html", it.next()); - assertEquals("/some/stuff.print/more", it.next()); - assertEquals("/some/stuff", it.next()); - assertFalse("done iterating", it.hasNext()); - } - - public void testRelativePathPost() { - final Iterator it = new ResourcePathIterator( - "some/stuff.print", "POST"); - assertTrue(it.hasNext()); - assertEquals("some/stuff.print", it.next()); - assertTrue(it.hasNext()); - assertEquals("some/stuff", it.next()); - assertTrue(it.hasNext()); - assertEquals("some", it.next()); - assertFalse("done iterating", it.hasNext()); + "/some/stuff.print/more.html"); + assertNext("/some/stuff.print/more.html", it); + assertNext("/some/stuff.print/more", it); + assertNext("/some/stuff", it); + assertFinished(it); } public void testRelativePathGet() { - final Iterator it = new ResourcePathIterator( - "some/stuff.print", "GET"); - assertEquals("some/stuff.print", it.next()); - assertEquals("some/stuff", it.next()); - assertFalse("done iterating", it.hasNext()); + final Iterator it = new ResourcePathIterator("some/stuff.print"); + assertNext("some/stuff.print", it); + assertNext("some/stuff", it); + assertFinished(it); + } + + private void assertNext(String expected, Iterator iterator) { + assertTrue("Iterator must have next", iterator.hasNext()); + assertEquals("Incorrect next value", expected, iterator.next()); + } + + private void assertFinished(Iterator iterator) { + + assertFalse("Iterator must not have next", iterator.hasNext()); + + try { + iterator.next(); + fail("Iterator should throw NoSuchElementException"); + } catch (NoSuchElementException nsee) { + // expected + } + } }