1e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera/*
2e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
3e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera *
5e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * This code is free software; you can redistribute it and/or modify it
6e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * under the terms of the GNU General Public License version 2 only, as
7e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * published by the Free Software Foundation.  Oracle designates this
8e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * particular file as subject to the "Classpath" exception as provided
9e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * by Oracle in the LICENSE file that accompanied this code.
10e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera *
11e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * This code is distributed in the hope that it will be useful, but WITHOUT
12e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * version 2 for more details (a copy is included in the LICENSE file that
15e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * accompanied this code).
16e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera *
17e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * You should have received a copy of the GNU General Public License version
18e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 2 along with this work; if not, write to the Free Software Foundation,
19e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera *
21e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * or visit www.oracle.com if you need additional information or have any
23e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * questions.
24e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */
25e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
26e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmerapackage sun.nio.fs;
27e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
28e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.nio.file.*;
29e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.nio.file.attribute.*;
30e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.util.*;
31e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.util.concurrent.TimeUnit;
32e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.io.IOException;
33e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
34e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport static sun.nio.fs.UnixNativeDispatcher.*;
35e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
36e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraclass UnixFileAttributeViews {
37e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
38e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    static class Basic extends AbstractBasicFileAttributeView {
39e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        protected final UnixPath file;
40e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        protected final boolean followLinks;
41e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
42e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        Basic(UnixPath file, boolean followLinks) {
43e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            this.file = file;
44e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            this.followLinks = followLinks;
45e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
46e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
47e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
48e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public BasicFileAttributes readAttributes() throws IOException {
49e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            file.checkRead();
50e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            try {
51e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                 UnixFileAttributes attrs =
52e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                     UnixFileAttributes.get(file, followLinks);
53e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                 return attrs.asBasicFileAttributes();
54e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            } catch (UnixException x) {
55e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                x.rethrowAsIOException(file);
56e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return null;    // keep compiler happy
57e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
58e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
59e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
60e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
61e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public void setTimes(FileTime lastModifiedTime,
62e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                             FileTime lastAccessTime,
63e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                             FileTime createTime) throws IOException
64e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
65e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            // null => don't change
66e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (lastModifiedTime == null && lastAccessTime == null) {
67e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                // no effect
68e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
69e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
70e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
71e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            // permission check
72e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            file.checkWrite();
73e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
74e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            int fd = file.openForAttributeAccess(followLinks);
75e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            try {
76e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                // assert followLinks || !UnixFileAttributes.get(fd).isSymbolicLink();
77e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
78e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                // if not changing both attributes then need existing attributes
79e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                if (lastModifiedTime == null || lastAccessTime == null) {
80e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    try {
81e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        UnixFileAttributes attrs = UnixFileAttributes.get(fd);
82e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        if (lastModifiedTime == null)
83e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                            lastModifiedTime = attrs.lastModifiedTime();
84e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        if (lastAccessTime == null)
85e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                            lastAccessTime = attrs.lastAccessTime();
86e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    } catch (UnixException x) {
87e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        x.rethrowAsIOException(file);
88e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    }
89e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                }
90e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
91e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                // uptime times
92e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                long modValue = lastModifiedTime.to(TimeUnit.MICROSECONDS);
93e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                long accessValue= lastAccessTime.to(TimeUnit.MICROSECONDS);
94e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
95e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                boolean retry = false;
96e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                try {
97e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    if (futimesSupported()) {
98e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        futimes(fd, accessValue, modValue);
99e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    } else {
100e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        utimes(file, accessValue, modValue);
101e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    }
102e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                } catch (UnixException x) {
103e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    // if futimes/utimes fails with EINVAL and one/both of the times is
104e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    // negative then we adjust the value to the epoch and retry.
105e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    if (x.errno() == UnixConstants.EINVAL &&
106e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        (modValue < 0L || accessValue < 0L)) {
107e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        retry = true;
108e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    } else {
109e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        x.rethrowAsIOException(file);
110e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    }
111e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                }
112e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                if (retry) {
113e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    if (modValue < 0L) modValue = 0L;
114e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    if (accessValue < 0L) accessValue= 0L;
115e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    try {
116e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        if (futimesSupported()) {
117e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                            futimes(fd, accessValue, modValue);
118e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        } else {
119e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                            utimes(file, accessValue, modValue);
120e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        }
121e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    } catch (UnixException x) {
122e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        x.rethrowAsIOException(file);
123e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    }
124e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                }
125e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            } finally {
126e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                close(fd);
127e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
128e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
129e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
130e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
131e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    private static class Posix extends Basic implements PosixFileAttributeView {
132e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String PERMISSIONS_NAME = "permissions";
133e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String OWNER_NAME = "owner";
134e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String GROUP_NAME = "group";
135e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
136e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        // the names of the posix attributes (incudes basic)
137e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        static final Set<String> posixAttributeNames =
138e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            Util.newSet(basicAttributeNames, PERMISSIONS_NAME, OWNER_NAME, GROUP_NAME);
139e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
140e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        Posix(UnixPath file, boolean followLinks) {
141e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            super(file, followLinks);
142e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
143e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
144e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        final void checkReadExtended() {
145e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            SecurityManager sm = System.getSecurityManager();
146e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (sm != null) {
147e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                file.checkRead();
148e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                sm.checkPermission(new RuntimePermission("accessUserInformation"));
149e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
150e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
151e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
152e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        final void checkWriteExtended() {
153e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            SecurityManager sm = System.getSecurityManager();
154e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (sm != null) {
155e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                file.checkWrite();
156e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                sm.checkPermission(new RuntimePermission("accessUserInformation"));
157e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
158e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
159e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
160e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
161e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public String name() {
162e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            return "posix";
163e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
164e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
165e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
166e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @SuppressWarnings("unchecked")
167e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public void setAttribute(String attribute, Object value)
168e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
169e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
170e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (attribute.equals(PERMISSIONS_NAME)) {
171e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                setPermissions((Set<PosixFilePermission>)value);
172e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
173e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
174e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (attribute.equals(OWNER_NAME)) {
175e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                setOwner((UserPrincipal)value);
176e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
177e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
178e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (attribute.equals(GROUP_NAME)) {
179e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                setGroup((GroupPrincipal)value);
180e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
181e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
182e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            super.setAttribute(attribute, value);
183e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
184e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
185e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        /**
186e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera         * Invoked by readAttributes or sub-classes to add all matching posix
187e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera         * attributes to the builder
188e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera         */
189e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        final void addRequestedPosixAttributes(PosixFileAttributes attrs,
190e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                                               AttributesBuilder builder)
191e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
192e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            addRequestedBasicAttributes(attrs, builder);
193e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(PERMISSIONS_NAME))
194e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(PERMISSIONS_NAME, attrs.permissions());
195e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(OWNER_NAME))
196e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                 builder.add(OWNER_NAME, attrs.owner());
197e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(GROUP_NAME))
198e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(GROUP_NAME, attrs.group());
199e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
200e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
201e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
202e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public Map<String,Object> readAttributes(String[] requested)
203e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
204e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
205e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            AttributesBuilder builder =
206e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                AttributesBuilder.create(posixAttributeNames, requested);
207e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            PosixFileAttributes attrs = readAttributes();
208e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            addRequestedPosixAttributes(attrs, builder);
209e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            return builder.unmodifiableMap();
210e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
211e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
212e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
213e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public UnixFileAttributes readAttributes() throws IOException {
214e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            checkReadExtended();
215e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            try {
216e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                 return UnixFileAttributes.get(file, followLinks);
217e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            } catch (UnixException x) {
218e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                x.rethrowAsIOException(file);
219e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return null;    // keep compiler happy
220e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
221e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
222e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
223e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        // chmod
224e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        final void setMode(int mode) throws IOException {
225e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            checkWriteExtended();
226e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            try {
227e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                if (followLinks) {
228e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    chmod(file, mode);
229e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                } else {
230e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    int fd = file.openForAttributeAccess(false);
231e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    try {
232e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        fchmod(fd, mode);
233e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    } finally {
234e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        close(fd);
235e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    }
236e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                }
237e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            } catch (UnixException x) {
238e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                x.rethrowAsIOException(file);
239e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
240e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
241e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
242e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        // chown
243e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        final void setOwners(int uid, int gid) throws IOException {
244e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            checkWriteExtended();
245e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            try {
246e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                if (followLinks) {
247e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    chown(file, uid, gid);
248e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                } else {
249e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                    lchown(file, uid, gid);
250e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                }
251e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            } catch (UnixException x) {
252e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                x.rethrowAsIOException(file);
253e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
254e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
255e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
256e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
257e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public void setPermissions(Set<PosixFilePermission> perms)
258e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
259e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
260e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            setMode(UnixFileModeAttribute.toUnixMode(perms));
261e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
262e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
263e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
264e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public void setOwner(UserPrincipal owner)
265e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
266e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
267e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (owner == null)
268e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                throw new NullPointerException("'owner' is null");
269e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (!(owner instanceof UnixUserPrincipals.User))
270e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                throw new ProviderMismatchException();
271e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (owner instanceof UnixUserPrincipals.Group)
272e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                throw new IOException("'owner' parameter can't be a group");
273e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            int uid = ((UnixUserPrincipals.User)owner).uid();
274e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            setOwners(uid, -1);
275e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
276e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
277e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
278e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public UserPrincipal getOwner() throws IOException {
279e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            return readAttributes().owner();
280e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
281e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
282e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
283e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public void setGroup(GroupPrincipal group)
284e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
285e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
286e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (group == null)
287e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                throw new NullPointerException("'owner' is null");
288e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (!(group instanceof UnixUserPrincipals.Group))
289e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                throw new ProviderMismatchException();
290e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            int gid = ((UnixUserPrincipals.Group)group).gid();
291e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            setOwners(-1, gid);
292e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
293e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
294e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
295e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    private static class Unix extends Posix {
296e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String MODE_NAME = "mode";
297e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String INO_NAME = "ino";
298e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String DEV_NAME = "dev";
299e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String RDEV_NAME = "rdev";
300e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String NLINK_NAME = "nlink";
301e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String UID_NAME = "uid";
302e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String GID_NAME = "gid";
303e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        private static final String CTIME_NAME = "ctime";
304e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
305e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        // the names of the unix attributes (including posix)
306e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        static final Set<String> unixAttributeNames =
307e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            Util.newSet(posixAttributeNames,
308e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        MODE_NAME, INO_NAME, DEV_NAME, RDEV_NAME,
309e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                        NLINK_NAME, UID_NAME, GID_NAME, CTIME_NAME);
310e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
311e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        Unix(UnixPath file, boolean followLinks) {
312e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            super(file, followLinks);
313e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
314e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
315e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
316e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public String name() {
317e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            return "unix";
318e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
319e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
320e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
321e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public void setAttribute(String attribute, Object value)
322e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
323e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
324e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (attribute.equals(MODE_NAME)) {
325e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                setMode((Integer)value);
326e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
327e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
328e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (attribute.equals(UID_NAME)) {
329e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                setOwners((Integer)value, -1);
330e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
331e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
332e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (attribute.equals(GID_NAME)) {
333e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                setOwners(-1, (Integer)value);
334e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                return;
335e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            }
336e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            super.setAttribute(attribute, value);
337e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
338e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
339e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        @Override
340e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        public Map<String,Object> readAttributes(String[] requested)
341e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            throws IOException
342e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        {
343e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            AttributesBuilder builder =
344e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                AttributesBuilder.create(unixAttributeNames, requested);
345e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            UnixFileAttributes attrs = readAttributes();
346e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            addRequestedPosixAttributes(attrs, builder);
347e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(MODE_NAME))
348e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(MODE_NAME, attrs.mode());
349e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(INO_NAME))
350e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(INO_NAME, attrs.ino());
351e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(DEV_NAME))
352e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(DEV_NAME, attrs.dev());
353e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(RDEV_NAME))
354e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(RDEV_NAME, attrs.rdev());
355e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(NLINK_NAME))
356e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(NLINK_NAME, attrs.nlink());
357e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(UID_NAME))
358e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(UID_NAME, attrs.uid());
359e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(GID_NAME))
360e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(GID_NAME, attrs.gid());
361e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            if (builder.match(CTIME_NAME))
362e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera                builder.add(CTIME_NAME, attrs.ctime());
363e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera            return builder.unmodifiableMap();
364e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        }
365e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
366e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
367e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    static Basic createBasicView(UnixPath file, boolean followLinks) {
368e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        return new Basic(file, followLinks);
369e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
370e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
371e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    static Posix createPosixView(UnixPath file, boolean followLinks) {
372e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        return new Posix(file, followLinks);
373e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
374e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
375e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    static Unix createUnixView(UnixPath file, boolean followLinks) {
376e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        return new Unix(file, followLinks);
377e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
378e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera
379e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    static FileOwnerAttributeViewImpl createOwnerView(UnixPath file, boolean followLinks) {
380e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera        return new FileOwnerAttributeViewImpl(createPosixView(file, followLinks));
381e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera    }
382e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera}
383