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.parser;
019    
020    import java.text.ParseException;
021    
022    import org.apache.commons.net.ftp.FTPClientConfig;
023    import org.apache.commons.net.ftp.FTPFile;
024    
025    /**
026     * Implementation of FTPFileEntryParser and FTPFileListParser for Netware Systems. Note that some of the proprietary
027     * extensions for Novell-specific operations are not supported. See
028     * <a href="http://www.novell.com/documentation/nw65/index.html?page=/documentation/nw65/ftp_enu/data/fbhbgcfa.html">http://www.novell.com/documentation/nw65/index.html?page=/documentation/nw65/ftp_enu/data/fbhbgcfa.html</a>
029     * for more details.
030     *
031     * @author <a href="rwinston@apache.org">Rory Winston</a>
032     * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
033     * @version $Id: NetwareFTPEntryParser.java 1299238 2012-03-10 17:12:28Z sebb $
034     * @since 1.5
035     */
036    public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
037    
038        /**
039         * Default date format is e.g. Feb 22 2006
040         */
041        private static final String DEFAULT_DATE_FORMAT = "MMM dd yyyy";
042    
043        /**
044         * Default recent date format is e.g. Feb 22 17:32
045         */
046        private static final String DEFAULT_RECENT_DATE_FORMAT = "MMM dd HH:mm";
047    
048        /**
049         * this is the regular expression used by this parser.
050         * Example: d [-W---F--] SCION_VOL2                        512 Apr 13 23:12 VOL2
051         */
052        private static final String REGEX = "(d|-){1}\\s+"      // Directory/file flag
053                + "\\[(.*)\\]\\s+"                              // Attributes
054                + "(\\S+)\\s+" + "(\\d+)\\s+"                   // Owner and size
055                + "(\\S+\\s+\\S+\\s+((\\d+:\\d+)|(\\d{4})))"    // Long/short date format
056                + "\\s+(.*)";                                   // Filename (incl. spaces)
057    
058        /**
059         * The default constructor for a NetwareFTPEntryParser object.
060         *
061         * @exception IllegalArgumentException
062         * Thrown if the regular expression is unparseable.  Should not be seen
063         * under normal conditions.  It it is seen, this is a sign that
064         * <code>REGEX</code> is  not a valid regular expression.
065         */
066        public NetwareFTPEntryParser() {
067            this(null);
068        }
069    
070        /**
071         * This constructor allows the creation of an NetwareFTPEntryParser object
072         * with something other than the default configuration.
073         *
074         * @param config The {@link FTPClientConfig configuration} object used to
075         * configure this parser.
076         * @exception IllegalArgumentException
077         * Thrown if the regular expression is unparseable.  Should not be seen
078         * under normal conditions.  It it is seen, this is a sign that
079         * <code>REGEX</code> is  not a valid regular expression.
080         * @since 1.4
081         */
082        public NetwareFTPEntryParser(FTPClientConfig config) {
083            super(REGEX);
084            configure(config);
085        }
086    
087        /**
088         * Parses a line of an NetwareFTP server file listing and converts it into a
089         * usable format in the form of an <code> FTPFile </code> instance.  If the
090         * file listing line doesn't describe a file, <code> null </code> is
091         * returned, otherwise a <code> FTPFile </code> instance representing the
092         * files in the directory is returned.
093         * <p>
094         * <p>
095         * Netware file permissions are in the following format:  RWCEAFMS, and are explained as follows:
096         * <ul>
097         * <li><b>S</b> - Supervisor; All rights.
098         * <li><b>R</b> - Read; Right to open and read or execute.
099         * <li><b>W</b> - Write; Right to open and modify.
100         * <li><b>C</b> - Create; Right to create; when assigned to a file, allows a deleted file to be recovered.
101         * <li><b>E</b> - Erase; Right to delete.
102         * <li><b>M</b> - Modify; Right to rename a file and to change attributes.
103         * <li><b>F</b> - File Scan; Right to see directory or file listings.
104         * <li><b>A</b> - Access Control; Right to modify trustee assignments and the Inherited Rights Mask.
105         * </ul>
106         *
107         * See <a href="http://www.novell.com/documentation/nfap10/index.html?page=/documentation/nfap10/nfaubook/data/abxraws.html">here</a>
108         * for more details
109         *
110         * @param entry A line of text from the file listing
111         * @return An FTPFile instance corresponding to the supplied entry
112         */
113        public FTPFile parseFTPEntry(String entry) {
114    
115            FTPFile f = new FTPFile();
116            if (matches(entry)) {
117                String dirString = group(1);
118                String attrib = group(2);
119                String user = group(3);
120                String size = group(4);
121                String datestr = group(5);
122                String name = group(9);
123    
124                try {
125                    f.setTimestamp(super.parseTimestamp(datestr));
126                } catch (ParseException e) {
127                     // intentionally do nothing
128                }
129    
130                //is it a DIR or a file
131                if (dirString.trim().equals("d")) {
132                    f.setType(FTPFile.DIRECTORY_TYPE);
133                } else // Should be "-"
134                {
135                    f.setType(FTPFile.FILE_TYPE);
136                }
137    
138                f.setUser(user);
139    
140                //set the name
141                f.setName(name.trim());
142    
143                //set the size
144                f.setSize(Long.parseLong(size.trim()));
145    
146                // Now set the permissions (or at least a subset thereof - full permissions would probably require
147                // subclassing FTPFile and adding extra metainformation there)
148                if (attrib.indexOf("R") != -1) {
149                    f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION,
150                            true);
151                }
152                if (attrib.indexOf("W") != -1) {
153                    f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION,
154                            true);
155                }
156    
157                return (f);
158            }
159            return null;
160    
161        }
162    
163        /**
164         * Defines a default configuration to be used when this class is
165         * instantiated without a {@link  FTPClientConfig  FTPClientConfig}
166         * parameter being specified.
167         * @return the default configuration for this parser.
168         */
169        @Override
170        protected FTPClientConfig getDefaultConfiguration() {
171            return new FTPClientConfig(FTPClientConfig.SYST_NETWARE,
172                    DEFAULT_DATE_FORMAT, DEFAULT_RECENT_DATE_FORMAT, null, null,
173                    null);
174        }
175    
176    }