| Method from com.sshtools.ant.Sftp Detail: |
public void addFileset(FileSet set) {
filesets.addElement(set);
}
A set of files to upload or download |
protected void checkConfiguration() throws BuildException {
/* 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!");
}
}
Checks to see that all required parameters are set. |
protected void chmod(SftpClient sftp,
String filename) throws IOException, BuildException {
sftp.chmod(Integer.parseInt(chmod, 8), resolveFile(filename));
}
|
protected void createParents(SftpClient sftp,
String filename) throws IOException, BuildException {
Vector parents = new Vector();
File dir = new File(filename);
String dirname;
while ((dirname = dir.getParent()) != null) {
dir = new File(dirname);
parents.addElement(dir);
}
for (int i = parents.size() - 1; i >= 0; i--) {
dir = (File) parents.elementAt(i);
if (!dirCache.contains(dir)) {
log("creating remote directory " + resolveFile(dir.getPath()),
Project.MSG_VERBOSE);
try {
sftp.mkdir(resolveFile(dir.getPath()));
} catch (IOException ex) {
}
dirCache.addElement(dir);
}
}
}
Creates all parent directories specified in a complete relative
pathname. Attempts to create existing directories will not cause
errors. |
protected void delFile(SftpClient sftp,
String filename) throws IOException, BuildException {
if (verbose) {
log("deleting " + filename);
}
try {
String remotefile = resolveFile(filename);
sftp.rm(remotefile);
log("File " + filename + " deleted from " + parent.host,
Project.MSG_VERBOSE);
transferred++;
} catch (IOException ex) {
String s = "could not delete file: " + ex.getMessage();
if (skipFailedTransfers == true) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
}
}
Delete a file from the remote host. |
public void execute(SshClient ssh) throws BuildException {
try {
Integer.parseInt(chmod, 8);
} catch (NumberFormatException ex) {
throw new BuildException(
"chmod attribute format is incorrect, use octal number format i.e 0777");
}
executeSFTPTask(ssh);
}
|
protected void executeSFTPTask(SshClient ssh) throws BuildException {
SftpClient sftp = null;
try {
sftp = ssh.openSftpClient();
if (action == MK_DIR) {
makeRemoteDir(sftp, remotedir);
} else {
if (remotedir.trim().length() > 0) {
log("Setting the remote directory "); //, Project.MSG_VERBOSE);
sftp.cd(remotedir);
}
// Get the absolute path of the remote directory
remotedir = sftp.pwd();
log("Remote directory is " + remotedir);
if (!remotedir.endsWith("/")) {
remotedir += "/";
}
log(ACTION_STRS[action] + " files");
transferFiles(sftp);
}
} catch (IOException ex) {
throw new BuildException("error during SFTP transfer: " + ex);
} finally {
if ((sftp != null) && !sftp.isClosed()) {
try {
log("Quiting SFTP", Project.MSG_VERBOSE);
sftp.quit();
} catch (IOException ex) {
// ignore it
}
}
}
}
|
protected void getFile(SftpClient sftp,
String dir,
String filename) throws IOException, BuildException {
try {
String localfile = filename;
if (localfile.indexOf("/") >= 0) {
localfile = localfile.substring(filename.lastIndexOf("/"));
}
File file = parent.getProject().resolveFile(new File(dir, localfile).getAbsolutePath());
log(dir);
log(filename);
log(file.getAbsolutePath());
if (newerOnly && isUpToDate(sftp, file, resolveFile(filename))) {
return;
}
if (verbose) {
log("transferring " + filename + " to " +
file.getAbsolutePath());
}
File pdir = fileUtils.getParentFile(file);
if (!pdir.exists()) {
pdir.mkdirs();
}
//sftp.lcd(dir);
// Get the file
sftp.get(filename, file.getAbsolutePath());
if (verbose) {
log("File " + file.getAbsolutePath() + " copied from " +
parent.host);
}
FileAttributes attrs = sftp.stat(filename);
file.setLastModified(attrs.getModifiedTime().longValue() * 1000);
transferred++;
} catch (IOException ioe) {
String s = "could not get file: " + ioe.getMessage();
if (skipFailedTransfers == true) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
}
}
Retrieve a single file to 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. |
protected boolean isUpToDate(SftpClient sftp,
File localFile,
String remoteFile) throws IOException, BuildException {
try {
log("Checking date for " + remoteFile, Project.MSG_VERBOSE);
FileAttributes attrs = sftp.stat(remoteFile);
// SFTP uses seconds since Jan 1 1970 UTC
long remoteTimestamp = attrs.getModifiedTime().longValue() * 1000; //files[0].getTimestamp().getTime().getTime();
// Java uses milliseconds since Jan 1 1970 UTC
long localTimestamp = localFile.lastModified();
if (this.action == SEND_FILES) {
return remoteTimestamp > localTimestamp;
} else {
return localTimestamp > remoteTimestamp;
}
} catch (IOException ex) {
return false;
}
}
Checks to see if the remote file is current as compared with the local
file. Returns true if the remote file is up to date. |
protected void makeRemoteDir(SftpClient sftp,
String dir) throws BuildException {
if (verbose) {
log("creating directory: " + dir);
}
try {
sftp.mkdir(dir);
} catch (IOException ex) {
log(ex.getMessage());
}
}
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 sendFile(SftpClient sftp,
String dir,
String filename) throws IOException, BuildException {
InputStream instream = null;
SftpFileOutputStream out = null;
try {
File file = parent.getProject().resolveFile(new File(dir, filename).getPath());
String remotefile = resolveFile(filename);
if (newerOnly && isUpToDate(sftp, file, remotefile)) {
return;
}
if (verbose) {
log("transferring " + file.getAbsolutePath() + " to " +
remotedir + remotefile);
}
instream = new BufferedInputStream(new FileInputStream(file));
createParents(sftp, filename);
sftp.put(file.getAbsolutePath(), remotefile);
// Set the umask
sftp.chmod(Integer.parseInt(chmod, 8), remotefile);
log("File " + file.getAbsolutePath() + " copied to " + parent.host,
Project.MSG_VERBOSE);
transferred++;
} catch (IOException ex1) {
String s = "Could not put file: " + ex1.getMessage();
if (skipFailedTransfers == true) {
log(s, Project.MSG_WARN);
skipped++;
} else {
throw new BuildException(s);
}
} finally {
try {
if (instream != null) {
instream.close();
}
} catch (IOException ex) {
// ignore it
}
try {
if (out != null) {
out.close();
}
} catch (IOException ex) {
}
}
}
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 setAction(Sftp.Action action) throws BuildException {
this.action = action.getAction();
}
Sets the FTP action to be taken. Currently accepts "put", "get", "del",
"mkdir", "chmod" and "list". |
public void setChmod(String theMode) {
this.chmod = theMode;
}
Sets the file permission mode (Unix only) for files sent to the server. |
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 setIgnoreNoncriticalErrors(boolean ignoreNoncriticalErrors) {
this.ignoreNoncriticalErrors = ignoreNoncriticalErrors;
}
set the flag to skip errors on directory creation.
(and maybe later other server specific errors) |
public void setNewer(boolean newer) {
this.newerOnly = newer;
}
A synonym for depends. Set to true to transmit only new or changed
files. |
public void setRemotedir(String remotedir) {
this.remotedir = remotedir;
}
Sets the remote working directory |
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 setVerbose(boolean verbose) {
this.verbose = verbose;
}
Set to true to receive notification about each file as it is
transferred. |
protected void transferFiles(SftpClient sftp) 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(sftp, fs);
}
}
}
log(transferred + " files " + COMPLETED_ACTION_STRS[action]);
if (skipped != 0) {
log(skipped + " files were not successfully " +
COMPLETED_ACTION_STRS[action]);
}
}
Sends all files specified by the configured filesets to the remote
server. |
protected int transferFiles(SftpClient sftp,
FileSet fs) throws IOException, BuildException {
FileScanner ds;
if (action == SEND_FILES) {
ds = fs.getDirectoryScanner(parent.getProject());
} else {
ds = new SftpDirectoryScanner(sftp);
fs.setupDirectoryScanner(ds, parent.getProject());
ds.scan();
}
String[] 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 = fileUtils.getParentFile(listing);
if (!pd.exists()) {
pd.mkdirs();
}
bw = new BufferedWriter(new FileWriter(listing));
}*/
for (int i = 0; i < dsfiles.length; i++) {
switch (action) {
case SEND_FILES: {
sendFile(sftp, dir, dsfiles[i]);
break;
}
case GET_FILES: {
getFile(sftp, dir, dsfiles[i]);
break;
}
case DEL_FILES: {
delFile(sftp, dsfiles[i]);
break;
}
case CHMOD: {
chmod(sftp, dsfiles[i]);
transferred++;
break;
}
default:throw new BuildException("unknown ftp action " +
action);
}
}
} finally {
if (bw != null) {
bw.close();
}
}
return dsfiles.length;
}
For each file in the fileset, do the appropriate action: send, get,
delete, or list. |