View Javadoc
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 java.io.File;
20  import java.io.IOException;
21  import java.nio.file.Files;
22  import java.nio.file.LinkOption;
23  import java.nio.file.Path;
24  import java.nio.file.attribute.FileOwnerAttributeView;
25  import java.nio.file.attribute.PosixFilePermission;
26  import java.security.Principal;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.Map;
30  import java.util.Set;
31  
32  import javax.annotation.Nonnull;
33  import javax.annotation.Nullable;
34  
35  /*
36   * File attributes
37   * Immutable
38   */
39  public class FileAttributes
40      implements PlexusIoResourceAttributes
41  {
42      @Nullable
43      private final Integer groupId;
44  
45      @Nullable
46      private final String groupName;
47  
48      @Nullable
49      private final Integer userId;
50  
51      private final String userName;
52  
53      private final boolean symbolicLink;
54  
55      private final int octalMode;
56  
57      private final Set<PosixFilePermission> permissions;
58  
59      public FileAttributes( @Nonnull File file, @Nonnull Map<Integer, String> userCache,
60                             @Nonnull Map<Integer, String> groupCache )
61          throws IOException
62      {
63  
64          Path path = file.toPath();
65          if ( AttributeUtils.isUnix( path ) )
66          {
67              Map<String, Object> attrs = Files.readAttributes( path, "unix:*", 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                  this.groupName = ( (Principal) attrs.get( "group" ) ).getName();
80                  groupCache.put( groupId, this.groupName );
81              }
82              userId = (Integer) attrs.get( "uid" );
83              String userName = userCache.get( userId );
84              if ( userName != null )
85              {
86                  this.userName = userName;
87              }
88              else
89              {
90                  this.userName = ( (Principal) attrs.get( "owner" ) ).getName();
91                  userCache.put( userId, this.userName );
92              }
93              octalMode = (Integer) attrs.get( "mode" ) & 0xfff; // Mask off top bits for compatibilty. Maybe check if we
94                                                                 // can skip this
95              symbolicLink = (Boolean) attrs.get( "isSymbolicLink" );
96          }
97          else
98          {
99              FileOwnerAttributeView fa = AttributeUtils.getFileOwnershipInfo( file );
100             this.userName = fa.getOwner().getName();
101             userId = null;
102             this.groupName = null;
103             this.groupId = null;
104             octalMode = PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE;
105             permissions = Collections.emptySet();
106             symbolicLink = Files.isSymbolicLink( path );
107         }
108 
109     }
110 
111     public static @Nonnull
112     PlexusIoResourceAttributes uncached( @Nonnull File file )
113         throws IOException
114     {
115         return new FileAttributes( file, new HashMap<Integer, String>(), new HashMap<Integer, String>() );
116     }
117 
118     @Nullable
119     public Integer getGroupId()
120     {
121 
122         return groupId;
123     }
124 
125     public boolean hasGroupId()
126     {
127         return false;
128     }
129 
130     public boolean hasUserId()
131     {
132         return false;
133     }
134 
135     @Nullable
136     public String getGroupName()
137     {
138         return groupName;
139     }
140 
141     public Integer getUserId()
142     {
143         return userId;
144     }
145 
146     public String getUserName()
147     {
148         return userName;
149     }
150 
151     public boolean isGroupExecutable()
152     {
153         return containsPermission( PosixFilePermission.GROUP_EXECUTE );
154     }
155 
156     private boolean containsPermission( PosixFilePermission groupExecute )
157     {
158         return permissions.contains( groupExecute );
159     }
160 
161     public boolean isGroupReadable()
162     {
163         return containsPermission( PosixFilePermission.GROUP_READ );
164     }
165 
166     public boolean isGroupWritable()
167     {
168         return containsPermission( PosixFilePermission.GROUP_WRITE );
169     }
170 
171     public boolean isOwnerExecutable()
172     {
173         return containsPermission( PosixFilePermission.OWNER_EXECUTE );
174     }
175 
176     public boolean isOwnerReadable()
177     {
178         return containsPermission( PosixFilePermission.OWNER_READ );
179     }
180 
181     public boolean isOwnerWritable()
182     {
183         return containsPermission( PosixFilePermission.OWNER_WRITE );
184     }
185 
186     public boolean isWorldExecutable()
187     {
188         return containsPermission( PosixFilePermission.OTHERS_EXECUTE );
189 
190     }
191 
192     public boolean isWorldReadable()
193     {
194         return containsPermission( PosixFilePermission.OTHERS_READ );
195     }
196 
197     public boolean isWorldWritable()
198     {
199         return containsPermission( PosixFilePermission.OTHERS_WRITE );
200     }
201 
202     public String toString()
203     {
204         StringBuilder sb = new StringBuilder();
205         sb.append( System.lineSeparator() );
206         sb.append( "File Attributes:" );
207         sb.append( System.lineSeparator() );
208         sb.append( "------------------------------" );
209         sb.append( System.lineSeparator() );
210         sb.append( "user: " );
211         sb.append( userName == null ? "" : userName );
212         sb.append( System.lineSeparator() );
213         sb.append( "group: " );
214         sb.append( groupName == null ? "" : groupName );
215         sb.append( System.lineSeparator() );
216         sb.append( "uid: " );
217         sb.append( hasUserId() ? Integer.toString( userId ) : "" );
218         sb.append( System.lineSeparator() );
219         sb.append( "gid: " );
220         sb.append( hasGroupId() ? Integer.toString( groupId ) : "" );
221 
222         return sb.toString();
223     }
224 
225     public int getOctalMode()
226     {
227         return octalMode;
228     }
229 
230     public int calculatePosixOctalMode()
231     {
232         int result = 0;
233 
234         if ( isOwnerReadable() )
235         {
236             result |= AttributeConstants.OCTAL_OWNER_READ;
237         }
238 
239         if ( isOwnerWritable() )
240         {
241             result |= AttributeConstants.OCTAL_OWNER_WRITE;
242         }
243 
244         if ( isOwnerExecutable() )
245         {
246             result |= AttributeConstants.OCTAL_OWNER_EXECUTE;
247         }
248 
249         if ( isGroupReadable() )
250         {
251             result |= AttributeConstants.OCTAL_GROUP_READ;
252         }
253 
254         if ( isGroupWritable() )
255         {
256             result |= AttributeConstants.OCTAL_GROUP_WRITE;
257         }
258 
259         if ( isGroupExecutable() )
260         {
261             result |= AttributeConstants.OCTAL_GROUP_EXECUTE;
262         }
263 
264         if ( isWorldReadable() )
265         {
266             result |= AttributeConstants.OCTAL_WORLD_READ;
267         }
268 
269         if ( isWorldWritable() )
270         {
271             result |= AttributeConstants.OCTAL_WORLD_WRITE;
272         }
273 
274         if ( isWorldExecutable() )
275         {
276             result |= AttributeConstants.OCTAL_WORLD_EXECUTE;
277         }
278 
279         return result;
280     }
281 
282     public String getOctalModeString()
283     {
284         return Integer.toString( getOctalMode(), 8 );
285     }
286 
287     public boolean isSymbolicLink()
288     {
289         return symbolicLink;
290     }
291 }