package org.exist.xquery.modules.ftpclient;
import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.Map.Entry;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.xquery.AbstractInternalModule;
import org.exist.xquery.FunctionDef;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.modules.ModuleUtils;
import org.exist.xquery.modules.ModuleUtils.ContextMapEntryModifier;
/**
*
* @author WStarcev
* @author Adam Retter <adam@existsolutions.com>
*/
public class FTPClientModule extends AbstractInternalModule {
public final static String NAMESPACE_URI = "http://exist-db.org/xquery/ftpclient";
public final static String PREFIX = "ftpclient";
public final static String INCLUSION_DATE = "2011-03-24";
public final static String RELEASED_IN_VERSION = "eXist-1.2";
public final static String CONNECTIONS_CONTEXTVAR = "_eXist_ftp_connections";
private static final Logger log = LogManager.getLogger(FTPClientModule.class);
private final static FunctionDef[] functions = {
new FunctionDef(GetConnectionFunction.signatures[0], GetConnectionFunction.class),
new FunctionDef(GetDirListFunction.signature, GetDirListFunction.class),
new FunctionDef(SendFileFunction.signature, SendFileFunction.class),
new FunctionDef(GetFileFunction.signature, GetFileFunction.class)
};
public FTPClientModule(Map<String, List<? extends Object>> parameters) {
super(functions, parameters);
}
@Override
public String getNamespaceURI() {
return NAMESPACE_URI;
}
@Override
public String getDefaultPrefix() {
return PREFIX;
}
@Override
public String getDescription() {
return "A module for performing FTP requests as a client";
}
@Override
public String getReleaseVersion() {
return RELEASED_IN_VERSION;
}
/**
* Stores a Connection in the Context of an XQuery.
*
* @param context The Context of the XQuery to store the Connection in
* @param ftp The connection to store
*
* @return A unique ID representing the connection
*/
public static synchronized long storeConnection(XQueryContext context, FTPClient ftp) {
return ModuleUtils.storeObjectInContextMap(context, FTPClientModule.CONNECTIONS_CONTEXTVAR, ftp);
}
/**
* Retrieves a previously stored Connection from the Context of an XQuery.
*
* @param context The Context of the XQuery containing the Connection
* @param connectionUID The UID of the Connection to retrieve from the Context of the XQuery
*
* @return DOCUMENT ME!
*/
public static FTPClient retrieveConnection(XQueryContext context, long connectionUID) {
return ModuleUtils.retrieveObjectFromContextMap(context, FTPClientModule.CONNECTIONS_CONTEXTVAR, connectionUID);
}
/**
* Resets the Module Context and closes any FTP connections for the XQueryContext.
*
* @param xqueryContext The XQueryContext
*/
@Override
public void reset(XQueryContext xqueryContext) {
// reset the module context
super.reset(xqueryContext);
// close any open Connections
closeAllConnections(xqueryContext);
}
/**
* Closes all the open DB Connections for the specified XQueryContext.
*
* @param xqueryContext The context to close JDBC Connections for
*/
private static void closeAllConnections(XQueryContext xqueryContext) {
ModuleUtils.modifyContextMap(xqueryContext, FTPClientModule.CONNECTIONS_CONTEXTVAR, new ContextMapEntryModifier<FTPClient>(){
@Override
public void modify(Map<Long, FTPClient> map) {
super.modify(map);
//empty the map
map.clear();
}
@Override
public void modify(Entry<Long, FTPClient> entry) {
final FTPClient con = entry.getValue();
try {
// close the Connection
con.logout();
} catch(IOException ioe) {
log.error(ioe.getMessage(), ioe);
} finally {
if(con.isConnected()) {
try {
con.disconnect();
} catch(IOException ioe) {
log.error(ioe.getMessage(), ioe);
}
}
}
}
});
// update the context
//ModuleUtils.storeContextMap(xqueryContext, FTPClientModule.CONNECTIONS_CONTEXTVAR, connections);
}
}