changeset 2026:ae67e52ef32f

Fixes to zip provider demo: 1. ZipFileSystem.{closeableObjects,fileSystems} not thread safe 2. Close does not remove object from closeableObjects (now closeables) 3. ZipFileSystem uses raw type 4. ZipFilePath.resolve(null) throws NPE Contributed-by: uckelman@nomic.net
author alanb
date Tue, 10 Nov 2009 11:39:41 +0000
parents a9c30b83ab4a
children a2cbf3efeaa1
files src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystem.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystemProvider.java
diffstat 3 files changed, 92 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java	Mon Nov 09 10:04:37 2009 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java	Tue Nov 10 11:39:41 2009 +0000
@@ -31,9 +31,11 @@
 package com.sun.nio.zipfs;
 
 import java.io.File;
+import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
 import java.nio.channels.SeekableByteChannel;
 import java.nio.file.*;
 import java.nio.file.DirectoryStream.Filter;
@@ -556,13 +558,15 @@
     }
 
     public ZipFilePath resolve(Path other) {
-        // zip/jar path are always absolute
         if (other == null) {
-            throw new NullPointerException();
+            return this;
         }
+
         if (!(other instanceof ZipFilePath)) {
             throw new ProviderMismatchException();
         }
+
+        // zip/jar path are always absolute
         ZipFilePath other1 = (ZipFilePath) other;
         if (other1.isAbsolute()) {
             return other1;
@@ -727,6 +731,73 @@
         return pathToZip;
     }
 
+    /**
+     * An {@link InputStream} which registers itself with the
+     * {@link ZipFileSystem} on creation and unregisters itself on
+     * closure.
+     */
+    private class ZipFilePathInputStream extends FilterInputStream {
+        public ZipFilePathInputStream(InputStream in) {
+            super(in);
+            fileSystem.registerCloseable(this);
+        }
+
+        @Override
+        public void close() throws IOException {
+            in.close();
+            fileSystem.unregisterCloseable(this);
+        }
+    }
+
+    /**
+     * A {@link SeekableByteChannel} which registers itself with the
+     * {@link ZipFileSystem} on creation and unregisters itself on
+     * closure.
+     */
+    private class ZipFilePathChannel implements SeekableByteChannel {
+        private final SeekableByteChannel ch;
+
+        public ZipFilePathChannel(SeekableByteChannel ch) {
+            this.ch = ch;
+            fileSystem.registerCloseable(this);
+        }
+
+        public long position() throws IOException {
+            return ch.position();
+        }
+
+        public SeekableByteChannel position(long newPos) throws IOException {
+            ch.position(newPos);
+            return this;
+        }
+
+        public int read(ByteBuffer dst) throws IOException {
+            return ch.read(dst);
+        }
+
+        public long size() throws IOException {
+            return ch.size();
+        }
+
+        public SeekableByteChannel truncate(long size) throws IOException {
+            ch.truncate(size);
+            return this;
+        }
+
+        public int write(ByteBuffer src) throws IOException {
+            return ch.write(src);
+        }
+
+        public boolean isOpen() {
+            return ch.isOpen();
+        }
+
+        public void close() throws IOException {
+            ch.close();
+            fileSystem.unregisterCloseable(this);
+        }
+    }
+
     @Override
     public InputStream newInputStream(OpenOption... options)
             throws IOException {
@@ -751,9 +822,8 @@
                     zfile.close();
                     throw new IOException("entry not found" + entryStr);
                 }
-                InputStream is = zfile.getInputStream(entry);
-                fileSystem.addCloseableObjects(is);
-                return is;
+
+                return new ZipFilePathInputStream(zfile.getInputStream(entry));
             }
         } finally {
             end();
@@ -1009,9 +1079,8 @@
                 InputStream in = zfile.getInputStream(entry);
                 Path pathtoZip = Paths.get(ZipUtils.readFileInZip(in));
                 zfile.close();
-                SeekableByteChannel sbc = FileChannel.open(pathtoZip, options);
-                fileSystem.addCloseableObjects(sbc);
-                return sbc;
+
+                return new ZipFilePathChannel(FileChannel.open(pathtoZip, options));
             }
         } finally {
             end();
--- a/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystem.java	Mon Nov 09 10:04:37 2009 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystem.java	Tue Nov 10 11:39:41 2009 +0000
@@ -51,7 +51,9 @@
     private final String defaultdir;
     private final ReadWriteLock closeLock = new ReentrantReadWriteLock();
     private boolean open = true;
-    private Set<Closeable> closeableObjects = new HashSet<Closeable>();
+
+    private final Set<Closeable> closeables =
+        Collections.synchronizedSet(new HashSet<Closeable>());
 
     ZipFileSystem(ZipFileSystemProvider provider,
             FileRef fref) {
@@ -117,7 +119,7 @@
     private void implClose(URI root) throws IOException {
         ZipUtils.remove(root); // remove cached filesystem
         provider.removeFileSystem(root);
-        Iterator<Closeable> itr = closeableObjects.iterator();
+        Iterator<Closeable> itr = closeables.iterator();
         while (itr.hasNext()) {
             try {
                 itr.next().close();
@@ -128,8 +130,12 @@
         }
     }
 
-    boolean addCloseableObjects(Closeable obj) {
-        return closeableObjects.add(obj);
+    boolean registerCloseable(Closeable c) {
+        return closeables.add(c);
+    }
+
+    boolean unregisterCloseable(Closeable c) {
+        return closeables.remove(c);
     }
 
     @Override
@@ -252,7 +258,8 @@
         }
     }
     private static final Set<String> supportedFileAttributeViews =
-            Collections.unmodifiableSet(new HashSet(Arrays.asList("basic", "zip", "jar")));
+            Collections.unmodifiableSet(
+                new HashSet<String>(Arrays.asList("basic", "zip", "jar")));
 
     @Override
     public Set<String> supportedFileAttributeViews() {
--- a/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystemProvider.java	Mon Nov 09 10:04:37 2009 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystemProvider.java	Tue Nov 10 11:39:41 2009 +0000
@@ -38,6 +38,7 @@
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.channels.FileChannel;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -46,7 +47,8 @@
         extends FileSystemProvider {
 
     private String scheme = "zip";
-    private Map<URI, ZipFileSystem> fileSystems = new HashMap<URI, ZipFileSystem>();
+    private Map<URI, ZipFileSystem> fileSystems =
+        Collections.synchronizedMap(new HashMap<URI, ZipFileSystem>());
 
     public ZipFileSystemProvider() {
     }