This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 2c65114610d5e01e62452f9fdb666496c764e938
Author: Lyor Goldstein <lgoldst...@apache.org>
AuthorDate: Fri Nov 19 05:35:19 2021 +0200

    [SSHD-1226] Using literal constants for SFTP attributes key names
---
 CHANGES.md                                         |   1 +
 .../org/apache/sshd/common/util/io/IoUtils.java    |  20 ++++
 .../java/org/apache/sshd/scp/server/ScpShell.java  |  22 ++--
 .../sftp/client/fs/SftpAclFileAttributeView.java   |   3 +-
 .../sftp/client/fs/SftpFileSystemProvider.java     | 126 ++++++++++++---------
 .../sftp/client/fs/SftpPosixFileAttributeView.java |   7 +-
 .../org/apache/sshd/sftp/common/SftpHelper.java    | 102 +++++++++--------
 .../sftp/server/AbstractSftpSubsystemHelper.java   | 109 +++++++++---------
 .../org/apache/sshd/sftp/server/FileHandle.java    |   4 +-
 .../sshd/sftp/server/SftpFileSystemAccessor.java   |  12 +-
 .../apache/sshd/sftp/client/SftpVersionsTest.java  |  15 ++-
 .../client/fs/AbstractSftpFilesSystemSupport.java  |   5 +-
 12 files changed, 239 insertions(+), 187 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 5efe967..de364fb 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -22,6 +22,7 @@
 
 * [SSHD-1193](https://issues.apache.org/jira/browse/SSHD-1193) Provide a more 
user-friendly text in case disconnecting due to timeout(s).
 * [SSHD-1196](https://issues.apache.org/jira/browse/SSHD-1196) Provide 
configurable support for SFTP output stream chunking behavior.
+* [SSHD-1226](https://issues.apache.org/jira/browse/SSHD-1226) Using literal 
constants for SFTP attributes key names
 
 ## Behavioral changes and enhancements
 
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/io/IoUtils.java 
b/sshd-common/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
index bba17b2..ccac669 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
@@ -70,6 +70,26 @@ public final class IoUtils {
     public static final List<String> WINDOWS_EXECUTABLE_EXTENSIONS
             = Collections.unmodifiableList(Arrays.asList(".bat", ".exe", 
".cmd"));
 
+    /* File view attributes names */
+    public static final String REGFILE_VIEW_ATTR = "isRegularFile";
+    public static final String DIRECTORY_VIEW_ATTR = "isDirectory";
+    public static final String SYMLINK_VIEW_ATTR = "isSymbolicLink";
+    public static final String NUMLINKS_VIEW_ATTR = "nlink";
+    public static final String OTHERFILE_VIEW_ATTR = "isOther";
+    public static final String EXECUTABLE_VIEW_ATTR = "isExecutable";
+    public static final String SIZE_VIEW_ATTR = "size";
+    public static final String OWNER_VIEW_ATTR = "owner";
+    public static final String GROUP_VIEW_ATTR = "group";
+    public static final String USERID_VIEW_ATTR = "uid";
+    public static final String GROUPID_VIEW_ATTR = "gid";
+    public static final String PERMISSIONS_VIEW_ATTR = "permissions";
+    public static final String ACL_VIEW_ATTR = "acl";
+    public static final String FILEKEY_VIEW_ATTR = "fileKey";
+    public static final String CREATE_TIME_VIEW_ATTR = "creationTime";
+    public static final String LASTMOD_TIME_VIEW_ATTR = "lastModifiedTime";
+    public static final String LASTACC_TIME_VIEW_ATTR = "lastAccessTime";
+    public static final String EXTENDED_VIEW_ATTR = "extended";
+
     /**
      * Size of preferred work buffer when reading / writing data to / from 
streams
      */
diff --git a/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java 
b/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java
index 232a4b0..0ed3119 100644
--- a/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java
+++ b/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java
@@ -727,36 +727,36 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
             }
 
             StringBuilder sb = new StringBuilder(abbrev.length() + 64);
-            if (is("isDirectory")) {
+            if (is(IoUtils.DIRECTORY_VIEW_ATTR)) {
                 sb.append('d');
-            } else if (is("isSymbolicLink")) {
+            } else if (is(IoUtils.SYMLINK_VIEW_ATTR)) {
                 sb.append('l');
-            } else if (is("isOther")) {
+            } else if (is(IoUtils.OTHERFILE_VIEW_ATTR)) {
                 sb.append('o');
             } else {
                 sb.append('-');
             }
 
             @SuppressWarnings("unchecked")
-            Set<PosixFilePermission> perms = (Set<PosixFilePermission>) 
attributes.get("permissions");
+            Set<PosixFilePermission> perms = (Set<PosixFilePermission>) 
attributes.get(IoUtils.PERMISSIONS_VIEW_ATTR);
             if (perms == null) {
                 perms = EnumSet.noneOf(PosixFilePermission.class);
             }
             sb.append(PosixFilePermissions.toString(perms));
 
-            Object nlinkValue = attributes.get("nlink");
+            Object nlinkValue = attributes.get(IoUtils.NUMLINKS_VIEW_ATTR);
             sb.append(' ').append(String.format("%3s", (nlinkValue != null) ? 
nlinkValue : "1"));
 
-            appendOwnerInformation(sb, "owner", "owner");
-            appendOwnerInformation(sb, "group", "group");
+            appendOwnerInformation(sb, IoUtils.OWNER_VIEW_ATTR, "owner");
+            appendOwnerInformation(sb, IoUtils.GROUP_VIEW_ATTR, "group");
 
-            Number length = (Number) attributes.get("size");
+            Number length = (Number) attributes.get(IoUtils.SIZE_VIEW_ATTR);
             if (length == null) {
                 length = 0L;
             }
             sb.append(' ').append(String.format("%1$8s", length));
 
-            String timeValue = toString((FileTime) 
attributes.get("lastModifiedTime"), optFullTime);
+            String timeValue = toString((FileTime) 
attributes.get(IoUtils.LASTMOD_TIME_VIEW_ATTR), optFullTime);
             sb.append(' ').append(timeValue);
 
             sb.append(' ').append(abbrev);
@@ -830,8 +830,8 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
                 }
             }
             if (!attrs.isEmpty()) {
-                attrs.computeIfAbsent("isExecutable", s -> 
Files.isExecutable(path));
-                attrs.computeIfAbsent("permissions", s -> 
IoUtils.getPermissionsFromFile(path.toFile()));
+                attrs.computeIfAbsent(IoUtils.EXECUTABLE_VIEW_ATTR, s -> 
Files.isExecutable(path));
+                attrs.computeIfAbsent(IoUtils.PERMISSIONS_VIEW_ATTR, s -> 
IoUtils.getPermissionsFromFile(path.toFile()));
             }
             return attrs;
         }
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpAclFileAttributeView.java
 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpAclFileAttributeView.java
index 9afde45..c8333b0 100644
--- 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpAclFileAttributeView.java
+++ 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpAclFileAttributeView.java
@@ -28,6 +28,7 @@ import java.nio.file.attribute.PosixFileAttributes;
 import java.nio.file.attribute.UserPrincipal;
 import java.util.List;
 
+import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.sftp.client.SftpClient;
 import org.apache.sshd.sftp.client.impl.AbstractSftpFileAttributeView;
 
@@ -47,7 +48,7 @@ public class SftpAclFileAttributeView extends 
AbstractSftpFileAttributeView impl
 
     @Override
     public void setOwner(UserPrincipal owner) throws IOException {
-        provider.setAttribute(path, "posix", "owner", owner, options);
+        provider.setAttribute(path, "posix", IoUtils.OWNER_VIEW_ATTR, owner, 
options);
     }
 
     @Override
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpFileSystemProvider.java
 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpFileSystemProvider.java
index 9d78e8f..0cda4e8 100644
--- 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpFileSystemProvider.java
+++ 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpFileSystemProvider.java
@@ -937,18 +937,20 @@ public class SftpFileSystemProvider extends 
FileSystemProvider {
         boolean traceEnabled = log.isTraceEnabled();
         for (String attr : attrValues) {
             switch (attr) {
-                case "acl":
+                case IoUtils.ACL_VIEW_ATTR: {
                     List<AclEntry> acl = attributes.getAcl();
                     if (acl != null) {
                         map.put(attr, acl);
                     }
                     break;
-                case "owner":
+                }
+                case IoUtils.OWNER_VIEW_ATTR: {
                     String owner = attributes.getOwner();
                     if (GenericUtils.length(owner) > 0) {
                         map.put(attr, new 
SftpFileSystem.DefaultUserPrincipal(owner));
                     }
                     break;
+                }
                 default:
                     if (traceEnabled) {
                         log.trace("readAclViewAttributes({})[{}] unknown 
attribute: {}", fs, attrs, attr);
@@ -964,35 +966,37 @@ public class SftpFileSystemProvider extends 
FileSystemProvider {
         // SftpPathImpl.withAttributeCache() invocation. So we ensure here 
that if we are already within a caching
         // scope, we do use the cached attributes, but if we are not, we clear 
any possibly cached attributes and
         // do actually read them from the remote.
-        return SftpPathImpl.withAttributeCache(path, p -> {
-            SftpClient.Attributes attributes = path.getAttributes();
-            if (attributes != null) {
-                return attributes;
+        return SftpPathImpl.withAttributeCache(path, p -> 
resolveRemoteFileAttributes(path, options));
+    }
+
+    protected SftpClient.Attributes resolveRemoteFileAttributes(SftpPath path, 
LinkOption... options) throws IOException {
+        SftpClient.Attributes attributes = path.getAttributes();
+        if (attributes != null) {
+            return attributes;
+        }
+        SftpFileSystem fs = path.getFileSystem();
+        try (SftpClient client = fs.getClient()) {
+            SftpClient.Attributes attrs;
+            if (IoUtils.followLinks(options)) {
+                attrs = client.stat(path.toString());
+            } else {
+                attrs = client.lstat(path.toString());
             }
-            SftpFileSystem fs = path.getFileSystem();
-            try (SftpClient client = fs.getClient()) {
-                SftpClient.Attributes attrs;
-                if (IoUtils.followLinks(options)) {
-                    attrs = client.stat(path.toString());
-                } else {
-                    attrs = client.lstat(path.toString());
-                }
-                if (log.isTraceEnabled()) {
-                    log.trace("readRemoteAttributes({})[{}]: {}", fs, path, 
attrs);
-                }
-                if (path instanceof SftpPathImpl) {
-                    ((SftpPathImpl) path).cacheAttributes(attrs);
-                }
-                return attrs;
-            } catch (SftpException e) {
-                if (e.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) {
-                    NoSuchFileException toThrow = new 
NoSuchFileException(path.toString());
-                    toThrow.initCause(e);
-                    throw toThrow;
-                }
-                throw e;
+            if (log.isTraceEnabled()) {
+                log.trace("resolveRemoteFileAttributes({})[{}]: {}", fs, path, 
attrs);
+            }
+            if (path instanceof SftpPathImpl) {
+                ((SftpPathImpl) path).cacheAttributes(attrs);
             }
-        });
+            return attrs;
+        } catch (SftpException e) {
+            if (e.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) {
+                NoSuchFileException toThrow = new 
NoSuchFileException(path.toString());
+                toThrow.initCause(e);
+                throw toThrow;
+            }
+            throw e;
+        }
     }
 
     protected NavigableMap<String, Object> readPosixViewAttributes(
@@ -1000,7 +1004,19 @@ public class SftpFileSystemProvider extends 
FileSystemProvider {
             throws IOException {
         PosixFileAttributes v = readAttributes(path, 
PosixFileAttributes.class, options);
         if ("*".equals(attrs)) {
-            attrs = 
"lastModifiedTime,lastAccessTime,creationTime,size,isRegularFile,isDirectory,isSymbolicLink,isOther,fileKey,owner,permissions,group";
+            attrs = IoUtils.LASTMOD_TIME_VIEW_ATTR
+                    + "," + IoUtils.LASTACC_TIME_VIEW_ATTR
+                    + "," + IoUtils.CREATE_TIME_VIEW_ATTR
+                    + "," + IoUtils.SIZE_VIEW_ATTR
+                    + "," + IoUtils.REGFILE_VIEW_ATTR
+                    + "," + IoUtils.DIRECTORY_VIEW_ATTR
+                    + "," + IoUtils.SYMLINK_VIEW_ATTR
+                    + "," + IoUtils.OTHERFILE_VIEW_ATTR
+                    + "," + IoUtils.FILEKEY_VIEW_ATTR
+                    + "," + IoUtils.OWNER_VIEW_ATTR
+                    + "," + IoUtils.GROUP_VIEW_ATTR
+                    + "," + IoUtils.PERMISSIONS_VIEW_ATTR
+                    + "," + IoUtils.FILEKEY_VIEW_ATTR;
         }
 
         NavigableMap<String, Object> map = new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -1008,40 +1024,40 @@ public class SftpFileSystemProvider extends 
FileSystemProvider {
         String[] attrValues = GenericUtils.split(attrs, ',');
         for (String attr : attrValues) {
             switch (attr) {
-                case "lastModifiedTime":
+                case IoUtils.LASTMOD_TIME_VIEW_ATTR:
                     map.put(attr, v.lastModifiedTime());
                     break;
-                case "lastAccessTime":
+                case IoUtils.LASTACC_TIME_VIEW_ATTR:
                     map.put(attr, v.lastAccessTime());
                     break;
-                case "creationTime":
+                case IoUtils.CREATE_TIME_VIEW_ATTR:
                     map.put(attr, v.creationTime());
                     break;
-                case "size":
+                case IoUtils.SIZE_VIEW_ATTR:
                     map.put(attr, v.size());
                     break;
-                case "isRegularFile":
+                case IoUtils.REGFILE_VIEW_ATTR:
                     map.put(attr, v.isRegularFile());
                     break;
-                case "isDirectory":
+                case IoUtils.DIRECTORY_VIEW_ATTR:
                     map.put(attr, v.isDirectory());
                     break;
-                case "isSymbolicLink":
+                case IoUtils.SYMLINK_VIEW_ATTR:
                     map.put(attr, v.isSymbolicLink());
                     break;
-                case "isOther":
+                case IoUtils.OTHERFILE_VIEW_ATTR:
                     map.put(attr, v.isOther());
                     break;
-                case "fileKey":
+                case IoUtils.FILEKEY_VIEW_ATTR:
                     map.put(attr, v.fileKey());
                     break;
-                case "owner":
+                case IoUtils.OWNER_VIEW_ATTR:
                     map.put(attr, v.owner());
                     break;
-                case "permissions":
+                case IoUtils.PERMISSIONS_VIEW_ATTR:
                     map.put(attr, v.permissions());
                     break;
-                case "group":
+                case IoUtils.GROUP_VIEW_ATTR:
                     map.put(attr, v.group());
                     break;
                 default:
@@ -1081,42 +1097,42 @@ public class SftpFileSystemProvider extends 
FileSystemProvider {
 
         SftpClient.Attributes attributes = new SftpClient.Attributes();
         switch (attr) {
-            case "lastModifiedTime":
+            case IoUtils.LASTMOD_TIME_VIEW_ATTR:
                 attributes.modifyTime((int) ((FileTime) 
value).to(TimeUnit.SECONDS));
                 break;
-            case "lastAccessTime":
+            case IoUtils.LASTACC_TIME_VIEW_ATTR:
                 attributes.accessTime((int) ((FileTime) 
value).to(TimeUnit.SECONDS));
                 break;
-            case "creationTime":
+            case IoUtils.CREATE_TIME_VIEW_ATTR:
                 attributes.createTime((int) ((FileTime) 
value).to(TimeUnit.SECONDS));
                 break;
-            case "size":
+            case IoUtils.SIZE_VIEW_ATTR:
                 attributes.size(((Number) value).longValue());
                 break;
-            case "permissions": {
+            case IoUtils.PERMISSIONS_VIEW_ATTR: {
                 @SuppressWarnings("unchecked")
                 Set<PosixFilePermission> attrSet = (Set<PosixFilePermission>) 
value;
                 attributes.perms(attributesToPermissions(path, attrSet));
                 break;
             }
-            case "owner":
+            case IoUtils.OWNER_VIEW_ATTR:
                 attributes.owner(((UserPrincipal) value).getName());
                 break;
-            case "group":
+            case IoUtils.GROUP_VIEW_ATTR:
                 attributes.group(((GroupPrincipal) value).getName());
                 break;
-            case "acl": {
+            case IoUtils.ACL_VIEW_ATTR: {
                 ValidateUtils.checkTrue("acl".equalsIgnoreCase(view), "ACL 
cannot be set via view=%s", view);
                 @SuppressWarnings("unchecked")
                 List<AclEntry> acl = (List<AclEntry>) value;
                 attributes.acl(acl);
                 break;
             }
-            case "isRegularFile":
-            case "isDirectory":
-            case "isSymbolicLink":
-            case "isOther":
-            case "fileKey":
+            case IoUtils.REGFILE_VIEW_ATTR:
+            case IoUtils.DIRECTORY_VIEW_ATTR:
+            case IoUtils.SYMLINK_VIEW_ATTR:
+            case IoUtils.OTHERFILE_VIEW_ATTR:
+            case IoUtils.FILEKEY_VIEW_ATTR:
                 throw new UnsupportedOperationException(
                         "setAttribute(" + path + ")[" + view + ":" + attr + 
"=" + value + "] modification N/A");
             default:
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpPosixFileAttributeView.java
 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpPosixFileAttributeView.java
index 147a5c9..2e5a0ac 100644
--- 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpPosixFileAttributeView.java
+++ 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/client/fs/SftpPosixFileAttributeView.java
@@ -30,6 +30,7 @@ import java.nio.file.attribute.UserPrincipal;
 import java.util.Set;
 
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.sftp.client.SftpClient;
 import org.apache.sshd.sftp.client.impl.AbstractSftpFileAttributeView;
 
@@ -75,12 +76,12 @@ public class SftpPosixFileAttributeView extends 
AbstractSftpFileAttributeView im
 
     @Override
     public void setPermissions(Set<PosixFilePermission> perms) throws 
IOException {
-        provider.setAttribute(path, "permissions", perms, options);
+        provider.setAttribute(path, IoUtils.PERMISSIONS_VIEW_ATTR, perms, 
options);
     }
 
     @Override
     public void setGroup(GroupPrincipal group) throws IOException {
-        provider.setAttribute(path, "group", group, options);
+        provider.setAttribute(path, IoUtils.GROUP_VIEW_ATTR, group, options);
     }
 
     @Override
@@ -90,6 +91,6 @@ public class SftpPosixFileAttributeView extends 
AbstractSftpFileAttributeView im
 
     @Override
     public void setOwner(UserPrincipal owner) throws IOException {
-        provider.setAttribute(path, "owner", owner, options);
+        provider.setAttribute(path, IoUtils.OWNER_VIEW_ATTR, owner, options);
     }
 }
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java
index 4386df4..beb1c32 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/common/SftpHelper.java
@@ -62,6 +62,7 @@ import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.sftp.SftpModuleProperties;
 import org.apache.sshd.sftp.client.SftpClient.Attribute;
 import org.apache.sshd.sftp.client.SftpClient.Attributes;
@@ -220,17 +221,17 @@ public final class SftpHelper {
     public static <B extends Buffer> B writeAttrsV3(B buffer, int version, 
Map<String, ?> attributes) {
         ValidateUtils.checkTrue(version == SftpConstants.SFTP_V3, "Illegal 
version: %d", version);
 
-        boolean isReg = getBool((Boolean) attributes.get("isRegularFile"));
-        boolean isDir = getBool((Boolean) attributes.get("isDirectory"));
-        boolean isLnk = getBool((Boolean) attributes.get("isSymbolicLink"));
+        boolean isReg = getBool((Boolean) 
attributes.get(IoUtils.REGFILE_VIEW_ATTR));
+        boolean isDir = getBool((Boolean) 
attributes.get(IoUtils.DIRECTORY_VIEW_ATTR));
+        boolean isLnk = getBool((Boolean) 
attributes.get(IoUtils.SYMLINK_VIEW_ATTR));
         @SuppressWarnings("unchecked")
-        Collection<PosixFilePermission> perms = 
(Collection<PosixFilePermission>) attributes.get("permissions");
-        Number size = (Number) attributes.get("size");
-        FileTime lastModifiedTime = (FileTime) 
attributes.get("lastModifiedTime");
-        FileTime lastAccessTime = (FileTime) attributes.get("lastAccessTime");
-        Map<?, ?> extensions = (Map<?, ?>) attributes.get("extended");
+        Collection<PosixFilePermission> perms = 
(Collection<PosixFilePermission>) attributes.get(IoUtils.PERMISSIONS_VIEW_ATTR);
+        Number size = (Number) attributes.get(IoUtils.SIZE_VIEW_ATTR);
+        FileTime lastModifiedTime = (FileTime) 
attributes.get(IoUtils.LASTMOD_TIME_VIEW_ATTR);
+        FileTime lastAccessTime = (FileTime) 
attributes.get(IoUtils.LASTACC_TIME_VIEW_ATTR);
+        Map<?, ?> extensions = (Map<?, ?>) 
attributes.get(IoUtils.EXTENDED_VIEW_ATTR);
         int flags = ((isReg || isLnk) && (size != null) ? 
SftpConstants.SSH_FILEXFER_ATTR_SIZE : 0)
-                    | (attributes.containsKey("uid") && 
attributes.containsKey("gid")
+                    | (attributes.containsKey(IoUtils.USERID_VIEW_ATTR) && 
attributes.containsKey(IoUtils.GROUPID_VIEW_ATTR)
                             ? SftpConstants.SSH_FILEXFER_ATTR_UIDGID : 0)
                     | ((perms != null) ? 
SftpConstants.SSH_FILEXFER_ATTR_PERMISSIONS : 0)
                     | (((lastModifiedTime != null) && (lastAccessTime != 
null)) ? SftpConstants.SSH_FILEXFER_ATTR_ACMODTIME : 0)
@@ -240,8 +241,8 @@ public final class SftpHelper {
             buffer.putLong(size.longValue());
         }
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_UIDGID) != 0) {
-            buffer.putInt(((Number) attributes.get("uid")).intValue());
-            buffer.putInt(((Number) attributes.get("gid")).intValue());
+            buffer.putInt(((Number) 
attributes.get(IoUtils.USERID_VIEW_ATTR)).intValue());
+            buffer.putInt(((Number) 
attributes.get(IoUtils.GROUPID_VIEW_ATTR)).intValue());
         }
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_PERMISSIONS) != 0) {
             buffer.putInt(attributesToPermissions(isReg, isDir, isLnk, perms));
@@ -269,20 +270,20 @@ public final class SftpHelper {
     public static <B extends Buffer> B writeAttrsV4(B buffer, int version, 
Map<String, ?> attributes) {
         ValidateUtils.checkTrue(version >= SftpConstants.SFTP_V4, "Illegal 
version: %d", version);
 
-        boolean isReg = getBool((Boolean) attributes.get("isRegularFile"));
-        boolean isDir = getBool((Boolean) attributes.get("isDirectory"));
-        boolean isLnk = getBool((Boolean) attributes.get("isSymbolicLink"));
+        boolean isReg = getBool((Boolean) 
attributes.get(IoUtils.REGFILE_VIEW_ATTR));
+        boolean isDir = getBool((Boolean) 
attributes.get(IoUtils.DIRECTORY_VIEW_ATTR));
+        boolean isLnk = getBool((Boolean) 
attributes.get(IoUtils.SYMLINK_VIEW_ATTR));
         @SuppressWarnings("unchecked")
-        Collection<PosixFilePermission> perms = 
(Collection<PosixFilePermission>) attributes.get("permissions");
-        Number size = (Number) attributes.get("size");
-        FileTime lastModifiedTime = (FileTime) 
attributes.get("lastModifiedTime");
-        FileTime lastAccessTime = (FileTime) attributes.get("lastAccessTime");
-        FileTime creationTime = (FileTime) attributes.get("creationTime");
+        Collection<PosixFilePermission> perms = 
(Collection<PosixFilePermission>) attributes.get(IoUtils.PERMISSIONS_VIEW_ATTR);
+        Number size = (Number) attributes.get(IoUtils.SIZE_VIEW_ATTR);
+        FileTime lastModifiedTime = (FileTime) 
attributes.get(IoUtils.LASTMOD_TIME_VIEW_ATTR);
+        FileTime lastAccessTime = (FileTime) 
attributes.get(IoUtils.LASTACC_TIME_VIEW_ATTR);
+        FileTime creationTime = (FileTime) 
attributes.get(IoUtils.CREATE_TIME_VIEW_ATTR);
         @SuppressWarnings("unchecked")
-        Collection<AclEntry> acl = (Collection<AclEntry>) 
attributes.get("acl");
-        Map<?, ?> extensions = (Map<?, ?>) attributes.get("extended");
+        Collection<AclEntry> acl = (Collection<AclEntry>) 
attributes.get(IoUtils.ACL_VIEW_ATTR);
+        Map<?, ?> extensions = (Map<?, ?>) 
attributes.get(IoUtils.EXTENDED_VIEW_ATTR);
         int flags = (((isReg || isLnk) && (size != null)) ? 
SftpConstants.SSH_FILEXFER_ATTR_SIZE : 0)
-                    | ((attributes.containsKey("owner") && 
attributes.containsKey("group"))
+                    | ((attributes.containsKey(IoUtils.OWNER_VIEW_ATTR) && 
attributes.containsKey(IoUtils.GROUP_VIEW_ATTR))
                             ? SftpConstants.SSH_FILEXFER_ATTR_OWNERGROUP : 0)
                     | ((perms != null) ? 
SftpConstants.SSH_FILEXFER_ATTR_PERMISSIONS : 0)
                     | ((lastModifiedTime != null) ? 
SftpConstants.SSH_FILEXFER_ATTR_MODIFYTIME : 0)
@@ -299,8 +300,10 @@ public final class SftpHelper {
             buffer.putLong(size.longValue());
         }
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_OWNERGROUP) != 0) {
-            buffer.putString(Objects.toString(attributes.get("owner"), 
SftpUniversalOwnerAndGroup.Owner.getName()));
-            buffer.putString(Objects.toString(attributes.get("group"), 
SftpUniversalOwnerAndGroup.Group.getName()));
+            buffer.putString(
+                    Objects.toString(attributes.get(IoUtils.OWNER_VIEW_ATTR), 
SftpUniversalOwnerAndGroup.Owner.getName()));
+            buffer.putString(
+                    Objects.toString(attributes.get(IoUtils.GROUP_VIEW_ATTR), 
SftpUniversalOwnerAndGroup.Group.getName()));
         }
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_PERMISSIONS) != 0) {
             buffer.putInt(attributesToPermissions(isReg, isDir, isLnk, perms));
@@ -664,32 +667,32 @@ public final class SftpHelper {
             int type = buffer.getUByte();
             switch (type) {
                 case SftpConstants.SSH_FILEXFER_TYPE_REGULAR:
-                    attrs.put("isRegular", Boolean.TRUE);
+                    attrs.put(IoUtils.REGFILE_VIEW_ATTR, Boolean.TRUE);
                     break;
                 case SftpConstants.SSH_FILEXFER_TYPE_DIRECTORY:
-                    attrs.put("isDirectory", Boolean.TRUE);
+                    attrs.put(IoUtils.DIRECTORY_VIEW_ATTR, Boolean.TRUE);
                     break;
                 case SftpConstants.SSH_FILEXFER_TYPE_SYMLINK:
-                    attrs.put("isSymbolicLink", Boolean.TRUE);
+                    attrs.put(IoUtils.SYMLINK_VIEW_ATTR, Boolean.TRUE);
                     break;
                 case SftpConstants.SSH_FILEXFER_TYPE_SOCKET:
                 case SftpConstants.SSH_FILEXFER_TYPE_CHAR_DEVICE:
                 case SftpConstants.SSH_FILEXFER_TYPE_BLOCK_DEVICE:
                 case SftpConstants.SSH_FILEXFER_TYPE_FIFO:
-                    attrs.put("isOther", Boolean.TRUE);
+                    attrs.put(IoUtils.OTHERFILE_VIEW_ATTR, Boolean.TRUE);
                     break;
                 default: // ignored
             }
         }
 
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_SIZE) != 0) {
-            attrs.put("size", buffer.getLong());
+            attrs.put(IoUtils.SIZE_VIEW_ATTR, buffer.getLong());
         }
 
         if (version == SftpConstants.SFTP_V3) {
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_UIDGID) != 0) {
-                attrs.put("uid", buffer.getInt());
-                attrs.put("gid", buffer.getInt());
+                attrs.put(IoUtils.USERID_VIEW_ATTR, buffer.getInt());
+                attrs.put(IoUtils.GROUPID_VIEW_ATTR, buffer.getInt());
             }
         } else {
             if ((version >= SftpConstants.SFTP_V6) && ((flags & 
SftpConstants.SSH_FILEXFER_ATTR_ALLOCATION_SIZE) != 0)) {
@@ -698,36 +701,37 @@ public final class SftpHelper {
             }
 
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_OWNERGROUP) != 0) {
-                attrs.put("owner", new 
DefaultGroupPrincipal(buffer.getString()));
-                attrs.put("group", new 
DefaultGroupPrincipal(buffer.getString()));
+                attrs.put(IoUtils.OWNER_VIEW_ATTR, new 
DefaultGroupPrincipal(buffer.getString()));
+                attrs.put(IoUtils.GROUP_VIEW_ATTR, new 
DefaultGroupPrincipal(buffer.getString()));
             }
         }
 
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_PERMISSIONS) != 0) {
-            attrs.put("permissions", permissionsToAttributes(buffer.getInt()));
+            attrs.put(IoUtils.PERMISSIONS_VIEW_ATTR, 
permissionsToAttributes(buffer.getInt()));
         }
 
         if (version == SftpConstants.SFTP_V3) {
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_ACMODTIME) != 0) {
-                attrs.put("lastAccessTime", readTime(buffer, version, flags));
-                attrs.put("lastModifiedTime", readTime(buffer, version, 
flags));
+                attrs.put(IoUtils.LASTACC_TIME_VIEW_ATTR, readTime(buffer, 
version, flags));
+                attrs.put(IoUtils.LASTMOD_TIME_VIEW_ATTR, readTime(buffer, 
version, flags));
             }
         } else if (version >= SftpConstants.SFTP_V4) {
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_ACCESSTIME) != 0) {
-                attrs.put("lastAccessTime", readTime(buffer, version, flags));
+                attrs.put(IoUtils.LASTACC_TIME_VIEW_ATTR, readTime(buffer, 
version, flags));
             }
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_CREATETIME) != 0) {
-                attrs.put("creationTime", readTime(buffer, version, flags));
+                attrs.put(IoUtils.CREATE_TIME_VIEW_ATTR, readTime(buffer, 
version, flags));
             }
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_MODIFYTIME) != 0) {
-                attrs.put("lastModifiedTime", readTime(buffer, version, 
flags));
+                attrs.put(IoUtils.LASTMOD_TIME_VIEW_ATTR, readTime(buffer, 
version, flags));
             }
+            // modification time sub-seconds
             if ((version >= SftpConstants.SFTP_V6) && (flags & 
SftpConstants.SSH_FILEXFER_ATTR_CTIME) != 0) {
                 attrs.put("ctime", readTime(buffer, version, flags));
             }
 
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_ACL) != 0) {
-                attrs.put("acl", readACLs(buffer, version));
+                attrs.put(IoUtils.ACL_VIEW_ATTR, readACLs(buffer, version));
             }
 
             if ((flags & SftpConstants.SSH_FILEXFER_ATTR_BITS) != 0) {
@@ -762,7 +766,7 @@ public final class SftpHelper {
         }
 
         if ((flags & SftpConstants.SSH_FILEXFER_ATTR_EXTENDED) != 0) {
-            attrs.put("extended", readExtensions(buffer));
+            attrs.put(IoUtils.EXTENDED_VIEW_ATTR, readExtensions(buffer));
         }
 
         return attrs;
@@ -1202,38 +1206,38 @@ public final class SftpHelper {
      *                    7</A>
      */
     public static String getLongName(String shortName, Map<String, ?> 
attributes) {
-        String owner = Objects.toString(attributes.get("owner"), null);
+        String owner = 
Objects.toString(attributes.get(IoUtils.OWNER_VIEW_ATTR), null);
         String username = OsUtils.getCanonicalUser(owner);
         if (GenericUtils.isEmpty(username)) {
             username = SftpUniversalOwnerAndGroup.Owner.getName();
         }
 
-        String group = Objects.toString(attributes.get("group"), null);
+        String group = 
Objects.toString(attributes.get(IoUtils.GROUP_VIEW_ATTR), null);
         group = OsUtils.resolveCanonicalGroup(group, owner);
         if (GenericUtils.isEmpty(group)) {
             group = SftpUniversalOwnerAndGroup.Group.getName();
         }
 
-        Number length = (Number) attributes.get("size");
+        Number length = (Number) attributes.get(IoUtils.SIZE_VIEW_ATTR);
         if (length == null) {
             length = 0L;
         }
 
         String lengthString = String.format("%1$8s", length);
-        String linkCount = Objects.toString(attributes.get("nlink"), null);
+        String linkCount = 
Objects.toString(attributes.get(IoUtils.NUMLINKS_VIEW_ATTR), null);
         if (GenericUtils.isEmpty(linkCount)) {
             linkCount = "1";
         }
 
-        Boolean isDirectory = (Boolean) attributes.get("isDirectory");
-        Boolean isLink = (Boolean) attributes.get("isSymbolicLink");
+        Boolean isDirectory = (Boolean) 
attributes.get(IoUtils.DIRECTORY_VIEW_ATTR);
+        Boolean isLink = (Boolean) attributes.get(IoUtils.SYMLINK_VIEW_ATTR);
         @SuppressWarnings("unchecked")
-        Set<PosixFilePermission> perms = (Set<PosixFilePermission>) 
attributes.get("permissions");
+        Set<PosixFilePermission> perms = (Set<PosixFilePermission>) 
attributes.get(IoUtils.PERMISSIONS_VIEW_ATTR);
         if (perms == null) {
             perms = EnumSet.noneOf(PosixFilePermission.class);
         }
         String permsString = PosixFilePermissions.toString(perms);
-        String timeStamp = UnixDateFormat.getUnixDate((FileTime) 
attributes.get("lastModifiedTime"));
+        String timeStamp = UnixDateFormat.getUnixDate((FileTime) 
attributes.get(IoUtils.LASTMOD_TIME_VIEW_ATTR));
         StringBuilder sb = new StringBuilder(
                 GenericUtils.length(linkCount) + GenericUtils.length(username) 
+ GenericUtils.length(group)
                                              + GenericUtils.length(timeStamp) 
+ GenericUtils.length(lengthString)
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/AbstractSftpSubsystemHelper.java
 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/AbstractSftpSubsystemHelper.java
index dc1123a..f219524 100644
--- 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/AbstractSftpSubsystemHelper.java
+++ 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/AbstractSftpSubsystemHelper.java
@@ -2324,13 +2324,14 @@ public abstract class AbstractSftpSubsystemHelper
     protected String getLongName(Path f, String shortName, 
SftpClient.Attributes attributes) throws IOException {
         return getLongName(f, shortName,
                 MapBuilder.<String, Object> builder()
-                        .put("owner", attributes.getOwner())
-                        .put("group", attributes.getGroup())
-                        .put("size", attributes.getSize())
-                        .put("isDirectory", attributes.isDirectory())
-                        .put("isSymbolicLink", attributes.isSymbolicLink())
-                        .put("permissions", 
SftpHelper.permissionsToAttributes(attributes.getPermissions()))
-                        .put("lastModifiedTime", 
attributes.getModifyTime()).build());
+                        .put(IoUtils.OWNER_VIEW_ATTR, attributes.getOwner())
+                        .put(IoUtils.GROUP_VIEW_ATTR, attributes.getGroup())
+                        .put(IoUtils.SIZE_VIEW_ATTR, attributes.getSize())
+                        .put(IoUtils.DIRECTORY_VIEW_ATTR, 
attributes.isDirectory())
+                        .put(IoUtils.SYMLINK_VIEW_ATTR, 
attributes.isSymbolicLink())
+                        .put(IoUtils.PERMISSIONS_VIEW_ATTR, 
SftpHelper.permissionsToAttributes(attributes.getPermissions()))
+                        .put(IoUtils.LASTMOD_TIME_VIEW_ATTR, 
attributes.getModifyTime())
+                        .build());
     }
 
     protected String getShortName(Path f) throws IOException {
@@ -2421,37 +2422,40 @@ public abstract class AbstractSftpSubsystemHelper
      * @param  options     The {@link LinkOption}s to use in order to access 
the file if necessary
      * @return             A {@link Map} of the retrieved attributes
      * @throws IOException If failed to access the file
-     * @see                #resolveMissingFileAttributes(Path, int, Map, 
LinkOption...)
+     * @see                #resolveReportedFileAttributes(Path, int, 
LinkOption...)
      */
     protected NavigableMap<String, Object> getAttributes(Path path, int flags, 
LinkOption... options)
             throws IOException {
-        return SftpPathImpl.withAttributeCache(path, file -> {
-            FileSystem fs = file.getFileSystem();
-            Collection<String> supportedViews = 
fs.supportedFileAttributeViews();
-            NavigableMap<String, Object> attrs = new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-            Collection<String> views;
-
-            if (GenericUtils.isEmpty(supportedViews)) {
-                views = Collections.emptyList();
-            } else if (supportedViews.contains("unix")) {
-                views = SftpFileSystemAccessor.DEFAULT_UNIX_VIEW;
-            } else {
-                views = GenericUtils.map(supportedViews, v -> v + ":*");
-            }
+        return SftpPathImpl.withAttributeCache(path, file -> 
resolveReportedFileAttributes(file, flags, options));
+    }
 
-            for (String v : views) {
-                Map<String, ?> ta = readFileAttributes(file, v, options);
-                if (MapEntryUtils.isNotEmpty(ta)) {
-                    attrs.putAll(ta);
-                }
-            }
+    protected NavigableMap<String, Object> resolveReportedFileAttributes(Path 
file, int flags, LinkOption... options)
+            throws IOException {
+        FileSystem fs = file.getFileSystem();
+        Collection<String> supportedViews = fs.supportedFileAttributeViews();
+        NavigableMap<String, Object> attrs = new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+        Collection<String> views;
+
+        if (GenericUtils.isEmpty(supportedViews)) {
+            views = Collections.emptyList();
+        } else if (supportedViews.contains("unix")) {
+            views = SftpFileSystemAccessor.DEFAULT_UNIX_VIEW;
+        } else {
+            views = GenericUtils.map(supportedViews, v -> v + ":*");
+        }
 
-            Map<String, ?> completions = resolveMissingFileAttributes(file, 
flags, attrs, options);
-            if (MapEntryUtils.isNotEmpty(completions)) {
-                attrs.putAll(completions);
+        for (String v : views) {
+            Map<String, ?> ta = readFileAttributes(file, v, options);
+            if (MapEntryUtils.isNotEmpty(ta)) {
+                attrs.putAll(ta);
             }
-            return attrs;
-        });
+        }
+
+        Map<String, ?> completions = resolveMissingFileAttributes(file, flags, 
attrs, options);
+        if (MapEntryUtils.isNotEmpty(completions)) {
+            attrs.putAll(completions);
+        }
+        return attrs;
     }
 
     /**
@@ -2628,7 +2632,7 @@ public abstract class AbstractSftpSubsystemHelper
             Object value = ae.getValue();
             String view = null;
             switch (attribute) {
-                case "size": {
+                case IoUtils.SIZE_VIEW_ATTR: {
                     long newSize = ((Number) value).longValue();
                     SftpFileSystemAccessor accessor = getFileSystemAccessor();
                     ServerSession session = getServerSession();
@@ -2639,36 +2643,36 @@ public abstract class AbstractSftpSubsystemHelper
                     }
                     continue;
                 }
-                case "uid":
+                case IoUtils.USERID_VIEW_ATTR:
                     view = "unix";
                     break;
-                case "gid":
+                case IoUtils.GROUPID_VIEW_ATTR:
                     view = "unix";
                     break;
-                case "owner":
+                case IoUtils.OWNER_VIEW_ATTR:
                     view = "posix";
                     value = toUser(file, (UserPrincipal) value);
                     break;
-                case "group":
+                case IoUtils.GROUP_VIEW_ATTR:
                     view = "posix";
                     value = toGroup(file, (GroupPrincipal) value);
                     break;
-                case "permissions":
+                case IoUtils.PERMISSIONS_VIEW_ATTR:
                     view = "posix";
                     break;
-                case "acl":
+                case IoUtils.ACL_VIEW_ATTR:
                     view = "acl";
                     break;
-                case "creationTime":
+                case IoUtils.CREATE_TIME_VIEW_ATTR:
                     view = "basic";
                     break;
-                case "lastModifiedTime":
+                case IoUtils.LASTMOD_TIME_VIEW_ATTR:
                     view = "basic";
                     break;
-                case "lastAccessTime":
+                case IoUtils.LASTACC_TIME_VIEW_ATTR:
                     view = "basic";
                     break;
-                case "extended":
+                case IoUtils.EXTENDED_VIEW_ATTR:
                     view = "extended";
                     break;
                 default: // ignored
@@ -2715,21 +2719,22 @@ public abstract class AbstractSftpSubsystemHelper
                     getServerSession(), file, view, attribute, value);
         }
 
-        if ("acl".equalsIgnoreCase(attribute) && "acl".equalsIgnoreCase(view)) 
{
+        if (IoUtils.ACL_VIEW_ATTR.equalsIgnoreCase(attribute) && 
"acl".equalsIgnoreCase(view)) {
             @SuppressWarnings("unchecked")
             List<AclEntry> acl = (List<AclEntry>) value;
             setFileAccessControl(file, acl, options);
-        } else if ("permissions".equalsIgnoreCase(attribute)) {
+        } else if (IoUtils.PERMISSIONS_VIEW_ATTR.equalsIgnoreCase(attribute)) {
             @SuppressWarnings("unchecked")
             Set<PosixFilePermission> perms = (Set<PosixFilePermission>) value;
             setFilePermissions(file, perms, options);
-        } else if ("owner".equalsIgnoreCase(attribute) || 
"group".equalsIgnoreCase(attribute)) {
+        } else if (IoUtils.OWNER_VIEW_ATTR.equalsIgnoreCase(attribute)
+                || IoUtils.GROUP_VIEW_ATTR.equalsIgnoreCase(attribute)) {
             setFileOwnership(file, attribute, (Principal) value, options);
-        } else if ("creationTime".equalsIgnoreCase(attribute)
-                || "lastModifiedTime".equalsIgnoreCase(attribute)
-                || "lastAccessTime".equalsIgnoreCase(attribute)) {
+        } else if (IoUtils.CREATE_TIME_VIEW_ATTR.equalsIgnoreCase(attribute)
+                || IoUtils.LASTMOD_TIME_VIEW_ATTR.equalsIgnoreCase(attribute)
+                || IoUtils.LASTACC_TIME_VIEW_ATTR.equalsIgnoreCase(attribute)) 
{
             setFileTime(file, view, attribute, (FileTime) value, options);
-        } else if ("extended".equalsIgnoreCase(view) && 
"extended".equalsIgnoreCase(attribute)) {
+        } else if (IoUtils.EXTENDED_VIEW_ATTR.equalsIgnoreCase(attribute) && 
"extended".equalsIgnoreCase(view)) {
             @SuppressWarnings("unchecked")
             Map<String, byte[]> extensions = (Map<String, byte[]>) value;
             setFileExtensions(file, extensions, options);
@@ -2776,9 +2781,9 @@ public abstract class AbstractSftpSubsystemHelper
          * used to set the file owner to a user principal that is not a group.
          */
         SftpFileSystemAccessor accessor = getFileSystemAccessor();
-        if ("owner".equalsIgnoreCase(attribute)) {
+        if (IoUtils.OWNER_VIEW_ATTR.equalsIgnoreCase(attribute)) {
             accessor.setFileOwner(serverSession, this, file, value, options);
-        } else if ("group".equalsIgnoreCase(attribute)) {
+        } else if (IoUtils.GROUP_VIEW_ATTR.equalsIgnoreCase(attribute)) {
             accessor.setGroupOwner(serverSession, this, file, value, options);
         } else {
             throw new UnsupportedOperationException("Unknown ownership 
attribute: " + attribute);
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/FileHandle.java 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/FileHandle.java
index 8e3b453..b583054 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/FileHandle.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/FileHandle.java
@@ -230,12 +230,12 @@ public class FileHandle extends Handle {
 
     public static FileAttribute<?> toFileAttribute(String key, Object val) {
         // Some ignored attributes sent by the SFTP client
-        if ("isOther".equals(key)) {
+        if (IoUtils.OTHERFILE_VIEW_ATTR.equals(key)) {
             if ((Boolean) val) {
                 throw new IllegalArgumentException("Not allowed to use " + key 
+ "=" + val);
             }
             return null;
-        } else if ("isRegular".equals(key)) {
+        } else if (IoUtils.REGFILE_VIEW_ATTR.equals(key)) {
             if (!(Boolean) val) {
                 throw new IllegalArgumentException("Not allowed to use " + key 
+ "=" + val);
             }
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpFileSystemAccessor.java
 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpFileSystemAccessor.java
index 70c1638..369aa9c 100644
--- 
a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpFileSystemAccessor.java
+++ 
b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpFileSystemAccessor.java
@@ -74,12 +74,12 @@ public interface SftpFileSystemAccessor {
      */
     NavigableMap<String, FileInfoExtractor<?>> FILEATTRS_RESOLVERS
             = NavigableMapBuilder.<String, FileInfoExtractor<?>> 
builder(String.CASE_INSENSITIVE_ORDER)
-                    .put("isRegularFile", FileInfoExtractor.ISREG)
-                    .put("isDirectory", FileInfoExtractor.ISDIR)
-                    .put("isSymbolicLink", FileInfoExtractor.ISSYMLINK)
-                    .put("permissions", FileInfoExtractor.PERMISSIONS)
-                    .put("size", FileInfoExtractor.SIZE)
-                    .put("lastModifiedTime", FileInfoExtractor.LASTMODIFIED)
+                    .put(IoUtils.REGFILE_VIEW_ATTR, FileInfoExtractor.ISREG)
+                    .put(IoUtils.DIRECTORY_VIEW_ATTR, FileInfoExtractor.ISDIR)
+                    .put(IoUtils.SYMLINK_VIEW_ATTR, 
FileInfoExtractor.ISSYMLINK)
+                    .put(IoUtils.PERMISSIONS_VIEW_ATTR, 
FileInfoExtractor.PERMISSIONS)
+                    .put(IoUtils.SIZE_VIEW_ATTR, FileInfoExtractor.SIZE)
+                    .put(IoUtils.LASTMOD_TIME_VIEW_ATTR, 
FileInfoExtractor.LASTMODIFIED)
                     .immutable();
 
     /** Whether to invoke {@link FileChannel#force(boolean)} on files open for 
write when closing */
diff --git 
a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java 
b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java
index 8a926a9..d277bbc 100644
--- a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java
+++ b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java
@@ -299,7 +299,7 @@ public class SftpVersionsTest extends 
AbstractSftpClientTestSupport {
                         }
 
                         @SuppressWarnings("unchecked")
-                        List<AclEntry> aclActual = (List<AclEntry>) 
attrs.put("acl", aclExpected);
+                        List<AclEntry> aclActual = (List<AclEntry>) 
attrs.put(IoUtils.ACL_VIEW_ATTR, aclExpected);
                         if (aclActual != null) {
                             log.info("resolveFileAttributes(" + file + ") 
replaced ACL: " + aclActual);
                         }
@@ -330,7 +330,8 @@ public class SftpVersionsTest extends 
AbstractSftpClientTestSupport {
             @Override
             public void modifyingAttributes(ServerSession session, Path path, 
Map<String, ?> attrs) {
                 @SuppressWarnings("unchecked")
-                List<AclEntry> aclActual = MapEntryUtils.isEmpty(attrs) ? null 
: (List<AclEntry>) attrs.get("acl");
+                List<AclEntry> aclActual
+                        = MapEntryUtils.isEmpty(attrs) ? null : 
(List<AclEntry>) attrs.get(IoUtils.ACL_VIEW_ATTR);
                 if (getTestedVersion() > SftpConstants.SFTP_V3) {
                     assertListEquals("Mismatched modifying ACL for file=" + 
path, aclExpected, aclActual);
                 } else {
@@ -342,7 +343,8 @@ public class SftpVersionsTest extends 
AbstractSftpClientTestSupport {
             public void modifiedAttributes(
                     ServerSession session, Path path, Map<String, ?> attrs, 
Throwable thrown) {
                 @SuppressWarnings("unchecked")
-                List<AclEntry> aclActual = MapEntryUtils.isEmpty(attrs) ? null 
: (List<AclEntry>) attrs.get("acl");
+                List<AclEntry> aclActual
+                        = MapEntryUtils.isEmpty(attrs) ? null : 
(List<AclEntry>) attrs.get(IoUtils.ACL_VIEW_ATTR);
                 if (getTestedVersion() > SftpConstants.SFTP_V3) {
                     assertListEquals("Mismatched modified ACL for file=" + 
path, aclExpected, aclActual);
                 } else {
@@ -418,7 +420,8 @@ public class SftpVersionsTest extends 
AbstractSftpClientTestSupport {
                         }
 
                         @SuppressWarnings("unchecked")
-                        Map<String, String> actExtensions = (Map<String, 
String>) attrs.put("extended", expExtensions);
+                        Map<String, String> actExtensions
+                                = (Map<String, String>) 
attrs.put(IoUtils.EXTENDED_VIEW_ATTR, expExtensions);
                         if (actExtensions != null) {
                             log.info("resolveFileAttributes(" + file + ") 
replaced extensions: " + actExtensions);
                         }
@@ -458,7 +461,7 @@ public class SftpVersionsTest extends 
AbstractSftpClientTestSupport {
             public void modifyingAttributes(ServerSession session, Path path, 
Map<String, ?> attrs) {
                 @SuppressWarnings("unchecked")
                 Map<String, byte[]> actExtensions
-                        = MapEntryUtils.isEmpty(attrs) ? null : (Map<String, 
byte[]>) attrs.get("extended");
+                        = MapEntryUtils.isEmpty(attrs) ? null : (Map<String, 
byte[]>) attrs.get(IoUtils.EXTENDED_VIEW_ATTR);
                 assertExtensionsMapEquals("modifying(" + path + ")", 
expExtensions, actExtensions);
             }
 
@@ -466,7 +469,7 @@ public class SftpVersionsTest extends 
AbstractSftpClientTestSupport {
             public void modifiedAttributes(ServerSession session, Path path, 
Map<String, ?> attrs, Throwable thrown) {
                 @SuppressWarnings("unchecked")
                 Map<String, byte[]> actExtensions
-                        = MapEntryUtils.isEmpty(attrs) ? null : (Map<String, 
byte[]>) attrs.get("extended");
+                        = MapEntryUtils.isEmpty(attrs) ? null : (Map<String, 
byte[]>) attrs.get(IoUtils.EXTENDED_VIEW_ATTR);
                 assertExtensionsMapEquals("modified(" + path + ")", 
expExtensions, actExtensions);
             }
         });
diff --git 
a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/fs/AbstractSftpFilesSystemSupport.java
 
b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/fs/AbstractSftpFilesSystemSupport.java
index b516290..9c71dfb 100644
--- 
a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/fs/AbstractSftpFilesSystemSupport.java
+++ 
b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/fs/AbstractSftpFilesSystemSupport.java
@@ -41,6 +41,7 @@ import java.util.Map;
 
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.util.OsUtils;
+import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.sftp.client.AbstractSftpClientTestSupport;
 import org.apache.sshd.sftp.client.SftpClientFactory;
 import org.apache.sshd.sftp.client.SftpVersionSelector;
@@ -165,10 +166,10 @@ public abstract class AbstractSftpFilesSystemSupport 
extends AbstractSftpClientT
 
         Map<String, ?> attrs = Files.readAttributes(file, "acl:*", 
LinkOption.NOFOLLOW_LINKS);
         outputDebugMessage("readAttributes(%s) %s", file, attrs);
-        assertEquals("Mismatched owner for " + file, aclView.getOwner(), 
attrs.get("owner"));
+        assertEquals("Mismatched owner for " + file, aclView.getOwner(), 
attrs.get(IoUtils.OWNER_VIEW_ATTR));
 
         @SuppressWarnings("unchecked")
-        List<AclEntry> acl = (List<AclEntry>) attrs.get("acl");
+        List<AclEntry> acl = (List<AclEntry>) attrs.get(IoUtils.ACL_VIEW_ATTR);
         outputDebugMessage("acls(%s) %s", file, acl);
         assertListEquals("Mismatched ACLs for " + file, aclView.getAcl(), acl);
 

Reply via email to