11package com .fizzed .jsync .vfs ;
22
33import com .fizzed .jsync .vfs .util .Checksums ;
4+ import com .fizzed .jsync .vfs .util .Permissions ;
45import org .slf4j .Logger ;
56import org .slf4j .LoggerFactory ;
67
1112import java .nio .file .attribute .BasicFileAttributeView ;
1213import java .nio .file .attribute .BasicFileAttributes ;
1314import java .nio .file .attribute .FileTime ;
15+ import java .nio .file .attribute .PosixFileAttributes ;
1416import java .util .ArrayList ;
1517import java .util .Iterator ;
1618import java .util .List ;
1921public class LocalVirtualFileSystem extends AbstractVirtualFileSystem {
2022 static private final Logger log = LoggerFactory .getLogger (LocalVirtualFileSystem .class );
2123
22- public LocalVirtualFileSystem (String name , VirtualPath pwd , boolean caseSensitive ) {
24+ private final boolean posix ;
25+
26+ public LocalVirtualFileSystem (String name , VirtualPath pwd , boolean caseSensitive , boolean posix ) {
2327 super (name , pwd , caseSensitive );
28+ this .posix = posix ;
2429 }
2530
2631 static public LocalVirtualFileSystem open () {
@@ -37,21 +42,29 @@ static public LocalVirtualFileSystem open(Path workingDir) {
3742
3843 final VirtualPath pwd = VirtualPath .parse (currentWorkingDir .toString (), true );
3944
40- log .debug ("Detected filesystem {} has pwd {}" , name , pwd );
45+ final boolean isPosixAttributes = FileSystems .getDefault ()
46+ .supportedFileAttributeViews ()
47+ .contains ("posix" );
48+
49+ log .debug ("Detected filesystem {} has pwd {}, posixAttrs {}" , name , pwd , isPosixAttributes );
4150
4251 // everything is case-sensitive except windows
4352 final boolean caseSensitive = !System .getProperty ("os.name" ).toLowerCase ().contains ("windows" );
4453
4554 log .debug ("Detected filesystem {} is case-sensitive={}" , name , caseSensitive );
4655
47- return new LocalVirtualFileSystem (name , pwd , caseSensitive );
56+ return new LocalVirtualFileSystem (name , pwd , caseSensitive , isPosixAttributes );
4857 }
4958
5059 @ Override
5160 public void close () throws Exception {
5261 // nothing to do
5362 }
5463
64+ public boolean isPosix () {
65+ return this .posix ;
66+ }
67+
5568 protected Path toNativePath (VirtualPath path ) {
5669 return Paths .get (path .toString ());
5770 }
@@ -60,10 +73,17 @@ protected VirtualPath toVirtualPathWithStat(VirtualPath path) throws IOException
6073 final Path nativePath = this .toNativePath (path );
6174
6275 // Fetch all attributes in ONE operation (and don't follow symlinks, we need to know the type)
63- final BasicFileAttributes attrs = Files .readAttributes (nativePath , BasicFileAttributes .class , LinkOption .NOFOLLOW_LINKS );
64- // TODO: if we're on posix, we can also do this
65- // fetches size, times, PLUS owner, group, and permissions
66- // PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class);
76+ final PosixFileAttributes posixAttrs ;
77+ final BasicFileAttributes attrs ;
78+ if (this .posix ) {
79+ posixAttrs = Files .readAttributes (nativePath , PosixFileAttributes .class , LinkOption .NOFOLLOW_LINKS );
80+ attrs = posixAttrs ;
81+ } else {
82+ posixAttrs = null ;
83+ attrs = Files .readAttributes (nativePath , BasicFileAttributes .class , LinkOption .NOFOLLOW_LINKS );
84+ }
85+
86+ // basic attributes get us much of what we need
6787 final long size = attrs .size ();
6888 final long modifiedTime = attrs .lastModifiedTime ().toMillis ();
6989 final long accessedTime = attrs .lastAccessTime ().toMillis ();
@@ -84,7 +104,13 @@ protected VirtualPath toVirtualPathWithStat(VirtualPath path) throws IOException
84104 type = VirtualFileType .OTHER ;
85105 }
86106
87- final VirtualFileStat stat = new VirtualFileStat (type , size , modifiedTime , accessedTime );
107+ // permissions are a tad trickier if they aren't really supported
108+ int perms = -1 ;
109+ if (posixAttrs != null ) {
110+ perms = Permissions .toPosixInt (posixAttrs .permissions ());
111+ }
112+
113+ final VirtualFileStat stat = new VirtualFileStat (type , size , modifiedTime , accessedTime , perms );
88114
89115 return new VirtualPath (path .getParentPath (), path .getName (), type == VirtualFileType .DIR , stat );
90116 }
0 commit comments