| Method from org.apache.tools.ant.taskdefs.optional.net.FTP Detail: |
public void addFileset(FileSet set) {
filesets.addElement(set);
}
A set of files to upload or download |
protected void checkAttributes() throws BuildException {
if (server == null) {
throw new BuildException("server attribute must be set!");
}
if (userid == null) {
throw new BuildException("userid attribute must be set!");
}
if (password == null) {
throw new BuildException("password attribute must be set!");
}
if ((action == LIST_FILES) && (listing == null)) {
throw new BuildException("listing attribute must be set for list "
+ "action!");
}
if (action == MK_DIR && remotedir == null) {
throw new BuildException("remotedir attribute must be set for "
+ "mkdir action!");
}
if (action == CHMOD && chmod == null) {
throw new BuildException("chmod attribute must be set for chmod "
+ "action!");
}
if (action == SITE_CMD && siteCommand == null) {
throw new BuildException("sitecommand attribute must be set for site "
+ "action!");
}
if (this.isConfigurationSet) {
try {
Class.forName("org.apache.commons.net.ftp.FTPClientConfig");
} catch (ClassNotFoundException e) {
throw new BuildException(
"commons-net.jar >= 1.4.0 is required for at least one"
+ " of the attributes specified.");
}
}
}
Checks to see that all required parameters are set. |
protected void createParents(FTPClient ftp,
String filename) throws IOException, BuildException {
File dir = new File(filename);
if (dirCache.contains(dir)) {
return;
}
Vector parents = new Vector();
String dirname;
while ((dirname = dir.getParent()) != null) {
File checkDir = new File(dirname);
if (dirCache.contains(checkDir)) {
break;
}
dir = checkDir;
parents.addElement(dir);
}
// find first non cached dir
int i = parents.size() - 1;
if (i >= 0) {
String cwd = ftp.printWorkingDirectory();
String parent = dir.getParent();
if (parent != null) {
if (!ftp.changeWorkingDirectory(resolveFile(parent))) {
throw new BuildException("could not change to "
+ "directory: " + ftp.getReplyString());
}
}
while (i >= 0) {
dir = (File) parents.elementAt(i--);
// check if dir exists by trying to change into it.
if (!ftp.changeWorkingDirectory(dir.getName())) {
// could not change to it - try to create it
log("creating remote directory "
+ resolveFile(dir.getPath()), Project.MSG_VERBOSE);
if (!ftp.makeDirectory(dir.getName())) {
handleMkDirFailure(ftp);
}
if (!ftp.changeWorkingDirectory(dir.getName())) {
throw new BuildException("could not change to "
+ "directory: " + ftp.getReplyString());
}
}
dirCache.add(dir);
}
ftp.changeWorkingDirectory(cwd);
}
}
Creates all parent directories specified in a complete relative
pathname. Attempts to create existing directories will not cause
errors. |
protected void delFile(FTPClient ftp,
String filename) throws IOException, BuildException {
if (verbose) {
log("deleting " + filename);
}
if (!ftp.deleteFile(resolveFile(filename))) {
String s = "could not delete file: " + ftp.getReplyString();
if (skipFailedTransfers) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
} else {
log("File " + filename + " deleted from " + server,
Project.MSG_VERBOSE);
transferred++;
}
}
Delete a file from the remote host. |
protected void doSiteCommand(FTPClient ftp,
String theCMD) throws IOException, BuildException {
boolean rc;
String[] myReply = null;
log("Doing Site Command: " + theCMD, Project.MSG_VERBOSE);
rc = ftp.sendSiteCommand(theCMD);
if (!rc) {
log("Failed to issue Site Command: " + theCMD, Project.MSG_WARN);
} else {
myReply = ftp.getReplyStrings();
for (int x = 0; x < myReply.length; x++) {
if (myReply[x].indexOf("200") == -1) {
log(myReply[x], Project.MSG_WARN);
}
}
}
}
Sends a site command to the ftp server |
public void execute() throws BuildException {
checkAttributes();
FTPClient ftp = null;
try {
log("Opening FTP connection to " + server, Project.MSG_VERBOSE);
ftp = new FTPClient();
if (this.isConfigurationSet) {
ftp = FTPConfigurator.configure(ftp, this);
}
ftp.setRemoteVerificationEnabled(enableRemoteVerification);
ftp.connect(server, port);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new BuildException("FTP connection failed: "
+ ftp.getReplyString());
}
log("connected", Project.MSG_VERBOSE);
log("logging in to FTP server", Project.MSG_VERBOSE);
if ((this.account != null && !ftp.login(userid, password, account))
|| (this.account == null && !ftp.login(userid, password))) {
throw new BuildException("Could not login to FTP server");
}
log("login succeeded", Project.MSG_VERBOSE);
if (binary) {
ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new BuildException("could not set transfer type: "
+ ftp.getReplyString());
}
} else {
ftp.setFileType(org.apache.commons.net.ftp.FTP.ASCII_FILE_TYPE);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new BuildException("could not set transfer type: "
+ ftp.getReplyString());
}
}
if (passive) {
log("entering passive mode", Project.MSG_VERBOSE);
ftp.enterLocalPassiveMode();
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new BuildException("could not enter into passive "
+ "mode: " + ftp.getReplyString());
}
}
// If an initial command was configured then send it.
// Some FTP servers offer different modes of operation,
// E.G. switching between a UNIX file system mode and
// a legacy file system.
if (this.initialSiteCommand != null) {
RetryHandler h = new RetryHandler(this.retriesAllowed, this);
final FTPClient lftp = ftp;
executeRetryable(h, new Retryable() {
public void execute() throws IOException {
doSiteCommand(lftp, FTP.this.initialSiteCommand);
}
}, "initial site command: " + this.initialSiteCommand);
}
// For a unix ftp server you can set the default mask for all files
// created.
if (umask != null) {
RetryHandler h = new RetryHandler(this.retriesAllowed, this);
final FTPClient lftp = ftp;
executeRetryable(h, new Retryable() {
public void execute() throws IOException {
doSiteCommand(lftp, "umask " + umask);
}
}, "umask " + umask);
}
// If the action is MK_DIR, then the specified remote
// directory is the directory to create.
if (action == MK_DIR) {
RetryHandler h = new RetryHandler(this.retriesAllowed, this);
final FTPClient lftp = ftp;
executeRetryable(h, new Retryable() {
public void execute() throws IOException {
makeRemoteDir(lftp, remotedir);
}
}, remotedir);
} else if (action == SITE_CMD) {
RetryHandler h = new RetryHandler(this.retriesAllowed, this);
final FTPClient lftp = ftp;
executeRetryable(h, new Retryable() {
public void execute() throws IOException {
doSiteCommand(lftp, FTP.this.siteCommand);
}
}, "Site Command: " + this.siteCommand);
} else {
if (remotedir != null) {
log("changing the remote directory to " + remotedir,
Project.MSG_VERBOSE);
ftp.changeWorkingDirectory(remotedir);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new BuildException("could not change remote "
+ "directory: " + ftp.getReplyString());
}
}
if (newerOnly && timeDiffAuto) {
// in this case we want to find how much time span there is between local
// and remote
timeDiffMillis = getTimeDiff(ftp);
}
log(ACTION_STRS[action] + " " + ACTION_TARGET_STRS[action]);
transferFiles(ftp);
}
} catch (IOException ex) {
throw new BuildException("error during FTP transfer: " + ex, ex);
} finally {
if (ftp != null && ftp.isConnected()) {
try {
log("disconnecting", Project.MSG_VERBOSE);
ftp.logout();
ftp.disconnect();
} catch (IOException ex) {
// ignore it
}
}
}
}
|
protected void executeRetryable(RetryHandler h,
Retryable r,
String descr) throws IOException {
h.execute(r, descr);
}
Executable a retryable object. |
public String getDefaultDateFormatConfig() {
return defaultDateFormatConfig;
}
|
protected void getFile(FTPClient ftp,
String dir,
String filename) throws IOException, BuildException {
OutputStream outstream = null;
try {
File file = getProject().resolveFile(new File(dir, filename).getPath());
if (newerOnly && isUpToDate(ftp, file, resolveFile(filename))) {
return;
}
if (verbose) {
log("transferring " + filename + " to "
+ file.getAbsolutePath());
}
File pdir = file.getParentFile();
if (!pdir.exists()) {
pdir.mkdirs();
}
outstream = new BufferedOutputStream(new FileOutputStream(file));
ftp.retrieveFile(resolveFile(filename), outstream);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
String s = "could not get file: " + ftp.getReplyString();
if (skipFailedTransfers) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
} else {
log("File " + file.getAbsolutePath() + " copied from "
+ server, Project.MSG_VERBOSE);
transferred++;
if (preserveLastModified) {
outstream.close();
outstream = null;
FTPFile[] remote = ftp.listFiles(resolveFile(filename));
if (remote.length > 0) {
FILE_UTILS.setFileLastModified(file,
remote[0].getTimestamp()
.getTime().getTime());
}
}
}
} finally {
FileUtils.close(outstream);
}
}
Retrieve a single file from the remote host. filename may
contain a relative path specification.
The file will then be retreived using the entire relative path spec -
no attempt is made to change directories. It is anticipated that this
may eventually cause problems with some FTP servers, but it simplifies
the coding. |
public String getRecentDateFormatConfig() {
return recentDateFormatConfig;
}
|
public String getServerLanguageCodeConfig() {
return serverLanguageCodeConfig.getValue();
}
|
public String getServerTimeZoneConfig() {
return serverTimeZoneConfig;
}
|
public String getShortMonthNamesConfig() {
return shortMonthNamesConfig;
}
|
public String getSystemTypeKey() {
return systemTypeKey.getValue();
}
|
Granularity getTimestampGranularity() {
return timestampGranularity;
}
|
protected boolean isUpToDate(FTPClient ftp,
File localFile,
String remoteFile) throws IOException, BuildException {
log("checking date for " + remoteFile, Project.MSG_VERBOSE);
FTPFile[] files = ftp.listFiles(remoteFile);
// For Microsoft's Ftp-Service an Array with length 0 is
// returned if configured to return listings in "MS-DOS"-Format
if (files == null || files.length == 0) {
// If we are sending files, then assume out of date.
// If we are getting files, then throw an error
if (action == SEND_FILES) {
log("Could not date test remote file: " + remoteFile
+ "assuming out of date.", Project.MSG_VERBOSE);
return false;
} else {
throw new BuildException("could not date test remote file: "
+ ftp.getReplyString());
}
}
long remoteTimestamp = files[0].getTimestamp().getTime().getTime();
long localTimestamp = localFile.lastModified();
long adjustedRemoteTimestamp =
remoteTimestamp + this.timeDiffMillis + this.granularityMillis;
StringBuffer msg;
synchronized(TIMESTAMP_LOGGING_SDF) {
msg = new StringBuffer(" [")
.append(TIMESTAMP_LOGGING_SDF.format(new Date(localTimestamp)))
.append("] local");
}
log(msg.toString(), Project.MSG_VERBOSE);
synchronized(TIMESTAMP_LOGGING_SDF) {
msg = new StringBuffer(" [")
.append(TIMESTAMP_LOGGING_SDF.format(new Date(adjustedRemoteTimestamp)))
.append("] remote");
}
if (remoteTimestamp != adjustedRemoteTimestamp) {
synchronized(TIMESTAMP_LOGGING_SDF) {
msg.append(" - (raw: ")
.append(TIMESTAMP_LOGGING_SDF.format(new Date(remoteTimestamp)))
.append(")");
}
}
log(msg.toString(), Project.MSG_VERBOSE);
if (this.action == SEND_FILES) {
return adjustedRemoteTimestamp >= localTimestamp;
} else {
return localTimestamp >= adjustedRemoteTimestamp;
}
}
Checks to see if the remote file is current as compared with the local
file. Returns true if the target file is up to date. |
protected void listFile(FTPClient ftp,
BufferedWriter bw,
String filename) throws IOException, BuildException {
if (verbose) {
log("listing " + filename);
}
FTPFile[] ftpfiles = ftp.listFiles(resolveFile(filename));
if (ftpfiles != null && ftpfiles.length > 0) {
bw.write(ftpfiles[0].toString());
bw.newLine();
transferred++;
}
}
List information about a single file from the remote host. filename
may contain a relative path specification.
The file listing will then be retrieved using the entire relative path
spec - no attempt is made to change directories. It is anticipated that
this may eventually cause problems with some FTP servers, but it
simplifies the coding. |
protected void makeRemoteDir(FTPClient ftp,
String dir) throws IOException, BuildException {
String workingDirectory = ftp.printWorkingDirectory();
if (verbose) {
if (dir.indexOf("/") == 0 || workingDirectory == null) {
log("Creating directory: " + dir + " in /");
} else {
log("Creating directory: " + dir + " in " + workingDirectory);
}
}
if (dir.indexOf("/") == 0) {
ftp.changeWorkingDirectory("/");
}
String subdir = "";
StringTokenizer st = new StringTokenizer(dir, "/");
while (st.hasMoreTokens()) {
subdir = st.nextToken();
log("Checking " + subdir, Project.MSG_DEBUG);
if (!ftp.changeWorkingDirectory(subdir)) {
if (!ftp.makeDirectory(subdir)) {
// codes 521, 550 and 553 can be produced by FTP Servers
// to indicate that an attempt to create a directory has
// failed because the directory already exists.
int rc = ftp.getReplyCode();
if (!(ignoreNoncriticalErrors
&& (rc == FTPReply.CODE_550 || rc == FTPReply.CODE_553
|| rc == CODE_521))) {
throw new BuildException("could not create directory: "
+ ftp.getReplyString());
}
if (verbose) {
log("Directory already exists");
}
} else {
if (verbose) {
log("Directory created OK");
}
ftp.changeWorkingDirectory(subdir);
}
}
}
if (workingDirectory != null) {
ftp.changeWorkingDirectory(workingDirectory);
}
}
Create the specified directory on the remote host. |
protected String resolveFile(String file) {
return file.replace(System.getProperty("file.separator").charAt(0),
remoteFileSep.charAt(0));
}
Correct a file path to correspond to the remote host requirements. This
implementation currently assumes that the remote end can handle
Unix-style paths with forward-slash separators. This can be overridden
with the separator task parameter. No attempt is made to
determine what syntax is appropriate for the remote host. |
protected void rmDir(FTPClient ftp,
String dirname) throws IOException, BuildException {
if (verbose) {
log("removing " + dirname);
}
if (!ftp.removeDirectory(resolveFile(dirname))) {
String s = "could not remove directory: " + ftp.getReplyString();
if (skipFailedTransfers) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
} else {
log("Directory " + dirname + " removed from " + server,
Project.MSG_VERBOSE);
transferred++;
}
}
Delete a directory, if empty, from the remote host. |
protected void sendFile(FTPClient ftp,
String dir,
String filename) throws IOException, BuildException {
InputStream instream = null;
try {
// XXX - why not simply new File(dir, filename)?
File file = getProject().resolveFile(new File(dir, filename).getPath());
if (newerOnly && isUpToDate(ftp, file, resolveFile(filename))) {
return;
}
if (verbose) {
log("transferring " + file.getAbsolutePath());
}
instream = new BufferedInputStream(new FileInputStream(file));
createParents(ftp, filename);
ftp.storeFile(resolveFile(filename), instream);
boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
if (!success) {
String s = "could not put file: " + ftp.getReplyString();
if (skipFailedTransfers) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
} else {
// see if we should issue a chmod command
if (chmod != null) {
doSiteCommand(ftp, "chmod " + chmod + " " + resolveFile(filename));
}
log("File " + file.getAbsolutePath() + " copied to " + server,
Project.MSG_VERBOSE);
transferred++;
}
} finally {
FileUtils.close(instream);
}
}
Sends a single file to the remote host. filename may
contain a relative path specification. When this is the case, sendFile
will attempt to create any necessary parent directories before sending
the file. The file will then be sent using the entire relative path
spec - no attempt is made to change directories. It is anticipated that
this may eventually cause problems with some FTP servers, but it
simplifies the coding. |
public void setAccount(String pAccount) {
this.account = pAccount;
}
Sets the login account to use on the specified server. |
public void setAction(String action) throws BuildException {
log("DEPRECATED - The setAction(String) method has been deprecated."
+ " Use setAction(FTP.Action) instead.");
Action a = new Action();
a.setValue(action);
this.action = a.getAction();
} Deprecated! since - 1.5.x.
setAction(String) is deprecated and is replaced with
setAction(FTP.Action) to make Ant's Introspection mechanism do the
work and also to encapsulate operations on the type in its own
class.
Sets the FTP action to be taken. Currently accepts "put", "get", "del",
"mkdir", "chmod", "list", and "site". |
public void setAction(Action action) throws BuildException {
this.action = action.getAction();
}
Sets the FTP action to be taken. Currently accepts "put", "get", "del",
"mkdir", "chmod", "list", and "site". |
public void setBinary(boolean binary) {
this.binary = binary;
}
If true, uses binary mode, otherwise text mode (default is binary). |
public void setChmod(String theMode) {
this.chmod = theMode;
}
Sets the file permission mode (Unix only) for files sent to the
server. |
public void setDefaultDateFormatConfig(String defaultDateFormat) {
if (defaultDateFormat != null && !defaultDateFormat.equals("")) {
this.defaultDateFormatConfig = defaultDateFormat;
configurationHasBeenSet();
}
}
Sets the defaultDateFormatConfig attribute. |
public void setDepends(boolean depends) {
this.newerOnly = depends;
}
Set to true to transmit only files that are new or changed from their
remote counterparts. The default is to transmit all files. |
public void setEnableRemoteVerification(boolean b) {
enableRemoteVerification = b;
}
Whether to verify that data and control connections are
connected to the same remote host. |
public void setIgnoreNoncriticalErrors(boolean ignoreNoncriticalErrors) {
this.ignoreNoncriticalErrors = ignoreNoncriticalErrors;
}
set the flag to skip errors on directory creation.
(and maybe later other server specific errors) |
public void setInitialSiteCommand(String initialCommand) {
this.initialSiteCommand = initialCommand;
}
Sets the initialSiteCommand attribute. This attribute
names a site command that will be executed immediately
after connection. |
public void setListing(File listing) {
this.listing = listing;
}
The output file for the "list" action. This attribute is ignored for
any other actions. |
public void setNewer(boolean newer) {
this.newerOnly = newer;
}
A synonym for depends. Set to true to transmit only new
or changed files.
See the related attributes timediffmillis and timediffauto. |
public void setPassive(boolean passive) {
this.passive = passive;
}
Specifies whether to use passive mode. Set to true if you are behind a
firewall and cannot connect without it. Passive mode is disabled by
default. |
public void setPassword(String password) {
this.password = password;
}
Sets the login password for the given user id. |
public void setPort(int port) {
this.port = port;
}
Sets the FTP port used by the remote server. |
public void setPreserveLastModified(boolean preserveLastModified) {
this.preserveLastModified = preserveLastModified;
}
Set to true to preserve modification times for "gotten" files. |
public void setRecentDateFormatConfig(String recentDateFormat) {
if (recentDateFormat != null && !recentDateFormat.equals("")) {
this.recentDateFormatConfig = recentDateFormat;
configurationHasBeenSet();
}
}
Sets the recentDateFormatConfig attribute. |
public void setRemotedir(String dir) {
this.remotedir = dir;
}
Sets the remote directory where files will be placed. This may be a
relative or absolute path, and must be in the path syntax expected by
the remote server. No correction of path syntax will be performed. |
public void setRetriesAllowed(String retriesAllowed) {
if ("FOREVER".equalsIgnoreCase(retriesAllowed)) {
this.retriesAllowed = Retryable.RETRY_FOREVER;
} else {
try {
int retries = Integer.parseInt(retriesAllowed);
if (retries < Retryable.RETRY_FOREVER) {
throw new BuildException(
"Invalid value for retriesAllowed attribute: "
+ retriesAllowed);
}
this.retriesAllowed = retries;
} catch (NumberFormatException px) {
throw new BuildException(
"Invalid value for retriesAllowed attribute: "
+ retriesAllowed);
}
}
}
Defines how many times to retry executing FTP command before giving up.
Default is 0 - try once and if failure then give up. |
public void setSeparator(String separator) {
remoteFileSep = separator;
}
Sets the remote file separator character. This normally defaults to the
Unix standard forward slash, but can be manually overridden using this
call if the remote server requires some other separator. Only the first
character of the string is used. |
public void setServer(String server) {
this.server = server;
}
Sets the FTP server to send files to. |
public void setServerLanguageCodeConfig(LanguageCode serverLanguageCode) {
if (serverLanguageCode != null && !"".equals(serverLanguageCode.getValue())) {
this.serverLanguageCodeConfig = serverLanguageCode;
configurationHasBeenSet();
}
}
Sets the serverLanguageCode attribute. |
public void setServerTimeZoneConfig(String serverTimeZoneId) {
if (serverTimeZoneId != null && !serverTimeZoneId.equals("")) {
this.serverTimeZoneConfig = serverTimeZoneId;
configurationHasBeenSet();
}
}
Sets the serverTimeZoneConfig attribute. |
public void setShortMonthNamesConfig(String shortMonthNames) {
if (shortMonthNames != null && !shortMonthNames.equals("")) {
this.shortMonthNamesConfig = shortMonthNames;
configurationHasBeenSet();
}
}
Sets the shortMonthNamesConfig attribute |
public void setSiteCommand(String siteCommand) {
this.siteCommand = siteCommand;
}
Sets the siteCommand attribute. This attribute
names the command that will be executed if the action
is "site". |
public void setSkipFailedTransfers(boolean skipFailedTransfers) {
this.skipFailedTransfers = skipFailedTransfers;
}
If true, enables unsuccessful file put, delete and get
operations to be skipped with a warning and the remainder
of the files still transferred. |
public void setSystemTypeKey(FTPSystemType systemKey) {
if (systemKey != null && !systemKey.getValue().equals("")) {
this.systemTypeKey = systemKey;
configurationHasBeenSet();
}
}
Sets the systemTypeKey attribute.
Method for setting FTPClientConfig remote system key. |
public void setTimeDiffAuto(boolean timeDiffAuto) {
this.timeDiffAuto = timeDiffAuto;
}
"true" to find out automatically the time difference
between local and remote machine.
This requires right to create
and delete a temporary file in the remote directory. |
public void setTimeDiffMillis(long timeDiffMillis) {
this.timeDiffMillis = timeDiffMillis;
}
number of milliseconds to add to the time on the remote machine
to get the time on the local machine.
use in conjunction with newer |
public void setTimestampGranularity(Granularity timestampGranularity) {
if (null == timestampGranularity || "".equals(timestampGranularity.getValue())) {
return;
}
this.timestampGranularity = timestampGranularity;
}
Sets the timestampGranularity attribute |
public void setUmask(String theUmask) {
this.umask = theUmask;
}
Sets the default mask for file creation on a unix server. |
public void setUserid(String userid) {
this.userid = userid;
}
Sets the login user id to use on the specified server. |
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
Set to true to receive notification about each file as it is
transferred. |
protected void transferFiles(FTPClient ftp) throws IOException, BuildException {
transferred = 0;
skipped = 0;
if (filesets.size() == 0) {
throw new BuildException("at least one fileset must be specified.");
} else {
// get files from filesets
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
if (fs != null) {
transferFiles(ftp, fs);
}
}
}
log(transferred + " " + ACTION_TARGET_STRS[action] + " "
+ COMPLETED_ACTION_STRS[action]);
if (skipped != 0) {
log(skipped + " " + ACTION_TARGET_STRS[action]
+ " were not successfully " + COMPLETED_ACTION_STRS[action]);
}
}
Sends all files specified by the configured filesets to the remote
server. |
protected int transferFiles(FTPClient ftp,
FileSet fs) throws IOException, BuildException {
DirectoryScanner ds;
if (action == SEND_FILES) {
ds = fs.getDirectoryScanner(getProject());
} else {
ds = new FTPDirectoryScanner(ftp);
fs.setupDirectoryScanner(ds, getProject());
ds.setFollowSymlinks(fs.isFollowSymlinks());
ds.scan();
}
String[] dsfiles = null;
if (action == RM_DIR) {
dsfiles = ds.getIncludedDirectories();
} else {
dsfiles = ds.getIncludedFiles();
}
String dir = null;
if ((ds.getBasedir() == null)
&& ((action == SEND_FILES) || (action == GET_FILES))) {
throw new BuildException("the dir attribute must be set for send "
+ "and get actions");
} else {
if ((action == SEND_FILES) || (action == GET_FILES)) {
dir = ds.getBasedir().getAbsolutePath();
}
}
// If we are doing a listing, we need the output stream created now.
BufferedWriter bw = null;
try {
if (action == LIST_FILES) {
File pd = listing.getParentFile();
if (!pd.exists()) {
pd.mkdirs();
}
bw = new BufferedWriter(new FileWriter(listing));
}
RetryHandler h = new RetryHandler(this.retriesAllowed, this);
if (action == RM_DIR) {
// to remove directories, start by the end of the list
// the trunk does not let itself be removed before the leaves
for (int i = dsfiles.length - 1; i >= 0; i--) {
final String dsfile = dsfiles[i];
executeRetryable(h, new Retryable() {
public void execute() throws IOException {
rmDir(ftp, dsfile);
}
}, dsfile);
}
} else {
final BufferedWriter fbw = bw;
final String fdir = dir;
if (this.newerOnly) {
this.granularityMillis =
this.timestampGranularity.getMilliseconds(action);
}
for (int i = 0; i < dsfiles.length; i++) {
final String dsfile = dsfiles[i];
executeRetryable(h, new Retryable() {
public void execute() throws IOException {
switch (action) {
case SEND_FILES:
sendFile(ftp, fdir, dsfile);
break;
case GET_FILES:
getFile(ftp, fdir, dsfile);
break;
case DEL_FILES:
delFile(ftp, dsfile);
break;
case LIST_FILES:
listFile(ftp, fbw, dsfile);
break;
case CHMOD:
doSiteCommand(ftp, "chmod " + chmod
+ " " + resolveFile(dsfile));
transferred++;
break;
default:
throw new BuildException("unknown ftp action " + action);
}
}
}, dsfile);
}
}
} finally {
FileUtils.close(bw);
}
return dsfiles.length;
}
For each file in the fileset, do the appropriate action: send, get,
delete, or list. |