001: /**
002: *
003: * edtFTPj
004: *
005: * Copyright (C) 2000-2004 Enterprise Distributed Technologies Ltd
006: *
007: * www.enterprisedt.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: *
023: * Bug fixes, suggestions and comments should be should posted on
024: * http://www.enterprisedt.com/forums/index.php
025: *
026: * Change Log:
027: *
028: * $Log: MLSXEntryParser.java,v $
029: * Revision 1.1 2007/01/15 23:02:50 bruceb
030: * Parses MLST and MLSD entries
031: *
032: * Revision 1.14 2006/10/11 08:57:40 hans
033: * Removed usage of deprecated FTPFile constructor and made cvsId final
034: *
035: * Revision 1.13 2006/05/23 04:10:17 bruceb
036: * support Unix listing starting with 'p'
037: *
038: * Revision 1.12 2005/06/03 11:26:25 bruceb
039: * comment change
040: *
041: * Revision 1.11 2005/04/01 13:57:15 bruceb
042: * minor tweak re groups
043: *
044: * Revision 1.10 2004/10/19 16:15:49 bruceb
045: * minor restructuring
046: *
047: * Revision 1.9 2004/10/18 15:58:15 bruceb
048: * setLocale
049: *
050: * Revision 1.8 2004/09/20 21:36:13 bruceb
051: * tweak to skip invalid lines
052: *
053: * Revision 1.7 2004/09/17 14:56:54 bruceb
054: * parse fixes including wrong year
055: *
056: * Revision 1.6 2004/07/23 08:32:36 bruceb
057: * made cvsId public
058: *
059: * Revision 1.5 2004/06/11 10:19:59 bruceb
060: * fixed bug re filename same as user
061: *
062: * Revision 1.4 2004/05/20 19:47:00 bruceb
063: * blanks in names fix
064: *
065: * Revision 1.3 2004/05/05 20:27:41 bruceb
066: * US locale for date formats
067: *
068: * Revision 1.2 2004/05/01 11:44:21 bruceb
069: * modified for server returning "total 3943" as first line
070: *
071: * Revision 1.1 2004/04/17 23:42:07 bruceb
072: * file parsing part II
073: *
074: * Revision 1.1 2004/04/17 18:37:23 bruceb
075: * new parse functionality
076: *
077: */package com.enterprisedt.net.ftp;
078:
079: import java.text.ParseException;
080: import java.text.SimpleDateFormat;
081: import java.util.Date;
082: import java.util.Locale;
083: import java.util.TimeZone;
084:
085: /**
086: * Parses the string returned from the MLSD or MLST command
087: * (defined in the "Extensions to FTP" IETF draft). Just grabs
088: * the basic fields, as most servers don't support anything else.
089: *
090: * @author Bruce Blackshaw
091: * @version $Revision: 1.1 $
092: */
093: public class MLSXEntryParser extends FTPFileParser {
094:
095: /**
096: * Revision control id
097: */
098: final public static String cvsId = "@(#)$Id: MLSXEntryParser.java,v 1.1 2007/01/15 23:02:50 bruceb Exp $";
099:
100: /**
101: * Fields that are possible
102: */
103: final private static String SIZE = "Size";
104:
105: final private static String MODIFY = "Modify";
106:
107: final private static String CREATE = "Create";
108:
109: final private static String TYPE = "Type";
110:
111: final private static String UNIQUE = "Unique";
112:
113: final private static String PERM = "Perm";
114:
115: final private static String LANG = "Lang";
116:
117: final private static String MEDIA_TYPE = "Media-Type";
118:
119: final private static String CHARSET = "CharSet";
120:
121: /**
122: * File type constants
123: */
124: final private static String FILE_TYPE = "file"; // a file entry
125: final private static String LISTED_DIR_TYPE = "cdir"; // the listed directory
126: final private static String PARENT_DIR_TYPE = "pdir"; // a parent directory
127: final private static String SUB_DIR_TYPE = "dir"; // a directory or sub-directory
128:
129: /**
130: * Format to interpret MTDM timestamp
131: */
132: private SimpleDateFormat tsFormat1 = new SimpleDateFormat(
133: "yyyyMMddHHmmss");
134:
135: /**
136: * Format to interpret MTDM timestamp
137: */
138: private SimpleDateFormat tsFormat2 = new SimpleDateFormat(
139: "yyyyMMddHHmmss.SSS");
140:
141: /**
142: * Instance initializer. Sets formatters to GMT.
143: */
144: {
145: tsFormat1.setTimeZone(TimeZone.getTimeZone("GMT"));
146: tsFormat2.setTimeZone(TimeZone.getTimeZone("GMT"));
147: }
148:
149: /**
150: * Parse server supplied string that is returned from MLST/D
151: *
152: * @param raw raw string to parse
153: */
154: public FTPFile parse(String raw) throws ParseException {
155: String[] fields = split(raw, ';');
156: String path = null;
157: FTPFile ftpFile = new FTPFile(raw);
158: for (int i = 0; i < fields.length; i++) {
159: String field = fields[i];
160: if (i + 1 == fields.length) {
161: path = field.trim(); // last field is the path
162: ftpFile.setPath(path);
163: String name = path;
164: int pos = name.lastIndexOf('/');
165: if (pos >= 0)
166: name = name.substring(pos);
167: ftpFile.setName(name);
168: } else {
169: int pos = field.indexOf('=');
170: if (pos > 0) {
171: String name = field.substring(0, pos);
172: String value = field.substring(++pos);
173: if (name.equalsIgnoreCase(SIZE)) {
174: ftpFile.setSize(parseSize(value));
175: } else if (name.equalsIgnoreCase(MODIFY)) {
176: ftpFile.setLastModified(parseDate(value));
177: } else if (name.equalsIgnoreCase(TYPE)) {
178: if (value.equalsIgnoreCase(FILE_TYPE))
179: ftpFile.setDir(false);
180: else
181: // assume a dir if not a file for the moment
182: ftpFile.setDir(true);
183: } else if (name.equalsIgnoreCase(PERM)) {
184: ftpFile.setPermissions(value);
185: } else if (name.equalsIgnoreCase(CREATE)) {
186: ftpFile.setCreated(parseDate(value));
187: }
188: }
189: }
190: }
191: return ftpFile;
192: }
193:
194: /**
195: * Parse the size string
196: *
197: * @param value string containing size value
198: * @return
199: * @throws ParseException
200: */
201: private long parseSize(String value) throws ParseException {
202: try {
203: return Long.parseLong(value);
204: } catch (NumberFormatException ex) {
205: throw new ParseException("Failed to parse size: " + value,
206: 0);
207: }
208: }
209:
210: /**
211: * Parse the date string. In format YYYYMMDDHHMMSS.sss
212: *
213: * @param value string to parse
214: * @return Date from string
215: * @throws ParseException
216: */
217: private Date parseDate(String value) throws ParseException {
218: try {
219: return tsFormat1.parse(value);
220: } catch (ParseException ex) {
221: return tsFormat2.parse(value);
222: }
223: }
224:
225: /**
226: * Set the locale for date parsing of listings. As
227: * the timestamps follow a standard without names of months,
228: * this is not used in this parser.
229: *
230: * @param locale locale to set
231: */
232: public void setLocale(Locale locale) {
233: // not required
234: }
235: }
|