You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2014/06/16 14:38:13 UTC

[2/2] git commit: [SSHD-317] UnsupportedOperationException uploading file Java 7/Windows

[SSHD-317] UnsupportedOperationException uploading file Java 7/Windows

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/97b38fb0
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/97b38fb0
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/97b38fb0

Branch: refs/heads/master
Commit: 97b38fb08e4a4fffb8fb01dd9d30ac2a2af16dee
Parents: 29ff339
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon Jun 16 14:21:35 2014 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon Jun 16 14:21:35 2014 +0200

----------------------------------------------------------------------
 .../file/nativefs/NativeFileSystemView.java     | 18 ++++-
 .../common/file/nativefs/NativeSshFile.java     | 44 ++++++++++-
 .../common/file/nativefs/NativeSshFileNio.java  | 81 ++++++++++++++++----
 3 files changed, 125 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/97b38fb0/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeFileSystemView.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeFileSystemView.java b/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeFileSystemView.java
index 9816b1e..9337349 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeFileSystemView.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeFileSystemView.java
@@ -45,6 +45,12 @@ import static org.apache.sshd.common.file.nativefs.NativeSshFile.normalizeSepara
  */
 public class NativeFileSystemView implements FileSystemView {
 
+    public enum UnsupportedAttributePolicy {
+        Ignore,
+        Warn,
+        ThrowException
+    }
+
     private final Logger LOG = LoggerFactory.getLogger(NativeFileSystemView.class);
 
 
@@ -60,6 +66,8 @@ public class NativeFileSystemView implements FileSystemView {
 
     private boolean caseInsensitive = false;
 
+    private UnsupportedAttributePolicy unsupportedAttributePolicy = UnsupportedAttributePolicy.Warn;
+
     /**
      * Constructor - internal do not use directly, use {@link NativeFileSystemFactory} instead
      */
@@ -141,6 +149,14 @@ public class NativeFileSystemView implements FileSystemView {
         return roots;
     }
 
+    public UnsupportedAttributePolicy getUnsupportedAttributePolicy() {
+        return unsupportedAttributePolicy;
+    }
+
+    public void setUnsupportedAttributePolicy(UnsupportedAttributePolicy unsupportedAttributePolicy) {
+        this.unsupportedAttributePolicy = unsupportedAttributePolicy;
+    }
+
     public String getUserName() {
         return userName;
     }
@@ -227,7 +243,7 @@ public class NativeFileSystemView implements FileSystemView {
 
     public NativeSshFile createNativeSshFile(String name, File file, String userName) {
         name = deNormalizeSeparateChar(name);
-        if (isJava7 && !isWindows) {
+        if (isJava7) {
             return new NativeSshFileNio(this, name, file, userName);
         } else {
 		    return new NativeSshFile(this, name, file, userName);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/97b38fb0/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFile.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFile.java b/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFile.java
index 0ece66c..d63d446 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFile.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFile.java
@@ -27,13 +27,17 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.lang.reflect.Method;
+import java.nio.channels.FileChannel;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import org.apache.sshd.common.file.SshFile;
@@ -640,8 +644,46 @@ public class NativeSshFile implements SshFile {
     }
 
     public void setAttributes(Map<Attribute, Object> attributes) throws IOException {
+        Set<Attribute> unsupported = new HashSet<Attribute>();
+        for (Attribute attribute : attributes.keySet()) {
+            Object value = attributes.get(attribute);
+            switch (attribute) {
+            case Size: {
+                long newSize = (Long) value;
+                FileChannel outChan = new FileOutputStream(file, true).getChannel();
+                outChan.truncate(newSize);
+                outChan.close();
+                continue;
+            }
+            case LastModifiedTime:
+                setLastModified((Long) value);
+                break;
+            default:
+                unsupported.add(attribute);
+                break;
+            }
+        }
+        handleUnsupportedAttributes(unsupported);
+    }
+
+    protected void handleUnsupportedAttributes(Collection<Attribute> attributes) {
         if (!attributes.isEmpty()) {
-            throw new UnsupportedOperationException();
+            StringBuilder sb = new StringBuilder();
+            for (Attribute attr : attributes) {
+                if (sb.length() > 0) {
+                    sb.append(", ");
+                }
+                sb.append(attr.name());
+            }
+            switch (nativeFileSystemView.getUnsupportedAttributePolicy()) {
+            case Ignore:
+                break;
+            case Warn:
+                LOG.warn("Unsupported attributes: " + sb.toString());
+                break;
+            case ThrowException:
+                throw new UnsupportedOperationException("Unsupported attributes: " + sb.toString());
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/97b38fb0/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFileNio.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFileNio.java b/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFileNio.java
index c4cde42..1cfef6b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFileNio.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/file/nativefs/NativeSshFileNio.java
@@ -58,27 +58,71 @@ public class NativeSshFileNio extends NativeSshFile {
     }
 
     public Map<Attribute, Object> getAttributes(boolean followLinks) throws IOException {
-        Map<String, Object> a = Files.readAttributes(
-                file.toPath(),
-                "unix:size,uid,owner,gid,group,isDirectory,isRegularFile,isSymbolicLink,permissions,creationTime,lastModifiedTime,lastAccessTime",
-                followLinks ? new LinkOption[0] : new LinkOption[] { LinkOption.NOFOLLOW_LINKS });
+        String[] attrs = new String[] { "unix:*", "posix:*", "*" };
+        Map<String, Object> a = null;
+        for (String attr : attrs) {
+            try {
+                a = Files.readAttributes(
+                        file.toPath(), attr,
+                        followLinks ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS});
+                break;
+            } catch (UnsupportedOperationException e) {
+                // Ignore
+            }
+        }
+        if (a == null) {
+            throw new IllegalStateException();
+        }
         Map<Attribute, Object> map = new HashMap<Attribute, Object>();
         map.put(Attribute.Size, a.get("size"));
-        map.put(Attribute.Uid, a.get("uid"));
-        map.put(Attribute.Owner, ((UserPrincipal) a.get("owner")).getName());
-        map.put(Attribute.Gid, a.get("gid"));
-        map.put(Attribute.Group, ((GroupPrincipal) a.get("group")).getName());
+        if (a.containsKey("uid")) {
+            map.put(Attribute.Uid, a.get("uid"));
+        }
+        if (a.containsKey("owner")) {
+            map.put(Attribute.Owner, ((UserPrincipal) a.get("owner")).getName());
+        } else {
+            map.put(Attribute.Owner, userName);
+        }
+        if (a.containsKey("gid")) {
+            map.put(Attribute.Gid, a.get("gid"));
+        }
+        if (a.containsKey("group")) {
+            map.put(Attribute.Group, ((GroupPrincipal) a.get("group")).getName());
+        } else {
+            map.put(Attribute.Group, userName);
+        }
         map.put(Attribute.IsDirectory, a.get("isDirectory"));
         map.put(Attribute.IsRegularFile, a.get("isRegularFile"));
         map.put(Attribute.IsSymbolicLink, a.get("isSymbolicLink"));
         map.put(Attribute.CreationTime, ((FileTime) a.get("creationTime")).toMillis());
         map.put(Attribute.LastModifiedTime, ((FileTime) a.get("lastModifiedTime")).toMillis());
         map.put(Attribute.LastAccessTime, ((FileTime) a.get("lastAccessTime")).toMillis());
-        map.put(Attribute.Permissions, fromPerms((Set<PosixFilePermission>) a.get("permissions")));
+        if (a.containsKey("permissions")) {
+            map.put(Attribute.Permissions, fromPerms((Set<PosixFilePermission>) a.get("permissions")));
+        } else {
+            EnumSet<Permission> p = EnumSet.noneOf(Permission.class);
+            if (isReadable()) {
+                p.add(Permission.UserRead);
+                p.add(Permission.GroupRead);
+                p.add(Permission.OthersRead);
+            }
+            if (isWritable()) {
+                p.add(Permission.UserWrite);
+                p.add(Permission.GroupWrite);
+                p.add(Permission.OthersWrite);
+            }
+            if (isExecutable()) {
+                p.add(Permission.UserExecute);
+                p.add(Permission.GroupExecute);
+                p.add(Permission.OthersExecute);
+            }
+            map.put(Attribute.Permissions, p);
+        }
         return map;
     }
 
     public void setAttributes(Map<Attribute, Object> attributes) throws IOException {
+        Set<Attribute> unsupported = new HashSet<Attribute>();
         for (Attribute attribute : attributes.keySet()) {
             String name = null;
             Object value = attributes.get(attribute);
@@ -91,18 +135,23 @@ public class NativeSshFileNio extends NativeSshFile {
                     continue;
                 }
                 case Uid:              name = "unix:uid"; break;
-                case Owner:            name = "unix:owner"; value = toUser((String) value); break;
                 case Gid:              name = "unix:gid"; break;
-                case Group:            name = "unix:group"; value = toGroup((String) value); break;
-                case Permissions:      name = "unix:permissions"; value = toPerms((EnumSet<Permission>) value); break;
-                case CreationTime:     name = "unix:creationTime"; value = FileTime.fromMillis((Long) value); break;
-                case LastModifiedTime: name = "unix:lastModifiedTime"; value = FileTime.fromMillis((Long) value); break;
-                case LastAccessTime:   name = "unix:lastAccessTime"; value = FileTime.fromMillis((Long) value); break;
+                case Owner:            name = "posix:owner"; value = toUser((String) value); break;
+                case Group:            name = "posix:group"; value = toGroup((String) value); break;
+                case Permissions:      name = "posix:permissions"; value = toPerms((EnumSet<Permission>) value); break;
+                case CreationTime:     name = "basic:creationTime"; value = FileTime.fromMillis((Long) value); break;
+                case LastModifiedTime: name = "basic:lastModifiedTime"; value = FileTime.fromMillis((Long) value); break;
+                case LastAccessTime:   name = "basic:lastAccessTime"; value = FileTime.fromMillis((Long) value); break;
             }
             if (name != null && value != null) {
-                Files.setAttribute(file.toPath(), name, value, LinkOption.NOFOLLOW_LINKS);
+                try {
+                    Files.setAttribute(file.toPath(), name, value, LinkOption.NOFOLLOW_LINKS);
+                } catch (UnsupportedOperationException e) {
+                    unsupported.add(attribute);
+                }
             }
         }
+        handleUnsupportedAttributes(unsupported);
     }
 
     public String readSymbolicLink() throws IOException {