diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-04-03 15:51:28 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-04-07 09:56:03 +0200 |
commit | af6d4a423967e033cdf51e3762d0a4d14f659983 (patch) | |
tree | 861b39f03785658afb9f3701ae1147e3db558c0c | |
parent | 90b4fd941e7a3e0eaa4ef39c0a320b965127b5f5 (diff) | |
download | sonarqube-af6d4a423967e033cdf51e3762d0a4d14f659983.tar.gz sonarqube-af6d4a423967e033cdf51e3762d0a4d14f659983.zip |
Hasnext() should not call doNext() when iterator already closed
-rw-r--r-- | server/sonar-server/src/main/java/org/sonar/server/util/CloseableIterator.java | 6 | ||||
-rw-r--r-- | server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java | 28 |
2 files changed, 34 insertions, 0 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/CloseableIterator.java b/server/sonar-server/src/main/java/org/sonar/server/util/CloseableIterator.java index 44903d9a0da..c8244454baa 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/CloseableIterator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/CloseableIterator.java @@ -28,9 +28,14 @@ import java.util.NoSuchElementException; public abstract class CloseableIterator<O> implements Iterator<O>, AutoCloseable { private O nextObject = null; + boolean isClosed = false; @Override public final boolean hasNext() { + // Optimization to not call bufferNext() when already closed + if (isClosed) { + return false; + } boolean hasNext = nextObject != null || bufferNext() != null; if (!hasNext) { close(); @@ -88,6 +93,7 @@ public abstract class CloseableIterator<O> implements Iterator<O>, AutoCloseable public final void close() { try { doClose(); + isClosed = true; } catch (Exception e) { Throwables.propagate(e); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java index 96913c04d7f..672ff885e02 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java @@ -96,6 +96,21 @@ public class CloseableIteratorTest { assertThat(it.isRemoved).isTrue(); } + @Test + public void has_next_should_not_call_do_next_when_already_closed() throws Exception { + DoNextShouldNotBeCalledWhenClosedIterator it = new DoNextShouldNotBeCalledWhenClosedIterator(); + + it.next(); + it.next(); + assertThat(it.hasNext()).isFalse(); + // this call to hasNext close the stream + assertThat(it.hasNext()).isFalse(); + assertThat(it.isClosed).isTrue(); + + // calling hasNext should not fail + it.hasNext(); + } + static class SimpleCloseableIterator extends CloseableIterator { int count = 0; boolean isClosed = false; @@ -147,4 +162,17 @@ public class CloseableIteratorTest { isClosed = true; } } + + static class DoNextShouldNotBeCalledWhenClosedIterator extends SimpleCloseableIterator { + + @Override + protected Object doNext() { + if (!isClosed) { + return super.doNext(); + } else { + throw new IllegalStateException("doNext should not be called when already closed"); + } + } + } + } |