    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            return sb.toString();
    409        }
    410
    411        private char formatType(){
    412            switch(_type) {
    413                case FILE_TYPE:
    414                    return '-';
    415                case DIRECTORY_TYPE:
    416                    return 'd';
    417                case SYMBOLIC_LINK_TYPE:
    418                    return 'l';
    419            }
    420            return '?';
    421        }
    422
    423        private String permissionToString(int access ){
    424            StringBuilder sb = new StringBuilder();
    425            if (hasPermission(access, READ_PERMISSION)) {
    426                sb.append('r');
    427            } else {
    428                sb.append('-');
    429            }
    430            if (hasPermission(access, WRITE_PERMISSION)) {
    431                sb.append('w');
    432            } else {
    433                sb.append('-');
    434            }
    435            if (hasPermission(access, EXECUTE_PERMISSION)) {
    436                sb.append('x');
    437            } else {
    438                sb.append('-');
    439            }
    440            return sb.toString();
    441        }
    442    }