View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.net.ftp.parser;
19  import java.io.BufferedReader;
20  import java.io.IOException;
21  import java.text.ParseException;
22  import java.util.StringTokenizer;
23  
24  import org.apache.commons.net.ftp.FTPClientConfig;
25  import org.apache.commons.net.ftp.FTPFile;
26  
27  /**
28   * Implementation FTPFileEntryParser and FTPFileListParser for VMS Systems.
29   * This is a sample of VMS LIST output
30   *
31   *  "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
32   *  "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
33   *  "DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
34   * <P><B>
35   * Note: VMSFTPEntryParser can only be instantiated through the
36   * DefaultFTPParserFactory by classname.  It will not be chosen
37   * by the autodetection scheme.
38   * </B>
39   * <P>
40   *
41   * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
42   * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
43   * @author <a href="sestegra@free.fr">Stephane ESTE-GRACIAS</a>
44   * @version $Id: VMSFTPEntryParser.java 1489361 2013-06-04 09:48:36Z sebb $
45   *
46   * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
47   * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
48   */
49  public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
50  {
51  
52      private static final String DEFAULT_DATE_FORMAT
53          = "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24
54  
55      /**
56       * this is the regular expression used by this parser.
57       */
58      private static final String REGEX =
59          "(.*;[0-9]+)\\s*"                                                   //1  file and version
60          + "(\\d+)/\\d+\\s*"                                                 //2  size/allocated
61          +"(\\S+)\\s+(\\S+)\\s+"                                             //3+4 date and time
62          + "\\[(([0-9$A-Za-z_]+)|([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+))\\]?\\s*" //5(6,7,8) owner
63          + "\\([a-zA-Z]*,([a-zA-Z]*),([a-zA-Z]*),([a-zA-Z]*)\\)";            //9,10,11 Permissions (O,G,W)
64      // TODO - perhaps restrict permissions to [RWED]* ?
65  
66  
67  
68      /**
69       * Constructor for a VMSFTPEntryParser object.
70       *
71       * @exception IllegalArgumentException
72       * Thrown if the regular expression is unparseable.  Should not be seen
73       * under normal conditions.  It it is seen, this is a sign that
74       * <code>REGEX</code> is  not a valid regular expression.
75       */
76      public VMSFTPEntryParser()
77      {
78          this(null);
79      }
80  
81      /**
82       * This constructor allows the creation of a VMSFTPEntryParser object with
83       * something other than the default configuration.
84       *
85       * @param config The {@link FTPClientConfig configuration} object used to
86       * configure this parser.
87       * @exception IllegalArgumentException
88       * Thrown if the regular expression is unparseable.  Should not be seen
89       * under normal conditions.  It it is seen, this is a sign that
90       * <code>REGEX</code> is  not a valid regular expression.
91       * @since 1.4
92       */
93      public VMSFTPEntryParser(FTPClientConfig config)
94      {
95          super(REGEX);
96          configure(config);
97      }
98  
99      /**
100      * Parses a line of a VMS FTP server file listing and converts it into a
101      * usable format in the form of an <code> FTPFile </code> instance.  If the
102      * file listing line doesn't describe a file, <code> null </code> is
103      * returned, otherwise a <code> FTPFile </code> instance representing the
104      * files in the directory is returned.
105      * <p>
106      * @param entry A line of text from the file listing
107      * @return An FTPFile instance corresponding to the supplied entry
108      */
109 //    @Override
110     public FTPFile parseFTPEntry(String entry)
111     {
112         //one block in VMS equals 512 bytes
113         long longBlock = 512;
114 
115         if (matches(entry))
116         {
117             FTPFile f = new FTPFile();
118             f.setRawListing(entry);
119             String name = group(1);
120             String size = group(2);
121             String datestr = group(3)+" "+group(4);
122             String owner = group(5);
123             String permissions[] = new String[3];
124             permissions[0]= group(9);
125             permissions[1]= group(10);
126             permissions[2]= group(11);
127             try
128             {
129                 f.setTimestamp(super.parseTimestamp(datestr));
130             }
131             catch (ParseException e)
132             {
133                  // intentionally do nothing
134             }
135 
136 
137             String grp;
138             String user;
139             StringTokenizer t = new StringTokenizer(owner, ",");
140             switch (t.countTokens()) {
141                 case 1:
142                     grp  = null;
143                     user = t.nextToken();
144                     break;
145                 case 2:
146                     grp  = t.nextToken();
147                     user = t.nextToken();
148                     break;
149                 default:
150                     grp  = null;
151                     user = null;
152             }
153 
154             if (name.lastIndexOf(".DIR") != -1)
155             {
156                 f.setType(FTPFile.DIRECTORY_TYPE);
157             }
158             else
159             {
160                 f.setType(FTPFile.FILE_TYPE);
161             }
162             //set FTPFile name
163             //Check also for versions to be returned or not
164             if (isVersioning())
165             {
166                 f.setName(name);
167             }
168             else
169             {
170                 name = name.substring(0, name.lastIndexOf(";"));
171                 f.setName(name);
172             }
173             //size is retreived in blocks and needs to be put in bytes
174             //for us humans and added to the FTPFile array
175             long sizeInBytes = Long.parseLong(size) * longBlock;
176             f.setSize(sizeInBytes);
177 
178             f.setGroup(grp);
179             f.setUser(user);
180             //set group and owner
181 
182             //Set file permission.
183             //VMS has (SYSTEM,OWNER,GROUP,WORLD) users that can contain
184             //R (read) W (write) E (execute) D (delete)
185 
186             //iterate for OWNER GROUP WORLD permissions
187             for (int access = 0; access < 3; access++)
188             {
189                 String permission = permissions[access];
190 
191                 f.setPermission(access, FTPFile.READ_PERMISSION, permission.indexOf('R')>=0);
192                 f.setPermission(access, FTPFile.WRITE_PERMISSION, permission.indexOf('W')>=0);
193                 f.setPermission(access, FTPFile.EXECUTE_PERMISSION, permission.indexOf('E')>=0);
194             }
195 
196             return f;
197         }
198         return null;
199     }
200 
201 
202     /**
203      * Reads the next entry using the supplied BufferedReader object up to
204      * whatever delemits one entry from the next.   This parser cannot use
205      * the default implementation of simply calling BufferedReader.readLine(),
206      * because one entry may span multiple lines.
207      *
208      * @param reader The BufferedReader object from which entries are to be
209      * read.
210      *
211      * @return A string representing the next ftp entry or null if none found.
212      * @exception IOException thrown on any IO Error reading from the reader.
213      */
214     @Override
215     public String readNextEntry(BufferedReader reader) throws IOException
216     {
217         String line = reader.readLine();
218         StringBuilder entry = new StringBuilder();
219         while (line != null)
220         {
221             if (line.startsWith("Directory") || line.startsWith("Total")) {
222                 line = reader.readLine();
223                 continue;
224             }
225 
226             entry.append(line);
227             if (line.trim().endsWith(")"))
228             {
229                 break;
230             }
231             line = reader.readLine();
232         }
233         return (entry.length() == 0 ? null : entry.toString());
234     }
235 
236     protected boolean isVersioning() {
237         return false;
238     }
239 
240     /**
241      * Defines a default configuration to be used when this class is
242      * instantiated without a {@link  FTPClientConfig  FTPClientConfig}
243      * parameter being specified.
244      * @return the default configuration for this parser.
245      */
246     @Override
247     protected FTPClientConfig getDefaultConfiguration() {
248         return new FTPClientConfig(
249                 FTPClientConfig.SYST_VMS,
250                 DEFAULT_DATE_FORMAT,
251                 null, null, null, null);
252     }
253 
254     // DEPRECATED METHODS - for API compatibility only - DO NOT USE
255 
256     /**
257      * DO NOT USE
258      * @deprecated (2.2) No other FTPFileEntryParser implementations have this method.
259      */
260     @Deprecated
261     public FTPFile[] parseFileList(java.io.InputStream listStream) throws IOException {
262         org.apache.commons.net.ftp.FTPListParseEngine engine = new org.apache.commons.net.ftp.FTPListParseEngine(this);
263         engine.readServerList(listStream, null);
264         return engine.getFiles();
265     }
266 
267 }
268 
269 /* Emacs configuration
270  * Local variables:        **
271  * mode:             java  **
272  * c-basic-offset:   4     **
273  * indent-tabs-mode: nil   **
274  * End:                    **
275  */