Skip to content

Commit 3f30589

Browse files
committed
Avoid multiple access to the file system
The plexus DirectoryScanner usually access the file system multiple times for each file, so cache all attributes
1 parent 9338f9d commit 3f30589

File tree

6 files changed

+230
-99
lines changed

6 files changed

+230
-99
lines changed

src/main/java/org/codehaus/plexus/components/io/attributes/FileAttributes.java

Lines changed: 86 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.nio.file.LinkOption;
2323
import java.nio.file.Path;
2424
import java.nio.file.attribute.FileOwnerAttributeView;
25+
import java.nio.file.attribute.FileTime;
2526
import java.nio.file.attribute.PosixFilePermission;
2627
import java.security.Principal;
2728
import 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
}

src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtils.java

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -43,69 +43,71 @@ public static PlexusIoResourceAttributes mergeAttributes( PlexusIoResourceAttrib
4343
{
4444
return base;
4545
}
46-
SimpleResourceAttributes result;
4746
if ( base == null )
4847
{
49-
result = new SimpleResourceAttributes();
48+
return new SimpleResourceAttributes(
49+
override.getUserId() != null && override.getUserId() != -1
50+
? override.getUserId()
51+
: def != null && def.getUserId() != null && def.getUserId() != -1
52+
? def.getUserId()
53+
: null,
54+
override.getUserName() != null
55+
? override.getUserName()
56+
: def != null
57+
? def.getUserName()
58+
: null,
59+
override.getGroupId() != null && override.getGroupId() != -1
60+
? override.getGroupId()
61+
: def != null && def.getGroupId() != null && def.getGroupId() != -1
62+
? def.getGroupId()
63+
: null,
64+
override.getGroupName() != null
65+
? override.getGroupName()
66+
: def != null
67+
? def.getGroupName()
68+
: null,
69+
override.getOctalMode() );
5070
}
5171
else
5272
{
53-
result = new SimpleResourceAttributes( base.getUserId(), base.getUserName(), base.getGroupId(),
54-
base.getGroupName(), base.getOctalMode() );
55-
result.setSymbolicLink( base.isSymbolicLink() );
73+
Integer uid = override.getUserId() != null && override.getUserId() != -1
74+
? override.getUserId()
75+
: base.getUserId() != null && base.getUserId() != -1
76+
? base.getUserId()
77+
: def.getUserId() != null && def.getUserId() != -1
78+
? def.getUserId()
79+
: null;
80+
String uname = override.getUserName() != null
81+
? override.getUserName()
82+
: base.getUserName() != null
83+
? base.getUserName()
84+
: def.getUserName();
85+
Integer gid = override.getGroupId() != null && override.getGroupId() != -1
86+
? override.getGroupId()
87+
: base.getGroupId() != null && base.getGroupId() != -1
88+
? base.getGroupId()
89+
: def.getGroupId() != null && def.getGroupId() != -1
90+
? def.getGroupId()
91+
: null;
92+
String gname = override.getGroupName() != null
93+
? override.getGroupName()
94+
: base.getGroupName() != null
95+
? base.getGroupName()
96+
: def.getGroupName();
97+
int mode = override.getOctalMode() > 0
98+
? override.getOctalMode()
99+
: base.getOctalMode() >= 0
100+
? base.getOctalMode()
101+
: def.getOctalMode();
102+
if ( base instanceof FileAttributes )
103+
{
104+
return new UserGroupModeFileAttributes( uid, uname, gid, gname, mode, (FileAttributes) base );
105+
}
106+
else
107+
{
108+
return new SimpleResourceAttributes( uid, uname, gid, gname, mode, base.isSymbolicLink() );
109+
}
56110
}
57-
58-
if ( override.getGroupId() != null && override.getGroupId() != -1 )
59-
{
60-
result.setGroupId( override.getGroupId() );
61-
}
62-
63-
if ( def != null && def.getGroupId() >= 0 && ( result.getGroupId() == null || result.getGroupId() < 0 ) )
64-
{
65-
result.setGroupId( def.getGroupId() );
66-
}
67-
68-
if ( override.getGroupName() != null )
69-
{
70-
result.setGroupName( override.getGroupName() );
71-
}
72-
73-
if ( def != null && result.getGroupName() == null )
74-
{
75-
result.setGroupName( def.getGroupName() );
76-
}
77-
78-
if ( override.getUserId() != null && override.getUserId() != -1 )
79-
{
80-
result.setUserId( override.getUserId() );
81-
}
82-
83-
if ( def != null && def.getUserId() >= 0 && ( result.getUserId() == null || result.getUserId() < 0 ) )
84-
{
85-
result.setUserId( def.getUserId() );
86-
}
87-
88-
if ( override.getUserName() != null )
89-
{
90-
result.setUserName( override.getUserName() );
91-
}
92-
93-
if ( def != null && result.getUserName() == null )
94-
{
95-
result.setUserName( def.getUserName() );
96-
}
97-
98-
if ( override.getOctalMode() > 0 )
99-
{
100-
result.setOctalMode( override.getOctalMode() );
101-
}
102-
103-
if ( def != null && result.getOctalMode() < 0 )
104-
{
105-
result.setOctalMode( def.getOctalMode() );
106-
}
107-
108-
return result;
109111
}
110112

111113
public static boolean isGroupExecutableInOctal( int mode )

src/main/java/org/codehaus/plexus/components/io/attributes/SimpleResourceAttributes.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ public SimpleResourceAttributes( Integer uid, String userName, Integer gid, Stri
4646
this.mode = mode;
4747
}
4848

49+
public SimpleResourceAttributes( Integer uid, String userName, Integer gid, String groupName, int mode, boolean isSymbolicLink )
50+
{
51+
this.uid = uid;
52+
this.userName = userName;
53+
this.gid = gid;
54+
this.groupName = groupName;
55+
this.mode = mode;
56+
this.isSymbolicLink = isSymbolicLink;
57+
}
58+
4959
public static PlexusIoResourceAttributes lastResortDummyAttributesForBrokenOS()
5060
{
5161
return new SimpleResourceAttributes();
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.codehaus.plexus.components.io.attributes;
2+
3+
/*
4+
* Copyright 2007 The Codehaus Foundation.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import javax.annotation.Nullable;
20+
21+
/*
22+
* A very simple pojo based PlexusIoResourceAttributes without any kind of backing
23+
*/
24+
public class UserGroupModeFileAttributes
25+
extends FileAttributes
26+
{
27+
28+
public UserGroupModeFileAttributes( Integer uid, String userName, Integer gid, String groupName, int mode, FileAttributes base )
29+
{
30+
super( uid, userName, gid, groupName, mode,
31+
base.isSymbolicLink(), base.isRegularFile(), base.isDirectory(), base.isOther(),
32+
base.getPermissions(), base.getSize(), base.getLastModifiedTime() );
33+
}
34+
35+
public String toString()
36+
{
37+
return String.format(
38+
"%nResource Attributes:%n------------------------------%nuser: %s%ngroup: %s%nuid: %d%ngid: %d%nmode: %06o",
39+
getUserName() == null ? "" : getUserName(),
40+
getGroupName() == null ? "" : getGroupName(),
41+
getUserId() != null ? getUserId() : 0,
42+
getGroupId() != null ? getGroupId() : 0,
43+
getOctalMode() );
44+
}
45+
46+
47+
}

0 commit comments

Comments
 (0)