8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE
authorsherman
Wed, 27 May 2015 12:23:35 -0700
changeset 30811 58432ddf9528
parent 30810 cbb29036f026
child 30812 50187495b0c7
8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE 8034773: (zipfs) newOutputstream uses CREATE_NEW when no options specified Summary: to open the new steram with appropricate open options Reviewed-by: alanb
jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java
jdk/test/jdk/nio/zipfs/ZFSTests.java
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed May 27 13:23:40 2015 +0100
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed May 27 12:23:35 2015 -0700
@@ -503,6 +503,7 @@
         boolean hasCreateNew = false;
         boolean hasCreate = false;
         boolean hasAppend = false;
+        boolean hasTruncate = false;
         for (OpenOption opt: options) {
             if (opt == READ)
                 throw new IllegalArgumentException("READ not allowed");
@@ -512,7 +513,11 @@
                 hasCreate = true;
             if (opt == APPEND)
                 hasAppend = true;
+            if (opt == TRUNCATE_EXISTING)
+                hasTruncate = true;
         }
+        if (hasAppend && hasTruncate)
+            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
         beginRead();                 // only need a readlock, the "update()" will
         try {                        // try to obtain a writelock when the os is
             ensureOpen();            // being closed.
@@ -564,6 +569,8 @@
             if (!(option instanceof StandardOpenOption))
                 throw new IllegalArgumentException();
         }
+        if (options.contains(APPEND) && options.contains(TRUNCATE_EXISTING))
+            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
     }
 
     // Returns a Writable/ReadByteChannel for now. Might consdier to use
@@ -711,15 +718,19 @@
             if (forWrite) {
                 checkWritable();
                 if (e == null) {
-                if (!options.contains(StandardOpenOption.CREATE_NEW))
-                    throw new NoSuchFileException(getString(path));
+                    if (!options.contains(StandardOpenOption.CREATE) &&
+                        !options.contains(StandardOpenOption.CREATE_NEW)) {
+                        throw new NoSuchFileException(getString(path));
+                    }
                 } else {
-                    if (options.contains(StandardOpenOption.CREATE_NEW))
+                    if (options.contains(StandardOpenOption.CREATE_NEW)) {
                         throw new FileAlreadyExistsException(getString(path));
+                    }
                     if (e.isDir())
                         throw new FileAlreadyExistsException("directory <"
                             + getString(path) + "> exists");
                 }
+                options = new HashSet<>(options);
                 options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
             } else if (e == null || e.isDir()) {
                 throw new NoSuchFileException(getString(path));
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java	Wed May 27 13:23:40 2015 +0100
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java	Wed May 27 12:23:35 2015 -0700
@@ -773,7 +773,7 @@
     {
         if (options.length == 0)
             return zfs.newOutputStream(getResolvedPath(),
-                                       CREATE_NEW, WRITE);
+                                       CREATE, TRUNCATE_EXISTING, WRITE);
         return zfs.newOutputStream(getResolvedPath(), options);
     }
 
--- a/jdk/test/jdk/nio/zipfs/ZFSTests.java	Wed May 27 13:23:40 2015 +0100
+++ b/jdk/test/jdk/nio/zipfs/ZFSTests.java	Wed May 27 12:23:35 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 7156873 8040059
+ * @bug 7156873 8040059 8028480 8034773
  * @summary ZipFileSystem regression tests
  *
  * @run main ZFSTests
@@ -30,15 +30,19 @@
  */
 
 
+import java.io.OutputStream;
 import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
 import java.nio.file.*;
-import java.util.Map;
-import java.util.HashMap;
+import java.nio.file.spi.*;
+import java.util.*;
 
 public class ZFSTests {
 
     public static void main(String[] args) throws Throwable {
         test7156873();
+        testOpenOptions();
     }
 
     static void test7156873() throws Throwable {
@@ -56,4 +60,44 @@
             Files.deleteIfExists(dir);
         }
     }
+
+    static void testOpenOptions() throws Throwable {
+        Path path = Paths.get("file.zip");
+        try {
+            URI uri = URI.create("jar:" + path.toUri());
+            Map<String, Object> env = new HashMap<String, Object>();
+            env.put("create", "true");
+            try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
+                FileSystemProvider fsp = fs.provider();
+                Set<? extends OpenOption> options;
+                Path p = fs.getPath("test.txt");
+                // 8028480
+                options = EnumSet.of(StandardOpenOption.CREATE,
+                                     StandardOpenOption.WRITE,
+                                     StandardOpenOption.APPEND);
+                try (FileChannel ch = fsp.newFileChannel(p, options)) {
+                    ch.write(ByteBuffer.wrap("Hello!".getBytes("ASCII")));
+                }
+                // 8034773
+                try (OutputStream os = fsp.newOutputStream(p, new OpenOption[0])) {
+                    os.write("Hello2!".getBytes("ASCII"));
+                }
+                if (!"Hello2!".equals(new String(
+                        Files.readAllBytes(fs.getPath("test.txt"))))) {
+                    throw new RuntimeException("failed to open as truncate_existing");
+                }
+
+                options = EnumSet.of(StandardOpenOption.CREATE,
+                                     StandardOpenOption.APPEND,
+                                     StandardOpenOption.TRUNCATE_EXISTING);
+                try (FileChannel ch = fsp.newFileChannel(p, options)) {
+                    throw new RuntimeException("expected IAE not thrown!");
+                } catch (IllegalArgumentException x) {
+                    // expected x.printStackTrace();
+                }
+            }
+        } finally {
+            Files.deleteIfExists(path);
+        }
+    }
 }