Package com.sos.VirtualFileSystem.SFTP

Source Code of com.sos.VirtualFileSystem.SFTP.SOSVfsSFtp

/********************************************************* 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.SFTP;
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.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.SOSOptionInFileName;
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.FTP.SOSVfsFtpFile;
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;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.SFTPv3Client;
import com.trilead.ssh2.SFTPv3DirectoryEntry;
import com.trilead.ssh2.SFTPv3FileAttributes;
import com.trilead.ssh2.SFTPv3FileHandle;
import com.trilead.ssh2.Session;

@I18NResourceBundle(baseName = "SOSVirtualFileSystem", defaultLocale = "en")
public class SOSVfsSFtp extends SOSVfsBaseClass implements ISOSVfsFileTransfer, ISOSVFSHandler, ISOSVirtualFileSystem, ISOSConnection {

  private final String          conClassName      = "SOSVfsSFtp";
  private Logger              logger          = Logger.getLogger(SOSVfsSFtp.class);

  private Vector<String>          vecDirectoryListing    = null;

  /** key file: ~/.ssh/id_rsa or ~/.ssh/id_dsa */
  protected String            authenticationFilename  = "";

  /** ssh connection object */
  protected Connection          sshConnection      = null;

  /** ssh session object */
  protected Session            sshSession        = null;

  /** SFTP Client **/
  protected SFTPv3Client          objFTPClient      = 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            isConnected        = false;

  // keep Track of current directory for ftp emulation
  private String              currentDirectory    = "";

  protected String            reply          = "OK";

  private char[]              authenticationFile    = null;

  /**
   *
   * \brief SOSVfsFtp
   *
   * \details
   *
   */
  public SOSVfsSFtp() {

  }

  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) {

    try {
      host = phost;
      port = pport;
      logger.debug(String.format("Try to connect to host '%1$s' at Port '%2$d'.", host, port));
      if (isConnected() == false) {
        sshConnection = new Connection(host, port);
        sshConnection.connect();
        isConnected = true;
        logger.debug(String.format("Connected to '%1$s' at Port '%2$d'.", host, port));
        LogReply();
      }
      else {
        logger.warn(String.format("host '%1$s' at Port '%2$d' is already connected.", host, port));
      }
    }
    catch (Exception e) {
      String strM = HostID("connect returns an exception");
      // e.printStackTrace(System.err);
      logger.error(strM, e);
      // throw new RuntimeException(strM, e);
    }
  }

  @SuppressWarnings("unused")
  private void connect(String hostname) throws SocketException, IOException, UnknownHostException {

    if (isConnected() == false)
      this.connect(hostname, 22);
  }

  /**
   * 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().mkdir(pathname, 484);
      reply = "mkdir OK";
      logger.debug(HostID("..ftp server reply [mkdir] [" + pathname + "]: " + getReplyString()));
    }
    catch (IOException e) {
      throw new RuntimeException(HostID("makeDirectory returns an exception"), e);
    }
  }

  /**
   * Removes a directory on the FTP server (if empty).
   * @param pathname The pathname of the directory to remove.
   * @throws java.lang.IOException
   */
  public void rmdir(String pathname) throws IOException {
    Client().rm(pathname);
    reply = "rm OK";
  }

  /**
   * turn passive transfer mode on.
   *
   * @return The reply code received from the server.
   */
  public int passive() {
    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;
    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)) {
          DoCD(strCurrentFile); // is this file-entry a subfolder?
          if (isNegativeCommandCompletion() == false) {
            if (strCurrentDirectory.trim().length() > 0 && 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 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;
  }

  // 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

  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();
    if (strReply.trim().length() > 0) {
      logger.debug(strReply);
    }

    return true;
  } // private boolean LogReply

  public boolean isNegativeCommandCompletion() {

    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::isNegativeCommandCompletion";
    int x = 0;
    // 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 = getReplyCode();

    return (x > 300);
  } // private boolean isNegativeCommandCompletion

  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 = 0;

    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) {

    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();
    String[] listFiles = null;
    try {
      listFiles = this.listNames(pathname);
    }
    catch (IOException e) {
      RaiseException(e, "listfiles in dir returns an exception");
    }
    if (listFiles != null) {
      for (int i = 0; i < listFiles.length; i++) {
        if (flag > 0 && isDirectory(listFiles[i])) {
          fileList.addAll(this.dir(pathname + "/" + listFiles[i], ((flag >= 1024) ? flag : flag + 1024)));
        }
        else {
          if (flag >= 1024) {
            fileList.add(pathname + "/" + listFiles[i].toString());
          }
          else {
            fileList.add(listFiles[i].toString());
          }
        }
      }
    }
    return fileList;
  }

  /**
   * Checks if file is a directory
   *
   * @param filename
   * @return true, if filename is a directory
   */
  @Override
  public boolean isDirectory(String filename) {
    try {
      return Client().stat(filename).isDirectory();
    }
    catch (Exception e) {
    }
    return false;
  }

  public String[] listNames(String pathname) throws IOException {
    pathname = resolvePathname(pathname);
    try {
      if (pathname.length() == 0)
        pathname = ".";
      if (!fileExists(pathname))
        return null;
      if (!isDirectory(pathname)) {
        File remoteFile = new File(pathname);
        reply = "ls OK";
        return new String[] { remoteFile.getName() };
      }
      Vector files = Client().ls(pathname);
      String[] rvFiles = new String[files.size()];

      for (int i = 0; i < files.size(); i++) {
        SFTPv3DirectoryEntry entry = (SFTPv3DirectoryEntry) files.get(i);
        rvFiles[i] = entry.filename;
      }
      reply = "ls OK";
      return rvFiles;
    }
    catch (Exception e) {
      reply = e.toString();
      return null;
    }
  }

  /**
   * 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 {
    remoteFile = resolvePathname(remoteFile);
    try {
      return Client().stat(remoteFile).size.longValue();
    }
    catch (com.trilead.ssh2.SFTPException e) {
      return -1;
    }
    catch (Exception e) {
      throw new Exception("Error occured checking size: " + e, e);
    }
  }

  /**
   * trim the response code at the beginning
   * @param response
   * @return the response string without response code
   * @throws Exception
   */
  @SuppressWarnings("unused")
  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) {
  // 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

  public long getFile(String remoteFile, String localFile, boolean append) throws Exception {
    String sourceLocation = resolvePathname(remoteFile);
    SFTPv3FileHandle sftpFileHandle = null;
    FileOutputStream fos = null;
    File transferFile = null;
    long remoteFileSize = -1;

    try {
      transferFile = new File(localFile);
      remoteFileSize = size(remoteFile);
      sftpFileHandle = objFTPClient.openFileRO(sourceLocation);

      fos = null;
      long offset = 0;
      try {
        fos = new FileOutputStream(transferFile, append);
        byte[] buffer = new byte[32768];
        while (true) {
          int len = objFTPClient.read(sftpFileHandle, offset, buffer, 0, buffer.length);
          if (len <= 0)
            break;
          fos.write(buffer, 0, len);
          offset += len;
        }
        fos.flush();
        fos.close();
        fos = null;

      }
      catch (Exception e) {
        throw new Exception("error occurred get file [" + transferFile.getAbsolutePath() + "]: " + e.getMessage());
      }
      finally {
        if (fos != null)
          try {
            fos.close();
            fos = null;
          }
          catch (Exception ex) {
          } // gracefully ignore this error
      }

      objFTPClient.closeFile(sftpFileHandle);
      sftpFileHandle = null;

      if (remoteFileSize > 0 && remoteFileSize != transferFile.length())
        throw new Exception("remote file size [" + remoteFileSize + "] and local file size [" + transferFile.length()
            + "] are different. Number of bytes written to local file: " + offset);

      return transferFile.length();
    }
    catch (Exception e) {
      throw e;
    }
    finally {
      try {
        objFTPClient.closeFile(sftpFileHandle);
      }
      catch (Exception e) {
      }
    }
  }

  public long readFile(String pstrFilename) throws Exception {
    SFTPv3FileHandle sftpFileHandle = null;

    try {
      String sourceLocation = resolvePathname(pstrFilename);
      long remoteFileSize = size(sourceLocation);
      sftpFileHandle = openFileRO(pstrFilename);

      long offset = 0;
      try {
        byte[] buffer = new byte[32768];
        while (true) {
          int len = objFTPClient.read(sftpFileHandle, offset, buffer, 0, buffer.length);
          if (len <= 0)
            break;
          offset += len;
        }
      }
      catch (Exception e) {
        throw new JobSchedulerException("error occurred reading file [" + pstrFilename + "]: " + e.getMessage());
      }

      // if (remoteFileSize > 0 && remoteFileSize != transferFile.length())
      // throw new Exception("remote file size [" + remoteFileSize + "] and local file size [" + transferFile.length()
      // + "] are different. Number of bytes written to local file: " + offset);

      return remoteFileSize;
    }
    catch (Exception e) {
      throw e;
    }
    finally {
      try {
        objFTPClient.closeFile(sftpFileHandle);
        sftpFileHandle = null;
      }
      catch (Exception e) {
        throw e;
      }
    }
  }

  // private SFTPv3FileHandle getHandle (final String pstrFileName) {
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::getHandle";
  //
  // String sourceLocation = resolvePathname(pstrFileName);
  //
  // SFTPv3FileHandle sftpFileHandle = null;
  // try {
  // sftpFileHandle = objFTPClient.openFileRO(sourceLocation);
  // }
  // catch (IOException e) {
  // e.printStackTrace();
  // }
  //
  // return sftpFileHandle;
  // }
  public SFTPv3FileHandle openFileRO(String pstrFilename) throws Exception {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::openFileRO";

    String sourceLocation = resolvePathname(pstrFilename);
    SFTPv3FileHandle sftpFileHandle = null;

    try {
      sftpFileHandle = objFTPClient.openFileRO(sourceLocation);
    }
    catch (Exception e) {
      throw new JobSchedulerException("error occurred opening file [" + sourceLocation + "]: " + e.getMessage());
    }
    finally {
    }

    return sftpFileHandle;
  }

  public SFTPv3FileHandle openFileWR(String pstrFilename) throws Exception {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::openFileWR";

    SFTPv3FileHandle sftpFileHandle = null;
    String sourceLocation = resolvePathname(pstrFilename);

    try {
      sftpFileHandle = objFTPClient.createFileTruncate(sourceLocation);

    }
    catch (Exception e) {
      throw new JobSchedulerException("error occurred opening file [" + sourceLocation + "]: " + e.getMessage());
    }
    finally {
    }

    return sftpFileHandle;
  }

  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;
    long lngNoOfBytesRead = 0;
    try {
      lngNoOfBytesRead = this.getFile(remoteFile, localFile, flgAppendLocalFile);
    }
    catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return lngNoOfBytesRead;
  }

  /**
   * 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
   */
  /**
   * 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) {

    this.put(localFile, remoteFile);
  }

  /**
   * 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 {
    long offset = 0;
    try {
      remoteFile = resolvePathname(remoteFile);
      SFTPv3FileHandle fileHandle = objFTPClient.createFileTruncate(remoteFile);
      File localF = new File(localFile);
      FileInputStream fis = null;
      try {
        fis = new FileInputStream(localF);
        byte[] buffer = new byte[32768];

        while (true) {
          int len = fis.read(buffer, 0, buffer.length);
          if (len <= 0)
            break;
          objFTPClient.write(fileHandle, offset, buffer, 0, len);
          offset += len;
        }

        fis.close();
        fis = null;

      }
      catch (Exception e) {
        RaiseException("error occurred writing file [" + localFile + "]: " + e.getMessage());
      }
      finally {
        if (fis != null)
          try {
            fis.close();
            fis = null;
          }
          catch (Exception ex) {
          } // gracefully ignore this error
      }
      objFTPClient.closeFile(fileHandle);
      logger.debug(String.format("file '%1$s' transfered to '%2$s'", localFile, remoteFile));
      fileHandle = null;
      reply = "put OK";
      return offset;
    }
    catch (Exception e) {
      reply = e.toString();
      RaiseException(e, "Error during putFile: " + e);
    }
    return offset;
  }

  /**
   * 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);
      return lngTotalBytesWritten;
    }
    catch (Exception e) {
      RaiseException(e, "putfile returns an exception");
    }
    finally {
      closeInput(in);
      closeObject(out);
    }
    return lngTotalBytesWritten;
  } // putFile

  private void RaiseException(final Exception e, final String pstrM) {
    logger.error(pstrM);
    e.printStackTrace(System.err);
    throw new JobSchedulerException(pstrM, e);
  }

  private void RaiseException(final String pstrM) {
    logger.error(pstrM);
    throw new JobSchedulerException(pstrM);
  }

  public SFTPv3Client 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) {
    notImplemented();
    // 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 -1;
  } // 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);
    // }
  }

  /**
   *
   * @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 {
    changeWorkingDirectory(directory);
    return 1;
  }

  private boolean fileExists(String filename) {

    try {
      SFTPv3FileAttributes attributes = Client().stat(filename);

      if (attributes != null) {
        return (attributes.isRegularFile() || attributes.isDirectory());
      }
      else {
        return false;
      }

    }
    catch (Exception e) {
      return false;
    }
  }

  public boolean changeWorkingDirectory(String pathname) throws IOException {
    pathname = resolvePathname(pathname);
    // cut trailing "/" if it's not the only character
    if (pathname.length() > 1 && pathname.endsWith("/"))
      pathname = pathname.substring(0, pathname.length() - 1);
    if (!fileExists(pathname)) {
      reply = "\"" + pathname + "\" doesn't exist.";
      return false;
    }
    if (!isDirectory(pathname)) {
      reply = "\"" + pathname + "\" is not a directory.";
      return false;
    }
    if (pathname.startsWith("/") || currentDirectory.length() == 0) {
      currentDirectory = pathname;
      reply = "cd OK";
      return true;
    }
    currentDirectory = pathname;
    reply = "cd OK";
    return true;
  }

  private String resolvePathname(String pathname) {
    if ((!pathname.startsWith("./") && !pathname.startsWith("/")) && currentDirectory.length() > 0) {
      // if (!pathname.startsWith("/") && currentDirectory.length()>0){
      String slash = "";
      if (!currentDirectory.endsWith("/"))
        slash = "/";
      pathname = currentDirectory + slash + pathname;
    }
    while (pathname.contains("\\")) {
      pathname = pathname.replace('\\', '/');
    }
    return pathname;
  }

  /**
   * 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().rm(pathname);
    reply = "rm OK";
    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";
    boolean isAuthenticated = false;

    try {
      gstrUser = strUserName;

      logger.debug(String.format("Try to login with user '%1$s'.", strUserName));
      isAuthenticated = sshConnection.authenticateWithPassword(strUserName, strPassword);

      if (!isAuthenticated)
        RaiseException("authentication failed");

      reply = "OK";
      logger.debug(String.format("user '%1$s' logged in.", strUserName));
      LogReply();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    LogReply();

  } // private boolean login

  @Override
  public void disconnect() {
    reply = "disconnect OK";
    if (objFTPClient != null)
      try {
        objFTPClient.close();
        objFTPClient = null;
      }
      catch (Exception ex) {
        reply = "disconnect: " + ex;
      } // gracefully ignore this error
    if (sshConnection != null)
      try {
        sshConnection.close();
        sshConnection = null;
      }
      catch (Exception ex) {
        reply = "disconnect: " + ex;
      } // gracefully ignore this error
    isConnected = false;

    logger.info(reply);
  }

  @Override
  public String getReplyString() {
    String strT = strReply;
    return strT;
  }

  @Override
  public boolean isConnected() {
    return isConnected;
  }

  // @Override
  // public String[] listNames(String pathname) throws IOException {
  // String strA[] = Client().listNames(pathname);
  // 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 (isConnected() == true) {
        disconnect();
        logger.debug(String.format("logout from host '%1$s', reply '%2$s'", objHost.Value(), getReplyString()));
      }
      else {
        logger.info("not connected, logout useless.");
      }
    }
    catch (Exception e) { // no error-handling needed, due to end-of session
      logger.warn("problems during logout. " + e.getMessage());
    }
  }

  public void rename(String from, String to) {
    from = resolvePathname(from);
    to = resolvePathname(to);
    try {
      Client().mv(from, to);
    }
    catch (Exception e) {
      reply = e.toString();
      RaiseException(e, "rename failed");
    }
    reply = "mv OK";
    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 {
    notImplemented();
  }

  @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 {
    objAO = pobjAO;
    // TODO allow alternate Authentications
    doAuthenticate(pobjAO);
    return this;
  }

  private ISOSConnection doAuthenticate(ISOSAuthenticationOptions pobjAO) throws Exception {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::doAuthenticate";

    boolean isAuthenticated = false;

    try {
      gstrUser = pobjAO.getUser().Value();
      String strPW = pobjAO.getPassword().Value();
      String strUserName = gstrUser;
      logger.debug(String.format("Try to login with user '%1$s'.", strUserName));

      if (pobjAO.getAuth_method().isPublicKey()) {
        SOSOptionInFileName objAF = pobjAO.getAuth_file();
        objAF.CheckMandatory(true);
        if (objAF.IsNotEmpty()) {
          char[] chrAFContent = objAF.JSFile().File2String().toCharArray();
          isAuthenticated = sshConnection.authenticateWithPublicKey(strUserName, chrAFContent, strPW);
        }
      }
      else {
        if (pobjAO.getAuth_method().isPassword()) {
          isAuthenticated = sshConnection.authenticateWithPassword(this.gstrUser, strPW);
        }
        else {
          throw new Exception("Unknown authentication method: " + pobjAO.getAuth_method().Value());
        }
      }
      if (!isAuthenticated) {
        RaiseException("authentication failed, auth_method=" + pobjAO.getAuth_method().Value() + ", auth_file=" + pobjAO.getAuth_file().Value());
      }
      reply = "OK";
      logger.debug(String.format("user '%1$s' logged in.", strUserName));
      LogReply();
    }
    catch (Exception e) {
      RaiseException(e, "Authentication problem");
    }
    finally {

    }
    return this;
  }

  @Override
  public void CloseConnection() throws Exception {
    if (isConnected()) {
      disconnect();
      logger.debug(String.format("Disconnected from host '%1$s'", objConnectionOptions.getHost().Value()));
      LogReply();
    }
  }

  private SFTPv3Client Client() {
    if (objFTPClient == null) {
      try {
        objFTPClient = new SFTPv3Client(sshConnection);
      }
      catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      /**
       * This listener is to write all commands and response from commands to system.out
       *
       */
      // this.Connect();
    }
    return objFTPClient;
  }

  @Override
  public ISOSConnection Connect() {
    logger.debug("Try to connect ...");
    try {
      this.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;
      }
    }
    isConnected = true;
    reply = "OK";

    return this;
  }

  @Override
  public ISOSConnection Connect(SOSConnection2OptionsAlternate pobjConnectionOptions) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::Connect";

    objConnection2Options = pobjConnectionOptions;
    try {

      objHost = objConnection2Options.getHost();
      objHost.CheckMandatory();
      objPort = objConnection2Options.getport();
      objPort.CheckMandatory();
      host = objHost.Value();
      port = objPort.value();
      this.connect(objHost.Value(), objPort.value());
      if (isConnected == false) {
        SOSConnection2OptionsSuperClass objAlternate = objConnection2Options.Alternatives();
        objHost = objAlternate.host;
        objPort = objAlternate.port;
        host = objHost.Value();
        port = objPort.value();
        logger.info(String.format("try alternate host due to connection-error ", host));
        this.connect(objHost.Value(), objPort.value());
        if (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) {
      e.printStackTrace();
      logger.error("exception occured", e);
      throw new JobSchedulerException("exception occured:", e);
    }

    return this;
  }

  @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);
    }
    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) {

    if (pobjFileTransferMode.isAscii()) {
      this.ascii();
      logger.debug("using ASCII mode for file transfer");
      logger.debug("ftp server reply [ascii]: " + getReplyString());
    }
    else {
      this.binary();
      logger.debug("using binary mode for file transfer");
      logger.debug("ftp server reply [binary]: " + 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) {
    if (vecDirectoryListing == null) {
      vecDirectoryListing = nList(folder, withSubFolder);
    }

    Vector<String> strB = new Vector<String>();
    Pattern pattern = Pattern.compile(regexp, 0);
    for (String strFile : vecDirectoryListing) {
      Matcher matcher = pattern.matcher(strFile);
      if (matcher.find() == true) {
        strB.add(strFile);
      }
    }

    return strB.toArray(new String[strB.size()]);
  }

  @Override
  public OutputStream getAppendFileStream(String strFileName) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::getAppendFileStream";

    OutputStream objO = null;
    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) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::getInputStream";

    InputStream objI = null;
    // SFTPv3FileHandle objI = getClient().openFileRO(strFileName);

    return objI;
  }

  @Override
  public String getModificationTime(String strFileName) {
    String strT = "";
    // TODO transform mtime to real date
    // try {
    // strT = Client().stat(strFileName).mtime;
    // }
    // catch (IOException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
    return strT;
  }

  @Override
  public OutputStream getOutputStream(String strFileName) {

    OutputStream objO = null;
    return objO;
  }

  @Override
  public void close() {
    // TODO Auto-generated method stub

  }

  @Override
  public void closeInput() {
    // TODO Auto-generated method stub

  }

  @Override
  public void closeOutput() {
    // TODO Auto-generated method stub

  }

  @Override
  public void flush() {
    // TODO Auto-generated method stub

  }

  @Override
  public int read(byte[] bteBuffer) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::read";

    int intL = -1;
    try {
      // int intMaxBuffLen = bteBuffer.length;
      int intMaxBuffLen = bteBuffer.length;
      // if (intMaxBuffLen > 32000) {
      // intMaxBuffLen = 32000;
      // }
      intL = objFTPClient.read(objInputFile, lngReadOffset, bteBuffer, 0, intMaxBuffLen);
      lngReadOffset += intL;
    }
    catch (IOException e) {
      e.printStackTrace();
    }

    return intL;
  }

  @Override
  public int read(byte[] bteBuffer, int intOffset, int intLength) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::read";
    int intL = -1;
    try {
      intL = objFTPClient.read(objInputFile, lngReadOffset, bteBuffer, 0, intLength);
      lngReadOffset += intL;
    }
    catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    return intL;
  }

  @Override
  public void write(byte[] bteBuffer, int intOffset, int intLength) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::write";
    try {
      objFTPClient.write(objOutputFile, lngWriteOffset, bteBuffer, 0, intLength);
      lngWriteOffset += intLength;
    }
    catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  @Override
  public void write(byte[] bteBuffer) {
    // TODO Auto-generated method stub

  }

  private SFTPv3FileHandle  objInputFile  = null;
  private long        lngReadOffset  = 0;
  private SFTPv3FileHandle  objOutputFile  = null;
  private long        lngWriteOffset  = 0;

  @Override
  public void openInputFile(String pstrFileName) {
    try {
      if (objInputFile == null || objInputFile.isClosed() == true) {
        objInputFile = openFileRO(pstrFileName);
        lngReadOffset = 0;
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Override
  public void openOutputFile(String pstrFileName) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::openOutputFile";

    try {
      objOutputFile = openFileWR(pstrFileName);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  @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 ControlEncoding(String pstrControlEncoding) {

  }

}
TOP

Related Classes of com.sos.VirtualFileSystem.SFTP.SOSVfsSFtp

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.