changeset 6630:7aea433e840f

Automated merge with http://hg.openjdk.java.net/lambda/lambda//jdk
author psandoz
date Mon, 26 Nov 2012 14:50:33 +0100
parents 46befad6ec66 663bf5f037d5
children 95fbc3044c96
files
diffstat 2 files changed, 66 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/AbstractPipeline.java	Thu Nov 22 11:15:26 2012 -0800
+++ b/src/share/classes/java/util/stream/AbstractPipeline.java	Mon Nov 26 14:50:33 2012 +0100
@@ -110,6 +110,12 @@
     protected AbstractPipeline(AbstractPipeline<?, E_IN> upstream, IntermediateOp<E_IN, E_OUT> op) {
         Objects.requireNonNull(upstream);
 
+        // A stream cannot be added if the source has already been consumed
+        if (upstream.sourceState.isConsumed()) {
+            throw new IllegalStateException("Stream source is already consumed");
+        }
+
+        // A stream can only be added to the tail stream
         if (upstream.linked) {
             throw new IllegalStateException("Parent stream is already linked to a child stream");
         }
@@ -132,6 +138,11 @@
     }
 
     protected<R> R evaluate(TerminalOp<E_OUT, R> terminal) {
+        // Evaluation can only be performed on the tail stream
+        if (linked == true) {
+            throw new IllegalStateException("Stream is already linked to a child stream");
+        }
+
         if (StreamOpFlag.PARALLEL.isKnown(sourceState.getSourceFlags())) {
             return evaluateParallel(terminal);
         }
@@ -139,7 +150,7 @@
             return evaluateSequential(terminal, sourceState.getSourceFlags());
     }
 
-    protected<R> R evaluateParallel(TerminalOp<E_OUT, R> terminal) {
+    private<R> R evaluateParallel(TerminalOp<E_OUT, R> terminal) {
         // Combined flags length is one greater than depth to hold initial value
         // Given an op whose index is i then the flags input to that op are at flags[i]
         // and the flags output from that op are at flags[i + 1]
@@ -200,7 +211,7 @@
     }
 
     @SuppressWarnings("unchecked")
-    protected <R> R evaluateSequential(TerminalOp<E_OUT, R> terminal, int sourceFlags) {
+    private <R> R evaluateSequential(TerminalOp<E_OUT, R> terminal, int sourceFlags) {
         return (R) terminal.evaluateSequential(new SequentialImplPipelineHelper(sourceState.spliterator(), sourceFlags, terminal.inputShape()));
     }
 
@@ -496,6 +507,11 @@
     @Override
     @SuppressWarnings("unchecked")
     public Iterator<E_OUT> iterator() {
+        // Iteration can only be performed on the tail stream
+        if (linked == true) {
+            throw new IllegalStateException("Stream is already linked to a child stream");
+        }
+
         Iterator iterator = sourceState.iterator();
 
         // Ensure the parallel flag is cleared, if set
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/StreamReuseTest.java	Thu Nov 22 11:15:26 2012 -0800
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/StreamReuseTest.java	Mon Nov 26 14:50:33 2012 +0100
@@ -103,6 +103,18 @@
     }
 
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTerminalStream(String name, StreamTestData<Integer> data) {
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.findFirst(), (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream findFirst / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), (Stream<Integer> s) -> s.findFirst(),
+                          IllegalStateException.class,
+                          "Stream map / findFirst succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testTwoIterators(String name, StreamTestData<Integer> data) {
         assertSecondFails(data,
                           (Stream<Integer> s) -> s.iterator(), (Stream<Integer> s) -> s.iterator(),
@@ -122,6 +134,18 @@
                           "Stream findFirst / iterator succeeded erroneously");
     }
 
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStreamIterator(String name, StreamTestData<Integer> data) {
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.iterator(), (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), (Stream<Integer> s) -> s.iterator(),
+                          IllegalStateException.class,
+                          "Stream map / iterator succeeded erroneously");
+    }
+
     // IntStream
 
     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
@@ -141,6 +165,18 @@
     }
 
     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTerminalStream(String name, IntStreamTestData data) {
+        assertSecondFails(data,
+                          (IntStream s) -> s.sum(), (IntStream s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "IntStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.map(i -> i), (IntStream s) -> s.sum(),
+                          IllegalStateException.class,
+                          "IntStream map / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
     public void testTwoIterators(String name, IntStreamTestData data) {
         assertSecondFails(data,
                           (IntStream s) -> s.iterator(), (IntStream s) -> s.iterator(),
@@ -159,4 +195,16 @@
                           IllegalStateException.class,
                           "Stream sum / iterator succeeded erroneously");
     }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testStreamIterator(String name, IntStreamTestData data) {
+        assertSecondFails(data,
+                          (IntStream s) -> s.iterator(), (IntStream s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "IntStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.map(i -> i), (IntStream s) -> s.iterator(),
+                          IllegalStateException.class,
+                          "IntStream map / iterator succeeded erroneously");
+    }
 }