scohen 2003/03/02 10:18:24 Added: net/src/java/org/apache/commons/net/ftp/parser EnterpriseUnixFTPEntryParser.java NTFTPEntryParser.java OS2FTPEntryParser.java UnixFTPEntryParser.java VMSFTPEntryParser.java Log: new FTPFileEntryParsers, formerly in ftp2 Revision Changes Path 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java Index: EnterpriseUnixFTPEntryParser.java =================================================================== package org.apache.commons.net.ftp.parser; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ import java.util.Calendar; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFileListParserImpl; /** * Parser for the Connect Enterprise Unix FTP Server From Sterling Commerce. * @version $Id: EnterpriseUnixFTPEntryParser.java,v 1.1 2003/03/02 18:18:24 scohen Exp $ * @author <a href="[EMAIL PROTECTED]">Winston Ojeda</a> */ public class EnterpriseUnixFTPEntryParser extends FTPFileListParserImpl { // sample output line //"-C--E-----FTP B QUA1I1 18128 41 Aug 12 13:56 QUADTEST" private static final String MONTHS = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"; private static final String REGEX = "(([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z]))" + "(\\S*)\\s*" + "(\\S+)\\s*" + "(\\S*)\\s*" + "(\\d*)\\s*" + "(\\d*)\\s*" + MONTHS + "\\s*" + "((?:[012]\\d*)|(?:3[01]))\\s*" + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s" + "(\\S*)(\\s*.*)"; /** * The sole constructor for a EnterpriseUnixFTPEntryParser object. * */ public EnterpriseUnixFTPEntryParser() { super(REGEX); } /** * Parses a line of a unix FTP server file listing and converts it into a * usable format in the form of an <code> FTPFile </code> instance. If * the file listing line doesn't describe a file, <code> null </code> is * returned, otherwise a <code> FTPFile </code> instance representing the * files in the directory is returned. * * @param entry A line of text from the file listing * @return An FTPFile instance corresponding to the supplied entry */ public FTPFile parseFTPEntry(String entry) { FTPFile file = new FTPFile(); file.setRawListing(entry); int type; boolean isDevice = false; if (matches(entry)) { String usr = group(14); String grp = group(15); String filesize = group(16); String mo = group(17); String da = group(18); String yr = group(20); String hr = group(21); String min = group(22); String name = group(23); file.setType(FTPFile.FILE_TYPE); file.setUser(usr); file.setGroup(grp); try { file.setSize(Integer.parseInt(filesize)); } catch (NumberFormatException e) { // intentionally do nothing } Calendar cal = Calendar.getInstance(); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.HOUR_OF_DAY, 0); try { int pos = MONTHS.indexOf(mo); int month = pos / 4; if (yr != null) { // it's a year cal.set(Calendar.YEAR, Integer.parseInt(yr)); } else { // it must be hour/minute or we wouldn't have matched int year = cal.get(Calendar.YEAR); // if the month we're reading is greater than now, it must // be last year if (cal.get(Calendar.MONTH) < month) { year--; } cal.set(Calendar.YEAR, year); cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hr)); cal.set(Calendar.MINUTE, Integer.parseInt(min)); } cal.set(Calendar.MONTH, month); cal.set(Calendar.DATE, Integer.parseInt(da)); file.setTimestamp(cal); } catch (NumberFormatException e) { // do nothing, date will be uninitialized } file.setName(name); return file; } return null; } } 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java Index: NTFTPEntryParser.java =================================================================== package org.apache.commons.net.ftp.parser; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ import java.util.Calendar; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFileListParserImpl; /** * This Class uses the ListParser class to validate the input string. * It also requires the NetComponents library version 1.3.7 or later * and the OROMatcher library for the regualar expressions stuff. * * * <P><B>USAGE:</B></P> * <LI>Create an instance of NTListParser</LI> * <dd>NTListParser parser = new NTListParser(); * <LI>Create an instance of FTPClient</LI> * <dd>FTPClient FTPClientObj = new FTPClient(); * <LI>Connect to the NODE </LI> * <dd>FTPClientObj.connect(); * <LI>Login to the NODE </LI> * <dd>FTPClientObj.login(username,password); * <LI>Switch directories if you have to</LI> * <dd>FTPClientObj.changeWorkingDirectory(thePath); * <LI>You might want to check if you are truly in a NT System</LI> * <dd><B>String am_I_NT = FTPClientObj.getSystemName()</B> * <dd>parse am_I_NT to find out * <LI>Call listFiles passing the newly created parser and a filename or a * mask to look for </LI> * <dd>FTPClientObj.listFiles(parser,filename); * <LI>You'll get back the list as an array of FTPFiles like this * <dd>FTPFile[] myNTFiles = FTPClientObj.listFiles(parser,filename); (or) * <dd>FTPFile[] myNTFiles = FTPClientObj.listFiles(parser); * <P> * That's all there is to it. * <P> * Each FTPFile object is populated just like any other FTPFile * object. The only thing not implemented at this time is the file * permissions, but I can do it if there is a real need for it. * <P> * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are in * the directory that you need to be. This parser will return the filtered * files from the directory it is in. This becomes crucial specialy if your * goal is to delete the output of the parser. * <P> * * @author <a href="[EMAIL PROTECTED]">Winston Ojeda</a> * @author <a href="mailto:[EMAIL PROTECTED]">Steve Cohen</a> * @version $Id: NTFTPEntryParser.java,v 1.1 2003/03/02 18:18:24 scohen Exp $ * @see org.apache.commons.net.ftp.FTPFileListParser */ public class NTFTPEntryParser extends FTPFileListParserImpl { private static final String REGEX = "((?:0[1-9])|(?:1[0-2]))-" + "((?:0[1-9])|(?:[1-2]\\d)|(?:3[0-1]))-" + "(\\d\\d)\\s*" + "((?:0[1-9])|(?:1[012])):" + "([0-5]\\d)\\s*" + "([AP])M\\s*" + "(<DIR>)?\\s*" + "([0-9]+)?\\s*" + "(\\S.*)"; /** * The sole constructor for an NTFTPEntryParser object. * * @exception IllegalArgumentException * Thrown if the regular expression is unparseable. Should not be seen * under normal conditions. It it is seen, this is a sign that * <code>REGEX</code> is not a valid regular expression. */ public NTFTPEntryParser() { super(REGEX); } /** * Parses a line of an NT FTP server file listing and converts it into a * usable format in the form of an <code> FTPFile </code> instance. If the * file listing line doesn't describe a file, <code> null </code> is * returned, otherwise a <code> FTPFile </code> instance representing the * files in the directory is returned. * <p> * @param entry A line of text from the file listing * @return An FTPFile instance corresponding to the supplied entry */ public FTPFile parseFTPEntry(String entry) { FTPFile f = new FTPFile(); f.setRawListing(entry); int type; boolean isDevice = false; if (matches(entry)) { String mo = group(1); String da = group(2); String yr = group(3); String hr = group(4); String min = group(5); String ampm = group(6); String dirString = group(7); String size = group(8); String name = group(9); if (null == name || name.equals(".") || name.equals("..")) { return (null); } f.setName(name); //convert all the calendar stuff to ints int month = new Integer(mo).intValue() - 1; int day = new Integer(da).intValue(); int year = new Integer(yr).intValue() + 2000; int hour = new Integer(hr).intValue(); int minutes = new Integer(min).intValue(); // Y2K stuff? this will break again in 2080 but I will // be sooooo dead anyways who cares. // SMC - IS NT's directory date REALLY still not Y2K-compliant? if (year > 2080) { year -= 100; } Calendar cal = Calendar.getInstance(); //set the calendar cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, minutes); cal.set(Calendar.HOUR, hour); cal.set(Calendar.YEAR, year); cal.set(Calendar.DATE, day); cal.set(Calendar.MONTH, month); int ap = Calendar.AM; if ("P".equals(ampm)) { ap = Calendar.PM; } cal.set(Calendar.AM_PM, ap); f.setTimestamp(cal); if ("<DIR>".equals(dirString)) { f.setType(FTPFile.DIRECTORY_TYPE); f.setSize(0); } else { f.setType(FTPFile.FILE_TYPE); if (null != size) { f.setSize(new Integer(size).intValue()); } } return (f); } return null; } } 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java Index: OS2FTPEntryParser.java =================================================================== package org.apache.commons.net.ftp.parser; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ import java.util.Calendar; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFileListParserImpl; /** * This Class uses the ListParser class to validate the input string. * It also requires the NetComponents library version 1.3.7 or later * and the OROMatcher library for the regualar expressions stuff. * * * <P><B>USAGE:</B></P> * <LI>Create an instance of OS2FTPEntryParser</LI> * <dd>OS2FTPEntryParser parser = new OS2FTPEntryParser(); * <LI>Create an instance of FTPClient</LI> * <dd>FTPClient FTPClientObj = new FTPClient(); * <LI>Connect to the NODE </LI> * <dd>FTPClientObj.connect(); * <LI>Login to the NODE </LI> * <dd>FTPClientObj.login(username,password); * <LI>Switch directories if you have to</LI> * <dd>FTPClientObj.changeWorkingDirectory(thePath); * <LI>You might want to check if you are truly in a OS2 System</LI> * <dd><B>String am_I_OS2 = FTPClientObj.getSystemName()</B> * <dd>parse am_I_OS2 to find out * <LI>Call listFiles passing the newly created parser and a filename or a mask * to look for </LI> * <dd>FTPClientObj.listFiles(parser,filename); * <LI>You'll get back the list as an array of FTPFiles like this * <dd>FTPFile[] myOS2Files = FTPClientObj.listFiles(parser,filename); (or) * <dd>FTPFile[] myOS2Files = FTPClientObj.listFiles(parser); * <P> * That's all there is to it. * <P> * Each FTPFile object is populated just like any other FTPFile * object. The only thing not implemented at this time is the file * permissions, but I can do it if there is a real need for it. * <P> * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are * in the directory that you need to be. This parser will return the filtered * files from the directory it is in. This becomes specially crucial if your * goal is to delete the output of the parser. * <P> * @author <a href="[EMAIL PROTECTED]">Winston Ojeda</a> * @author <a href="mailto:[EMAIL PROTECTED]">Steve Cohen</a> * @version $Id: OS2FTPEntryParser.java,v 1.1 2003/03/02 18:18:24 scohen Exp $ * @see org.apache.commons.net.ftp.FTPFileListParser */ public class OS2FTPEntryParser extends FTPFileListParserImpl { private static final String REGEX = "(\\s+|[0-9]+)\\s*" + "(\\s+|[A-Z]+)\\s*" + "(DIR|\\s+)\\s*" + "((?:0[1-9])|(?:1[0-2]))-" + "((?:0[1-9])|(?:[1-2]\\d)|(?:3[0-1]))-" + "(\\d\\d)\\s*" + "(?:([0-1]\\d)|(?:2[0-3])):" + "([0-5]\\d)\\s*" + "(\\S.*)"; /** * The sole constructor for a OS2FTPEntryParser object. * * @exception IllegalArgumentException * Thrown if the regular expression is unparseable. Should not be seen * under normal conditions. It it is seen, this is a sign that * <code>REGEX</code> is not a valid regular expression. */ public OS2FTPEntryParser() { super(REGEX); } /** * Parses a line of an OS2 FTP server file listing and converts it into a * usable format in the form of an <code> FTPFile </code> instance. If the * file listing line doesn't describe a file, <code> null </code> is * returned, otherwise a <code> FTPFile </code> instance representing the * files in the directory is returned. * <p> * @param entry A line of text from the file listing * @return An FTPFile instance corresponding to the supplied entry */ public FTPFile parseFTPEntry(String entry) { FTPFile f = new FTPFile(); if (matches(entry)) { String size = group(1); String attrib = group(2); String dirString = group(3); String mo = group(4); String da = group(5); String yr = group(6); String hr = group(7); String min = group(8); String name = group(9); //is it a DIR or a file if (dirString.trim().equals("DIR") || attrib.trim().equals("DIR")) { f.setType(FTPFile.DIRECTORY_TYPE); } else { f.setType(FTPFile.FILE_TYPE); } Calendar cal = Calendar.getInstance(); //convert all the calendar stuff to ints int month = new Integer(mo).intValue() - 1; int day = new Integer(da).intValue(); int year = new Integer(yr).intValue() + 2000; int hour = new Integer(hr).intValue(); int minutes = new Integer(min).intValue(); // Y2K stuff? this will break again in 2080 but I will // be sooooo dead anyways who cares. // SMC - IS OS2's directory date REALLY still not Y2K-compliant? if (year > 2080) { year -= 100; } //set the calendar cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, minutes); cal.set(Calendar.HOUR_OF_DAY, hour); cal.set(Calendar.YEAR, year); cal.set(Calendar.DATE, day); cal.set(Calendar.MONTH, month); f.setTimestamp(cal); //set the name f.setName(name.trim()); //set the size Long theSize = new Long(size.trim()); theSize = new Long(String.valueOf(theSize.intValue())); f.setSize(theSize.longValue()); return (f); } return null; } } 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java Index: UnixFTPEntryParser.java =================================================================== package org.apache.commons.net.ftp.parser; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ import java.util.Calendar; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFileListParserImpl; /** * This class is based on the logic of Daniel Savarese's * DefaultFTPListParser, but adapted to use regular expressions and to fit the * new FTPFileEntryParser interface. * @author <a href="mailto:[EMAIL PROTECTED]">Steve Cohen</a> * @version $Id: UnixFTPEntryParser.java,v 1.1 2003/03/02 18:18:24 scohen Exp $ */ public class UnixFTPEntryParser extends FTPFileListParserImpl { private static final String MONTHS = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"; private static final String REGEX = "([bcdlf-])" + "(((r|-)(w|-)(x|-))((r|-)(w|-)(x|-))((r|-)(w|-)(x|-)))\\s+" + "(\\d+)\\s+" + "(\\S+)\\s+" + "(\\S+)\\s+" + "(\\d+)\\s+" + MONTHS + "\\s+" + "((?:[0-9])|(?:[0-2][0-9])|(?:3[0-1]))\\s+" + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s" + "(\\S+)(\\s*.*)"; /** * The sole constructor for a UnixFTPEntryParser object. * * @exception IllegalArgumentException * Thrown if the regular expression is unparseable. Should not be seen * under normal conditions. It it is seen, this is a sign that * <code>REGEX</code> is not a valid regular expression. */ public UnixFTPEntryParser() { super(REGEX); } /** * Parses a line of a unix (standard) FTP server file listing and converts * it into a usable format in the form of an <code> FTPFile </code> * instance. If the file listing line doesn't describe a file, * <code> null </code> is returned, otherwise a <code> FTPFile </code> * instance representing the files in the directory is returned. * <p> * @param entry A line of text from the file listing * @return An FTPFile instance corresponding to the supplied entry */ public FTPFile parseFTPEntry(String entry) { FTPFile file = new FTPFile(); file.setRawListing(entry); int type; boolean isDevice = false; if (matches(entry)) { String typeStr = group(1); String hardLinkCount = group(15); String usr = group(16); String grp = group(17); String filesize = group(18); String mo = group(19); String da = group(20); String yr = group(22); String hr = group(23); String min = group(24); String name = group(25); String endtoken = group(26); switch (typeStr.charAt(0)) { case 'd': type = FTPFile.DIRECTORY_TYPE; break; case 'l': type = FTPFile.SYMBOLIC_LINK_TYPE; break; case 'b': case 'c': isDevice = true; // break; - fall through default: type = FTPFile.FILE_TYPE; } file.setType(type); int g = 4; for (int access = 0; access < 3; access++, g += 4) { // Use != '-' to avoid having to check for suid and sticky bits file.setPermission(access, FTPFile.READ_PERMISSION, (!group(g).equals("-"))); file.setPermission(access, FTPFile.WRITE_PERMISSION, (!group(g + 1).equals("-"))); file.setPermission(access, FTPFile.EXECUTE_PERMISSION, (!group(g + 2).equals("-"))); } if (!isDevice) { try { file.setHardLinkCount(Integer.parseInt(hardLinkCount)); } catch (NumberFormatException e) { // intentionally do nothing } } file.setUser(usr); file.setGroup(grp); try { file.setSize(Integer.parseInt(filesize)); } catch (NumberFormatException e) { // intentionally do nothing } Calendar cal = Calendar.getInstance(); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.HOUR_OF_DAY, 0); try { int pos = MONTHS.indexOf(mo); int month = pos / 4; if (null != yr) { // it's a year cal.set(Calendar.YEAR, Integer.parseInt(yr)); } else { // it must be hour/minute or we wouldn't have matched int year = cal.get(Calendar.YEAR); // if the month we're reading is greater than now, it must // be last year if (cal.get(Calendar.MONTH) < month) { year--; } cal.set(Calendar.YEAR, year); cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hr)); cal.set(Calendar.MINUTE, Integer.parseInt(min)); } cal.set(Calendar.MONTH, month); cal.set(Calendar.DATE, Integer.parseInt(da)); file.setTimestamp(cal); } catch (NumberFormatException e) { // do nothing, date will be uninitialized } if (null == endtoken) { file.setName(name); } else { // oddball cases like symbolic links, file names // with spaces in them. name += endtoken; if (type == FTPFile.SYMBOLIC_LINK_TYPE) { int end = name.indexOf(" -> "); // Give up if no link indicator is present if (end == -1) { file.setName(name); } else { file.setName(name.substring(0, end)); file.setLink(name.substring(end + 4)); } } else { file.setName(name); } } return file; } return null; } } 1.1 jakarta-commons/net/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java Index: VMSFTPEntryParser.java =================================================================== package org.apache.commons.net.ftp.parser; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Commons" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ import java.util.Calendar; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFileListParserImpl; /** * This Class uses the FTPEntryParser class to validate the input string. * It also requires the NetComponents library version 1.3.7 or later * and the OROMatcher library for the regualar expressions stuff. * * * <P><B>USAGE:</B></P> * <LI>Create an instance of VMSFTPEntryParser</LI> * <dd>VMSFTPEntryParser parser = new VMSFTPEntryParser(boolean); * <dd><code>True</code> = returns all versions of a file with the respective * ;# * <dd><code>False</code> = only the last version will return <B>(Default)</B> * <LI>Create an instance of FTPClient</LI> * <dd>FTPClient FTPClientObj = new FTPClient(); * <LI>Connect to the NODE </LI> * <dd>FTPClientObj.connect(); * <LI>Login to the NODE </LI> * <dd>FTPClientObj.login(username,password); * <LI>Switch directories if you have to</LI> * <dd>FTPClientObj.changeWorkingDirectory(thePath); * <LI>You might want to check if you are truly in a VMS System</LI> * <dd>And how do I do that you ask? easy... VMS is such a wonderful OS * that when we do <dd><B>String am_I_VMS = FTPClientObj.getSystemName()</B> * <dd>it returns NULL, while everyone else returns the FTP servername * <LI>Call listFiles passing the newly created parser and a filename or a mask * to look for </LI> <dd>FTPClientObj.listFiles(parser,filename); * <LI>You'll get back the list as an array of FTPFile objects like this * <dd>FTPFile[] myVMSFiles = FTPClientObj.listFiles(parser,filename); (or) * <dd>FTPFile[] myVMSFiles = FTPClientObj.listFiles(parser); * <dd>If <code>filename</code> is a filename and versioning is OFF, the * version <dd>you requested will come back without the ;# * <P> * That's all there is to it. * <P> * Each FTPFile object is populated just like any other FTPFile * object. The only thing not implemented at this time is the file * permissions, but I can do it if there is a real need for it. * <P> * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are * in the directory that you need to be. This parser will return the filtered * files from the directory it is in. This becomes crucial specialy if your * goal is to delete the output of the parser. * <P> * @author <a href="[EMAIL PROTECTED]">Winston Ojeda</a> * @author <a href="mailto:[EMAIL PROTECTED]">Steve Cohen</a> * @version $Id: VMSFTPEntryParser.java,v 1.1 2003/03/02 18:18:24 scohen Exp $ */ public class VMSFTPEntryParser extends FTPFileListParserImpl { private String prefix = "[" + getClass().getName() + "] "; private boolean versioning; /* This is how a VMS LIST output really looks "1-JUN.LIS;1 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)", "1-JUN.LIS;2 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)", "DATA.DIR;1 1/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)", */ private static final String MONTHS = "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)"; private static final String REGEX = "(.*;[0-9]+)\\s*" + "(\\d+)/\\d+\\s*" + "(\\d{1,2})-" + MONTHS + "-([0-9]{4})\\s*" + "((?:[01]\\d)|(?:2[0-3])):([012345]\\d):([012345]\\d)\\s*" + "\\[([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+)\\]\\s*" + "(\\([a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*\\))"; /** * Convenience Constructor for a VMSFTPEntryParser object. Sets the * <code>versioning</code> member false * * @exception IllegalArgumentException * Thrown if the regular expression is unparseable. Should not be seen * under normal conditions. It it is seen, this is a sign that * <code>REGEX</code> is not a valid regular expression. */ public VMSFTPEntryParser() { this(false); } /** * Constructor for a VMSFTPEntryParser object. Sets the versioning member * to the supplied value. * * @param versioning Value to which versioning is to be set. * * @exception IllegalArgumentException * Thrown if the regular expression is unparseable. Should not be seen * under normal conditions. It it is seen, this is a sign that * <code>REGEX</code> is not a valid regular expression. */ public VMSFTPEntryParser(boolean versioning) { super(REGEX); this.versioning = versioning; } /** * Parses a line of a VMS FTP server file listing and converts it into a * usable format in the form of an <code> FTPFile </code> instance. If the * file listing line doesn't describe a file, <code> null </code> is * returned, otherwise a <code> FTPFile </code> instance representing the * files in the directory is returned. * <p> * @param entry A line of text from the file listing * @return An FTPFile instance corresponding to the supplied entry */ public FTPFile parseFTPEntry(String entry) { //one block in VMS equals 512 bytes Integer oneBlock = new Integer(512); int intBlock = oneBlock.intValue(); long longBlock = 512; if (matches(entry)) { FTPFile f = new FTPFile(); f.setRawListing(entry); String name = group(1); String size = group(2); String day = group(3); String mo = group(4); String yr = group(5); String hr = group(6); String min = group(7); String sec = group(8); String grp = group(9); String owner = group(10); if (name.lastIndexOf(".DIR") != -1) { f.setType(FTPFile.DIRECTORY_TYPE); } else { f.setType(FTPFile.FILE_TYPE); } //set FTPFile name //Check also for versions to be returned or not if (versioning) { f.setName(name); } else { name = name.substring(0, name.lastIndexOf(";")); f.setName(name); } //size is retreived in blocks and needs to be put in bytes //for us humans and added to the FTPFile array Long theSize = new Long(size); long sizeInBytes = theSize.longValue() * longBlock; f.setSize(sizeInBytes); //set the date Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(Calendar.DATE, new Integer(day).intValue()); cal.set(Calendar.MONTH, MONTHS.indexOf(mo) / 4); cal.set(Calendar.YEAR, new Integer(yr).intValue()); cal.set(Calendar.HOUR_OF_DAY, new Integer(hr).intValue()); cal.set(Calendar.MINUTE, new Integer(min).intValue()); cal.set(Calendar.SECOND, new Integer(sec).intValue()); f.setTimestamp(cal); f.setGroup(grp); f.setUser(owner); //set group and owner //Since I don't need the persmissions on this file (RWED), I'll //leave that for further development. 'Cause it will be a bit //elaborate to do it right with VMSes World, Global and so forth. return f; } return null; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]