diff --git a/src/share/classes/java/util/BitSet.java b/src/share/classes/java/util/BitSet.java index dc63a268ec76a52b12f59018a92d90cfefcfd73d..56faccc66fba4d0156bb895f94fecd380f4be174 100644 --- a/src/share/classes/java/util/BitSet.java +++ b/src/share/classes/java/util/BitSet.java @@ -29,6 +29,8 @@ import java.io.*; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.LongBuffer; +import java.util.stream.IntStream; +import java.util.stream.StreamSupport; /** * This class implements a vector of bits that grows as needed. Each @@ -1188,4 +1190,47 @@ public class BitSet implements Cloneable, java.io.Serializable { b.append('}'); return b.toString(); } + + /** + * Returns a stream of indices for which this {@code BitSet} + * contains a bit in the set state. The indices are returned + * in order, from lowest to highest. The size of the stream + * is the number of bits in the set state, equal to the value + * returned by the {@link #cardinality()} method. + * + *

The bit set must remain constant during the execution of the + * terminal stream operation. Otherwise, the result of the terminal + * stream operation is undefined. + * + * @return a stream of integers representing set indices + * @since 1.8 + */ + public IntStream stream() { + class BitSetIterator implements PrimitiveIterator.OfInt { + int next = nextSetBit(0); + + @Override + public boolean hasNext() { + return next != -1; + } + + @Override + public int nextInt() { + if (next != -1) { + int ret = next; + next = nextSetBit(next+1); + return ret; + } else { + throw new NoSuchElementException(); + } + } + } + + return StreamSupport.intStream( + () -> Spliterators.spliterator( + new BitSetIterator(), cardinality(), + Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED), + Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED); + } } diff --git a/src/share/classes/java/util/Random.java b/src/share/classes/java/util/Random.java index 6e87e3a645ba3e564c0d56793daf56463f37fdbe..c169e053dfd5be4a81452022fbcb7145f6111ed7 100644 --- a/src/share/classes/java/util/Random.java +++ b/src/share/classes/java/util/Random.java @@ -26,6 +26,10 @@ package java.util; import java.io.*; import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; + import sun.misc.Unsafe; /** @@ -512,6 +516,59 @@ class Random implements java.io.Serializable { } } + /** + * Returns a stream of pseudorandom, uniformly distributed + * {@code integer} values from this random number generator's + * sequence. Values are obtained as needed by calling + * {@link #nextInt()}. + * + * @return an infinite stream of {@code integer} values + * @since 1.8 + */ + public IntStream ints() { + return IntStream.generate(this::nextInt); + } + + /** + * Returns a stream of pseudorandom, uniformly distributed + * {@code long} values from this random number generator's + * sequence. Values are obtained as needed by calling + * {@link #nextLong()}. + * + * @return an infinite stream of {@code long} values + * @since 1.8 + */ + public LongStream longs() { + return LongStream.generate(this::nextLong); + } + + /** + * Returns a stream of pseudorandom, uniformly distributed + * {@code double} values between {@code 0.0} and {@code 1.0} + * from this random number generator's sequence. Values are + * obtained as needed by calling {@link #nextDouble()}. + * + * @return an infinite stream of {@code double} values + * @since 1.8 + */ + public DoubleStream doubles() { + return DoubleStream.generate(this::nextDouble); + } + + /** + * Returns a stream of pseudorandom, Gaussian ("normally") + * distributed {@code double} values with mean {@code 0.0} + * and standard deviation {@code 1.0} from this random number + * generator's sequence. Values are obtained as needed by + * calling {@link #nextGaussian()}. + * + * @return an infinite stream of {@code double} values + * @since 1.8 + */ + public DoubleStream gaussians() { + return DoubleStream.generate(this::nextGaussian); + } + /** * Serializable fields for Random. * diff --git a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java index c19d51285742344752bc67df77c003db9b5c88be..0532d3d4382b34c87de5e1b02e66a57871bfe2ea 100644 --- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -39,6 +39,9 @@ import java.io.ObjectStreamField; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; /** * A random number generator isolated to the current thread. Like the @@ -241,6 +244,26 @@ public class ThreadLocalRandom extends Random { return offset + nextInt((int) n); } + @Override + public IntStream ints() { + return IntStream.generate(() -> current().nextInt()); + } + + @Override + public LongStream longs() { + return LongStream.generate(() -> current().nextLong()); + } + + @Override + public DoubleStream doubles() { + return DoubleStream.generate(() -> current().nextDouble()); + } + + @Override + public DoubleStream gaussians() { + return DoubleStream.generate(() -> current().nextGaussian()); + } + /** * Returns a pseudorandom, uniformly distributed value between the * given least value (inclusive) and bound (exclusive). diff --git a/src/share/classes/java/util/jar/JarFile.java b/src/share/classes/java/util/jar/JarFile.java index 84c03753cfef85c5c47a6edfeb0274eb465ab4cb..a70be7a6e2dfd2d994deee972298e4605701c428 100644 --- a/src/share/classes/java/util/jar/JarFile.java +++ b/src/share/classes/java/util/jar/JarFile.java @@ -29,6 +29,8 @@ import java.io.*; import java.lang.ref.SoftReference; import java.net.URL; import java.util.*; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import java.util.zip.*; import java.security.CodeSigner; import java.security.cert.Certificate; @@ -235,20 +237,42 @@ class JarFile extends ZipFile { return null; } + private class JarEntryIterator implements Enumeration, + Iterator + { + final Enumeration e = JarFile.super.entries(); + + public boolean hasNext() { + return e.hasMoreElements(); + } + + public JarEntry next() { + ZipEntry ze = e.nextElement(); + return new JarFileEntry(ze); + } + + public boolean hasMoreElements() { + return hasNext(); + } + + public JarEntry nextElement() { + return next(); + } + } + /** * Returns an enumeration of the zip file entries. */ public Enumeration entries() { - final Enumeration enum_ = super.entries(); - return new Enumeration() { - public boolean hasMoreElements() { - return enum_.hasMoreElements(); - } - public JarFileEntry nextElement() { - ZipEntry ze = enum_.nextElement(); - return new JarFileEntry(ze); - } - }; + return new JarEntryIterator(); + } + + @Override + public Stream stream() { + return StreamSupport.stream(Spliterators.spliterator( + new JarEntryIterator(), size(), + Spliterator.ORDERED | Spliterator.DISTINCT | + Spliterator.IMMUTABLE | Spliterator.NONNULL)); } private class JarFileEntry extends JarEntry { diff --git a/src/share/classes/java/util/zip/ZipFile.java b/src/share/classes/java/util/zip/ZipFile.java index 9693809331a38a5c286e8c6456526360c5a6ee0c..f334f36d1b0a6a0b4d1320d084b5600514acee28 100644 --- a/src/share/classes/java/util/zip/ZipFile.java +++ b/src/share/classes/java/util/zip/ZipFile.java @@ -36,11 +36,15 @@ import java.util.ArrayDeque; import java.util.Deque; import java.util.Enumeration; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Spliterator; +import java.util.Spliterators; import java.util.WeakHashMap; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + import static java.util.zip.ZipConstants64.*; /** @@ -471,49 +475,80 @@ class ZipFile implements ZipConstants, Closeable { return name; } + private class ZipEntryIterator implements Enumeration, Iterator { + private int i = 0; + + public ZipEntryIterator() { + ensureOpen(); + } + + public boolean hasMoreElements() { + return hasNext(); + } + + public boolean hasNext() { + synchronized (ZipFile.this) { + ensureOpen(); + return i < total; + } + } + + public ZipEntry nextElement() { + return next(); + } + + public ZipEntry next() { + synchronized (ZipFile.this) { + ensureOpen(); + if (i >= total) { + throw new NoSuchElementException(); + } + long jzentry = getNextEntry(jzfile, i++); + if (jzentry == 0) { + String message; + if (closeRequested) { + message = "ZipFile concurrently closed"; + } else { + message = getZipMessage(ZipFile.this.jzfile); + } + throw new ZipError("jzentry == 0" + + ",\n jzfile = " + ZipFile.this.jzfile + + ",\n total = " + ZipFile.this.total + + ",\n name = " + ZipFile.this.name + + ",\n i = " + i + + ",\n message = " + message + ); + } + ZipEntry ze = getZipEntry(null, jzentry); + freeEntry(jzfile, jzentry); + return ze; + } + } + } + /** * Returns an enumeration of the ZIP file entries. * @return an enumeration of the ZIP file entries * @throws IllegalStateException if the zip file has been closed */ public Enumeration entries() { - ensureOpen(); - return new Enumeration() { - private int i = 0; - public boolean hasMoreElements() { - synchronized (ZipFile.this) { - ensureOpen(); - return i < total; - } - } - public ZipEntry nextElement() throws NoSuchElementException { - synchronized (ZipFile.this) { - ensureOpen(); - if (i >= total) { - throw new NoSuchElementException(); - } - long jzentry = getNextEntry(jzfile, i++); - if (jzentry == 0) { - String message; - if (closeRequested) { - message = "ZipFile concurrently closed"; - } else { - message = getZipMessage(ZipFile.this.jzfile); - } - throw new ZipError("jzentry == 0" + - ",\n jzfile = " + ZipFile.this.jzfile + - ",\n total = " + ZipFile.this.total + - ",\n name = " + ZipFile.this.name + - ",\n i = " + i + - ",\n message = " + message - ); - } - ZipEntry ze = getZipEntry(null, jzentry); - freeEntry(jzfile, jzentry); - return ze; - } - } - }; + return new ZipEntryIterator(); + } + + /** + * Return an ordered {@code Stream} over the ZIP file entries. + * Entries appear in the {@code Stream} in the order they appear in + * the central directory of the ZIP file. + * + * @return an ordered {@code Stream} of entries in this ZIP file + * @throws IllegalStateException if the zip file has been closed + * @since 1.8 + */ + public Stream stream() { + return StreamSupport.stream(Spliterators.spliterator( + new ZipEntryIterator(), size(), + Spliterator.ORDERED | Spliterator.DISTINCT | + Spliterator.IMMUTABLE | Spliterator.NONNULL)); } private ZipEntry getZipEntry(String name, long jzentry) { diff --git a/test/java/util/BitSet/BitSetStreamTest.java b/test/java/util/BitSet/BitSetStreamTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a7fae5c94211b65f52c878e91f5776590930f6c8 --- /dev/null +++ b/test/java/util/BitSet/BitSetStreamTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.lang.Integer; +import java.lang.Object; +import java.lang.System; +import java.util.BitSet; +import java.util.OptionalInt; +import java.util.PrimitiveIterator; +import java.util.Random; +import java.util.function.IntSupplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +/** + * @test + * @summary test BitSet stream + * @bug 8012645 + * @run testng BitSetStreamTest + */ +public class BitSetStreamTest { + static class Fibs implements IntSupplier { + private int n1 = 0; + private int n2 = 1; + + static int fibs(int n) { + Fibs f = new Fibs(); + while (n-- > 0) f.getAsInt(); + return f.getAsInt(); + } + + public int getAsInt() { int s = n1; n1 = n2; n2 = s + n1; return s; } + } + + private static final Object[][] testcases = new Object[][] { + { "none", IntStream.empty() }, + { "index 0", IntStream.of(0) }, + { "index 255", IntStream.of(255) }, + { "every bit", IntStream.range(0, 255) }, + { "step 2", IntStream.range(0, 255, 2) }, + { "step 3", IntStream.range(0, 255, 3) }, + { "step 5", IntStream.range(0, 255, 5) }, + { "step 7", IntStream.range(0, 255, 7) }, + { "1, 10, 100, 1000", IntStream.of(1, 10, 100, 1000) }, + { "25 fibs", IntStream.generate(new Fibs()).limit(25) } + }; + + @DataProvider(name = "cases") + public static Object[][] produceCases() { + return testcases; + } + + @Test + public void testFibs() { + Fibs f = new Fibs(); + assertEquals(0, f.getAsInt()); + assertEquals(1, f.getAsInt()); + assertEquals(1, f.getAsInt()); + assertEquals(2, f.getAsInt()); + assertEquals(3, f.getAsInt()); + assertEquals(5, f.getAsInt()); + assertEquals(8, f.getAsInt()); + assertEquals(13, f.getAsInt()); + assertEquals(987, Fibs.fibs(16)); + } + + @Test(dataProvider = "cases") + public void testBitsetStream(String name, IntStream data) { + BitSet bs = new BitSet(); + long setBits = data.distinct() + .peek(i -> bs.set(i)) + .count(); + + assertEquals(bs.cardinality(), setBits); + assertEquals(bs.cardinality(), bs.stream().reduce(0, (s, i) -> s+1)); + + PrimitiveIterator.OfInt it = bs.stream().iterator(); + for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) { + assertTrue(it.hasNext()); + assertEquals(it.nextInt(), i); + } + assertFalse(it.hasNext()); + } + + @Test + public void testRandomStream() { + final int size = 1024 * 1024; + final int[] seeds = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, + 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}; + final byte[] bytes = new byte[size]; + for (int seed : seeds) { + final Random random = new Random(seed); + random.nextBytes(bytes); + final BitSet bitSet = BitSet.valueOf(bytes); + final int cardinality = bitSet.cardinality(); + final IntStream stream = bitSet.stream(); + final int[] array = stream.toArray(); + assertEquals(array.length, cardinality); + int nextSetBit = -1; + for (int i=0; i < cardinality; i++) { + nextSetBit = bitSet.nextSetBit(nextSetBit + 1); + assertEquals(array[i], nextSetBit); + } + } + } +} diff --git a/test/java/util/Random/RandomStreamTest.java b/test/java/util/Random/RandomStreamTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c2edf4fee5ef8e32ce8c659524fd2f09411835e3 --- /dev/null +++ b/test/java/util/Random/RandomStreamTest.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import java.util.Random; + +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.DoubleStream; +import java.util.stream.Stream; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +/** + * @test + * @run testng RandomStreamTest + * @summary test stream methods on Random + * @author Brian Goetz + */ +public class RandomStreamTest { + + private static final int SIZE = 1000; + + @DataProvider(name = "suppliers") + public Object[][] randomSuppliers() { + return new Object[][] { + {new Random(), SIZE}, + {new SecureRandom(), SIZE} + }; + } + + @Test(dataProvider = "suppliers") + public void testRandomIntStream(final Random random, final int count) { + final List destination = new ArrayList<>(count); + random.ints().limit(count).forEach(destination::add); + assertEquals(destination.size(), count); + } + + @Test(dataProvider = "suppliers") + public void testRandomLongStream(final Random random, final int count) { + final List destination = new ArrayList<>(count); + random.longs().limit(count).forEach(destination::add); + assertEquals(destination.size(), count); + } + + @Test(dataProvider = "suppliers") + public void testRandomDoubleStream(final Random random, final int count) { + final List destination = new ArrayList<>(count); + random.doubles().limit(count).forEach(destination::add); + random.doubles().limit(count).forEach(d -> assertTrue(d >= 0.0 && d < 1.0)); + assertEquals(destination.size(), count); + } + + @Test(dataProvider = "suppliers") + public void testRandomGaussianStream(final Random random, final int count) { + final List destination = new ArrayList<>(count); + random.gaussians().limit(count).forEach(destination::add); + assertEquals(destination.size(), count); + } + + @Test + public void testIntStream() { + final long seed = System.currentTimeMillis(); + final Random r1 = new Random(seed); + final int[] a = new int[SIZE]; + for (int i=0; i < SIZE; i++) { + a[i] = r1.nextInt(); + } + + final Random r2 = new Random(seed); // same seed + final int[] b = r2.ints().limit(SIZE).toArray(); + assertEquals(a, b); + } + + @Test + public void testLongStream() { + final long seed = System.currentTimeMillis(); + final Random r1 = new Random(seed); + final long[] a = new long[SIZE]; + for (int i=0; i < SIZE; i++) { + a[i] = r1.nextLong(); + } + + final Random r2 = new Random(seed); // same seed + final long[] b = r2.longs().limit(SIZE).toArray(); + assertEquals(a, b); + } + + @Test + public void testDoubleStream() { + final long seed = System.currentTimeMillis(); + final Random r1 = new Random(seed); + final double[] a = new double[SIZE]; + for (int i=0; i < SIZE; i++) { + a[i] = r1.nextDouble(); + } + + final Random r2 = new Random(seed); // same seed + final double[] b = r2.doubles().limit(SIZE).toArray(); + assertEquals(a, b); + } + + @Test + public void testGaussianStream() { + final long seed = System.currentTimeMillis(); + final Random r1 = new Random(seed); + final double[] a = new double[SIZE]; + for (int i=0; i < SIZE; i++) { + a[i] = r1.nextGaussian(); + } + + final Random r2 = new Random(seed); // same seed + final double[] b = r2.gaussians().limit(SIZE).toArray(); + assertEquals(a, b); + } + + @Test + public void testThreadLocalIntStream() throws InterruptedException { + final ExecutorService e = Executors.newFixedThreadPool(10); + final ThreadLocalRandom tlr = ThreadLocalRandom.current(); + + final class RandomTask implements Runnable { + int[] randoms; + + @Override + public void run() { + randoms = tlr.ints().limit(SIZE).toArray(); + } + } + final RandomTask[] tasks = new RandomTask[10]; + for (int i=0; i < tasks.length; i++) { + tasks[i] = new RandomTask(); + } + for (int i=0; i < tasks.length; i++) { + e.submit(tasks[i]); + } + e.shutdown(); + e.awaitTermination(3, TimeUnit.SECONDS); + for (int i=1; i < tasks.length; i++) { + assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms)); + } + } + + @Test + public void testThreadLocalLongStream() throws InterruptedException { + final ExecutorService e = Executors.newFixedThreadPool(10); + final ThreadLocalRandom tlr = ThreadLocalRandom.current(); + + final class RandomTask implements Runnable { + long[] randoms; + + @Override + public void run() { + randoms = tlr.longs().limit(SIZE).toArray(); + } + } + final RandomTask[] tasks = new RandomTask[10]; + for (int i=0; i < tasks.length; i++) { + tasks[i] = new RandomTask(); + } + for (int i=0; i < tasks.length; i++) { + e.submit(tasks[i]); + } + e.shutdown(); + e.awaitTermination(3, TimeUnit.SECONDS); + for (int i=1; i < tasks.length; i++) { + assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms)); + } + } + + @Test + public void testThreadLocalDoubleStream() throws InterruptedException { + final ExecutorService e = Executors.newFixedThreadPool(10); + final ThreadLocalRandom tlr = ThreadLocalRandom.current(); + + final class RandomTask implements Runnable { + double[] randoms; + + @Override + public void run() { + randoms = tlr.doubles().limit(SIZE).toArray(); + } + } + final RandomTask[] tasks = new RandomTask[10]; + for (int i=0; i < tasks.length; i++) { + tasks[i] = new RandomTask(); + } + for (int i=0; i < tasks.length; i++) { + e.submit(tasks[i]); + } + e.shutdown(); + e.awaitTermination(3, TimeUnit.SECONDS); + for (int i=1; i < tasks.length; i++) { + assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms)); + } + } + + @Test + public void testThreadLocalGaussianStream() throws InterruptedException { + final ExecutorService e = Executors.newFixedThreadPool(10); + final ThreadLocalRandom tlr = ThreadLocalRandom.current(); + + final class RandomTask implements Runnable { + double[] randoms; + + @Override + public void run() { + randoms = tlr.gaussians().limit(SIZE).toArray(); + } + } + final RandomTask[] tasks = new RandomTask[10]; + for (int i=0; i < tasks.length; i++) { + tasks[i] = new RandomTask(); + } + for (int i=0; i < tasks.length; i++) { + e.submit(tasks[i]); + } + e.shutdown(); + e.awaitTermination(3, TimeUnit.SECONDS); + for (int i=1; i < tasks.length; i++) { + assertFalse(Arrays.equals(tasks[0].randoms, tasks[i].randoms)); + } + } + +} diff --git a/test/java/util/zip/ZipFile/StreamZipEntriesTest.java b/test/java/util/zip/ZipFile/StreamZipEntriesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..38199e4694c3a149fa0a2b2a7ab855f719da0585 --- /dev/null +++ b/test/java/util/zip/ZipFile/StreamZipEntriesTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @run testng StreamZipEntriesTest + * @summary Make sure we can stream entries of a zip file. + */ + +import java.io.File; +import java.io.IOException; +import java.lang.Object; +import java.lang.System; +import java.util.jar.JarFile; +import java.util.jar.JarEntry; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +public class StreamZipEntriesTest { + + @Test + public void testStreamZip() throws IOException { + try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip"))) { + zf.stream().forEach(e -> assertTrue(e instanceof ZipEntry)); + zf.stream().forEach(e -> assertEquals(e.toString(), "ReadZip.java")); + + Object elements[] = zf.stream().toArray(); + assertEquals(1, elements.length); + assertEquals(elements[0].toString(), "ReadZip.java"); + } + } + + @Test + public void testStreamJar() throws IOException { + try (JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"))) { + jf.stream().forEach(e -> assertTrue(e instanceof JarEntry)); + + Object elements[] = jf.stream().toArray(); + assertEquals(3, elements.length); + assertEquals(elements[0].toString(), "META-INF/"); + assertEquals(elements[1].toString(), "META-INF/MANIFEST.MF"); + assertEquals(elements[2].toString(), "ReleaseInflater.java"); + } + } + + @Test + public void testClosedZipFile() throws IOException { + ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip")); + zf.close(); + try { + Stream s = zf.stream(); + fail("Should have thrown IllegalStateException"); + } catch (IllegalStateException e) { + // expected; + } + } + + @Test + public void testClosedJarFile() throws IOException { + JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar")); + jf.close(); + try { + Stream s = jf.stream(); + fail("Should have thrown IllegalStateException"); + } catch (IllegalStateException e) { + // expected; + } + } +}