aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2015-04-03 15:51:28 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2015-04-07 09:56:03 +0200
commitaf6d4a423967e033cdf51e3762d0a4d14f659983 (patch)
tree861b39f03785658afb9f3701ae1147e3db558c0c
parent90b4fd941e7a3e0eaa4ef39c0a320b965127b5f5 (diff)
downloadsonarqube-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.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java28
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");
+ }
+ }
+ }
+
}