001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.net.ftp;
019    import java.io.Serializable;
020    import java.util.Calendar;
021    import java.util.Formatter;
022    
023    /***
024     * The FTPFile class is used to represent information about files stored
025     * on an FTP server.
026     * <p>
027     * <p>
028     * @see FTPFileEntryParser
029     * @see FTPClient#listFiles
030     ***/
031    
032    public class FTPFile implements Serializable
033    {
034        private static final long serialVersionUID = 9010790363003271996L;
035    
036        /** A constant indicating an FTPFile is a file. ***/
037        public static final int FILE_TYPE = 0;
038        /** A constant indicating an FTPFile is a directory. ***/
039        public static final int DIRECTORY_TYPE = 1;
040        /** A constant indicating an FTPFile is a symbolic link. ***/
041        public static final int SYMBOLIC_LINK_TYPE = 2;
042        /** A constant indicating an FTPFile is of unknown type. ***/
043        public static final int UNKNOWN_TYPE = 3;
044    
045        /** A constant indicating user access permissions. ***/
046        public static final int USER_ACCESS = 0;
047        /** A constant indicating group access permissions. ***/
048        public static final int GROUP_ACCESS = 1;
049        /** A constant indicating world access permissions. ***/
050        public static final int WORLD_ACCESS = 2;
051    
052        /** A constant indicating file/directory read permission. ***/
053        public static final int READ_PERMISSION = 0;
054        /** A constant indicating file/directory write permission. ***/
055        public static final int WRITE_PERMISSION = 1;
056        /**
057         * A constant indicating file execute permission or directory listing
058         * permission.
059         ***/
060        public static final int EXECUTE_PERMISSION = 2;
061    
062        private int _type, _hardLinkCount;
063        private long _size;
064        private String _rawListing, _user, _group, _name, _link;
065        private Calendar _date;
066        private boolean[] _permissions[]; // e.g. _permissions[USER_ACCESS][READ_PERMISSION]
067    
068        /*** Creates an empty FTPFile. ***/
069        public FTPFile()
070        {
071            _permissions = new boolean[3][3];
072            _rawListing = null;
073            _type = UNKNOWN_TYPE;
074            // init these to values that do not occur in listings
075            // so can distinguish which fields are unset
076            _hardLinkCount = 0; // 0 is invalid as a link count
077            _size = -1; // 0 is valid, so use -1
078            _user = "";
079            _group = "";
080            _date = null;
081            _name = null;
082        }
083    
084    
085        /***
086         * Set the original FTP server raw listing from which the FTPFile was
087         * created.
088         * <p>
089         * @param rawListing  The raw FTP server listing.
090         ***/
091        public void setRawListing(String rawListing)
092        {
093            _rawListing = rawListing;
094        }
095    
096        /***
097         * Get the original FTP server raw listing used to initialize the FTPFile.
098         * <p>
099         * @return The original FTP server raw listing used to initialize the
100         *         FTPFile.
101         ***/
102        public String getRawListing()
103        {
104            return _rawListing;
105        }
106    
107    
108        /***
109         * Determine if the file is a directory.
110         * <p>
111         * @return True if the file is of type <code>DIRECTORY_TYPE</code>, false if
112         *         not.
113         ***/
114        public boolean isDirectory()
115        {
116            return (_type == DIRECTORY_TYPE);
117        }
118    
119        /***
120         * Determine if the file is a regular file.
121         * <p>
122         * @return True if the file is of type <code>FILE_TYPE</code>, false if
123         *         not.
124         ***/
125        public boolean isFile()
126        {
127            return (_type == FILE_TYPE);
128        }
129    
130        /***
131         * Determine if the file is a symbolic link.
132         * <p>
133         * @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
134         *         not.
135         ***/
136        public boolean isSymbolicLink()
137        {
138            return (_type == SYMBOLIC_LINK_TYPE);
139        }
140    
141        /***
142         * Determine if the type of the file is unknown.
143         * <p>
144         * @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
145         *         not.
146         ***/
147        public boolean isUnknown()
148        {
149            return (_type == UNKNOWN_TYPE);
150        }
151    
152    
153        /***
154         * Set the type of the file (<code>DIRECTORY_TYPE</code>,
155         * <code>FILE_TYPE</code>, etc.).
156         * <p>
157         * @param type  The integer code representing the type of the file.
158         ***/
159        public void setType(int type)
160        {
161            _type = type;
162        }
163    
164    
165        /***
166         * Return the type of the file (one of the <code>_TYPE</code> constants),
167         * e.g., if it is a directory, a regular file, or a symbolic link.
168         * <p>
169         * @return The type of the file.
170         ***/
171        public int getType()
172        {
173            return _type;
174        }
175    
176    
177        /***
178         * Set the name of the file.
179         * <p>
180         * @param name  The name of the file.
181         ***/
182        public void setName(String name)
183        {
184            _name = name;
185        }
186    
187        /***
188         * Return the name of the file.
189         * <p>
190         * @return The name of the file.
191         ***/
192        public String getName()
193        {
194            return _name;
195        }
196    
197    
198        /**
199         * Set the file size in bytes.
200         * @param size The file size in bytes.
201         */
202        public void setSize(long size)
203        {
204            _size = size;
205        }
206    
207    
208        /***
209         * Return the file size in bytes.
210         * <p>
211         * @return The file size in bytes.
212         ***/
213        public long getSize()
214        {
215            return _size;
216        }
217    
218    
219        /***
220         * Set the number of hard links to this file.  This is not to be
221         * confused with symbolic links.
222         * <p>
223         * @param links  The number of hard links to this file.
224         ***/
225        public void setHardLinkCount(int links)
226        {
227            _hardLinkCount = links;
228        }
229    
230    
231        /***
232         * Return the number of hard links to this file.  This is not to be
233         * confused with symbolic links.
234         * <p>
235         * @return The number of hard links to this file.
236         ***/
237        public int getHardLinkCount()
238        {
239            return _hardLinkCount;
240        }
241    
242    
243        /***
244         * Set the name of the group owning the file.  This may be
245         * a string representation of the group number.
246         * <p>
247         * @param group The name of the group owning the file.
248         ***/
249        public void setGroup(String group)
250        {
251            _group = group;
252        }
253    
254    
255        /***
256         * Returns the name of the group owning the file.  Sometimes this will be
257         * a string representation of the group number.
258         * <p>
259         * @return The name of the group owning the file.
260         ***/
261        public String getGroup()
262        {
263            return _group;
264        }
265    
266    
267        /***
268         * Set the name of the user owning the file.  This may be
269         * a string representation of the user number;
270         * <p>
271         * @param user The name of the user owning the file.
272         ***/
273        public void setUser(String user)
274        {
275            _user = user;
276        }
277    
278        /***
279         * Returns the name of the user owning the file.  Sometimes this will be
280         * a string representation of the user number.
281         * <p>
282         * @return The name of the user owning the file.
283         ***/
284        public String getUser()
285        {
286            return _user;
287        }
288    
289    
290        /***
291         * If the FTPFile is a symbolic link, use this method to set the name of the
292         * file being pointed to by the symbolic link.
293         * <p>
294         * @param link  The file pointed to by the symbolic link.
295         ***/
296        public void setLink(String link)
297        {
298            _link = link;
299        }
300    
301    
302        /***
303         * If the FTPFile is a symbolic link, this method returns the name of the
304         * file being pointed to by the symbolic link.  Otherwise it returns null.
305         * <p>
306         * @return The file pointed to by the symbolic link (null if the FTPFile
307         *         is not a symbolic link).
308         ***/
309        public String getLink()
310        {
311            return _link;
312        }
313    
314    
315        /***
316         * Set the file timestamp.  This usually the last modification time.
317         * The parameter is not cloned, so do not alter its value after calling
318         * this method.
319         * <p>
320         * @param date A Calendar instance representing the file timestamp.
321         ***/
322        public void setTimestamp(Calendar date)
323        {
324            _date = date;
325        }
326    
327    
328        /***
329         * Returns the file timestamp.  This usually the last modification time.
330         * <p>
331         * @return A Calendar instance representing the file timestamp.
332         ***/
333        public Calendar getTimestamp()
334        {
335            return _date;
336        }
337    
338    
339        /***
340         * Set if the given access group (one of the <code> _ACCESS </code>
341         * constants) has the given access permission (one of the
342         * <code> _PERMISSION </code> constants) to the file.
343         * <p>
344         * @param access The access group (one of the <code> _ACCESS </code>
345         *               constants)
346         * @param permission The access permission (one of the
347         *               <code> _PERMISSION </code> constants)
348         * @param value  True if permission is allowed, false if not.
349         ***/
350        public void setPermission(int access, int permission, boolean value)
351        {
352            _permissions[access][permission] = value;
353        }
354    
355    
356        /***
357         * Determines if the given access group (one of the <code> _ACCESS </code>
358         * constants) has the given access permission (one of the
359         * <code> _PERMISSION </code> constants) to the file.
360         * <p>
361         * @param access The access group (one of the <code> _ACCESS </code>
362         *               constants)
363         * @param permission The access permission (one of the
364         *               <code> _PERMISSION </code> constants)
365         ***/
366        public boolean hasPermission(int access, int permission)
367        {
368            return _permissions[access][permission];
369        }
370    
371        /***
372         * Returns a string representation of the FTPFile information.
373         *
374         * @return A string representation of the FTPFile information.
375         */
376        @Override
377        public String toString()
378        {
379            return getRawListing();
380        }
381    
382        /***
383         * Returns a string representation of the FTPFile information.
384         * This currently mimics the Unix listing format.
385         *
386         * @return A string representation of the FTPFile information.
387         * @since 3.0
388         */
389        public String toFormattedString()
390        {
391            StringBuilder sb = new StringBuilder();
392            Formatter fmt = new Formatter(sb);
393            sb.append(formatType());
394            sb.append(permissionToString(USER_ACCESS));
395            sb.append(permissionToString(GROUP_ACCESS));
396            sb.append(permissionToString(WORLD_ACCESS));
397            fmt.format(" %4d", Integer.valueOf(getHardLinkCount()));
398            fmt.format(" %-8s %-8s", getGroup(), getUser());
399            fmt.format(" %8d", Long.valueOf(getSize()));
400            Calendar timestamp = getTimestamp();
401            if (timestamp != null) {
402                fmt.format(" %1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", timestamp);
403                fmt.format(" %1$tZ", timestamp);
404                sb.append(' ');
405            }
406            sb.append(' ');
407            sb.append(getName());
408            fmt.close();
409            return sb.toString();
410        }
411    
412        private char formatType(){
413            switch(_type) {
414                case FILE_TYPE:
415                    return '-';
416                case DIRECTORY_TYPE:
417                    return 'd';
418                case SYMBOLIC_LINK_TYPE:
419                    return 'l';
420            }
421            return '?';
422        }
423    
424        private String permissionToString(int access ){
425            StringBuilder sb = new StringBuilder();
426            if (hasPermission(access, READ_PERMISSION)) {
427                sb.append('r');
428            } else {
429                sb.append('-');
430            }
431            if (hasPermission(access, WRITE_PERMISSION)) {
432                sb.append('w');
433            } else {
434                sb.append('-');
435            }
436            if (hasPermission(access, EXECUTE_PERMISSION)) {
437                sb.append('x');
438            } else {
439                sb.append('-');
440            }
441            return sb.toString();
442        }
443    }