/********************************************************* begin of preamble
**
** Copyright (C) 2003-2010 Software- und Organisations-Service GmbH.
** All rights reserved.
**
** This file may be used under the terms of either the
**
** GNU General Public License version 2.0 (GPL)
**
** as published by the Free Software Foundation
** http://www.gnu.org/licenses/gpl-2.0.txt and appearing in the file
** LICENSE.GPL included in the packaging of this file.
**
** or the
**
** Agreement for Purchase and Licensing
**
** as offered by Software- und Organisations-Service GmbH
** in the respective terms of supply that ship with this file.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
********************************************************** end of preamble*/
package com.sos.VirtualFileSystem.FTP;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
import com.sos.JSHelper.Basics.JSJobUtilities;
import com.sos.JSHelper.Exceptions.JobSchedulerException;
import com.sos.JSHelper.Options.SOSOptionHostName;
import com.sos.JSHelper.Options.SOSOptionPortNumber;
import com.sos.JSHelper.Options.SOSOptionTransferMode;
import com.sos.VirtualFileSystem.DataElements.SOSFileList;
import com.sos.VirtualFileSystem.DataElements.SOSFileListEntry;
import com.sos.VirtualFileSystem.DataElements.SOSFolderName;
import com.sos.VirtualFileSystem.Interfaces.ISOSAuthenticationOptions;
import com.sos.VirtualFileSystem.Interfaces.ISOSConnection;
import com.sos.VirtualFileSystem.Interfaces.ISOSConnectionOptions;
import com.sos.VirtualFileSystem.Interfaces.ISOSSession;
import com.sos.VirtualFileSystem.Interfaces.ISOSShellOptions;
import com.sos.VirtualFileSystem.Interfaces.ISOSVFSHandler;
import com.sos.VirtualFileSystem.Interfaces.ISOSVfsFileTransfer;
import com.sos.VirtualFileSystem.Interfaces.ISOSVirtualFile;
import com.sos.VirtualFileSystem.Interfaces.ISOSVirtualFileSystem;
import com.sos.VirtualFileSystem.Interfaces.ISOSVirtualFolder;
import com.sos.VirtualFileSystem.Options.SOSConnection2OptionsAlternate;
import com.sos.VirtualFileSystem.Options.SOSConnection2OptionsSuperClass;
import com.sos.VirtualFileSystem.common.SOSVfsBaseClass;
import com.sos.i18n.Msg;
import com.sos.i18n.Msg.BundleBaseName;
import com.sos.i18n.annotation.I18NMessage;
import com.sos.i18n.annotation.I18NMessages;
import com.sos.i18n.annotation.I18NResourceBundle;
@I18NResourceBundle(baseName = "SOSVirtualFileSystem", defaultLocale = "en")
public class SOSVfsFtp extends SOSVfsBaseClass implements ISOSVfsFileTransfer, ISOSVFSHandler, ISOSVirtualFileSystem, ISOSConnection {
private final String conClassName = "SOSVfsFtp";
private Logger logger = Logger.getLogger(SOSVfsFtp.class);
private SOSFtpServerReply objFTPReply = null;
protected Msg objMsg = new Msg(new BundleBaseName(this.getClass()
.getAnnotation(I18NResourceBundle.class)
.baseName()));
@I18NMessages(value = { @I18NMessage("Disconnected from host '%1$s' on port '%2$d'."), //
@I18NMessage(value = "Disconnected from host '%1$s' on port '%2$d'.", //
locale = "en_UK", //
explanation = "Disconnected from host '%1$s' on port '%2$d'." //
), //
@I18NMessage(value = "Verbindung zum Rechner '%1$s' �ber Port-Nummer '%2$d' beendet.", //
locale = "de", //
explanation = "Disconnected from host '%1$s' on port '%2$d'." //
), //
@I18NMessage(value = "Disconnected from host '%1$s' on port '%2$d'.", locale = "es", //
explanation = "Disconnected from host '%1$s' on port '%2$d'." //
), //
@I18NMessage(value = "Disconnected from host '%1$s' on port '%2$d'.", locale = "fr", //
explanation = "Disconnected from host '%1$s' on port '%2$d'." //
), //
@I18NMessage(value = "Disconnected from host '%1$s' on port '%2$d'.", locale = "it", //
explanation = "Disconnected from host '%1$s' on port '%2$d'." //
) //
}, msgnum = "SOSVfs-I-0109", msgurl = "SOSVfs-I-0109")
/*!
* \var SOSVfs_I_0109
* \brief Disconnected from host '%1$s' on port '%2$d'.
*/
public static final String SOSVfs_I_0109 = "SOSVfs_I_0109";
@I18NMessages(value = { @I18NMessage("Connection to host '%1$s' on port '%2$d' not possible, error is '%3$s'"), //
@I18NMessage(value = "Connection to host '%1$s' on port '%2$d' not possible, error is '%3$s'", //
locale = "en_UK", //
explanation = "Connection to host '%1$s' on port '%2$d' not possible" //
), //
@I18NMessage(value = "Verbindung zum Rechner '%1$s' �ber Port-Nummer '%2$d' nicht m�glich. Fehler: %3$s", //
locale = "de", //
explanation = "Connection to host '%1$s' on port '%2$d' not possible, error is '%3$s'" //
), //
@I18NMessage(value = "Connection to host '%1$s' on port '%2$d' not possible, error is '%3$s'", locale = "es", //
explanation = "Connection to host '%1$s' on port '%2$d' not possible" //
), //
@I18NMessage(value = "Connection to host '%1$s' on port '%2$d' not possible, error is '%3$s'", locale = "fr", //
explanation = "Connection to host '%1$s' on port '%2$d' not possible" //
), //
@I18NMessage(value = "Connection to host '%1$s' on port '%2$d' not possible, error is '%3$s'", locale = "it", //
explanation = "Connection to host '%1$s' on port '%2$d' not possible" //
) //
}, msgnum = "SOSVfs-E-0107", msgurl = "SOSVfs-E-0107")
/*!
* \var SOSVfs_E_0107
* \brief Connection to host '%1$s' on port '%2$d' not possible
*/
public static final String SOSVfs_E_0107 = "SOSVfs_E_0107";
@I18NMessages(value = { @I18NMessage("..server reply [%1$s] (with param '%2$s') is '%3$s'."), //
@I18NMessage(value = "..server reply [%1$s] (with param '%2$s') is '%3$s'.", //
locale = "en_UK", //
explanation = "..server reply [%1$s] (with param '%2$s') is '%3$s'." //
), //
@I18NMessage(value = "..Antwort des Rechners nach Kommando '%1$s' (mit Parameter '%2$s') lautet: '%3$s'.", //
locale = "de", //
explanation = "..server reply [%1$s] (with param '%2$s') is '%3$s'." //
), //
@I18NMessage(value = "..server reply [%1$s] (with param '%2$s') is '%3$s'.", locale = "es", //
explanation = "..server reply [%1$s] (with param '%2$s') is '%3$s'." //
), //
@I18NMessage(value = "..server reply [%1$s] (with param '%2$s') is '%3$s'.", locale = "fr", //
explanation = "..server reply [%1$s] (with param '%2$s') is '%3$s'." //
), //
@I18NMessage(value = "..server reply [%1$s] (with param '%2$s') is '%3$s'.", locale = "it", //
explanation = "..server reply [%1$s] (with param '%2$s') is '%3$s'." //
) //
}, msgnum = "SOSVfs-E-0106", msgurl = "SOSVfs-E-0106")
/*!
* \var SOSVfs_D_0106
* \brief ..server reply [%1$s] (with param '%2$s') is '%3$s'.
*/
public static final String SOSVfs_E_0106 = "SOSVfs_E_0106";
@I18NMessages(value = {
@I18NMessage("processing aborted, '%1$s' returns an exception, see stacktrace on stderr"), //
@I18NMessage(value = "processing aborted, '%1$s' returns an exception, see stacktrace on stderr", //
locale = "en_UK", //
explanation = "%1$s returns an exception, see stacktrace on stderr" //
), //
@I18NMessage(value = "Verarbeitung wird abgebrochen, '%1$s' verursacht einen Ausnahmefehler (exception) und beendet sich. Weitere Informationen im StackTrace.", //
locale = "de", //
explanation = "%1$s returns an exception" //
), //
@I18NMessage(value = "%1$s returns an exception, see stacktrace on stderr", locale = "es", //
explanation = "%1$s returns an exception" //
), //
@I18NMessage(value = "%1$s returns an exception, see stacktrace on stderr", locale = "fr", //
explanation = "%1$s returns an exception" //
), //
@I18NMessage(value = "%1$s returns an exception, see stacktrace on stderr", locale = "it", //
explanation = "%1$s returns an exception" //
) //
}, msgnum = "SOSVfs-E-0105", msgurl = "SOSVfs-E-0105")
/*!
* \var SOSVfs_E_0105
* \brief %1$s returns an exception
*/
public static final String SOSVfs_E_0105 = "SOSVfs_E_0105";
@I18NMessages(value = { @I18NMessage("Try to connect to host '%1$s' at Port '%2$d'."), //
@I18NMessage(value = "Try to connect to host '%1$s' at Port '%2$d'.", locale = "en_UK", //
explanation = "Try to connect to host '%1$s' at Port '%2$d'." //
), //
@I18NMessage(value = "Starte einen Verbindungsaufbau mit Rechner '%1$s' �ber Port-Nummer '%2$d'.", locale = "de", //
explanation = "Try to connect to host '%1$s' at Port '%2$d'." //
) //
}, msgnum = "SOSVfs-D-0101", msgurl = "SOSVfs-D-0101")
/*!
* \var SOSVfs-I-0101
* \brief Try to connect to host '%1$s' at Port '%2$d'.
*/
public static final String SOSVfs_D_0101 = "SOSVfs-D-0101";
@I18NMessages(value = { @I18NMessage("Connected to '%1$s' at Port '%2$d'."), //
@I18NMessage(value = "Connected to '%1$s' at Port '%2$d'.", locale = "en_UK", //
explanation = "Connected to '%1$s' at Port '%2$d'." //
), //
@I18NMessage(value = "Verbunden mit Rechner '%1$s' �ber Port-Nummer '%2$d'.", locale = "de", //
explanation = "Verbunden mit Rechner '%1$s' �ber Port-Nummer '%2$d'." //
) //
}, msgnum = "SOSVfs-D-0102", msgurl = "SOSVfs-D-0102")
/*!
* \var SOSVfs_D_0102
* \brief Connected to '%1$s' at Port '%2$d'.
*/
public static final String SOSVfs_D_0102 = "SOSVfs_D_0102";
@I18NMessages(value = { @I18NMessage("host '%1$s' at Port '%2$d' is already connected."), //
@I18NMessage(value = "host '%1$s' at Port '%2$d' is already connected.", locale = "en_UK", //
explanation = "host '%1$s' at Port '%2$d' is already connected." //
), //
@I18NMessage(value = "Der Rechner '%1$s' an Port-Nummer '%2$d' ist bereits verbunden.", locale = "de", //
explanation = "Der Rechner '%1$s' an Port-Nummer '%2$d' ist bereits verbunden." //
) //
}, msgnum = "SOSVfs-D-0103", msgurl = "SOSVfs-D-0103")
/*!
* \var SOSVfs_D_0103
* \brief host '%1$s' at Port '%2$d' is already connected.
*/
public static final String SOSVfs_D_0103 = "SOSVfs_D_0103";
private Vector<String> vecDirectoryListing = null;
private FTPClient objFTPClient = null;
@Deprecated
private ISOSConnectionOptions objConnectionOptions = null;
private SOSConnection2OptionsAlternate objConnection2Options = null;
private String strCurrentPath = EMPTY_STRING;
private String strReply = EMPTY_STRING;
private ProtocolCommandListener listener = null;
private String host = EMPTY_STRING;
private int port = 0;
private String gstrUser = EMPTY_STRING;
private SOSOptionHostName objHost = null;
private SOSOptionPortNumber objPort = null;
protected boolean utf8Supported = false;
protected boolean restSupported = false;
protected boolean mlsdSupported = false;
protected boolean modezSupported = false;
protected boolean dataChannelEncrypted = false;
/**
*
* \brief SOSVfsFtp
*
* \details
*
*/
public SOSVfsFtp() {
}
private String HostID(String pstrText) {
return "(" + gstrUser + "@" + host + ":" + port + ") " + pstrText;
}
/*
* @param host the remote ftp server
* @param port the port number of the remote server
* @throws java.net.SocketException
* @throws java.io.IOException
* @throws java.net.UnknownHostException
* @see org.apache.commons.net.SocketClient#connect(java.lang.String, int)
*/
public void connect(String phost, int pport) {
final String conMethodName = conClassName + "::connect";
try {
host = phost;
port = pport;
String strM = String.format(objMsg.getMsg(SOSVfs_D_0101), host, port);
logger.debug(strM);
if (isConnected() == false) {
Client().connect(host, port);
logger.debug(String.format(objMsg.getMsg(SOSVfs_D_0102), host, port));
LogReply();
}
else {
logger.warn(String.format(objMsg.getMsg(SOSVfs_D_0102), host, port));
}
}
catch (Exception e) {
e.printStackTrace(System.err);
// RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
/*
* @param host the remote ftp server
* @param port the port number of the remote server
* @throws java.net.SocketException
* @throws java.io.IOException
* @throws java.net.UnknownHostException
* @see org.apache.commons.net.SocketClient#connect(java.lang.String)
*/
@SuppressWarnings("unused")
private void connect(String hostname) throws SocketException, IOException, UnknownHostException {
if (isConnected() == false)
Client().connect(hostname);
}
/**
* Creates a new subdirectory on the FTP server in the current directory .
* @param pathname The pathname of the directory to create.
* @return True if successfully completed, false if not.
* @throws java.lang.IOException
*/
public void mkdir(String pathname) {
final String conMethodName = conClassName + "::mkdir";
try {
Client().makeDirectory(pathname);
logger.debug(HostID(String.format(objMsg.getMsg(SOSVfs_E_0106), conMethodName, pathname, getReplyString())));
}
catch (IOException e) {
String strM = HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName));
e.printStackTrace(System.err);
throw new RuntimeException(strM, e);
}
}
/**
* Removes a directory on the FTP server (if empty).
* @param pathname The pathname of the directory to remove.
* @return True if successfully completed, false if not.
* @throws java.lang.IOException
*/
public void rmdir(String pathname) throws IOException {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::rmdir";
Client().removeDirectory(pathname);
logger.debug(HostID(String.format(objMsg.getMsg(SOSVfs_E_0106), conMethodName, pathname, getReplyString())));
}
/**
* turn passive transfer mode on.
*
* @return The reply code received from the server.
*/
public int passive() {
final String conMethodName = conClassName + "::passive";
try {
int i = Client().pasv();
if (isPositiveCommandCompletion() == false) {
throw new RuntimeException(HostID(String.format(objMsg.getMsg(SOSVfs_E_0106), conMethodName, "", getReplyString())));
}
else {
this.logger.debug(HostID(String.format(objMsg.getMsg(SOSVfs_E_0106), conMethodName, "", getReplyString())));
}
return i;
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return 0;
}
/**
* return a listing of the contents of a directory in short format on
* the remote machine
* @param pathname on remote machine
* @return a listing of the contents of a directory on the remote machine
*
* @exception Exception
* @see #dir()
*/
public Vector<String> nList(String pathname) {
return getFilenames(pathname);
} // nList
private Vector<String> getFilenames(String pathname) {
return getFilenames(pathname, false);
}
/**
* return a listing of the contents of a directory in short format on
* the remote machine (without subdirectory)
*
* @param pathname on remote machine
* @return a listing of the contents of a directory on the remote machine
* @throws IOException
*
* @exception Exception
* @see #dir()
*/
private Vector<String> getFilenames(String pstrPathName, boolean flgRecurseSubFolders) {
String strCurrentDirectory = null;
// TODO vecDirectoryListing = null; pr�fen, ob notwendig
vecDirectoryListing = null;
if (vecDirectoryListing == null) {
vecDirectoryListing = new Vector<String>();
String[] fileList = null;
strCurrentDirectory = DoPWD();
String lstrPathName = pstrPathName.trim();
if (lstrPathName.length() <= 0) {
lstrPathName = ".";
}
if (lstrPathName.equals(".")) {
lstrPathName = strCurrentDirectory;
}
if (1 == 1) {
try {
fileList = listNames(lstrPathName);
// fileList = listNames(pstrPathName);
}
catch (IOException e) {
e.printStackTrace(System.err);
}
}
// else {
// FTPFile[] objFtpFiles = Client().listFiles(lstrPathName);
// if (objFtpFiles != null) {
// int i = 0;
// for (FTPFile ftpFile : objFtpFiles) {
// fileList[i++] = ftpFile.getName();
// }
// }
// }
if (fileList == null) {
return vecDirectoryListing;
}
for (String strCurrentFile : fileList) {
if (isNotHiddenFile(strCurrentFile)) {
if (flgRecurseSubFolders == false) {
if (strCurrentFile.startsWith(strCurrentDirectory) == false)
strCurrentFile = strCurrentDirectory + "/" + strCurrentFile;
vecDirectoryListing.add(strCurrentFile);
}
else {
DoCD(strCurrentFile); // is this file-entry a subfolder?
if (isNegativeCommandCompletion()) {
if (strCurrentFile.startsWith(strCurrentDirectory) == false)
strCurrentFile = strCurrentDirectory + "/" + strCurrentFile;
vecDirectoryListing.add(strCurrentFile);
}
else {
DoCD(strCurrentDirectory);
if (flgRecurseSubFolders) {
Vector<String> vecNames = getFilenames(strCurrentFile);
if (vecNames != null) {
vecDirectoryListing.addAll(vecNames);
}
}
}
}
}
}
}
logger.debug("strCurrentDirectory = " + strCurrentDirectory);
if (strCurrentDirectory != null) {
DoCD(strCurrentDirectory);
DoPWD();
}
return vecDirectoryListing;
} // nList
public boolean isDirectory(final String pstrPathName) {
boolean flgResult = false;
if (isNotHiddenFile(pstrPathName)) {
if (strCurrentPath.length() <= 0) {
strCurrentPath = getCurrentPath();
}
DoCD(pstrPathName); // is this file-entry a subfolder?
if (isNegativeCommandCompletion()) {
}
else { // yes, it's a subfolder. undo the cd now
DoCD(strCurrentPath);
flgResult = true;
}
}
return flgResult;
}
public String DoPWD() {
final String conMethodName = conClassName + "::DoPWD";
String lstrCurrentPath = "";
try {
logger.debug("Try pwd.");
lstrCurrentPath = getCurrentPath();
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return lstrCurrentPath;
} // private int DoPWD
private String getCurrentPath() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::getCurrentPath";
String lstrCurrentPath = strCurrentPath;
try {
Client().pwd();
lstrCurrentPath = getReplyString();
logger.debug(HostID(String.format(objMsg.getMsg(SOSVfs_E_0106), conMethodName, "", lstrCurrentPath)));
// Windows reply from pwd is : 257 "/kb" is current directory.
// Unix reply from pwd is : 257 "/home/kb"
int idx = lstrCurrentPath.indexOf('"'); // Unix?
if (idx >= 0) {
lstrCurrentPath = lstrCurrentPath.substring(idx + 1, lstrCurrentPath.length() - idx + 1);
idx = lstrCurrentPath.indexOf('"');
if (idx >= 0) {
lstrCurrentPath = lstrCurrentPath.substring(0, idx);
}
}
LogReply();
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return lstrCurrentPath;
}
@SuppressWarnings("unused")
private int DoCDUP() {
final String conMethodName = conClassName + "::DoCDUP";
try {
logger.debug("Try cdup .");
Client().cdup();
LogReply();
DoPWD();
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return 0;
} // private int DoPWD
private int DoCD(final String strFolderName) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::DoCD";
int x = 0;
try {
logger.debug("Try cd with '" + strFolderName + "'.");
x = cd(strFolderName);
LogReply();
}
catch (IOException e) {
}
return x;
} // private int DoCD
private boolean LogReply() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::LogReply";
strReply = getReplyString();
logger.debug(HostID(strReply));
return true;
} // private boolean LogReply
public boolean isNegativeCommandCompletion() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::isNegativeCommandCompletion";
int x = Client().getReplyCode();
return (x > 300);
} // private boolean isNegativeCommandCompletion
public void CompletePendingCommand() {
final String conMethodName = conClassName + "::CompletePendingCommand";
try {
if (Client().completePendingCommand() == false) {
logout();
disconnect();
RaiseException(HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
if (isNegativeCommandCompletion()) {
throw new JobSchedulerException("..error occurred 'NegativeCommandCompletion' on the FTP server: " + getReplyString());
}
}
private boolean isPositiveCommandCompletion() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::isPositiveCommandCompletion";
int x = Client().getReplyCode();
return (x <= 300);
} // private boolean isPositiveCommandCompletion
public boolean isNotHiddenFile(final String strFileName) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::isNotHiddenFile";
if (strFileName.equalsIgnoreCase("..") == false && strFileName.equalsIgnoreCase(".") == false) {
return true; // not a hidden file
}
return false; // it is a hidden-file
} // private boolean isNotHiddenFile
/**
* return a listing of the contents of a directory in short format on
* the remote machine
* @param pathname on remote machine
* @return a listing of the contents of a directory on the remote machine
*
* @exception Exception
* @see #dir()
*/
@Override
public Vector<String> nList(String pathname, final boolean flgRecurseSubFolder) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::nList";
try {
return getFilenames(pathname, flgRecurseSubFolder);
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return null; // useless, but required by syntax-check
} // nList
/**
* return a listing of the contents of a directory in short format on
* the remote machine
*
* @return a listing of the contents of a directory on the remote machine
*
* @exception Exception
* @see #nList( String )
* @see #dir()
* @see #dir( String )
*/
@Override
public Vector<String> nList() throws Exception {
return getFilenames();
} // nList
/**
* return a listing of the contents of a directory in short format on
* the remote machine (without subdirectory)
*
* @return a listing of the contents of a directory on the remote machine
*
* @exception Exception
* @see #nList( String )
* @see #dir()
* @see #dir( String )
*/
private Vector<String> getFilenames() throws Exception {
return getFilenames("", false);
} // getFilenames
private Vector<String> getFilenames(boolean flgRecurseSubFolders) throws Exception {
return getFilenames("", flgRecurseSubFolders);
} // getFilenames
/**
* return a listing of the contents of a directory in short format on
* the remote machine
*
* @return a listing of the contents of a directory on the remote machine
*
* @exception Exception
* @see #nList( String )
* @see #dir()
* @see #dir( String )
*/
@Override
public Vector<String> nList(boolean recursive) throws Exception {
return getFilenames(recursive);
} // nList
/**
* return a listing of the files in a directory in long format on
* the remote machine
* @param pathname on remote machine
* @return a listing of the contents of a directory on the remote machine
* @exception Exception
* @see #nList()
* @see #nList( String )
* @see #dir()
*/
public SOSFileList dir(String pathname) {
Vector<String> strList = getFilenames(pathname);
String[] strT = (String[]) strList.toArray(new String[strList.size()]);
SOSFileList objFileList = new SOSFileList(strT);
return objFileList;
}
/**
* return a listing of a directory in long format on
* the remote machine
*
* @param pathname on remote machine
* @return a listing of the contents of a directory on the remote machine
* @exception Exception
* @see #nList()
* @see #nList( String )
* @see #dir()
*/
@Override
public SOSFileList dir(String pathname, int flag) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::dir";
SOSFileList fileList = new SOSFileList();
FTPFile[] listFiles = null;
try {
listFiles = Client().listFiles(pathname);
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
for (int i = 0; i < listFiles.length; i++) {
if (flag > 0 && listFiles[i].isDirectory()) {
fileList.addAll(this.dir(pathname + "/" + listFiles[i].toString(), ((flag >= 1024) ? flag : flag + 1024)));
}
else {
if (flag >= 1024) {
fileList.add(pathname + "/" + listFiles[i].toString());
}
else {
fileList.add(listFiles[i].toString());
}
}
}
return fileList;
}
/**
* return a listing of the files of the current directory in long format on
* the remote machine
* @return a listing of the contents of the current directory on the remote machine
* @exception Exception
* @see #nList()
* @see #nList( String )
* @see #dir( String )
*/
public SOSFileList dir() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::dir";
try {
return dir(".");
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return null;
}
/**
* @return The entire text from the last FTP response as a String.
*/
public String getResponse() {
return this.getReplyString();
}
/**
* return the size of remote-file on the remote machine on success, otherwise -1
* @param remoteFile the file on remote machine
* @return the size of remote-file on remote machine
*/
public long size(String remoteFile) throws Exception {
Client().sendCommand("SIZE " + remoteFile);
LogReply();
if (Client().getReplyCode() == FTPReply.CODE_213)
return Long.parseLong(trimResponseCode(this.getReplyString()));
else
return -1L; // file not found or size not available
}
/**
* trim the response code at the beginning
* @param response
* @return the response string without response code
* @throws Exception
*/
private String trimResponseCode(String response) throws Exception {
if (response.length() < 5)
return response;
return response.substring(4).trim();
}
/**
* Retrieves a named file from the ftp server.
*
* @param localFile The name of the local file.
* @param remoteFile The name of the remote file.
* @exception Exception
* @see #getFile( String, String )
*/
public void get(String remoteFile, String localFile) {
final String conMethodName = conClassName + "::get";
FileOutputStream out = null;
boolean rc = false;
try {
out = new FileOutputStream(localFile);
rc = Client().retrieveFile(remoteFile, out);
if (rc == false) {
RaiseException(HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
finally {
closeObject(out);
}
} // get
private void closeObject(OutputStream objO) {
try {
if (objO != null) {
objO.flush();
objO.close();
objO = null;
}
}
catch (Exception e) {
}
}
private void closeInput(InputStream objO) {
try {
if (objO != null) {
objO.close();
objO = null;
}
}
catch (IOException e) {
}
}
/**
* Retrieves a named file from the ftp server.
*
* @param localFile The name of the local file.
* @param remoteFile The name of the remote file.
* @return The total number of bytes retrieved.
* @see #get( String, String )
* @exception Exception
*/
@Override
public long getFile(String remoteFile, String localFile) {
final boolean flgAppendLocalFile = false;
return this.getFile(remoteFile, localFile, flgAppendLocalFile);
}
/**
* Retrieves a named file from the ftp server.
*
* @param localFile The name of the local file.
* @param remoteFile The name of the remote file.
* @param append Appends the remote file to the local file.
* @return The total number of bytes retrieved.
* @see #get( String, String )
* @exception Exception
*/
@Override
public long getFile(String remoteFile, String localFile, boolean append) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::getFile";
InputStream in = null;
OutputStream out = null;
long totalBytes = 0;
try {
// TODO get filesize and report as a message
in = Client().retrieveFileStream(remoteFile);
if (in == null) {
throw new JobSchedulerException("Could not open stream for " + remoteFile + ". Perhaps the file does not exist. Reply from ftp server: "
+ getReplyString());
}
if (isPositiveCommandCompletion() == false) {
throw new JobSchedulerException("..error occurred in getFile() [retrieveFileStream] on the FTP server for file [" + remoteFile + "]: "
+ getReplyString());
}
// TODO Buffersize must be an Option
byte[] buffer = new byte[4096];
out = new FileOutputStream(new File(localFile), append);
// TODO get progress info
int bytes_read = 0;
synchronized (this) {
while ((bytes_read = in.read(buffer)) != -1) {
// TODO create progress message
out.write(buffer, 0, bytes_read);
out.flush();
totalBytes += bytes_read;
}
}
closeInput(in);
closeObject(out);
this.CompletePendingCommand();
// TODO create completed Message
if (totalBytes > 0)
return totalBytes;
else
return -1L;
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
finally {
closeInput(in);
closeObject(out);
}
return totalBytes;
}
/**
* Stores a file on the server using the given name.
* @param localFile The name of the local file.
* @param remoteFile The name of the remote file.
* @return True if successfully completed, false if not.
* @exception Exception
* @see #putFile( String, String )
*/
@Override
public void put(String localFile, String remoteFile) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::put";
FileInputStream in = null;
boolean rc = false;
try {
in = new FileInputStream(localFile);
// TODO get progress info
rc = Client().storeFile(remoteFile, in);
if (rc == false) {
RaiseException("put returns a negative returncode");
}
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
finally {
closeInput(in);
}
}
/**
* Stores a file on the server using the given name.
*
* @param localFile The name of the local file.
* @param remoteFile The name of the remote file.
* @return The total number of bytes written.
*
* @exception Exception
* @see #put( String, String )
*/
@Override
// ISOSVfsFileTransfer
public long putFile(String localFile, String remoteFile) throws Exception {
OutputStream outputStream = Client().storeFileStream(remoteFile);
if (isNegativeCommandCompletion()) {
RaiseException("..error occurred in get storeFileStream() on the FTP server for file [" + remoteFile + "]: " + getReplyString());
}
long i = putFile(localFile, outputStream);
logger.debug(String.format("file '%1$s' transfered to '%2$s'", localFile, remoteFile));
return i;
} // putFile
/**
* written to store a file on the server using the given name.
*
* @param localfile The name of the local file.
* @param an OutputStream through which data can be
* @return The total number of bytes written.
* @exception Exception
*/
@SuppressWarnings("null")
@Override
public long putFile(String localFile, OutputStream out) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::putFile";
if (out == null)
RaiseException("OutputStream null value.");
FileInputStream in = null;
long lngTotalBytesWritten = 0;
try {
// TODO Buffersize must be an Option
byte[] buffer = new byte[4096];
in = new FileInputStream(new File(localFile));
// TODO get progress info
int bytesWritten;
synchronized (this) {
while ((bytesWritten = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesWritten);
lngTotalBytesWritten += bytesWritten;
}
}
closeInput(in);
closeObject(out);
this.CompletePendingCommand();
// if (Client().completePendingCommand() == false) {
// logout();
// disconnect();
// RaiseException("Filetransfer failed. completePendingCommand() returns false");
// }
// if (isNegativeCommandCompletion()) {
// RaiseException("..error occurred in putFile() on the FTP server for file [" + localFile + "]: " + getReplyString());
// }
return lngTotalBytesWritten;
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
finally {
closeInput(in);
closeObject(out);
}
return lngTotalBytesWritten;
} // putFile
private void RaiseException(final Exception e, final String pstrM) {
if (flgStackTracePrinted == false) {
e.printStackTrace(System.err);
logger.error(pstrM);
flgStackTracePrinted = true;
}
throw new JobSchedulerException(pstrM, e);
}
private void RaiseException(final String pstrM) {
logger.error(pstrM);
throw new JobSchedulerException(pstrM);
}
public FTPClient getClient() {
return Client();
}
/**
* append a local file to the remote one on the server
*
* @param localFile The name of the local file.
* @param remoteFile The name of the remote file.
*
* @return The total number of bytes appended.
*
* @exception Exception
* @see #put( String, String )
* @see #putFile( String, String )
*/
@Override
public long appendFile(String localFile, String remoteFile) {
final String conMethodName = conClassName + "::appendFile";
long i = 0;
try {
i = putFile(localFile, Client().appendFileStream(remoteFile));
logger.info("bytes appended : " + i);
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return i;
} // appendFile
/**
* Using ASCII mode for file transfers
* @return True if successfully completed, false if not.
* @throws IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public void ascii() {
final String conMethodName = conClassName + "::ascii";
try {
boolean flgResult = Client().setFileType(FTP.ASCII_FILE_TYPE);
if (flgResult == false) {
throw new JobSchedulerException("setFileType not possible, due to : " + getReplyString());
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
/**
* Using Binary mode for file transfers
* @return True if successfully completed, false if not.
* @throws IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public void binary() {
final String conMethodName = conClassName + "::binary";
try {
boolean flgResult = Client().setFileType(FTP.BINARY_FILE_TYPE);
if (flgResult == false) {
throw new JobSchedulerException("setFileType not possible, due to : " + getReplyString());
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
/**
*
* @param directory The new working directory.
* @return The reply code received from the server.
* @throws IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public int cd(String directory) throws IOException {
return Client().cwd(directory);
}
/**
* Deletes a file on the FTP server.
* @param The pathname of the file to be deleted.
* @return True if successfully completed, false if not.
* @throws IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public void delete(String pathname) throws IOException {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::delete";
Client().deleteFile(pathname);
logger.info(String.format("File deleted : %1$s, reply is %2$s", pathname, getReplyString()));
}
@Override
public void login(String strUserName, String strPassword) {
final String conMethodName = conClassName + "::login";
try {
logger.debug(String.format("Try to login with user '%1$s'.", strUserName));
Client().login(strUserName, strPassword);
// TODO pr�fen, ob wirklich eingeloggt
logger.debug(HostID(String.format("user '%1$s' logged in.", strUserName)));
LogReply();
try {
postLoginOperations();
}
catch (Exception e) {
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
LogReply();
} // private boolean login
/**
* Performs some post-login operations, such trying to detect server support
* for utf8.
*
*/
private void postLoginOperations() throws Exception {
// synchronized (lock) {
// if (objOptions.CheckServerFeatures.value() == true) { // JIRA SOSFTP-92
Client().sendCommand("FEAT");
LogReply();
// }
if (objFTPReply.getCode() == FTPReply.SYSTEM_STATUS) {
String[] lines = objFTPReply.getMessages();
for (int i = 1; i < lines.length - 1; i++) {
String feat = lines[i].trim().toUpperCase();
// REST STREAM supported?
if ("REST STREAM".equalsIgnoreCase(feat)) {
restSupported = true;
continue;
}
// UTF8 supported?
if ("UTF8".equalsIgnoreCase(feat)) {
utf8Supported = true;
Client().setControlEncoding("UTF-8");
continue;
}
// MLSD supported?
if ("MLSD".equalsIgnoreCase(feat)) {
mlsdSupported = true;
continue;
}
// MODE Z supported?
if ("MODE Z".equalsIgnoreCase(feat) || feat.startsWith("MODE Z ")) {
modezSupported = true;
continue;
}
}
}
// Turn UTF 8 on (if supported).
if (utf8Supported) {
Client().sendCommand("OPTS UTF8 ON");
LogReply();
}
// Data channel security.
// if (security == SECURITY_FTPS || security == SECURITY_FTPES) {
// Client().sendCommand("PBSZ 0");
// LogReply();
// Client().sendCommand("PROT P");
// LogReply();
//
// if (objFTPReply.isSuccessCode()) {
// dataChannelEncrypted = true;
// }
// }
}
@Override
public boolean changeWorkingDirectory(String pathname) {
final String conMethodName = conClassName + "::changeWorkingDirectory";
try {
Client().cwd(pathname);
logger.debug("..ftp server reply [directory exists] [" + pathname + "]: " + getReplyString());
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return true;
}
@Override
public void disconnect() {
final String conMethodName = conClassName + "::disconnect";
try {
if (Client().isConnected()) {
Client().disconnect();
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
@Override
public String getReplyString() {
String strT = Client().getReplyString();
objFTPReply = new SOSFtpServerReply(strT);
return strT;
}
@Override
public boolean isConnected() {
return Client().isConnected();
}
@Override
public String[] listNames(String pathname) throws IOException {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::listNames";
String strA[] = Client().listNames(pathname);
for (int i = 0; i < strA.length; i++) {
strA[i] = strA[i].replaceAll("\\\\", "/");
}
logger.debug(String.format("reply from FTP-Server is %1$s, code = %2$d", Client().getReplyString(), Client().getReplyCode()));
return strA;
}
@Override
public void logout() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::logout";
try {
if (this.Client().isConnected() == true) {
this.Client().logout();
String strHost = host;
if (objHost != null) {
strHost = objHost.Value();
}
logger.debug(String.format("logout from host '%1$s', reply '%2$s'", strHost, getReplyString()));
}
else {
logger.info("not connected, logout useless.");
}
}
catch (IOException e) { // no error-handling needed, due to end-of session
logger.warn("problems during logout. " + e.getMessage());
}
}
public void rename(String from, String to) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::rename";
try {
this.Client().rename(from, to);
}
catch (IOException e) {
e.printStackTrace();
RaiseException(e, "rename failed");
}
logger.info(String.format("rename file '%1$s' to '%2$s'.", from, to));
}
@Override
public ISOSVFSHandler getHandler() {
return this;
}
@Override
public void ExecuteCommand(String strCmd) throws Exception {
final String conMethodName = conClassName + "::ExecuteCommand";
objFTPClient.sendCommand(strCmd);
logger.debug(HostID(String.format(objMsg.getMsg(SOSVfs_E_0106), conMethodName, strCmd, getReplyString())));
}
@Override
public String createScriptFile(String pstrContent) throws Exception {
notImplemented();
return null;
}
@Override
public Integer getExitCode() {
notImplemented();
return null;
}
@Override
public String getExitSignal() {
notImplemented();
return null;
}
@SuppressWarnings("unused")
private ISOSAuthenticationOptions objAO = null;
@Override
public ISOSConnection Authenticate(ISOSAuthenticationOptions pobjAO) throws Exception {
String user = pobjAO.getUser().Value();
String Passwd = pobjAO.getPassword().Value();
this.login(user, Passwd);
objAO = pobjAO;
return this;
}
@Override
public void CloseConnection() throws Exception {
if (Client().isConnected()) {
Client().disconnect();
LogReply();
logger.debug(String.format(objMsg.getMsg(SOSVfs_I_0109), host, port));
}
}
private FTPClient Client() {
if (objFTPClient == null) {
objFTPClient = new FTPClient();
FTPClientConfig conf = new FTPClientConfig();
// conf.setServerLanguageCode("fr");
// objFTPClient.configure(conf);
/**
* This listener is to write all commands and response from commands to system.out
*
*/
// TODO create a hidden debug-option to activate this listener
if (objConnection2Options != null) {
if (objConnection2Options.ProtocolCommandListener.value() == true) {
listener = new PrintCommandListener(new PrintWriter(System.out));
objFTPClient.addProtocolCommandListener(listener);
}
}
listener = new PrintCommandListener(new PrintWriter(System.out));
// TODO implement as an additional Option-setting
String strAddFTPProtocol = System.getenv("AddFTPProtocol");
if (strAddFTPProtocol != null && strAddFTPProtocol.equalsIgnoreCase("true")) {
objFTPClient.addProtocolCommandListener(listener);
}
}
return objFTPClient;
}
/**
*
* \brief Connect
*
* \details
*
* \return
*
* @return
*/
@Override
public ISOSConnection Connect() {
final String conMethodName = conClassName + "::Connect";
String strH = host = objConnectionOptions.getHost().Value();
int intP = port = objConnectionOptions.getPort().value();
logger.debug(objMsg.getMsg(String.format(SOSVfs_D_0101), strH, intP));
try {
this.connect(strH, intP);
logger.debug(String.format(objMsg.getMsg(SOSVfs_D_0102), strH, intP));
}
catch (RuntimeException e) {
logger.info(String.format(objMsg.getMsg(SOSVfs_E_0107), host, port, e.getMessage()));
String strAltHost = host = objConnectionOptions.getalternative_host().Value();
int intAltPort = port = objConnectionOptions.getalternative_port().value();
if (isNotEmpty(strAltHost) && intAltPort > 0) {
logger.debug(objMsg.getMsg(String.format(SOSVfs_D_0101), strAltHost, intAltPort));
this.connect(strAltHost, intAltPort);
logger.debug(String.format(objMsg.getMsg(SOSVfs_D_0102), strAltHost, intAltPort));
}
else {
logger.info(String.format(objMsg.getMsg(SOSVfs_E_0107), host, port, e.getMessage()));
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
return this;
}
/**
*
* \brief Connect
*
* \details
*
* \return
*
* @param pobjConnectionOptions
* @return
*/
public ISOSConnection Connect(SOSConnection2OptionsAlternate pobjConnectionOptions) {
final String conMethodName = conClassName + "::Connect";
objConnection2Options = pobjConnectionOptions;
try {
objHost = objConnection2Options.getHost();
objPort = objConnection2Options.getport();
this.connect(objHost.Value(), objPort.value());
if (Client().isConnected() == false) {
SOSConnection2OptionsSuperClass objAlternate = objConnection2Options.Alternatives();
objHost = objAlternate.host;
objPort = objAlternate.port;
logger.info(String.format("try alternate host due to connection-error", host));
this.connect(objHost.Value(), objPort.value());
if (Client().isConnected() == false) {
objHost = null;
objPort = null;
host = "";
port = -1;
RaiseException("Connection not possible");
}
}
// TODO find the "Microsoft FTP Server" String from the reply and set the HostType accordingly
// TODO respect Proxy-Server. implement handling of
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return this;
}
@Deprecated
@Override
public ISOSConnection Connect(ISOSConnectionOptions pobjConnectionOptions) throws Exception {
final String conMethodName = conClassName + "::Connect";
objConnectionOptions = pobjConnectionOptions;
try {
String host = objConnectionOptions.getHost().Value();
int port = objConnectionOptions.getPort().value();
// TODO try alternate host, if this connection is not possible
this.connect(host, port);
// TODO find the "Microsoft FTP Server" String from the reply and set the HostType accordingly
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return this;
}
@Override
public ISOSConnection Connect(String pstrHostName, int pintPortNumber) throws Exception {
this.connect(pstrHostName, pintPortNumber);
if (objConnectionOptions != null) {
objConnectionOptions.getHost().Value(pstrHostName);
objConnectionOptions.getPort().value(pintPortNumber);
}
return this;
}
@Override
public void CloseSession() throws Exception {
this.logout();
}
@Override
public ISOSSession OpenSession(ISOSShellOptions pobjShellOptions) throws Exception {
notImplemented();
return null;
}
@Override
public ISOSVirtualFile TransferMode(SOSOptionTransferMode pobjFileTransferMode) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::TransferMode";
String strMode = pobjFileTransferMode.getDescription();
if (pobjFileTransferMode.isAscii()) {
this.ascii();
}
else {
this.binary();
}
logger.debug(String.format("using %1$s mode for file transfer", strMode));
logger.debug(String.format("ftp server reply [%1$s]: %2$s", strMode, getReplyString()));
return null;
}
public SOSFileListEntry getNewVirtualFile(final String pstrFileName) {
SOSFileListEntry objF = new SOSFileListEntry(pstrFileName);
objF.VfsHandler(this);
return objF;
}
@Override
public ISOSVirtualFolder mkdir(SOSFolderName pobjFolderName) {
this.mkdir(pobjFolderName.Value());
return null;
}
@Override
public boolean rmdir(SOSFolderName pobjFolderName) throws IOException {
this.rmdir(pobjFolderName.Value());
return true;
}
@Override
public ISOSConnection getConnection() {
return this;
}
@Override
public ISOSSession getSession() {
return null;
}
@Override
public SOSFileList dir(SOSFolderName pobjFolderName) {
this.dir(pobjFolderName.Value());
return null;
}
@Override
public StringBuffer getStdErr() throws Exception {
// TODO Auto-generated method stub
return null;
}
@Override
public StringBuffer getStdOut() throws Exception {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean remoteIsWindowsShell() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setJSJobUtilites(JSJobUtilities pobjJSJobUtilities) {
// TODO Auto-generated method stub
}
@Override
public ISOSVirtualFile getFileHandle(String pstrFilename) {
final String conMethodName = conClassName + "::getFileHandle";
ISOSVirtualFile objFtpFile = new SOSVfsFtpFile(pstrFilename);
logger.debug(String.format("%2$s: getFileHandle for %1$s ", pstrFilename, conMethodName));
objFtpFile.setHandler(this);
return objFtpFile;
}
@Override
public String[] getFilelist(String folder, String regexp, int flag, boolean withSubFolder) {
// TODO vecDirectoryListing = null; pr�fen, ob notwendig
vecDirectoryListing = null;
if (vecDirectoryListing == null) {
vecDirectoryListing = nList(folder, withSubFolder);
}
Vector<String> strB = new Vector<String>();
Pattern pattern = Pattern.compile(regexp, 0);
for (String strFile : vecDirectoryListing) {
/**
* the file_spec has to be compared to the filename only ... excluding the path
*/
String strFileName = new File(strFile).getName();
Matcher matcher = pattern.matcher(strFileName);
if (matcher.find() == true) {
strB.add(strFile);
}
}
return strB.toArray(new String[strB.size()]);
}
@Override
public OutputStream getAppendFileStream(String strFileName) {
final String conMethodName = conClassName + "::getAppendFileStream";
OutputStream objO = null;
try {
objO = Client().appendFileStream(strFileName);
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return objO;
}
@Override
public long getFileSize(String strFileName) {
final String conMethodName = conClassName + "::getFileSize";
long lngFileSize = 0;
try {
lngFileSize = this.size(strFileName);
}
catch (Exception e) {
e.printStackTrace();
RaiseException(e, "Problem with " + conMethodName);
}
// TODO Auto-generated method stub
return lngFileSize;
}
@Override
public InputStream getInputStream(String strFileName) {
final String conMethodName = conClassName + "::getInputStream";
InputStream objI = null;
try {
if (modezSupported == true) {
}
objI = Client().retrieveFileStream(strFileName);
if (objI == null) {
LogReply();
}
}
catch (IOException e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return objI;
}
@Override
public String getModificationTime(String strFileName) {
final String conMethodName = conClassName + "::getModificationTime";
String strT = null;
// Es gibt Probleme bei der standalone-compilation mit javac. unter eclipse l�uft es fehlerfrei
try {
// strT = Client().getModificationTime(strFileName);
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
return strT;
}
@Override
public OutputStream getOutputStream(String strFileName) {
OutputStream objO = null;
try {
objO = Client().storeFileStream(strFileName);
LogReply();
}
catch (IOException e) {
e.printStackTrace();
}
return objO;
}
@Override
public void close() {
final String conMethodName = conClassName + "::close";
try {
/**
* don't do that, because if no command is pending this will lead into
* a huge waittime and an exception.
*/
// this.CompletePendingCommand();
// Client().completePendingCommand();
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
@Override
public void closeInput() {
}
@Override
public void closeOutput() {
final String conMethodName = conClassName + "::closeOutput";
try {
// this.getOutputStream(strFileName);
// Client().completePendingCommand();
this.CompletePendingCommand();
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
}
@Override
public void flush() {
}
@Override
public int read(byte[] bteBuffer) {
return 0;
}
@Override
public int read(byte[] bteBuffer, int intOffset, int intLength) {
return 0;
}
@Override
public void write(byte[] bteBuffer, int intOffset, int intLength) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::write";
}
@Override
public void write(byte[] bteBuffer) {
}
@Override
public void openInputFile(String pstrFileName) {
}
@Override
public void openOutputFile(String pstrFileName) {
}
@Override
public Vector<ISOSVirtualFile> getFiles(String string) {
return null;
}
@Override
public Vector<ISOSVirtualFile> getFiles() {
return null;
}
public void putFile(ISOSVirtualFile objVirtualFile) {
final String conMethodName = conClassName + "::putFile";
String strName = objVirtualFile.getName();
// strName = new File(strName).getAbsolutePath();
// if (strName.startsWith("c:") == true) {
// strName = strName.substring(3);
// }
ISOSVirtualFile objVF = (ISOSVirtualFile) this.getFileHandle(strName);
OutputStream objOS = objVF.getFileOutputStream();
InputStream objFI = objVirtualFile.getFileInputStream();
// TODO Buffersize must be defined via Options-Class
int lngBufferSize = 1024;
byte[] buffer = new byte[lngBufferSize];
int intBytesTransferred;
long totalBytes = 0;
try {
synchronized (this) {
while ((intBytesTransferred = objFI.read(buffer)) != -1) {
objOS.write(buffer, 0, intBytesTransferred);
totalBytes += intBytesTransferred;
}
objFI.close();
objOS.flush();
objOS.close();
}
}
catch (Exception e) {
RaiseException(e, HostID(String.format(objMsg.getMsg(SOSVfs_E_0105), conMethodName)));
}
finally {
}
}
@Override
/* ISOSVfsFiletransfer */
public void ControlEncoding(String pstrControlEncoding) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::ControlEncoding";
if (pstrControlEncoding.length() > 0) {
objFTPClient.setControlEncoding(pstrControlEncoding);
LogReply();
}
}
}