JrtFileAttributeView.java revision 13901:b2a69d66dc65
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 */
25package jdk.internal.jrtfs;
26
27import java.nio.file.LinkOption;
28import java.nio.file.attribute.*;
29import java.io.IOException;
30import java.util.LinkedHashMap;
31import 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 */
42final 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}
190