this merges the master head of https://github.com/helma-org/apps-modules-mirror into helma
568 lines
16 KiB
JavaScript
568 lines
16 KiB
JavaScript
/*
|
|
* Helma License Notice
|
|
*
|
|
* The contents of this file are subject to the Helma License
|
|
* Version 2.0 (the "License"). You may not use this file except in
|
|
* compliance with the License. A copy of the License is available at
|
|
* http://adele.helma.org/download/helma/license.txt
|
|
*
|
|
* Copyright 1998-2007 Helma Software. All Rights Reserved.
|
|
*
|
|
* $RCSfile: Ftp.js,v $
|
|
* $Author$
|
|
* $Revision$
|
|
* $Date$
|
|
*/
|
|
|
|
|
|
/**
|
|
* @fileoverview Default properties and methods of the FTP prototype.
|
|
* <br /><br />
|
|
* To use this optional module, its repository needs to be added to the
|
|
* application, for example by calling app.addRepository('modules/helma/Ftp.js')
|
|
*/
|
|
|
|
// requires helma.File
|
|
app.addRepository("modules/helma/File.js");
|
|
|
|
/**
|
|
* Define the global namespace if not existing
|
|
*/
|
|
if (!global.helma) {
|
|
global.helma = {};
|
|
}
|
|
|
|
/**
|
|
* Constructor for FTP client objects, to send and receive files from an FTP server.
|
|
* <br /><br />
|
|
* @class This class represents a FTP client, providing
|
|
* access to an FTP server.
|
|
*
|
|
* @example var ftp = new helma.Ftp("ftp.mydomain.com");
|
|
* @param {String} server as String, the address of the FTP Server to connect to
|
|
* @constructor
|
|
*/
|
|
helma.Ftp = function(server) {
|
|
var OK = 0;
|
|
var SOCKET = 1;
|
|
var TIMEOUT = 2;
|
|
var LOGIN = 10;
|
|
var LOGOUT = 11;
|
|
var BINARY = 20;
|
|
var ASCII = 21;
|
|
var ACTIVE = 22;
|
|
var PASSIVE = 23;
|
|
var CD = 30;
|
|
var LCD = 31;
|
|
var PWD = 32;
|
|
var DIR = 33;
|
|
var MKDIR = 34;
|
|
var RMDIR = 35;
|
|
var GET = 40;
|
|
var PUT = 41;
|
|
var DELETE = 42;
|
|
var RENAME = 43;
|
|
|
|
var FTP = Packages.org.apache.commons.net.ftp.FTP;
|
|
var FtpClient = Packages.org.apache.commons.net.ftp.FTPClient;
|
|
var BufferedInputStream = java.io.BufferedInputStream;
|
|
var BufferedOutputStream = java.io.BufferedOutputStream;
|
|
var FileInputStream = java.io.FileInputStream;
|
|
var FileOutputStream = java.io.FileOutputStream;
|
|
var ByteArrayInputStream = java.io.ByteArrayInputStream;
|
|
var ByteArrayOutputStream = java.io.ByteArrayOutputStream;
|
|
|
|
var self = this;
|
|
var className = "helma.Ftp";
|
|
|
|
var ftpclient = new FtpClient();
|
|
var localDir;
|
|
|
|
var error = function(methName, errMsg) {
|
|
var tx = java.lang.Thread.currentThread();
|
|
tx.dumpStack();
|
|
app.log("Error in " + className + ":" + methName + ": " + errMsg);
|
|
return;
|
|
};
|
|
|
|
var debug = function(methName, msg) {
|
|
msg = msg ? " " + msg : "";
|
|
app.debug(className + ":" + methName + msg);
|
|
return;
|
|
};
|
|
|
|
var setStatus = function(status) {
|
|
if (self.status === OK) {
|
|
self.status = status;
|
|
}
|
|
return;
|
|
};
|
|
|
|
var getStatus = function() {
|
|
return self.status;
|
|
};
|
|
|
|
this.server = server;
|
|
this.status = OK;
|
|
|
|
/** @ignore */
|
|
this.toString = function() {
|
|
return "[helma.Ftp " + server + "]";
|
|
};
|
|
|
|
/**
|
|
* Set the default timeout in milliseconds to use when opening a socket.
|
|
*/
|
|
this.setReadTimeout = function(timeout) {
|
|
try {
|
|
ftpclient.setDefaultTimeout(timeout);
|
|
debug("setReadTimeout", timeout);
|
|
return true;
|
|
} catch(x) {
|
|
error("setReadTimeout", x);
|
|
setStatus(SOCKET);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Sets the timeout in milliseconds to use when reading from the data connection.
|
|
*/
|
|
this.setTimeout = function(timeout) {
|
|
try {
|
|
ftpclient.setDataTimeout(timeout);
|
|
debug("setTimeout", timeout);
|
|
return true;
|
|
} catch(x) {
|
|
error("setTimeout", x);
|
|
setStatus(TIMEOUT);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Logs in to the FTP server.
|
|
*
|
|
* @param {String} username as String
|
|
* @param {String} password as String
|
|
* @return Boolean true if the login was successful, otherwise false
|
|
* @type Boolean
|
|
*/
|
|
this.login = function(username, password) {
|
|
try {
|
|
ftpclient.connect(this.server);
|
|
var result = ftpclient.login(username, password);
|
|
debug("login", username + "@" + server);
|
|
return result;
|
|
} catch(x) {
|
|
error("login", x);
|
|
setStatus(LOGIN);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Sets transfer mode to binary for transmitting images and other non-text files.
|
|
*
|
|
* @example ftp.binary();
|
|
*/
|
|
this.binary = function() {
|
|
try {
|
|
var result = ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
|
|
debug("binary");
|
|
return result;
|
|
} catch(x) {
|
|
error("binary", x);
|
|
setStatus(BINARY);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Sets transfer mode to ascii for transmitting text-based data.
|
|
*
|
|
* @example ftp.ascii();
|
|
*/
|
|
this.ascii = function() {
|
|
try {
|
|
var result = ftpclient.setFileType(FTP.ASCII_FILE_TYPE);
|
|
debug("ascii");
|
|
return result;
|
|
} catch(x) {
|
|
error("ascii", x);
|
|
setStatus(ASCII);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Switches the connection to use active mode.
|
|
*
|
|
* @example ftp.active();
|
|
*/
|
|
this.active = function() {
|
|
try {
|
|
ftpclient.enterLocalActiveMode();
|
|
debug("active");
|
|
return true;
|
|
} catch(x) {
|
|
error("active", x);
|
|
setStatus(ACTIVE);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Switches the connection to use passive mode.
|
|
*
|
|
* @example ftp.passive();
|
|
*/
|
|
this.passive = function() {
|
|
try {
|
|
ftpclient.enterLocalPassiveMode();
|
|
debug("passive");
|
|
return true;
|
|
} catch(x) {
|
|
error("passive", x);
|
|
setStatus(PASSIVE);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Returns the path of the current working directory.
|
|
*
|
|
* @example var remotepath = ftp.pwd();
|
|
* @type String
|
|
* @return String containing the current working directory path
|
|
*/
|
|
this.pwd = function() {
|
|
try {
|
|
debug("pwd");
|
|
return ftpclient.printWorkingDirectory();
|
|
} catch(x) {
|
|
error("pwd", x);
|
|
setStatus(PWD);
|
|
}
|
|
return;
|
|
};
|
|
|
|
/**
|
|
* Returns a listing of the files contained in a directory on the FTP server.
|
|
* <br /><br />
|
|
* Lists the files contained in the current working
|
|
* directory or, if an alternative path is specified, the
|
|
* files contained in the specified directory.
|
|
*
|
|
* @example var filelist = ftp.dir();
|
|
* @param {String} path as String, optional alternative directory
|
|
* @return Array containing the list of files in that directory
|
|
* @type Array
|
|
*/
|
|
this.dir = function(path) {
|
|
try {
|
|
debug("dir", path);
|
|
return ftpclient.listNames(path ? path : ".");
|
|
} catch(x) {
|
|
error("dir", x);
|
|
setStatus(DIR);
|
|
}
|
|
return;
|
|
};
|
|
|
|
/**
|
|
* Creates a new directory on the server.
|
|
* <br /><br />
|
|
* The name of the directory is determined as the function's
|
|
* string parameter. Returns false when an error occured
|
|
* (e.g. due to access restrictions, directory already
|
|
* exists etc.), otherwise true.
|
|
*
|
|
* @param {String} dir as String, the name of the directory to be created
|
|
* @return Boolean true if the directory was successfully created, false if there was an error
|
|
* @type Boolean
|
|
*/
|
|
this.mkdir = function(dir) {
|
|
try {
|
|
var result = ftpclient.makeDirectory(dir);
|
|
debug("mkdir", dir);
|
|
return result;
|
|
} catch(x) {
|
|
error("mkdir", x);
|
|
setStatus(MKDIR);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Deletes a directory on the FTP server.
|
|
*
|
|
* @param {String} dir as String, the name of the directory to be deleted
|
|
* @return Boolean true if the deletion was successful, false otherwise
|
|
* @type Boolean
|
|
*/
|
|
this.rmdir = function(dir) {
|
|
try {
|
|
var result = ftpclient.removeDirectory(dir);
|
|
debug("rmdir", dir);
|
|
return result;
|
|
} catch(x) {
|
|
error("rmdir", x);
|
|
setStatus(RMDIR);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Changes the working directory on the FTP server.
|
|
*
|
|
* @example ftp.cd("/home/users/fred/www"); // use absolute pathname
|
|
* @example ftp.cd(".."); // change to parent directory
|
|
* @example ftp.cd("images"); // use relative pathname
|
|
* @param {String} dir as String, the path that the remote working directory should be changed to
|
|
*/
|
|
this.cd = function(path) {
|
|
try {
|
|
var result = ftpclient.changeWorkingDirectory(path);
|
|
debug("cd", path);
|
|
return result;
|
|
} catch(x) {
|
|
error("cd", x);
|
|
setStatus(CD);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Changes the working directory of the local machine when being connected to an FTP server.
|
|
*
|
|
* @example ftp.lcd("/home/users/fred/www"); // use absolute pathname
|
|
* @example ftp.lcd(".."); // change to parent directory
|
|
* @example ftp.lcd("images"); // use relative pathname
|
|
* @param {String} dir as String, the path that the local working directory should be changed to
|
|
*/
|
|
this.lcd = function(dir) {
|
|
try {
|
|
localDir = new helma.File(dir);
|
|
if (!localDir.exists()) {
|
|
localDir.mkdir();
|
|
debug("lcd", dir);
|
|
}
|
|
return true;
|
|
} catch(x) {
|
|
error("lcd", x);
|
|
setStatus(LCD);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Transfers a file from the local file system to the remote server.
|
|
* <br /><br />
|
|
* Returns true if the transmission was successful, otherwise false.
|
|
*
|
|
* @param {String} localFile as String, the name of the file to be uploaded
|
|
* @param {String} remoteFile as String, the name of the remote destination file
|
|
* @return Boolean true if the file was successfully uploaded, false if there was an error
|
|
* @type Boolean
|
|
*/
|
|
this.putFile = function(localFile, remoteFile) {
|
|
try {
|
|
if (localFile instanceof File || localFile instanceof helma.File) {
|
|
var f = localFile;
|
|
} else if (typeof localFile == "string") {
|
|
if (localDir == null)
|
|
var f = new helma.File(localFile);
|
|
else
|
|
var f = new helma.File(localDir, localFile);
|
|
}
|
|
var stream = new BufferedInputStream(
|
|
new FileInputStream(f.getPath())
|
|
);
|
|
if (!remoteFile) {
|
|
remoteFile = f.getName();
|
|
}
|
|
var result = ftpclient.storeFile(remoteFile, stream);
|
|
stream.close();
|
|
debug("putFile", remoteFile);
|
|
return result;
|
|
} catch(x) {
|
|
error("putFile", x);
|
|
setStatus(PUT);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Transfers text from a string to a file on the FTP server.
|
|
*
|
|
* @example ftp.putString("Hello, World!", "message.txt");
|
|
* @param {String} str as String, the text content that should be uploaded
|
|
* @param {String} remoteFile as String, the name of the remote destination file
|
|
* @param {String} charset as String, optional
|
|
* @return Boolean true if the file was successfully uploaded, false if there was an error
|
|
* @type Boolean
|
|
*/
|
|
this.putString = function(str, remoteFile, charset) {
|
|
try {
|
|
str = new java.lang.String(str);
|
|
var bytes = charset ? str.getBytes(charset) : str.getBytes();
|
|
var stream = ByteArrayInputStream(bytes);
|
|
var result = ftpclient.storeFile(remoteFile, stream);
|
|
debug("putString", remoteFile);
|
|
return result;
|
|
} catch(x) {
|
|
error("putString", x);
|
|
setStatus(PUT);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Transfers a byte array to a file on the FTP server.
|
|
* @param {Array} bytes The byte array that should be uploaded
|
|
* @param {String} remoteFile The name of the remote destination file
|
|
* @return Boolean True if the file was successfully uploaded, false if there was an error
|
|
* @type Boolean
|
|
*/
|
|
this.putBytes = function(bytes, remoteFile) {
|
|
try {
|
|
var stream = ByteArrayInputStream(bytes);
|
|
var result = ftpclient.storeFile(remoteFile, stream);
|
|
debug("putBytes", remoteFile);
|
|
return result;
|
|
} catch(x) {
|
|
error("putBytes", x);
|
|
setStatus(PUT);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Transfers a file from the FTP server to the local file system.
|
|
*
|
|
* @example ftp.getFile(".htaccess", "htaccess.txt");
|
|
* @param {String} remoteFile as String, the name of the file that should be downloaded
|
|
* @param {String} localFile as String, the name which the file should be stored under
|
|
* @see #cd
|
|
* @see #lcd
|
|
*/
|
|
this.getFile = function(remoteFile, localFile) {
|
|
try {
|
|
if (localDir == null)
|
|
var f = new helma.File(localFile);
|
|
else
|
|
var f = new helma.File(localDir, localFile);
|
|
var stream = new BufferedOutputStream(
|
|
new FileOutputStream(f.getPath())
|
|
);
|
|
var result = ftpclient.retrieveFile(remoteFile, stream);
|
|
stream.close();
|
|
debug("getFile", remoteFile);
|
|
return result;
|
|
} catch(x) {
|
|
error("getFile", x);
|
|
setStatus(GET);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Retrieves a file from the FTP server and returns it as string.
|
|
*
|
|
* @example var str = ftp.getString("messages.txt");
|
|
* @param {String} remoteFile as String, the name of the file that should be downloaded
|
|
* @return String containing the data of the downloaded file
|
|
* @type String
|
|
* @see #cd
|
|
*/
|
|
this.getString = function(remoteFile) {
|
|
try {
|
|
var stream = ByteArrayOutputStream();
|
|
ftpclient.retrieveFile(remoteFile, stream);
|
|
debug("getString", remoteFile);
|
|
return stream.toString();
|
|
} catch(x) {
|
|
error("getString", x);
|
|
setStatus(GET);
|
|
}
|
|
return;
|
|
};
|
|
|
|
/**
|
|
* Deletes a file on the FTP server.
|
|
*
|
|
* @example var str = ftp.deleteFile("messages.txt");
|
|
* @param {String} remoteFile as String, the name of the file to be deleted
|
|
* @return Boolean true if the deletion was successful, false otherwise
|
|
* @type Boolean
|
|
*/
|
|
this.deleteFile = function(remoteFile) {
|
|
try {
|
|
var result = ftpclient.deleteFile(remoteFile);
|
|
debug("deleteFile", remoteFile);
|
|
return result;
|
|
} catch(x) {
|
|
error("deleteFile", x);
|
|
setStatus(DELETE);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Renames a file on the FTP server.
|
|
*
|
|
* @example var success = ftp.renameFile("messages.tmp", "messages.txt");
|
|
* @param {String} from the name of the original file
|
|
* @param {String} to the new name the original file should get
|
|
* @return Boolean true if renaming the remote file was successful, false otherwise
|
|
* @type Boolean
|
|
*/
|
|
this.renameFile = function(from, to) {
|
|
try {
|
|
var result = ftpclient.rename(from, to);
|
|
debug("renameFile", from + "->" + to);
|
|
return result;
|
|
} catch(x) {
|
|
error("renameFile", x);
|
|
setStatus(RENAME);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Terminates the current FTP session.
|
|
*/
|
|
this.logout = function() {
|
|
try {
|
|
var result = ftpclient.logout();
|
|
ftpclient.disconnect();
|
|
debug("logout");
|
|
return result;
|
|
} catch(x) {
|
|
error("logout", x);
|
|
setStatus(LOGOUT);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
for (var i in this)
|
|
this.dontEnum(i);
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/** @ignore */
|
|
helma.Ftp.toString = function() {
|
|
return "[helma.Ftp]";
|
|
};
|
|
|
|
|
|
helma.lib = "Ftp";
|
|
helma.dontEnum(helma.lib);
|
|
for (var i in helma[helma.lib])
|
|
helma[helma.lib].dontEnum(i);
|
|
for (var i in helma[helma.lib].prototype)
|
|
helma[helma.lib].prototype.dontEnum(i);
|
|
delete helma.lib;
|