Package com.sos.VirtualFileSystem.FTP

Source Code of com.sos.VirtualFileSystem.FTP.SOSVfsFtpBaseClass

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

}
TOP

Related Classes of com.sos.VirtualFileSystem.FTP.SOSVfsFtpBaseClass

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.