1 /*
   2  * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  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.IOException;
  29 import java.nio.file.attribute.BasicFileAttributeView;
  30 import java.nio.file.attribute.FileAttributeView;
  31 import java.nio.file.attribute.FileTime;
  32 import java.nio.file.attribute.GroupPrincipal;
  33 import java.nio.file.attribute.PosixFileAttributeView;
  34 import java.nio.file.attribute.PosixFilePermission;
  35 import java.nio.file.attribute.UserPrincipal;
  36 import java.util.LinkedHashMap;
  37 import java.util.Map;
  38 import java.util.Set;
  39 
  40 /**
  41  * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
  42  */
  43 class ZipFileAttributeView implements PosixFileAttributeView {
  44     private static enum AttrID {
  45         size,
  46         creationTime,
  47         lastAccessTime,
  48         lastModifiedTime,
  49         isDirectory,
  50         isRegularFile,
  51         isSymbolicLink,
  52         isOther,
  53         fileKey,
  54         compressedSize,
  55         crc,
  56         method,
  57         permissions
  58     };
  59 
  60     private static enum ViewType {
  61         zip,
  62         posix,
  63         basic
  64     }
  65 
  66     private final ZipPath path;
  67     private final ViewType type;
  68 
  69     private ZipFileAttributeView(ZipPath path, ViewType type) {
  70         this.path = path;
  71         this.type = type;
  72     }
  73 
  74     @SuppressWarnings("unchecked") // Cast to V
  75     static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
  76         if (type == null)
  77             throw new NullPointerException();
  78         if (type == BasicFileAttributeView.class)
  79             return (V)new ZipFileAttributeView(path, ViewType.basic);
  80         if (type == PosixFileAttributeView.class)
  81             return (V)new ZipFileAttributeView(path, ViewType.posix);
  82         if (type == ZipFileAttributeView.class)
  83             return (V)new ZipFileAttributeView(path, ViewType.zip);
  84         return null;
  85     }
  86 
  87     static ZipFileAttributeView get(ZipPath path, String type) {
  88         if (type == null)
  89             throw new NullPointerException();
  90         if (type.equals("basic"))
  91             return new ZipFileAttributeView(path, ViewType.basic);
  92         if (type.equals("posix"))
  93             return new ZipFileAttributeView(path, ViewType.posix);
  94         if (type.equals("zip"))
  95             return new ZipFileAttributeView(path, ViewType.zip);
  96         return null;
  97     }
  98 
  99     @Override
 100     public String name() {
 101         switch (type) {
 102         case zip:
 103             return "zip";
 104         case posix:
 105             return "posix";
 106         case basic:
 107         default:
 108             return "basic";
 109         }
 110     }
 111 
 112     public ZipFileAttributes readAttributes() throws IOException {
 113         return path.getAttributes();
 114     }
 115 
 116     @Override
 117     public void setTimes(FileTime lastModifiedTime,
 118                          FileTime lastAccessTime,
 119                          FileTime createTime)
 120         throws IOException
 121     {
 122         path.setTimes(lastModifiedTime, lastAccessTime, createTime);
 123     }
 124 
 125     void setAttribute(String attribute, Object value)
 126         throws IOException
 127     {
 128         try {
 129             if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
 130                 setTimes((FileTime)value, null, null);
 131             if (AttrID.valueOf(attribute) == AttrID.lastAccessTime)
 132                 setTimes(null, (FileTime)value, null);
 133             if (AttrID.valueOf(attribute) == AttrID.creationTime)
 134                 setTimes(null, null, (FileTime)value);
 135             return;
 136         } catch (IllegalArgumentException x) {}
 137         throw new UnsupportedOperationException("'" + attribute +
 138             "' is unknown or read-only attribute");
 139     }
 140 
 141     Map<String, Object> readAttributes(String attributes)
 142         throws IOException
 143     {
 144         ZipFileAttributes zfas = readAttributes();
 145         LinkedHashMap<String, Object> map = new LinkedHashMap<>();
 146         if ("*".equals(attributes)) {
 147             for (AttrID id : AttrID.values()) {
 148                 try {
 149                     map.put(id.name(), attribute(id, zfas));
 150                 } catch (IllegalArgumentException x) {}
 151             }
 152         } else {
 153             String[] as = attributes.split(",");
 154             for (String a : as) {
 155                 try {
 156                     map.put(a, attribute(AttrID.valueOf(a), zfas));
 157                 } catch (IllegalArgumentException x) {}
 158             }
 159         }
 160         return map;
 161     }
 162 
 163     Object attribute(AttrID id, ZipFileAttributes zfas) {
 164         switch (id) {
 165         case size:
 166             return zfas.size();
 167         case creationTime:
 168             return zfas.creationTime();
 169         case lastAccessTime:
 170             return zfas.lastAccessTime();
 171         case lastModifiedTime:
 172             return zfas.lastModifiedTime();
 173         case isDirectory:
 174             return zfas.isDirectory();
 175         case isRegularFile:
 176             return zfas.isRegularFile();
 177         case isSymbolicLink:
 178             return zfas.isSymbolicLink();
 179         case isOther:
 180             return zfas.isOther();
 181         case fileKey:
 182             return zfas.fileKey();
 183         case compressedSize:
 184             if (type == ViewType.zip)
 185                 return zfas.compressedSize();
 186             break;
 187         case crc:
 188             if (type == ViewType.zip)
 189                 return zfas.crc();
 190             break;
 191         case method:
 192             if (type == ViewType.zip)
 193                 return zfas.method();
 194             break;
 195         case permissions:
 196             if (type == ViewType.zip || type == ViewType.posix) {
 197                 try {
 198                    return zfas.permissions();
 199                 } catch (UnsupportedOperationException e) {
 200                     return null;
 201                 }
 202             }
 203             break;
 204         }
 205         return null;
 206     }
 207 
 208     @Override
 209     public UserPrincipal getOwner() throws IOException {
 210         throw new UnsupportedOperationException("ZipFileSystem does not support getOwner.");
 211     }
 212 
 213     @Override
 214     public void setOwner(UserPrincipal owner) throws IOException {
 215         throw new UnsupportedOperationException("ZipFileSystem does not support setOwner.");
 216     }
 217 
 218     @Override
 219     public void setPermissions(Set<PosixFilePermission> perms) throws IOException {
 220         readAttributes().setPermissions(perms);
 221     }
 222 
 223     @Override
 224     public void setGroup(GroupPrincipal group) throws IOException {
 225         throw new UnsupportedOperationException("ZipFileSystem does not support setGroup.");
 226     }
 227 }