1 /* 2 * Copyright (c) 2014, 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 package jdk.internal.jrtfs; 26 27 import java.nio.file.LinkOption; 28 import java.nio.file.attribute.*; 29 import java.io.IOException; 30 import java.util.LinkedHashMap; 31 import java.util.Map; 32 33 /** 34 * File attribute view for jrt file system. 35 * 36 * @implNote This class needs to maintain JDK 8 source compatibility. 37 * 38 * It is used internally in the JDK to implement jimage/jrtfs access, 39 * but also compiled and delivered as part of the jrtfs.jar to support access 40 * to the jimage file provided by the shipped JDK by tools running on JDK 8. 41 */ 42 final class JrtFileAttributeView implements BasicFileAttributeView { 43 44 private static enum AttrID { 45 46 size, 47 creationTime, 48 lastAccessTime, 49 lastModifiedTime, 50 isDirectory, 51 isRegularFile, 52 isSymbolicLink, 53 isOther, 54 fileKey, 55 compressedSize, 56 extension 57 }; 58 59 private final AbstractJrtPath path; 60 private final boolean isJrtView; 61 private final LinkOption[] options; 62 63 private JrtFileAttributeView(AbstractJrtPath path, boolean isJrtView, LinkOption... options) { 64 this.path = path; 65 this.isJrtView = isJrtView; 66 this.options = options; 67 } 68 69 @SuppressWarnings("unchecked") // Cast to V 70 static <V extends FileAttributeView> V get(AbstractJrtPath path, Class<V> type, LinkOption... options) { 71 if (type == null) { 72 throw new NullPointerException(); 73 } 74 if (type == BasicFileAttributeView.class) { 75 return (V) new JrtFileAttributeView(path, false, options); 76 } 77 if (type == JrtFileAttributeView.class) { 78 return (V) new JrtFileAttributeView(path, true, options); 79 } 80 return null; 81 } 82 83 static JrtFileAttributeView get(AbstractJrtPath path, String type, LinkOption... options) { 84 if (type == null) { 85 throw new NullPointerException(); 86 } 87 if (type.equals("basic")) { 88 return new JrtFileAttributeView(path, false, options); 89 } 90 if (type.equals("jrt")) { 91 return new JrtFileAttributeView(path, true, options); 92 } 93 return null; 94 } 95 96 @Override 97 public String name() { 98 return isJrtView ? "jrt" : "basic"; 99 } 100 101 @Override 102 public AbstractJrtFileAttributes readAttributes() throws IOException { 103 return path.getAttributes(options); 104 } 105 106 @Override 107 public void setTimes(FileTime lastModifiedTime, 108 FileTime lastAccessTime, 109 FileTime createTime) 110 throws IOException { 111 path.setTimes(lastModifiedTime, lastAccessTime, createTime); 112 } 113 114 void setAttribute(String attribute, Object value) 115 throws IOException { 116 try { 117 if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime) { 118 setTimes((FileTime) value, null, null); 119 } 120 if (AttrID.valueOf(attribute) == AttrID.lastAccessTime) { 121 setTimes(null, (FileTime) value, null); 122 } 123 if (AttrID.valueOf(attribute) == AttrID.creationTime) { 124 setTimes(null, null, (FileTime) value); 125 } 126 return; 127 } catch (IllegalArgumentException x) { 128 } 129 throw new UnsupportedOperationException("'" + attribute 130 + "' is unknown or read-only attribute"); 131 } 132 133 Map<String, Object> readAttributes(String attributes) 134 throws IOException { 135 AbstractJrtFileAttributes jrtfas = readAttributes(); 136 LinkedHashMap<String, Object> map = new LinkedHashMap<>(); 137 if ("*".equals(attributes)) { 138 for (AttrID id : AttrID.values()) { 139 try { 140 map.put(id.name(), attribute(id, jrtfas)); 141 } catch (IllegalArgumentException x) { 142 } 143 } 144 } else { 145 String[] as = attributes.split(","); 146 for (String a : as) { 147 try { 148 map.put(a, attribute(AttrID.valueOf(a), jrtfas)); 149 } catch (IllegalArgumentException x) { 150 } 151 } 152 } 153 return map; 154 } 155 156 Object attribute(AttrID id, AbstractJrtFileAttributes jrtfas) { 157 switch (id) { 158 case size: 159 return jrtfas.size(); 160 case creationTime: 161 return jrtfas.creationTime(); 162 case lastAccessTime: 163 return jrtfas.lastAccessTime(); 164 case lastModifiedTime: 165 return jrtfas.lastModifiedTime(); 166 case isDirectory: 167 return jrtfas.isDirectory(); 168 case isRegularFile: 169 return jrtfas.isRegularFile(); 170 case isSymbolicLink: 171 return jrtfas.isSymbolicLink(); 172 case isOther: 173 return jrtfas.isOther(); 174 case fileKey: 175 return jrtfas.fileKey(); 176 case compressedSize: 177 if (isJrtView) { 178 return jrtfas.compressedSize(); 179 } 180 break; 181 case extension: 182 if (isJrtView) { 183 return jrtfas.extension(); 184 } 185 break; 186 } 187 return null; 188 } 189 }