< prev index next >

src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java

Print this page
rev 53716 : 8213031: (zipfs) Add support for POSIX file permissions


  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nio.zipfs;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.OutputStream;
  32 import java.net.URI;
  33 import java.nio.channels.FileChannel;
  34 import java.nio.channels.SeekableByteChannel;
  35 import java.nio.file.*;
  36 import java.nio.file.DirectoryStream.Filter;
  37 import java.nio.file.attribute.BasicFileAttributeView;
  38 import java.nio.file.attribute.FileAttribute;
  39 import java.nio.file.attribute.FileTime;



  40 import java.util.Arrays;
  41 import java.util.Iterator;
  42 import java.util.Map;
  43 import java.util.NoSuchElementException;
  44 import java.util.Objects;
  45 import java.util.Set;
  46 
  47 import static java.nio.charset.StandardCharsets.UTF_8;
  48 import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
  49 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
  50 import static java.nio.file.StandardOpenOption.CREATE;
  51 import static java.nio.file.StandardOpenOption.READ;
  52 import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
  53 import static java.nio.file.StandardOpenOption.WRITE;
  54 
  55 /**
  56  * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
  57  */
  58 final class ZipPath implements Path {
  59 
  60     private final ZipFileSystem zfs;
  61     private final byte[] path;
  62     private volatile int[] offsets;
  63     private int hashcode = 0;  // cached hashcode (created lazily)
  64 
  65     ZipPath(ZipFileSystem zfs, byte[] path) {
  66         this(zfs, path, false);
  67     }
  68 
  69     ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) {
  70         this.zfs = zfs;
  71         if (normalized) {
  72             this.path = path;
  73         } else {
  74             if (zfs.zc.isUTF8()) {
  75                 this.path = normalize(path);
  76             } else {    // see normalize(String);
  77                 this.path = normalize(zfs.getString(path));
  78             }
  79         }
  80     }


 739     {
 740         ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
 741         if (zfas == null)
 742             throw new NoSuchFileException(toString());
 743         return zfas;
 744     }
 745 
 746     void setAttribute(String attribute, Object value, LinkOption... options)
 747         throws IOException
 748     {
 749         String type = null;
 750         String attr = null;
 751         int colonPos = attribute.indexOf(':');
 752         if (colonPos == -1) {
 753             type = "basic";
 754             attr = attribute;
 755         } else {
 756             type = attribute.substring(0, colonPos++);
 757             attr = attribute.substring(colonPos);
 758         }
 759         ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
 760         if (view == null)
 761             throw new UnsupportedOperationException("view <" + view + "> is not supported");
 762         view.setAttribute(attr, value);
 763     }
 764 
 765     void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
 766         throws IOException
 767     {
 768         zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
 769     }
 770 
 771     Map<String, Object> readAttributes(String attributes, LinkOption... options)




 772         throws IOException



 773 






 774     {
 775         String view = null;
 776         String attrs = null;
 777         int colonPos = attributes.indexOf(':');
 778         if (colonPos == -1) {
 779             view = "basic";
 780             attrs = attributes;
 781         } else {
 782             view = attributes.substring(0, colonPos++);
 783             attrs = attributes.substring(colonPos);
 784         }
 785         ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
 786         if (zfv == null) {
 787             throw new UnsupportedOperationException("view not supported");
 788         }
 789         return zfv.readAttributes(attrs);
 790     }
 791 
 792     FileStore getFileStore() throws IOException {
 793         // each ZipFileSystem only has one root (as requested for now)
 794         if (exists())
 795             return zfs.getFileStore(this);
 796         throw new NoSuchFileException(zfs.getString(path));
 797     }
 798 
 799     boolean isSameFile(Path other) throws IOException {
 800         if (this.equals(other))
 801             return true;
 802         if (other == null ||
 803             this.getFileSystem() != other.getFileSystem())
 804             return false;
 805         this.checkAccess();
 806         ((ZipPath)other).checkAccess();
 807         return Arrays.equals(this.getResolvedPath(),
 808                              ((ZipPath)other).getResolvedPath());
 809     }


 918             // create directory or file
 919             target.createDirectory();
 920         } else {
 921             InputStream is = zfs.newInputStream(getResolvedPath());
 922             try {
 923                 OutputStream os = target.newOutputStream();
 924                 try {
 925                     byte[] buf = new byte[8192];
 926                     int n = 0;
 927                     while ((n = is.read(buf)) != -1) {
 928                         os.write(buf, 0, n);
 929                     }
 930                 } finally {
 931                     os.close();
 932                 }
 933             } finally {
 934                 is.close();
 935             }
 936         }
 937         if (copyAttrs) {
 938             BasicFileAttributeView view =
 939                 ZipFileAttributeView.get(target, BasicFileAttributeView.class);
 940             try {
 941                 view.setTimes(zfas.lastModifiedTime(),
 942                               zfas.lastAccessTime(),
 943                               zfas.creationTime());


 944             } catch (IOException x) {
 945                 // rollback?
 946                 try {
 947                     target.delete();
 948                 } catch (IOException ignore) { }
 949                 throw x;
 950             }
 951         }
 952     }
 953 
 954     private static int decode(char c) {
 955         if ((c >= '0') && (c <= '9'))
 956             return c - '0';
 957         if ((c >= 'a') && (c <= 'f'))
 958             return c - 'a' + 10;
 959         if ((c >= 'A') && (c <= 'F'))
 960             return c - 'A' + 10;
 961         assert false;
 962         return -1;
 963     }




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nio.zipfs;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.OutputStream;
  32 import java.net.URI;
  33 import java.nio.channels.FileChannel;
  34 import java.nio.channels.SeekableByteChannel;
  35 import java.nio.file.*;
  36 import java.nio.file.DirectoryStream.Filter;

  37 import java.nio.file.attribute.FileAttribute;
  38 import java.nio.file.attribute.FileTime;
  39 import java.nio.file.attribute.GroupPrincipal;
  40 import java.nio.file.attribute.PosixFilePermission;
  41 import java.nio.file.attribute.UserPrincipal;
  42 import java.util.Arrays;
  43 import java.util.Iterator;
  44 import java.util.Map;
  45 import java.util.NoSuchElementException;
  46 import java.util.Objects;
  47 import java.util.Set;
  48 
  49 import static java.nio.charset.StandardCharsets.UTF_8;
  50 import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
  51 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
  52 import static java.nio.file.StandardOpenOption.CREATE;
  53 import static java.nio.file.StandardOpenOption.READ;
  54 import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
  55 import static java.nio.file.StandardOpenOption.WRITE;
  56 
  57 /**
  58  * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
  59  */
  60 final class ZipPath implements Path {
  61 
  62     final ZipFileSystem zfs;
  63     private final byte[] path;
  64     private volatile int[] offsets;
  65     private int hashcode = 0;  // cached hashcode (created lazily)
  66 
  67     ZipPath(ZipFileSystem zfs, byte[] path) {
  68         this(zfs, path, false);
  69     }
  70 
  71     ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) {
  72         this.zfs = zfs;
  73         if (normalized) {
  74             this.path = path;
  75         } else {
  76             if (zfs.zc.isUTF8()) {
  77                 this.path = normalize(path);
  78             } else {    // see normalize(String);
  79                 this.path = normalize(zfs.getString(path));
  80             }
  81         }
  82     }


 741     {
 742         ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
 743         if (zfas == null)
 744             throw new NoSuchFileException(toString());
 745         return zfas;
 746     }
 747 
 748     void setAttribute(String attribute, Object value, LinkOption... options)
 749         throws IOException
 750     {
 751         String type = null;
 752         String attr = null;
 753         int colonPos = attribute.indexOf(':');
 754         if (colonPos == -1) {
 755             type = "basic";
 756             attr = attribute;
 757         } else {
 758             type = attribute.substring(0, colonPos++);
 759             attr = attribute.substring(colonPos);
 760         }
 761         ZipFileAttributeView.get(this, type).setAttribute(attr, value);



 762     }
 763 
 764     void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
 765         throws IOException
 766     {
 767         zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
 768     }
 769 
 770     void setOwner(UserPrincipal owner) throws IOException {
 771         zfs.setOwner(getResolvedPath(), owner);
 772     }
 773 
 774     void setPermissions(Set<PosixFilePermission> perms)
 775         throws IOException
 776     {
 777         zfs.setPermissions(getResolvedPath(), perms);
 778     }
 779 
 780     void setGroup(GroupPrincipal group) throws IOException {
 781         zfs.setGroup(getResolvedPath(), group);
 782     }
 783 
 784     Map<String, Object> readAttributes(String attributes, LinkOption... options)
 785         throws IOException
 786     {
 787         String view = null;
 788         String attrs = null;
 789         int colonPos = attributes.indexOf(':');
 790         if (colonPos == -1) {
 791             view = "basic";
 792             attrs = attributes;
 793         } else {
 794             view = attributes.substring(0, colonPos++);
 795             attrs = attributes.substring(colonPos);
 796         }
 797         return ZipFileAttributeView.get(this, view).readAttributes(attrs);




 798     }
 799 
 800     FileStore getFileStore() throws IOException {
 801         // each ZipFileSystem only has one root (as requested for now)
 802         if (exists())
 803             return zfs.getFileStore(this);
 804         throw new NoSuchFileException(zfs.getString(path));
 805     }
 806 
 807     boolean isSameFile(Path other) throws IOException {
 808         if (this.equals(other))
 809             return true;
 810         if (other == null ||
 811             this.getFileSystem() != other.getFileSystem())
 812             return false;
 813         this.checkAccess();
 814         ((ZipPath)other).checkAccess();
 815         return Arrays.equals(this.getResolvedPath(),
 816                              ((ZipPath)other).getResolvedPath());
 817     }


 926             // create directory or file
 927             target.createDirectory();
 928         } else {
 929             InputStream is = zfs.newInputStream(getResolvedPath());
 930             try {
 931                 OutputStream os = target.newOutputStream();
 932                 try {
 933                     byte[] buf = new byte[8192];
 934                     int n = 0;
 935                     while ((n = is.read(buf)) != -1) {
 936                         os.write(buf, 0, n);
 937                     }
 938                 } finally {
 939                     os.close();
 940                 }
 941             } finally {
 942                 is.close();
 943             }
 944         }
 945         if (copyAttrs) {
 946             ZipFileAttributeView view =
 947                 ZipFileAttributeView.get(target, ZipFileAttributeView.class);
 948             try {
 949                 view.setTimes(zfas.lastModifiedTime(),
 950                               zfas.lastAccessTime(),
 951                               zfas.creationTime());
 952                 // copy permissions
 953                 view.setPermissions(zfas.storedPermissions().orElse(null));
 954             } catch (IOException x) {
 955                 // rollback?
 956                 try {
 957                     target.delete();
 958                 } catch (IOException ignore) { }
 959                 throw x;
 960             }
 961         }
 962     }
 963 
 964     private static int decode(char c) {
 965         if ((c >= '0') && (c <= '9'))
 966             return c - '0';
 967         if ((c >= 'a') && (c <= 'f'))
 968             return c - 'a' + 10;
 969         if ((c >= 'A') && (c <= 'F'))
 970             return c - 'A' + 10;
 971         assert false;
 972         return -1;
 973     }


< prev index next >