/**
*
* edtFTPj
*
* Copyright (C) 2000-2004 Enterprise Distributed Technologies Ltd
*
* www.enterprisedt.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Bug fixes, suggestions and comments should be should posted on
* http://www.enterprisedt.com/forums/index.php
*
* Change Log:
*
* $Log: OS400FileParser.java,v $
* Revision 1.1 2011-01-16 22:44:36 bruceb
* new parser
*
*
*/
package com.enterprisedt.net.ftp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import com.enterprisedt.util.debug.Logger;
/**
* Represents a remote Netware file parser
*
* @author Bruce Blackshaw
* @version $Revision: 1.1 $
*/
public class OS400FileParser extends FTPFileParser {
/*
* Directory field
*/
private final static String DIR = "*DIR";
/*
* Directory field
*/
private final static String DDIR = "*DDIR";
/*
* MEM field?
*/
private final static String MEM = "*MEM";
/*
* Number of expected fields
*/
private final static int MIN_EXPECTED_FIELD_COUNT = 6;
/*
* Date formats
*/
private final static String DATE_FORMAT_1 = "dd'/'MM'/'yy' 'HH':'mm':'ss";
private final static String DATE_FORMAT_2 = "dd'/'MM'/'yyyy' 'HH':'mm':'ss";
private final static String DATE_FORMAT_3 = "dd'.'MM'.'yy' 'HH':'mm':'ss";
private final static String DATE_FORMAT_11 = "yy'/'MM'/'dd' 'HH':'mm':'ss";
private final static String DATE_FORMAT_12 = "yyyy'/'MM'/'dd' 'HH':'mm':'ss";
private final static String DATE_FORMAT_13 = "yy'.'MM'.'dd' 'HH':'mm':'ss";
private final static String DATE_FORMAT_21 = "MM'/'dd'/'yy' 'HH':'mm':'ss";
private final static String DATE_FORMAT_22 = "MM'/'dd'/'yyyy' 'HH':'mm':'ss";
private final static String DATE_FORMAT_23 = "MM'.'dd'.'yy' 'HH':'mm':'ss";
/*
* array of formats
*/
private static String[] formats1 = {DATE_FORMAT_1,DATE_FORMAT_2,DATE_FORMAT_3};
private static String[] formats2 = {DATE_FORMAT_11,DATE_FORMAT_12,DATE_FORMAT_13};
private static String[] formats3 = { DATE_FORMAT_21, DATE_FORMAT_22, DATE_FORMAT_23 };
private String[][] formats = {formats1,formats2,formats3};
/*
* Logging object
*/
private static Logger log = Logger.getLogger("OS400FileParser");
private int formatIndex = 0;
private Locale locale;
public OS400FileParser() {
locale = Locale.getDefault();
}
/**
* Set the locale for date parsing of listings
*
* @param locale locale to set
*/
public void setLocale(Locale locale) {
this.locale = locale;
}
public String toString() {
return "OS400";
}
/**
* Valid format for this parser
*
* @param listing listing to test
* @return true if valid
*/
public boolean isValidFormat(String[] listing) {
int count = Math.min(listing.length, 10);
boolean dir = false;
boolean ddir = false;
boolean lib = false;
boolean stmf = false;
boolean flr = false;
boolean file = false;
for (int i = 0; i < count; i++) {
if (listing[i].indexOf("*DIR") > 0)
dir = true;
else if (listing[i].indexOf("*FILE") > 0)
file = true;
else if (listing[i].indexOf("*FLR") > 0)
flr = true;
else if (listing[i].indexOf("*DDIR") > 0)
ddir = true;
else if (listing[i].indexOf("*STMF") > 0)
stmf = true;
else if (listing[i].indexOf("*LIB") > 0)
lib = true;
}
if (dir || file || ddir || lib || stmf || flr)
return true;
log.debug("Not in OS/400 format");
return false;
}
/*
* Parse server supplied string. Listing looks like the below:
*
* CFT 45056 04/12/06 14:19:31 *FILE AFTFRE1.FILE
* CFT *MEM AFTFRE1.FILE/AFTFRE1.MBR
* CFT 36864 28/11/06 15:19:30 *FILE AFTFRE2.FILE
* CFT *MEM AFTFRE2.FILE/AFTFRE2.MBR
* CFT 45056 04/12/06 14:19:37 *FILE AFTFRE6.FILE
* CFT *MEM AFTFRE6.FILE/AFTFRE6.MBR
* QSYSOPR 28672 01/12/06 20:08:04 *FILE FPKI45POK5.FILE
* QSYSOPR *MEM FPKI45POK5.FILE/FPKI45POK5.MBR
*/
public FTPFile parse(String raw) throws DateParseException {
String[] fields = split(raw);
// skip blank lines
if(fields.length <= 0)
return null;
// return what we can for MEM
if (fields.length >= 2 && fields[1].equals(MEM)) {
String owner = fields[0];
String name = fields[2];
FTPFile file = new FTPFile(raw, name, 0, false, null);
file.setOwner(owner);
return file;
}
if (fields.length < MIN_EXPECTED_FIELD_COUNT)
return null;
// first field is owner
String owner = fields[0];
// next is size
long size = 0L;
try {
size = Long.parseLong(fields[1]);
}
catch (NumberFormatException ex) {
log.warn("Failed to parse size: " + fields[1]);
}
String lastModifiedStr = fields[2] + " " + fields[3];
Date lastModified = getLastModified(lastModifiedStr);
// test is dir
boolean isDir = false;
if (fields[4] == DIR || fields[4] == DDIR)
isDir = true;
String name = fields[5];
if (name.endsWith("/"))
{
isDir = true;
name = name.substring(0, name.length() - 1);
}
FTPFile file = new FTPFile(raw, name, size, isDir, lastModified);
file.setOwner(owner);
return file;
}
private Date getLastModified(String lastModifiedStr) throws DateParseException {
Date lastModified = null;
if (formatIndex >= formats.length) {
log.warn("Exhausted formats - failed to parse date");
return null;
}
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 2);
int prevIndex = formatIndex;
for (int i = formatIndex; i < formats.length; i++, formatIndex++) {
for (int j = 0; j < formats[i].length; j++) {
try {
SimpleDateFormat dateFormatter = new SimpleDateFormat(formats[formatIndex][j], locale);
lastModified = dateFormatter.parse(lastModifiedStr);
if (lastModified.after(cal.getTime())) {
log.debug("Swapping to alternate format (found date in future)");
continue;
}
else // all ok, exit loop
return lastModified;
}
catch (ParseException ex) {
continue;
}
}
}
if (formatIndex >= formats.length) {
log.warn("Exhausted formats - failed to parse date");
return null;
}
if (formatIndex > prevIndex) { // we've changed formatters so redo
throw new DateParseException(null);
}
return lastModified;
}
}