]> source.dussan.org Git - sonarqube.git/commitdiff
improve CloseableIterator: implementation and coverage
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 2 Jun 2015 15:57:05 +0000 (17:57 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 2 Jun 2015 16:01:17 +0000 (18:01 +0200)
server/sonar-server/src/main/java/org/sonar/server/util/CloseableIterator.java
server/sonar-server/src/test/java/org/sonar/server/util/CloseableIteratorTest.java

index b63a332be9c3ad1d8ad356b6e87b8f1137ec9246..b718dbe094dda5b806943ab73b6c83c826ae62c9 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.util;
 
 import com.google.common.base.Throwables;
+import java.io.Closeable;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import javax.annotation.CheckForNull;
@@ -59,28 +60,8 @@ public abstract class CloseableIterator<O> implements Iterator<O>, AutoCloseable
   public static <T> CloseableIterator<T> from(final Iterator<T> iterator) {
     // early fail
     requireNonNull(iterator);
-    checkArgument(!(iterator instanceof CloseableIterator), "This method does not support creating a CloseableIterator from a CloseableIterator");
-    return new CloseableIterator<T>() {
-      @Override
-      public boolean hasNext() {
-        return iterator.hasNext();
-      }
-
-      @Override
-      public T next() {
-        return iterator.next();
-      }
-
-      @Override
-      protected T doNext() {
-        throw new UnsupportedOperationException("hasNext has been override, doNext is never called");
-      }
-
-      @Override
-      protected void doClose() throws Exception {
-        // do nothing
-      }
-    };
+    checkArgument(!(iterator instanceof AutoCloseable), "This method does not support creating a CloseableIterator from an Iterator which is Closeable");
+    return new RegularIteratorWrapper<>(iterator);
   }
 
   private O nextObject = null;
@@ -157,4 +138,31 @@ public abstract class CloseableIterator<O> implements Iterator<O>, AutoCloseable
 
   protected abstract void doClose() throws Exception;
 
+  private static class RegularIteratorWrapper<T> extends CloseableIterator<T> {
+    private final Iterator<T> iterator;
+
+    public RegularIteratorWrapper(Iterator<T> iterator) {
+      this.iterator = iterator;
+    }
+
+    @Override
+    public boolean hasNext() {
+      return iterator.hasNext();
+    }
+
+    @Override
+    public T next() {
+      return iterator.next();
+    }
+
+    @Override
+    protected T doNext() {
+      throw new UnsupportedOperationException("hasNext has been override, doNext is never called");
+    }
+
+    @Override
+    protected void doClose() throws Exception {
+      // do nothing
+    }
+  }
 }
index 83f06bf385bb04e48f580c9a52063a019ab78474..057e5975c3b38867b8e51bf9d14bebd3efcfaf9d 100644 (file)
@@ -19,7 +19,9 @@
  */
 package org.sonar.server.util;
 
+import java.io.IOException;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.NoSuchElementException;
 import org.junit.Test;
 
@@ -117,7 +119,7 @@ public class CloseableIteratorTest {
   }
 
   @Test(expected = NoSuchElementException.class)
-  public void emptyIterator_next_throws_NoSuchElemetException() {
+  public void emptyIterator_next_throws_NoSuchElementException() {
     CloseableIterator.emptyCloseableIterator().next();
   }
 
@@ -131,6 +133,35 @@ public class CloseableIteratorTest {
     CloseableIterator.from(new SimpleCloseableIterator());
   }
 
+  @Test(expected = IllegalArgumentException.class)
+  public void from_iterator_throws_IAE_if_arg_is_a_AutoCloseable() {
+    CloseableIterator.from(new CloseableIt());
+  }
+
+  private static class CloseableIt implements Iterator<String>, AutoCloseable {
+    private final Iterator<String> delegate = Collections.<String>emptyList().iterator();
+
+    @Override
+    public void remove() {
+      delegate.remove();
+    }
+
+    @Override
+    public String next() {
+      return delegate.next();
+    }
+
+    @Override
+    public boolean hasNext() {
+      return delegate.hasNext();
+    }
+
+    @Override
+    public void close() throws IOException {
+      // no need to implement it for real
+    }
+  }
+
   @Test
   public void verify_has_next_from_iterator_with_empty_iterator() {
     assertThat(CloseableIterator.from(Collections.<String>emptyList().iterator()).hasNext()).isFalse();