/********************************************************* 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.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.ProtocolCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
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.annotation.I18NResourceBundle;
/**
* \class SOSVfsFtpBaseClass
*
* \brief SOSVfsFtpBaseClass -
*
* \details
*
* \section SOSVfsFtpBaseClass.java_intro_sec Introduction
*
* \section SOSVfsFtpBaseClass.java_samples Some Samples
*
* \code
* .... code goes here ...
* \endcode
*
* <p style="text-align:center">
* <br />---------------------------------------------------------------------------
* <br /> APL/Software GmbH - Berlin
* <br />##### generated by ClaviusXPress (http://www.sos-berlin.com) #########
* <br />---------------------------------------------------------------------------
* </p>
* \author KB
* \version 21.04.2011
* \see reference
*
* Created on 21.04.2011 19:31:35
*/
/**
* @author KB
*
*/
@I18NResourceBundle(baseName = "SOSVirtualFileSystem", defaultLocale = "en")
public class SOSVfsFtpBaseClass extends SOSVfsBaseClass implements ISOSVfsFileTransfer, ISOSVFSHandler, ISOSVirtualFileSystem, ISOSConnection {
@SuppressWarnings("unused")
private final String conClassName = "SOSVfsFtpBaseClass";
private static final Logger logger = Logger.getLogger(SOSVfsFtpBaseClass.class);
@Deprecated
protected Vector<String> vecDirectoryListing = null;
protected ISOSConnectionOptions objConnectionOptions = null;
protected SOSConnection2OptionsAlternate objConnection2Options = null;
protected String strCurrentPath = EMPTY_STRING;
protected String strReply = EMPTY_STRING;
protected ProtocolCommandListener listener = null;
protected String host = EMPTY_STRING;
protected int port = 0;
protected String gstrUser = EMPTY_STRING;
protected SOSOptionHostName objHost = null;
protected SOSOptionPortNumber objPort = null;
public SOSVfsFtpBaseClass() {
//
}
protected String HostID(String pstrText) {
return "(" + gstrUser + "@" + host + ":" + port + ") " + pstrText;
}
/**
* 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) {
try {
Client().makeDirectory(pathname);
logger.debug(HostID("..ftp server reply [mkdir] [" + pathname + "]: " + getReplyString()));
}
catch (IOException e) {
throw new RuntimeException(HostID("makeDirectory returns an exception"), e);
}
}
protected FTPClient Client() {
return null;
}
@Override
public ISOSConnection Connect() {
logger.debug("Try to connect ...");
try {
connect(objConnectionOptions.getHost().Value(), objConnectionOptions.getPort().value());
logger.info(String.format("successful connected to Host '%1$s' at port '%1$d'.", objConnectionOptions.getHost().Value(),
objConnectionOptions.getPort().value()));
}
catch (RuntimeException e) {
if (objConnectionOptions.getalternative_host().IsNotEmpty() && objConnectionOptions.getalternative_port().IsNotEmpty()) {
logger.info("Not possible to connect to Host. Try alternate host.");
this.connect(objConnectionOptions.getalternative_host().Value(), //
objConnectionOptions.getalternative_port().value());
logger.info(String.format("successful connected to Host '%1$s' at port '%1$d'.", objConnectionOptions.getalternative_host().Value(), //
objConnectionOptions.getalternative_port().value()));
}
else {
throw e;
}
}
return this;
}
public void connect(String value, int value2) {
// TODO Auto-generated method stub
}
public ISOSConnection Connect(SOSConnection2OptionsAlternate pobjConnectionOptions) {
@SuppressWarnings("unused")
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;
throw new JobSchedulerException("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) {
e.printStackTrace();
logger.error("exception occured", e);
throw new JobSchedulerException("exception occured:", e);
}
return this;
}
@Deprecated
@Override
public ISOSConnection Connect(ISOSConnectionOptions pobjConnectionOptions) throws Exception {
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
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) {
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;
}
/*
* @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);
}
/**
* 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 {
Client().removeDirectory(pathname);
}
/**
* turn passive transfer mode on.
*
* @return The reply code received from the server.
*/
public int passive() {
try {
int i = Client().pasv();
if (isPositiveCommandCompletion() == false) {
throw new RuntimeException(HostID("..ftp server reply [enterLocalPassiveMode]: " + getReplyString()));
}
else {
this.logger.debug(HostID("..ftp server reply [enterLocalPassiveMode]: " + getReplyString()));
}
return i;
}
catch (IOException e) {
throw new JobSchedulerException(HostID("pasv returns exception"), e);
}
}
public void CompletePendingCommand() {
try {
if (Client().completePendingCommand() == false) {
logout();
disconnect();
RaiseException("File transfer failed. completePendingCommand() returns false");
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
RaiseException("File transfer failed. completePendingCommand() raised an exception");
}
}
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
/*
* @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)
*/
/**
* 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
@Override
public void CloseConnection() throws Exception {
if (Client().isConnected()) {
Client().disconnect();
logger.debug(String.format("Disconnected from host '%1$s'", objConnection2Options.getHost().Value()));
LogReply();
}
}
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
protected boolean LogReply() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::LogReply";
strReply = getReplyString();
logger.debug(strReply);
return true;
} // private boolean LogReply
public boolean isNegativeCommandCompletion() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::isNegativeCommandCompletion";
// TODO separate Routine draus machen
// try {
// if (Client().completePendingCommand() == false) {
// logout();
// disconnect();
// RaiseException("File transfer failed. completePendingCommand() returns false");
// }
// }
// catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
int x = Client().getReplyCode();
return (x > 300);
} // private boolean isNegativeCommandCompletion
/**
* 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) {
try {
return getFilenames(pathname, flgRecurseSubFolder);
}
catch (Exception e) {
throw new JobSchedulerException("getfilenames in nLixt returns an exception", e);
}
} // 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) {
SOSFileList fileList = new SOSFileList();
FTPFile[] listFiles;
try {
listFiles = Client().listFiles(pathname);
}
catch (IOException e) {
throw new RuntimeException("listfiles in dir returns an exception", e);
}
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() {
try {
return dir(".");
}
catch (Exception e) {
throw new RuntimeException("dir returns an exception", e);
}
}
/**
* @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;
}
/**
* 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();
}
/**
*
* @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 {
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) {
@SuppressWarnings("unused")
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(String.format("user '%1$s' logged in.", strUserName));
LogReply();
}
catch (IOException e) {
e.printStackTrace();
}
LogReply();
} // private boolean login
@Override
public boolean changeWorkingDirectory(String pathname) {
try {
Client().cwd(pathname);
logger.debug("..ftp server reply [directory exists] [" + pathname + "]: " + getReplyString());
}
catch (IOException e) {
throw new RuntimeException("cwd returns an exception", e);
}
return true;
}
@Override
public void disconnect() {
try {
if (Client().isConnected()) {
Client().disconnect();
}
}
catch (IOException e) {
logger.warn("Problems during disconnect. " + e.getLocalizedMessage());
}
}
@Override
public String getReplyString() {
String strT = Client().getReplyString();
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() {
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());
}
}
protected void RaiseException(final Exception e, final String pstrM) {
logger.error(pstrM);
e.printStackTrace(System.err);
throw new JobSchedulerException(pstrM, e);
}
protected void RaiseException(final String pstrM) {
logger.error(pstrM);
throw new JobSchedulerException(pstrM);
}
@Override
public InputStream getInputStream(String strFileName) {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::getInputStream";
InputStream objI = null;
try {
objI = Client().retrieveFileStream(strFileName);
if (objI == null) {
LogReply();
}
}
catch (IOException e) {
e.printStackTrace();
logger.error("Problem with " + conMethodName, e);
}
return objI;
}
@Override
public String getModificationTime(String strFileName) {
String strT = null;
// Es gibt Probleme bei der standalone-compilation mit javac. unter eclipse l�uft es fehlerfrei
// try {
// strT = Client().getModificationTime(strFileName);
// }
// catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
return strT;
}
@Override
public OutputStream getOutputStream(String strFileName) {
OutputStream objO = null;
try {
objO = Client().storeFileStream(strFileName);
LogReply();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return objO;
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
@Override
public int read(byte[] bteBuffer) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int read(byte[] bteBuffer, int intOffset, int intLength) {
// TODO Auto-generated method stub
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) {
// TODO Auto-generated method stub
}
@Override
public void openInputFile(String pstrFileName) {
// TODO Auto-generated method stub
}
@Override
public void openOutputFile(String pstrFileName) {
// TODO Auto-generated method stub
}
@Override
public Vector<ISOSVirtualFile> getFiles(String string) {
// TODO Auto-generated method stub
return null;
}
@Override
public Vector<ISOSVirtualFile> getFiles() {
// TODO Auto-generated method stub
return null;
}
public void putFile(ISOSVirtualFile objVirtualFile) {
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();
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) {
throw new JobSchedulerException("putfile reports exception", e);
}
finally {
}
}
@Override
public void closeInput() {
// TODO Auto-generated method stub
}
@Override
public void closeOutput() {
try {
// this.getOutputStream(strFileName);
Client().completePendingCommand();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void close() {
try {
Client().completePendingCommand();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
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() {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::DoPWD";
String lstrCurrentPath = "";
try {
logger.debug("Try pwd.");
lstrCurrentPath = getCurrentPath();
}
catch (Exception e) {
logger.error(HostID("Problems with pwd"), e);
}
return lstrCurrentPath;
} // private int DoPWD
private String getCurrentPath() {
String lstrCurrentPath = strCurrentPath;
try {
Client().pwd();
lstrCurrentPath = getReplyString();
logger.debug(String.format("reply from pwd is : %1$s", 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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return lstrCurrentPath;
}
@SuppressWarnings("unused")
private int DoCDUP() {
final String conMethodName = conClassName + "::DoCDUP";
try {
logger.debug("Try cdup .");
Client().cdup();
LogReply();
DoPWD();
}
catch (IOException e) {
logger.error("Problems with CDUP", e);
}
return 0;
} // private int DoPWD
/**
* 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) {
FileOutputStream out = null;
boolean rc = false;
try {
out = new FileOutputStream(localFile);
rc = Client().retrieveFile(remoteFile, out);
if (rc == false) {
throw new JobSchedulerException("retrieveFile returns a negative return-code");
}
}
catch (IOException e) {
throw new JobSchedulerException("get returns an exception", e);
}
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) {
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);
if (Client().completePendingCommand() == false) {
logout();
disconnect();
throw (new JobSchedulerException("File transfer failed."));
}
if (isNegativeCommandCompletion()) {
throw new JobSchedulerException("..error occurred in getFile() on the FTP server for file [" + remoteFile + "]: " + getReplyString());
}
// TODO create completed Message
if (totalBytes > 0)
return totalBytes;
else
return -1L;
}
catch (IOException e) {
RaiseException(e, "getFile returns an exception");
}
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) {
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, "put returns an exception");
}
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) {
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);
if (Client().completePendingCommand() == false) {
logout();
disconnect();
RaiseException("File transfer 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, "putfile returns an exception");
}
finally {
closeInput(in);
closeObject(out);
}
return lngTotalBytesWritten;
} // putFile
/**
* 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) {
long i;
try {
i = putFile(localFile, Client().appendFileStream(remoteFile));
logger.info("bytes appended : " + i);
}
catch (IOException e) {
throw new RuntimeException("appendFileStream returns an exception", e);
}
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() {
try {
boolean flgResult = Client().setFileType(FTP.ASCII_FILE_TYPE);
if (flgResult == false) {
throw new JobSchedulerException("setFileType not possible, due to : " + getReplyString());
}
}
catch (IOException e) {
throw new JobSchedulerException("ascii returns an exception", e);
}
}
/**
* 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() {
try {
boolean flgResult = Client().setFileType(FTP.BINARY_FILE_TYPE);
if (flgResult == false) {
throw new JobSchedulerException("setFileType not possible, due to : " + getReplyString());
}
}
catch (IOException e) {
throw new JobSchedulerException("setFileType to binary returns an exception", e);
}
}
public void rename(String from, String to) {
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 {
Client().sendCommand(strCmd);
logger.debug("..ftp server reply 'sendCommand' [" + 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 {
gstrUser = pobjAO.getUser().Value();
String Passwd = pobjAO.getPassword().Value();
this.login(gstrUser, Passwd);
objAO = pobjAO;
return this;
}
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) {
e.printStackTrace();
RaiseException(e, "problem with " + 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 void ControlEncoding(String pstrControlEncoding) {
// TODO Auto-generated method stub
}
}