2222import java .nio .file .LinkOption ;
2323import java .nio .file .Path ;
2424import java .nio .file .attribute .FileOwnerAttributeView ;
25+ import java .nio .file .attribute .FileTime ;
2526import java .nio .file .attribute .PosixFilePermission ;
2627import java .security .Principal ;
2728import java .util .Collections ;
@@ -52,62 +53,77 @@ public class FileAttributes
5253
5354 private final boolean symbolicLink ;
5455
56+ private final boolean regularFile ;
57+
58+ private final boolean directory ;
59+
60+ private final boolean other ;
61+
5562 private final int octalMode ;
5663
5764 private final Set <PosixFilePermission > permissions ;
5865
66+ private final long size ;
67+
68+ private final FileTime lastModifiedTime ;
69+
5970 public FileAttributes ( @ Nonnull File file , @ Nonnull Map <Integer , String > userCache ,
6071 @ Nonnull Map <Integer , String > groupCache )
6172 throws IOException
6273 {
6374
6475 Path path = file .toPath ();
65- if ( AttributeUtils .isUnix ( path ) )
76+ Set <String > views = path .getFileSystem ().supportedFileAttributeViews ();
77+ String names ;
78+ if ( views .contains ( "unix" ) )
79+ {
80+ names = "unix:*" ;
81+ }
82+ else if ( views .contains ( "posix" ) )
6683 {
67- Map <String , Object > attrs = Files .readAttributes ( path , "unix:permissions,gid,uid,isSymbolicLink,mode" , LinkOption .NOFOLLOW_LINKS );
68- this .permissions = (Set <PosixFilePermission >) attrs .get ( "permissions" );
69-
70- groupId = (Integer ) attrs .get ( "gid" );
71-
72- String groupName = groupCache .get ( groupId );
73- if ( groupName != null )
74- {
75- this .groupName = groupName ;
76- }
77- else
78- {
79- Object group = Files .getAttribute ( path , "unix:group" , LinkOption .NOFOLLOW_LINKS );
80- this .groupName = ( (Principal ) group ).getName ();
81- groupCache .put ( groupId , this .groupName );
82- }
83- userId = (Integer ) attrs .get ( "uid" );
84- String userName = userCache .get ( userId );
85- if ( userName != null )
86- {
87- this .userName = userName ;
88- }
89- else
90- {
91- Object owner = Files .getAttribute ( path , "unix:owner" , LinkOption .NOFOLLOW_LINKS );
92- this .userName = ( (Principal ) owner ).getName ();
93- userCache .put ( userId , this .userName );
94- }
95- octalMode = (Integer ) attrs .get ( "mode" ) & 0xfff ; // Mask off top bits for compatibilty. Maybe check if we
96- // can skip this
97- symbolicLink = (Boolean ) attrs .get ( "isSymbolicLink" );
84+ names = "posix:*" ;
9885 }
9986 else
10087 {
101- FileOwnerAttributeView fa = AttributeUtils .getFileOwnershipInfo ( file );
102- this .userName = fa .getOwner ().getName ();
103- userId = null ;
104- this .groupName = null ;
105- this .groupId = null ;
106- octalMode = PlexusIoResourceAttributes .UNKNOWN_OCTAL_MODE ;
107- permissions = Collections .emptySet ();
108- symbolicLink = Files .isSymbolicLink ( path );
88+ names = "basic:*" ;
10989 }
90+ Map <String , Object > attrs = Files .readAttributes ( path , names , LinkOption .NOFOLLOW_LINKS );
91+ if ( !attrs .containsKey ( "group" ) && !attrs .containsKey ( "owner" ) && views .contains ( "owner" ) )
92+ {
93+ Map <String , Object > ownerAttrs = Files .readAttributes ( path , "owner:*" , LinkOption .NOFOLLOW_LINKS );
94+ Map <String , Object > newAttrs = new HashMap <>( attrs );
95+ newAttrs .putAll ( ownerAttrs );
96+ attrs = newAttrs ;
97+ }
98+ this .groupId = (Integer ) attrs .get ( "gid" );
99+ this .groupName = attrs .containsKey ( "group" ) ? ((Principal ) attrs .get ( "group" ) ).getName () : null ;
100+ this .userId = (Integer ) attrs .get ( "uid" );
101+ this .userName = attrs .containsKey ( "owner" ) ? ((Principal ) attrs .get ( "owner" ) ).getName () : null ;
102+ this .symbolicLink = (Boolean ) attrs .get ( "isSymbolicLink" );
103+ this .regularFile = (Boolean ) attrs .get ( "isRegularFile" );
104+ this .directory = (Boolean ) attrs .get ( "isDirectory" );
105+ this .other = (Boolean ) attrs .get ( "isOther" );
106+ this .octalMode = attrs .containsKey ( "mode" ) ? (Integer ) attrs .get ( "mode" ) & 0xfff : PlexusIoResourceAttributes .UNKNOWN_OCTAL_MODE ;
107+ this .permissions = attrs .containsKey ( "permissions" ) ? (Set <PosixFilePermission >) attrs .get ( "permissions" ) : Collections .<PosixFilePermission >emptySet ();
108+ this .size = (Long ) attrs .get ( "size" );
109+ this .lastModifiedTime = (FileTime ) attrs .get ( "lastModifiedTime" );
110+ }
110111
112+ public FileAttributes ( @ Nullable Integer userId , String userName , @ Nullable Integer groupId , @ Nullable String groupName ,
113+ int octalMode , boolean symbolicLink , boolean regularFile , boolean directory , boolean other ,
114+ Set <PosixFilePermission > permissions , long size , FileTime lastModifiedTime ) {
115+ this .userId = userId ;
116+ this .userName = userName ;
117+ this .groupId = groupId ;
118+ this .groupName = groupName ;
119+ this .octalMode = octalMode ;
120+ this .symbolicLink = symbolicLink ;
121+ this .regularFile = regularFile ;
122+ this .directory = directory ;
123+ this .other = other ;
124+ this .permissions = permissions ;
125+ this .size = size ;
126+ this .lastModifiedTime = lastModifiedTime ;
111127 }
112128
113129 public static @ Nonnull
@@ -290,4 +306,34 @@ public boolean isSymbolicLink()
290306 {
291307 return symbolicLink ;
292308 }
309+
310+ public boolean isRegularFile ()
311+ {
312+ return regularFile ;
313+ }
314+
315+ public boolean isDirectory ()
316+ {
317+ return directory ;
318+ }
319+
320+ public boolean isOther ()
321+ {
322+ return other ;
323+ }
324+
325+ public long getSize ()
326+ {
327+ return size ;
328+ }
329+
330+ public FileTime getLastModifiedTime ()
331+ {
332+ return lastModifiedTime ;
333+ }
334+
335+ protected Set <PosixFilePermission > getPermissions ()
336+ {
337+ return permissions ;
338+ }
293339}
0 commit comments