Coverage report

  %line %branch
org.apache.commons.net.ftp.parser.UnixFTPEntryParser
94% 
100% 

 1  
 /*
 2  
  * Copyright 2001-2005 The Apache Software Foundation
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.apache.commons.net.ftp.parser;
 17  
 import java.text.ParseException;
 18  
 
 19  
 import org.apache.commons.net.ftp.FTPClientConfig;
 20  
 import org.apache.commons.net.ftp.FTPFile;
 21  
 
 22  
 /**
 23  
  * Implementation FTPFileEntryParser and FTPFileListParser for standard
 24  
  * Unix Systems.
 25  
  *
 26  
  * This class is based on the logic of Daniel Savarese's
 27  
  * DefaultFTPListParser, but adapted to use regular expressions and to fit the
 28  
  * new FTPFileEntryParser interface.
 29  
  * @version $Id: UnixFTPEntryParser.java 161712 2005-04-18 02:57:04Z scohen $
 30  
  * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
 31  
  */
 32  
 public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
 33  
 {
 34  
     /**
 35  
      * months abbreviations looked for by this parser.  Also used
 36  
      * to determine which month is matched by the parser
 37  
      */
 38  
     private static final String DEFAULT_MONTHS =
 39  
         "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
 40  
     
 41  
     static final String DEFAULT_DATE_FORMAT 
 42  
 		= "MMM d yyyy"; //Nov 9 2001
 43  
     
 44  
     static final String DEFAULT_RECENT_DATE_FORMAT 
 45  
 		= "MMM d HH:mm"; //Nov 9 20:06
 46  
 
 47  
     static final String NUMERIC_DATE_FORMAT 
 48  
 		= "yyyy-MM-dd HH:mm"; //2001-11-09 20:06
 49  
 
 50  
     /**
 51  
      * Some Linux distributions are now shipping an FTP server which formats
 52  
      * file listing dates in an all-numeric format: 
 53  
      * <code>"yyyy-MM-dd HH:mm</code>.  
 54  
      * This is a very welcome development,  and hopefully it will soon become 
 55  
      * the standard.  However, since it is so new, for now, and possibly 
 56  
      * forever, we merely accomodate it, but do not make it the default.
 57  
      * <p>
 58  
      * For now end users may specify this format only via 
 59  
      * <code>UnixFTPEntryParser(FTPClientConfig)</code>.
 60  
      * Steve Cohen - 2005-04-17
 61  
      */
 62  5
     public static final FTPClientConfig NUMERIC_DATE_CONFIG =
 63  
         new FTPClientConfig(
 64  
                 FTPClientConfig.SYST_UNIX,
 65  
                 NUMERIC_DATE_FORMAT,
 66  
                 null, class="keyword">null, class="keyword">null, class="keyword">null);
 67  
 
 68  
     /**
 69  
      * this is the regular expression used by this parser.
 70  
      *
 71  
      * Permissions:
 72  
      *    r   the file is readable
 73  
      *    w   the file is writable
 74  
      *    x   the file is executable
 75  
      *    -   the indicated permission is not granted
 76  
      *    L   mandatory locking occurs during access (the set-group-ID bit is
 77  
      *        on and the group execution bit is off)
 78  
      *    s   the set-user-ID or set-group-ID bit is on, and the corresponding
 79  
      *        user or group execution bit is also on
 80  
      *    S   undefined bit-state (the set-user-ID bit is on and the user
 81  
      *        execution bit is off)
 82  
      *    t   the 1000 (octal) bit, or sticky bit, is on [see chmod(1)], and
 83  
      *        execution is on
 84  
      *    T   the 1000 bit is turned on, and execution is off (undefined bit-
 85  
      *        state)
 86  
      */
 87  
     private static final String REGEX =
 88  
         "([bcdlfmpSs-])"
 89  
         +"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s+"
 90  
         + "(\\d+)\\s+"
 91  
         + "(\\S+)\\s+"
 92  
         + "(?:(\\S+)\\s+)?"
 93  
         + "(\\d+)\\s+"
 94  
         
 95  
         /*
 96  
           numeric or standard format date
 97  
         */
 98  
         + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S+\\s+\\S+))\\s+"
 99  
 		
 100  
         /* 
 101  
            year (for non-recent standard format) 
 102  
 		   or time (for numeric or recent standard format  
 103  
 		*/
 104  
 		+ "(\\d+(?::\\d+)?)\\s+"
 105  
         
 106  
 		+ "(\\S*)(\\s*.*)";
 107  
 
 108  
 
 109  
     /**
 110  
      * The default constructor for a UnixFTPEntryParser object.
 111  
      *
 112  
      * @exception IllegalArgumentException
 113  
      * Thrown if the regular expression is unparseable.  Should not be seen
 114  
      * under normal conditions.  It it is seen, this is a sign that
 115  
      * <code>REGEX</code> is  not a valid regular expression.
 116  
      */
 117  
     public UnixFTPEntryParser()
 118  
     {
 119  46
         this(null);
 120  46
     }
 121  
 
 122  
     /**
 123  
      * This constructor allows the creation of a UnixFTPEntryParser object with
 124  
      * something other than the default configuration.
 125  
      *
 126  
      * @param config The {@link FTPClientConfig configuration} object used to 
 127  
      * configure this parser.
 128  
      * @exception IllegalArgumentException
 129  
      * Thrown if the regular expression is unparseable.  Should not be seen
 130  
      * under normal conditions.  It it is seen, this is a sign that
 131  
      * <code>REGEX</code> is  not a valid regular expression.
 132  
      * @since 1.4
 133  
      */
 134  
     public UnixFTPEntryParser(FTPClientConfig config)
 135  
     {
 136  47
         super(REGEX);
 137  47
         configure(config);
 138  47
     }
 139  
 
 140  
 
 141  
     /**
 142  
      * Parses a line of a unix (standard) FTP server file listing and converts
 143  
      * it into a usable format in the form of an <code> FTPFile </code>
 144  
      * instance.  If the file listing line doesn't describe a file,
 145  
      * <code> null </code> is returned, otherwise a <code> FTPFile </code>
 146  
      * instance representing the files in the directory is returned.
 147  
      * <p>
 148  
      * @param entry A line of text from the file listing
 149  
      * @return An FTPFile instance corresponding to the supplied entry
 150  
      */
 151  
 	public FTPFile parseFTPEntry(String entry) {
 152  77
         FTPFile file = new FTPFile();
 153  77
         file.setRawListing(entry);
 154  
         int type;
 155  77
         boolean isDevice = false;
 156  
 
 157  77
         if (matches(entry))
 158  
         {
 159  53
             String typeStr = group(1);
 160  53
             String hardLinkCount = group(15);
 161  53
             String usr = group(16);
 162  53
             String grp = group(17);
 163  53
             String filesize = group(18);
 164  53
             String datestr = group(19) + " " + group(20);
 165  53
             String name = group(21);
 166  53
             String endtoken = group(22);
 167  
 
 168  
             try
 169  
             {
 170  53
                 file.setTimestamp(super.parseTimestamp(datestr));
 171  
             }
 172  9
             catch (ParseException e)
 173  
             {
 174  9
             	return null;  // this is a parsing failure too.
 175  44
             }
 176  
             
 177  
             
 178  
             // bcdlfmpSs-
 179  44
             switch (typeStr.charAt(0))
 180  
             {
 181  
             case 'd':
 182  9
                 type = FTPFile.DIRECTORY_TYPE;
 183  9
                 break;
 184  
             case 'l':
 185  4
                 type = FTPFile.SYMBOLIC_LINK_TYPE;
 186  4
                 break;
 187  
             case 'b':
 188  
             case 'c':
 189  2
                 isDevice = true;
 190  
                 // break; - fall through
 191  
             case 'f':
 192  
             case '-':
 193  31
             	type = FTPFile.FILE_TYPE;
 194  31
             	break;
 195  
             default:
 196  0
                 type = FTPFile.UNKNOWN_TYPE;
 197  
             }
 198  
 
 199  44
             file.setType(type);
 200  
 
 201  44
             int g = 4;
 202  176
             for (int access = 0; access < 3; access++, g += 4)
 203  
             {
 204  
                 // Use != '-' to avoid having to check for suid and sticky bits
 205  132
                 file.setPermission(access, FTPFile.READ_PERMISSION,
 206  
                                    (!group(g).equals("-")));
 207  132
                 file.setPermission(access, FTPFile.WRITE_PERMISSION,
 208  
                                    (!group(g + 1).equals("-")));
 209  
 
 210  132
                 String execPerm = group(g + 2);
 211  132
                 if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0)))
 212  
                 {
 213  58
                     file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true);
 214  
                 }
 215  
                 else
 216  
                 {
 217  74
                     file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false);
 218  
                 }
 219  
             }
 220  
 
 221  44
             if (!isDevice)
 222  
             {
 223  
                 try
 224  
                 {
 225  42
                     file.setHardLinkCount(Integer.parseInt(hardLinkCount));
 226  
                 }
 227  0
                 catch (NumberFormatException e)
 228  
                 {
 229  
                     // intentionally do nothing
 230  42
                 }
 231  
             }
 232  
 
 233  44
             file.setUser(usr);
 234  44
             file.setGroup(grp);
 235  
 
 236  
             try
 237  
             {
 238  44
                 file.setSize(Long.parseLong(filesize));
 239  
             }
 240  0
             catch (NumberFormatException e)
 241  
             {
 242  
                 // intentionally do nothing
 243  44
             }
 244  
             
 245  44
             if (null == endtoken)
 246  
             {
 247  0
                 file.setName(name);
 248  
             }
 249  
             else
 250  
             {
 251  
                 // oddball cases like symbolic links, file names
 252  
                 // with spaces in them.
 253  44
                 name += endtoken;
 254  44
                 if (type == FTPFile.SYMBOLIC_LINK_TYPE)
 255  
                 {
 256  
 
 257  4
                     int end = name.indexOf(" -> ");
 258  
                     // Give up if no link indicator is present
 259  4
                     if (end == -1)
 260  
                     {
 261  2
                         file.setName(name);
 262  
                     }
 263  
                     else
 264  
                     {
 265  2
                         file.setName(name.substring(0, end));
 266  2
                         file.setLink(name.substring(end + 4));
 267  
                     }
 268  
 
 269  
                 }
 270  
                 else
 271  
                 {
 272  40
                     file.setName(name);
 273  
                 }
 274  
             }
 275  44
             return file;
 276  
         }
 277  24
         return null;
 278  
 	}
 279  
 
 280  
     /**
 281  
      * Defines a default configuration to be used when this class is
 282  
      * instantiated without a {@link  FTPClientConfig  FTPClientConfig}
 283  
      * parameter being specified.
 284  
      * @return the default configuration for this parser.
 285  
      */
 286  
     protected FTPClientConfig getDefaultConfiguration() {
 287  54
         return new FTPClientConfig(
 288  
                 FTPClientConfig.SYST_UNIX,
 289  
                 DEFAULT_DATE_FORMAT,
 290  
                 DEFAULT_RECENT_DATE_FORMAT,
 291  
                 null, class="keyword">null, class="keyword">null);
 292  
     }
 293  
     
 294  
     
 295  
     
 296  
 
 297  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.