Package com.sos.VirtualFileSystem.DataElements

Source Code of com.sos.VirtualFileSystem.DataElements.SOSFileListEntry

/********************************************************* 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.DataElements;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.sos.JSHelper.Basics.JSToolBox;
import com.sos.JSHelper.Exceptions.JobSchedulerException;
import com.sos.VirtualFileSystem.FTP.SOSFTPOptions;
import com.sos.VirtualFileSystem.Factory.VFSFactory;
import com.sos.VirtualFileSystem.Interfaces.ISOSFtpOptions;
import com.sos.VirtualFileSystem.Interfaces.ISOSVFSHandler;
import com.sos.VirtualFileSystem.Interfaces.ISOSVfsFileTransfer;
import com.sos.VirtualFileSystem.Interfaces.ISOSVirtualFile;
import com.sos.VirtualFileSystem.Options.SOSConnection2OptionsAlternate;
import com.sos.VirtualFileSystem.zip.SOSVfsZip;
import com.sos.i18n.annotation.I18NResourceBundle;
import com.sos.scheduler.model.SchedulerObjectFactory;
import com.sos.scheduler.model.commands.JSCmdAddOrder;
import com.sos.scheduler.model.objects.Params;
import com.sos.scheduler.model.objects.Spooler;

/**
* <p style="text-align:center">
* <br />---------------------------------------------------------------------------
APL/Software GmbH - Berlin
##### generated by ClaviusXPress (http://www.sos-berlin.com) #########
Montag, 15. Oktober 2007, Klaus.Buettner@sos-berlin.com (KB)
* <br />---------------------------------------------------------------------------
* </p>
* SOSFileListEntry - Datenstruktur f�r Dateiverarbeitung
* <p>
* Diese Klasse rep�sentiert eine Datenstruktur f�r die Dateiverarbeitung
* von lokalen und remote Dateien.
* </p>
* <p>
* Verwendung findet diese Struktur beim download von Dateien, deren Name
* �ber einen (regul�ren) Ausdruck definiert ist und dabei dann mehr als
* eine Datei relevant ist.
* </p>
* @author Klaus.Buettner@sos-berlin.com
* @version 0.9
* @see reference
* @exception classname description
*
*/
@I18NResourceBundle(baseName = "SOSVirtualFileSystem", defaultLocale = "en")
public class SOSFileListEntry extends JSToolBox implements Runnable /* , ISOSVirtualFile */{
  private static String    conClassName        = "SOSFileListEntry";
  private Logger        logger            = Logger.getLogger(SOSFileListEntry.class);
  private boolean        flgNoDataSent        = false;
  private ISOSVirtualFile    fleSourceTransferFile    = null;
  private ISOSVirtualFile    fleSourceFile        = null;
  private ISOSVirtualFile    fleTargetFile        = null;
  private String        strSourceFileName      = null;
  private String        strSourceTransferName    = null;
  private String        strTargetTransferName    = null;
  private String        strTargetFileName      = null;
  private long        lngNoOfBytesTransferred    = 0;
  private long        lngFileSize          = -1L;
  private String        strZipFileName        = "";
  private long        lngTransferProgress      = 0;
  private boolean        flgTransactionalRemoteFile  = false;
  private boolean        flgTransactionalLocalFile  = false;
  public long          zeroByteCount        = 0;
  private long        lngOriginalFileSize      = 0;
  @SuppressWarnings("unused")
  private boolean        flgTransferSkipped      = false;
  // private JSFile objFile = null;
  private SOSFTPOptions    objOptions          = null;
  private String        strAtomicFileName      = EMPTY_STRING;
  private enuTransferStatus  eTransferStatus        = enuTransferStatus.transferUndefined;
  public enum enuTransferStatus {
    transferUndefined, waiting4transfer, transferring, transferInProgress, transferred, transfer_skipped, transfer_has_errors, transfer_aborted, compressed, notOverwritten, deleted, renamed, IgnoredDueToZerobyteConstraint, setBack, polling
  }
  private ISOSVfsFileTransfer  objDataSourceClient    = null;
  private ISOSVfsFileTransfer  objDataTargetClient    = null;
  private ISOSVirtualFile    objTargetTransferFile  = null;
  private ISOSVirtualFile    objSourceTransferFile  = null;
  private SOSFileList      objParent        = null;
  private boolean        flgFileExists      = false;
  private String        strMD5Hash        = "n.a.";
  @SuppressWarnings("unused")
  private Date        dteStartTransfer    = null;
  @SuppressWarnings("unused")
  private Date        dteEndTransfer      = null;
  @SuppressWarnings("unused")
  private ISOSVfsFileTransfer  objVfsHandler      = null;
  private long        guid          = System.currentTimeMillis()// unique id for each file

  /**
   * \brief getobjDataSourceClient
   *
   * \details
   * getter
   *
   * @return the objDataSourceClient
   */
  public ISOSVfsFileTransfer getDataSourceClient() {
    return objDataSourceClient;
  }

  /**
   * \brief setobjDataSourceClient -
   *
   * \details
   * setter
   *
   * @param objDataSourceClient the value for objDataSourceClient to set
   */
  public void setDataSourceClient(ISOSVfsFileTransfer pobjDataSourceClient) {
    this.objDataSourceClient = pobjDataSourceClient;
  }

  /**
   * \brief getobjDataTargetClient
   *
   * \details
   * getter
   *
   * @return the objDataTargetClient
   */
  public ISOSVfsFileTransfer getDataTargetClient() {
    return objDataTargetClient;
  }

  /**
   * \brief setobjDataTargetClient -
   *
   * \details
   * setter
   *
   * @param objDataTargetClient the value for objDataTargetClient to set
   */
  public void setDataTargetClient(ISOSVfsFileTransfer objDataTargetClient) {
    this.objDataTargetClient = objDataTargetClient;
  }

  public void VfsHandler(final ISOSVfsFileTransfer pobjVfs) {
    this.objVfsHandler = pobjVfs;
  }

  public SOSFileListEntry() {
  }

  public void setParent(SOSFileList objFileList) {
    this.objParent = objFileList;
    this.objDataSourceClient = objParent.objDataSourceClient;
    this.objDataTargetClient = objParent.objDataTargetClient;
    if (objDataSourceClient != null) {
      lngOriginalFileSize = objDataSourceClient.getFileHandle(strSourceFileName).getFileSize();
      lngFileSize = lngOriginalFileSize;
    }
  }

  public String SourceTransferName() {
    return strSourceTransferName;
  }

  public String TargetTransferName() {
    return strTargetTransferName;
  }

  // public ISOSVirtualFile getFile() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::getFile";
  //
  // checkFilehandle();
  // return objFile;
  // } // private File getFile
  public String getZipFileName() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::getZipFileName";
    return strZipFileName;
  } // private String getZipFileName

  // private ISOSVirtualFile checkFilehandle() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::checkFilehandle";
  //
  // if (objFile == null) {
  // objFile = new JSFile(strSourceFileName);
  // lngFileSize = objFile.length();
  // }
  //
  // return objFile;
  // } // private JSFile checkFilehandle
  // public boolean notExists() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::notExists";
  //
  // return checkFilehandle().exists() == false;
  // } // private boolean notExists
  // public long length() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::exists";
  //
  // return checkFilehandle().length();
  // } // private boolean exists
  // public String getAbsolutePath() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::getAbsolutePath";
  //
  // return checkFilehandle().getAbsolutePath();
  // } // private String getAbsolutePath
  //
  // public String getName() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::getName";
  //
  // return checkFilehandle().getName();
  // } // private String getAbsolutePath
  // public boolean delete() {
  //
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::delete";
  //
  // if (checkFilehandle().delete() == false) {
  // // TODO Fehlerstatus setzen und im Protokoll drauf hinweisen. �bertragung abbrechen ? Hierbei wohl nicht, oder?
  // throw new RuntimeException("..error occurred, could not remove local file: " + this.getAbsolutePath());
  // }
  // else {
  // logger.debug("file deleted: " + this.getAbsolutePath());
  // }
  //
  // return true;
  // } // private String delete
  public enuTransferStatus getTransferStatus() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::getTransferStatus";
    return eTransferStatus;
  } // private enuTransferStatus getTransferStatus

  public void TransferStatus(final enuTransferStatus peTransferStatus) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::TransferStatus";
    this.setStatus(peTransferStatus);
  } // private void TransferStatus

  public void setTransferSkipped() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::setTransferSkipped";
    this.eTransferStatus = enuTransferStatus.transfer_skipped;
    logger.debug(String.format("transfer skipped for file %1$s ", this.strSourceFileName));
  } // private void TransferStatus

  public void setNotOverwritten() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::setNotOverwritten";
    this.eTransferStatus = enuTransferStatus.notOverwritten;
    logger.debug(String.format("transfer skipped for file %1$s due to overwrite constraint", this.strSourceFileName));
  } // private void TransferStatus

  public String TargetFileName() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::TargetFileName";
    return strTargetFileName;
  } // private String TargetFileName

  public void NoOfBytesTransferred(final long plngNoOfBytesTransferred) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::NoOfBytesTransferred";
    this.lngNoOfBytesTransferred = plngNoOfBytesTransferred;
    logger.info("number of bytes transferred : " + plngNoOfBytesTransferred);
  } // private void NoOfBytesTransferred

  public void setTransactionalRemoteFile() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::setTransactionalRemoteFile";
    this.flgTransactionalRemoteFile = true;
  } // private void setTransactionalRemoteFile

  public boolean getTransactionalLocalFile() {
    return flgTransactionalLocalFile;
  }

  public void setTransactionalLocalFile() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::setTransactionalRemoteFile";
    this.flgTransactionalLocalFile = true;
  } // private void setTransactionalRemoteFile

  public ISOSVirtualFile getTargetFile(final ISOSFtpOptions objO) {
    fleSourceTransferFile = null;
    fleSourceFile = objDataSourceClient.getFileHandle(strSourceFileName);
    fleTargetFile = null;
    // first assumption: localfilename and localTransferfileName are identical
    strSourceTransferName = fleSourceFile.getName();
    // second assumption: localfilename and TargetFileName are equal (until it changed)
    strTargetFileName = fleSourceFile.getName();
    if (objO.getcompress_files().value() == true) { // compress file before sending
      strSourceTransferName = fleSourceFile.MakeZIPFile(objO.getcompressed_file_extension().Value());
      strTargetFileName = strTargetFileName + objO.getcompressed_file_extension().Value();
    }
    strTargetFileName = getFileNameWithoutPath(strTargetFileName);
    strTargetTransferName = strTargetFileName;
    if (objO.getreplacing().IsNotEmpty()) {
      try {
        strTargetFileName = objO.getreplacing().doReplace(strTargetFileName, objO.getreplacement().Value());
      }
      catch (Exception e) {
        e.printStackTrace(System.err);
        logger.error(e.getLocalizedMessage(), new JobSchedulerException("getreplacing().doReplace aborted with an exception", e));
      }
      // String currPath = "";
      // String strParent = fleSourceTransferFile.getParent();
      // if (isNotEmpty(strParent)) {
      // currPath = normalized(strParent);
      // }
      // strSourceTransferName = new File(currPath + currTransferFilename).getName();
      // ? logger.debug("source filename [" + this.SourceFileName() + "] will transferred to: " + strTargetFileName);
    }
    if (objO.getatomic_prefix().IsNotEmpty() || objO.getatomic_suffix().IsNotEmpty()) {
      setTransactionalRemoteFile();
      strTargetTransferName = MakeAtomicFileName(objO);
    }
    return null;
  }

  private String MakeFileNameReplacing(final String pstrFileName) {
    String strR = pstrFileName.replaceAll("\\\\", "/"); // avoid trouble with regexp-groups
    String strReplaceWith = objOptions.getreplacement().Value();
    try {
      strR = objOptions.getreplacing().doReplace(strR, strReplaceWith);
    }
    catch (Exception e) {
      e.printStackTrace(System.err);
      logger.error(e.getLocalizedMessage(), new JobSchedulerException("getreplacing().doReplace aborted with an exception", e));
    }
    return strR;
  }

  private String getFileNameWithoutPath(final String pstrTargetFileName) {
    String strT = pstrTargetFileName;
    if (strT.contains("\\")) {
      strT = strT.replaceAll("\\\\", "/");
    }
    String[] strA = strT.split("/");
    strT = strA[strA.length - 1];
    return strT;
  }

  protected String normalized(String str) {
    str = str.replaceAll("\\\\", "/");
    return (str.endsWith("/") || str.endsWith("\\") ? str : str + "/");
  }

  /**
   *
   * \brief MakeAtomicFileName
   *
   * \details
   * This Method creates a intermediate File-Name, which is used on the target as the first filename
   * After successfull completion of the whole transfer, this name will be renamed to the
   * final targetFileName.
   *
   * An intermediate filename is mostly used to avoid that a file-trigger on the target-host
   * will react to early on the transfer.
   *
   * \return the intermediate filename (without foldername) on the target-host
   *
   * @param ISOSFtpOptions.objO
   * @return intermediate TargetTransferFileName
   */
  public String MakeAtomicFileName(final ISOSFtpOptions objO) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::MakeAtomicFileName";
    String strAtomicSuffix = objO.getatomic_suffix().Value();
    String strAtomicPrefix = objO.getatomic_prefix().Value();
    // if (this.flgTransactionalRemoteFile) {
    strTargetTransferName = strTargetFileName + strAtomicSuffix.trim();
    strTargetTransferName = strAtomicPrefix + strTargetTransferName;
    strAtomicFileName = strTargetTransferName;
    // }
    return strTargetTransferName.trim();
  } // private String MakeAtomicFileName

  public void DeleteSourceFile() {
    objDataSourceClient.getFileHandle(strSourceFileName).delete();
    logger.info(String.format("Source-File %1$s deleted", strSourceFileName));
  }

  public void setStatus(final enuTransferStatus peTransferStatus) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::setStatus";
    String strM = "";
    this.eTransferStatus = peTransferStatus;
    switch (peTransferStatus) {
      case transferInProgress:
        strM = "processing in progress";
        break;
      case waiting4transfer:
        strM = "waiting for processing";
        // TODO Message senden
        break;
      case transfer_skipped:
        dteEndTransfer = Now();
        strM = "processing skipped";
        // TODO Message senden
        break;
      case transferring:
        strM = "processing started";
        dteStartTransfer = Now();
        // TODO Message senden
        break;
      case transferred:
        strM = "processing normal end";
        dteEndTransfer = Now();
        // TODO Message senden
        break;
      case transfer_aborted:
        strM = "processing abnormal end";
        dteEndTransfer = Now();
        // TODO Message senden
        break;
      default:
        break;
    }
    if (isNotEmpty(strM)) {
      // TODO send not only transferred - messages. make it customizable
      if (objOptions.SendTransferHistory.value() == true) {
        if (objOptions.transactional.value() == false && peTransferStatus == enuTransferStatus.transferred) {
          sendTransferHistory();
        }
      }
      switch (peTransferStatus) {
        case transferInProgress:
          logger.debug(String.format("%1$s for file %2$s, actual %3$,d bytes", strM, strSourceFileName, lngTransferProgress));
          break;
        default:
          logger.debug(String.format("%1$s for file %2$s", strM, strSourceFileName));
          break;
      }
    }
  } // private void TransferStatus

  public void Log4Debug() {
    logger.debug("SourceFileName         = " + this.SourceFileName());
    logger.debug("SourceTransferFileName = " + this.SourceTransferName());
    logger.debug("TargetTransferFileName = " + this.TargetTransferName());
    logger.debug("TargetFileName         = " + this.TargetFileName());
  }

  public SOSFileListEntry(String pstrLocalFileName) {
    this("", pstrLocalFileName, 0);
  }

  public SOSFileListEntry(String pstrRemoteFileName, String pstrLocalFileName, long plngNoOfBytesTransferred) {
    strTargetFileName = pstrRemoteFileName;
    strSourceFileName = pstrLocalFileName;
    lngNoOfBytesTransferred = plngNoOfBytesTransferred;
    // this.setStatus(enuTransfesrStatus.waiting4transfer);
  }

  public String toString() {
    String strT = String.format("Operation = %4$s, TargetFile = %1$s, SourceFile = %2$s, BytesTransferred = %3$s", this.RemoteFileName(),
        this.SourceFileName(), this.NoOfBytesTransferred(), objOptions.operation.Value());
    return strT;
  }

  public String toCsv() {
    String strT = String.format("TargetFile = %1$s, SourceFile = %2$s, BytesTransferred = %3$s", this.RemoteFileName(), this.SourceFileName(),
        this.NoOfBytesTransferred());
    return strT;
  }

  public String RemoteFileName() {
    return strTargetFileName;
  }

  public void setRemoteFileName(String pstrRemoteFileName) {
    this.strTargetFileName = pstrRemoteFileName;
  }

  public String SourceFileName() {
    return strSourceFileName;
  }

  public void setSourceFileName(String pstrLocalFileName) {
    this.strSourceFileName = pstrLocalFileName;
  }

  public long NoOfBytesTransferred() {
    return lngNoOfBytesTransferred;
  }

  /**
   *
   * \brief setNoOfBytesTransferred
   *
   * \details
   * This Method must be called only at the end of the transfer.
   * Otherwise a call would result in a "FileSize"-Exception.
   *
   * \return void
   *
   * @param plngNoOfBytesTransferred
   */
  public void setNoOfBytesTransferred(long plngNoOfBytesTransferred) {
    this.lngNoOfBytesTransferred = plngNoOfBytesTransferred;
    if (lngFileSize <= 0) { // if the file is compressed, then the original filesize may be to big
      lngFileSize = objDataSourceClient.getFileHandle(strSourceFileName).getFileSize();
    }
    if (lngFileSize != plngNoOfBytesTransferred) {
      logger.error(String.format("File-Size failure for file '%3$s'. No of bytes transferred '%1$d', size of file is '%2$d'", plngNoOfBytesTransferred,
          lngFileSize, strSourceFileName), new JobSchedulerException("FileSize"));
      this.setStatus(enuTransferStatus.transfer_aborted);
      throw new JobSchedulerException("FileSize");
    }
    if (lngOriginalFileSize != plngNoOfBytesTransferred) {
      logger.error(String.format("File-Size failure. No of bytes transferred '%1$d', original size of file '%2$d'", plngNoOfBytesTransferred,
          lngOriginalFileSize), new JobSchedulerException("FileSize"));
      this.setStatus(enuTransferStatus.transfer_aborted);
      throw new JobSchedulerException("FileSize");
    }
    this.setStatus(enuTransferStatus.transferred);
    // TODO Message "transferCompleted absetzen"
  }

  /**
   * \brief setlngTransferProgress -
   *
   * \details
   * setter
   *
   * @param lngTransferProgress the value for lngTransferProgress to set
   */
  public void setTransferProgress(long plngTransferProgress) {
    this.lngTransferProgress = plngTransferProgress;
    this.setStatus(enuTransferStatus.transferInProgress);
    String lstrTargetFileName = strTargetFileName;
    if (objDataTargetClient.getHandler() instanceof SOSVfsZip) {
      lstrTargetFileName = String.format("%1$s(%2$s)", objOptions.remote_dir.Value(), strTargetFileName);
    }
    logger.info(String.format("%1$,d bytes for file '%2$s' transferred to '%3$s'", lngTransferProgress, strSourceFileName, lstrTargetFileName));
  }

  /**
   * \brief getlngTransferProgress
   *
   * \details
   * getter
   *
   * @return the lngTransferProgress
   */
  public long getTransferProgress() {
    return lngTransferProgress;
  }

  public void StartTransfer() {
    this.setStatus(enuTransferStatus.transferring);
  }

  public void EndTransfer(final long plngNoOfBytesTransferred) {
    this.setNoOfBytesTransferred(plngNoOfBytesTransferred);
    this.EndTransfer();
  }

  public void EndTransfer() {
    this.setStatus(enuTransferStatus.transferred);
  }

  public void Options(final SOSFTPOptions pobjOptions) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::Options";
    this.objOptions = pobjOptions;
  } // private void Options

  // TODO polling �ber die File-Gr��e

  /**
   * Diese Routine pr�ft *nur* auf dem lokalen fileSystem und ist aus der "Send"-Klasse kopiert.
   * hier hat sie nichts zu suchen, da das polling f�r dateien in der Engine erfolgen muss,
   * unabh�ngig davon, wo die Dateien liegen. Es mu� *immer* die Datasource gepollt werden.
   *
   * Auf alle F�lle mu� hier �ber das Vfs auf die Datei(en) zugegriffen werden.
   */
  public boolean CheckFileSizeIsChanging() throws Exception {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::polling";
    String lastmd5file = "";
    String message = "";

    try {
      // TODO TransferStatus "polling" einbauen
      String fileName = strSourceFileName;
      if (objOptions.poll_timeout.value() > 0 && isNotEmpty(fileName)) {
        setStatus(enuTransferStatus.polling);
        double delay = objOptions.poll_interval.value();
        double nrOfTries = (objOptions.poll_timeout.value() * 60) / delay;
        int tries = 0;
        boolean found = true;
        logger.info("polling for file: " + fileName);
        // TODO in die Implementation des ISOSVirtualFile verschieben
        File fleFile = new File(fileName);
        // TODO �ber Option auf FileSize ausweichen, da MD5 bei gro�en dateien eine ziemliche Last erzeugt
        lastmd5file = sos.util.SOSCrypt.MD5encrypt(fleFile);
        Thread.sleep((long) delay * 1000);
        for (int i = 0; i < nrOfTries; i++) {
          tries++;
          String newMD5File = sos.util.SOSCrypt.MD5encrypt(fleFile);
          logger.debug(i + " polling and checking md5 hash: " + newMD5File);
          if (!lastmd5file.equals(newMD5File)) {
            lastmd5file = newMD5File;
            logger.info("polling for file ..." + fileName);
            Thread.sleep((long) delay * 1000);
            if (i + 1 == nrOfTries) {
              found = false;
              message = message + " " + fileName;
            }
          }
          else {
            break;
          }
        }
        if (!found) {
          message = "During triggering for " + objOptions.poll_timeout.value() + " minutes the file " + message + " has been changed repeatedly";
          if (objOptions.force_files.value() == true) {
            logger.error(message);
            throw new JobSchedulerException(message);
          }
          else {
            logger.info(message);
            return false;
          }
        }
      }
      return true;
    }
    catch (Exception e) {
      throw new JobSchedulerException("error in  " + conMethodName + " error while polling, cause: " + e);
    }
  }

  // Runnable
  @Override
  public void run() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::run";
    boolean flgNewConnectionUsed = false;
    try {
      logger.debug("thread is starting...");
      ISOSVFSHandler objVFS4Source = null;
      ISOSVFSHandler objVFS4Target = null;
      if (objDataSourceClient == null) {
        flgNewConnectionUsed = true;
        objVFS4Source = VFSFactory.getHandler(objOptions.getDataSourceType());
        objVFS4Source.setSource();
        objVFS4Source.Connect(objOptions.getConnectionOptions().Source());
        objVFS4Source.Authenticate(objOptions);
        objDataSourceClient = (ISOSVfsFileTransfer) objVFS4Source;
        objVFS4Source.setSource();
        objVFS4Source.Options(objOptions);
      }
      if (objDataTargetClient == null) {
        flgNewConnectionUsed = true;
        objVFS4Target = VFSFactory.getHandler(objOptions.getDataTargetType());
        objVFS4Target.setTarget();
        objVFS4Target.Connect(objOptions.getConnectionOptions().Target());
        objVFS4Target.Authenticate(objOptions);
        objDataTargetClient = (ISOSVfsFileTransfer) objVFS4Target;
        objVFS4Target.setTarget();
        objVFS4Target.Options(objOptions);
      }

      ISOSVirtualFile objSourceFile = objDataSourceClient.getFileHandle(strSourceFileName);
      if (objSourceFile.notExists() == true) {
        throw new JobSchedulerException(".. file '" + strSourceFileName + "' does not exist ");
      }
      /**
       * hier nicht verwenden, weil es zu sp�t kommt.     
       */
      // if (CheckFileSizeIsChanging() == false) {
      // // TODO Exception ausl�sen
      // return;
      // }
     
      if (objOptions.TransferZeroByteFiles() == false && objSourceFile.isEmptyFile()) {
        this.TransferStatus(enuTransferStatus.transfer_skipped);
        return;
      }
     
      File subParent = null;
      String subPath = "";
      String strTargetFolderName = objOptions.TargetDir.Value();
      String localDir = objOptions.SourceDir.Value();
      boolean recursive = objOptions.recursive.value();
      if (recursive) {
        // TODO Das Erstellen des Verzeichnis mu� eine separate Methode werden
        // �berpr�fen, ob das Verzeichnis auf den Target (-Server) existiert, wenn nicht dann soll das gleiche Verzeichnis generiert
        // werden
        if (objSourceFile.getParentVfs() != null && objSourceFile.getParentVfsFile().isDirectory()) {
          subPath = strSourceFileName.substring((localDir.length() + 1)); // Unterverzeichnisse sind alle Verzeichnisse unterhalb
          // der localDir
          subParent = new File(subPath).getParentFile();
          if (subParent != null) {
            subPath = subPath.replaceAll("\\\\", File.separator);
            subPath = subPath.substring(0, subPath.length() - new File(strSourceFileName.toString()).getName().length() - 1);
            logger.debug(".. creating sub-directory on data-target: " + subPath);
            String[] ftpFiles = objDataTargetClient.listNames(strTargetFolderName + "/" + subPath);
            if (ftpFiles == null || ftpFiles.length == 0) {
              objDataTargetClient.mkdir(strTargetFolderName + File.separator + subPath);
            }
          }
        }
      }
      this.getTargetFile(objOptions); // TODO Namen �ndern
      // if (subParent != null && recursive) {
      // // fleTransferFile = new File((subParent != null ? subParent.getName() + "/" : "") + fleTransferFile.getName());
      // // strTransferFilename = (subParent != null ? subPath + "/" : "") + fleTransferFile.getName();
      // }
      if (objOptions.transactional.value() == true) {
        this.setTransactionalLocalFile();
      }

      String strOp = objOptions.operation.Value();
      if (strOp.equalsIgnoreCase("delete")) {
        objSourceFile.delete();
        logger.debug(String.format("filename '%1$s' deleted", strSourceFileName));
        this.setStatus(enuTransferStatus.deleted);
        return;
      }

      if (strOp.equalsIgnoreCase("rename")) {
        String strNewFileName = MakeFileNameReplacing(strSourceFileName);
        logger.debug(String.format("filename %1$s, renamed to %2$s", strSourceFileName, strNewFileName));
        objSourceFile.rename(strNewFileName);
        this.setStatus(enuTransferStatus.renamed);
        return;
      }

      ISOSVirtualFile objTargetFile = objDataTargetClient.getFileHandle(MakeFullPathName(objOptions.TargetDir.Value(), strTargetFileName));
      if (strTargetFileName.equalsIgnoreCase(strTargetTransferName) == false) {
        objTargetTransferFile = objDataTargetClient.getFileHandle(MakeFullPathName(objOptions.TargetDir.Value(), strTargetTransferName));
      }
      else {
        objTargetTransferFile = objTargetFile;
      }

      if (objOptions.compress_files.value() == true) {
        objSourceTransferFile = objDataSourceClient.getFileHandle(strSourceTransferName);
        this.lngFileSize = objSourceTransferFile.getFileSize();
        lngOriginalFileSize = this.lngFileSize;
      }
      else {
        strSourceTransferName = getFileNameWithoutPath(strSourceTransferName);
        objSourceTransferFile = objDataSourceClient.getFileHandle(MakeFullPathName(objOptions.SourceDir.Value(), strSourceTransferName));
      }
      this.flgFileExists = objTargetFile.FileExists();
      if (objOptions.DoNotOverwrite() && flgFileExists == true) {
        logger.debug("data-target(-server) reply [filename exists] [" + strTargetFileName + "]: " + objDataTargetClient.getReplyString());
        this.setNotOverwritten();
        return;
      }
      /*
       * Hier kann �ber die Streams auch, ohne Zwischendatei, von einem Server
       * zum anderen, der Transfer stattfinden. Input = Server1, Output = Server2.
       * Es ist damit auch ein Server2Server f�r FTP (SFTP und FTPs??) m�glich.
       *
       * Es gibt f�r FTP auch die andere M�glichkeit �ber Server2Server, siehe apache-Klassen.
       */
      // InputStream objInputStream = objSourceTransferFile.getFileInputStream();
      // OutputStream objOutputStream = null;
      // if (objOptions.append_files.value() == true) {
      // objOutputStream = objTargetTransferFile.getFileAppendStream();
      // }
      // else {
      // objOutputStream = objTargetTransferFile.getFileOutputStream();
      // }
      // this.doTransfer(objInputStream, objOutputStream);
      this.doTransfer(objSourceTransferFile, objTargetTransferFile);
      if (objOptions.isAtomicTransfer()) {
        if (objOptions.transactional.value() == false) {
          if (objOptions.overwrite_files.value() == true & flgFileExists == true) {
            // hier werden Dateien gel�scht, vor dem umbenennen.
            // Besser: auch erstmal umbenennen und dann erst l�schen
            objTargetFile.delete();
          }
          objTargetTransferFile.rename(MakeFullPathName(objOptions.TargetDir.Value(), this.TargetFileName()));
        }
      }
      if (flgNewConnectionUsed == true) {
        objDataSourceClient.logout();
        objDataSourceClient.disconnect();
        objDataTargetClient.logout();
        objDataTargetClient.disconnect();
      }
    }
    catch (Exception e) {
      String strT = "error. unable to transfer data, reason: " + e;
      e.printStackTrace(System.err);
      // TODO rollback?
      logger.error(strT);
      throw new JobSchedulerException(strT, e);
    }
  }

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

  @SuppressWarnings("null")
  // private long doTransfer(final InputStream objInput, final OutputStream objOutput) {
  private long doTransfer(final ISOSVirtualFile objInput, final ISOSVirtualFile objOutput) {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::doTransfer";
    boolean flgClosingDone = false;
    if (objOutput == null) {
      RaiseException("virtual Target File has null value.");
    }
    if (objInput == null) {
      RaiseException("virtual source file has null value.");
    }
    boolean flgCreateSecurityHash = objOptions.CreateSecurityHash.value();
    MessageDigest md = null;
    if (flgCreateSecurityHash) {
      try {
        // TODO implement in value-method of securityhashtype
        md = MessageDigest.getInstance(objOptions.SecurityHashType.Value());
      }
      catch (NoSuchAlgorithmException e1) {
        e1.printStackTrace();
        flgCreateSecurityHash = false;
      }
    }
    long lngTotalBytesTransferred = 0;
    this.setStatus(enuTransferStatus.transferring);
    try {
      int lngBufferSize = objOptions.BufferSize.value();
      byte[] buffer = new byte[lngBufferSize];
      int intBytesTransferred;
      synchronized (this) {
        while ((intBytesTransferred = objInput.read(buffer)) != -1) {
          try {
            objOutput.write(buffer, 0, intBytesTransferred);
          }
          catch (JobSchedulerException e) {
            break;
          }
          // TODO in case of wrong outputbuffer tha handling of the error must be improved
          lngTotalBytesTransferred += intBytesTransferred;
          setTransferProgress(lngTotalBytesTransferred);
          if (flgCreateSecurityHash) {
            md.update(buffer, 0, intBytesTransferred);
          }
        }
      }
      objInput.closeInput();
      objOutput.closeOutput();
      flgClosingDone = true;
      if (flgCreateSecurityHash) {
        strMD5Hash = toHexString(md.digest());
        logger.info(String.format("Security hash (%3$s) for file %2$s is %1$s", strMD5Hash, strSourceTransferName, objOptions.SecurityHashType.Value()));
      }
      // objDataTargetClient.CompletePendingCommand();
      if (objDataTargetClient.isNegativeCommandCompletion()) {
        RaiseException("..error occurred during transfer on the data-target for file [" + objTargetTransferFile.getName() + "]: "
            + objDataTargetClient.getReplyString());
      }
      // objDataSourceClient.CompletePendingCommand();
      if (objDataSourceClient.isNegativeCommandCompletion()) {
        RaiseException("..error occurred during transfer on the data-source for file [" + objSourceTransferFile.getName() + "]: "
            + objDataSourceClient.getReplyString());
      }
      this.setNoOfBytesTransferred(lngTotalBytesTransferred);
      // this.TransferStatus(enuTransferStatus.transferred);
      return lngTotalBytesTransferred;
    }
    catch (Exception e) {
      RaiseException(e, "transfer aborted with an exception");
    }
    finally {
      if (flgClosingDone == false) {
        objInput.closeInput();
        objOutput.closeOutput();
        flgClosingDone = true;
      }
    }
    return lngTotalBytesTransferred;
  } // putFile

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

  /*
  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) {
    }
  }
  */
  public String getAtomicFileName() {
    return strAtomicFileName;
  }

  public void setAtomicFileName(String pstrValue) {
    strAtomicFileName = pstrValue;
  }

  public boolean FileExists() {
    return flgFileExists;
  }

  // public void run() {
  // @SuppressWarnings("unused")
  // final String conMethodName = conClassName + "::run";
  //
  // try {
  // logger.debug("thread is starting...");
  //
  // ISOSVFSHandler objVFS = VFSFactory.getHandler(objOptions.protocol.Value());
  //
  // objVFS.Connect(objOptions);
  // objVFS.Authenticate(objOptions);
  //
  // ftpClient = (ISOSVfsFileTransfer) objVFS;
  //
  // File localFile = this.getFile();
  // if (this.getFile() == null) {
  // return;
  // }
  //
  // String strSourceFileName = this.getAbsolutePath();
  // if (this.notExists()) {
  // throw new JobSchedulerException(".. file [" + strSourceFileName + "] does not exist ");
  // }
  //
  // if (polling() == false) {
  // return;
  // }
  //
  // if (objOptions.TransferZeroByteFiles() == false && this.isEmptyFile()) {
  // this.TransferStatus(enuTransferStatus.transfer_skipped);
  // return;
  // }
  //
  // File subParent = null;
  // String subPath = "";
  // String strTargetFolderName = objOptions.remote_dir.Value();
  // String localDir = objOptions.local_dir.Value();
  // boolean recursive = objOptions.recursive.value();
  // if (recursive && objOptions.isFilePath() == false) {
  // // TODO Das Erstellen des Verzeichnis mu� eine separate Methode werden
  // // �berpr�fen, ob das Verzeichnis auf den FTP Server existiert, wenn nicht dann soll das gleiche Verzeichnis generiert
  // // werden
  // if (localFile.getParent() != null && localFile.getParentFile().isDirectory()) { // es existieren Vaterknoten
  // subPath = strSourceFileName.substring((localDir.length() + 1)); // Unterverzeichnisse sind alle
  // // Verzeichnisse unterhalb der localDir
  // subParent = new File(subPath).getParentFile();
  //
  // if (subParent != null) {
  // subPath = subPath.replaceAll("\\\\", "/");
  // subPath = subPath.substring(0, subPath.length() - new File(strSourceFileName.toString()).getName().length() - 1);
  // logger.debug(".. creating sub-directory on remote host: " + subPath);
  // String[] ftpFiles = ftpClient.listNames(strTargetFolderName + "/" + subPath);
  // if (ftpFiles == null || ftpFiles.length == 0) {
  // ftpClient.mkdir(strTargetFolderName + "/" + subPath);
  // }
  // }
  // }
  // }
  //
  // this.getTargetFile(objOptions);
  //
  // if (subParent != null && recursive) {
  // // fleTransferFile = new File((subParent != null ? subParent.getName() + "/" : "") + fleTransferFile.getName());
  // // strTransferFilename = (subParent != null ? subPath + "/" : "") + fleTransferFile.getName();
  // }
  //
  // long bytesSend = 0;
  // Vector<String> vecTargetFileNamesList = ftpClient.nList(strTargetFileName);
  // logger.debug("target-server reply [filename exists] [" + strTargetFileName + "]: " + ftpClient.getReplyString());
  //
  // if (objOptions.transactional.value() == true) {
  // this.setTransactionalLocalFile();
  // }
  //
  // if (objOptions.DoNotOverwrite()) {
  // if (vecTargetFileNamesList.isEmpty() == false) {
  // this.setNotOverwritten();
  // return;
  // }
  // }
  //
  // if (objOptions.isAtomicTransfer()) {
  // this.setStatus(enuTransferStatus.transferring);
  // bytesSend = ftpClient.putFile(this.SourceTransferName(), this.TargetTransferName());
  //
  // if (objOptions.overwrite_files.value() == true) {
  // // hier werden Dateien gel�scht, vor dem umbenennen.
  // // Besser: auch erstmal umbenennen und dann erst l�schen
  // if (vecTargetFileNamesList.isEmpty() == false && vecTargetFileNamesList.contains(strTargetFileName)) {
  // ftpClient.delete(strTargetFileName);
  // }
  // }
  //
  // // TODO Warum schon hier umbenennen, und nicht erst dann, wenn alle Dateien �bertragen sind? In FileListentry ist das zu
  // // finden
  // if (objOptions.transactional.value() == false) {
  // ftpClient.rename(this.TargetTransferName(), this.TargetFileName());
  // }
  // }
  // else {
  // this.setStatus(enuTransferStatus.transferring);
  // if (objOptions.append_files.value() == true) {
  // bytesSend = ftpClient.appendFile(this.SourceTransferName(), this.TargetTransferName());
  // }
  // else {
  // bytesSend = ftpClient.putFile(this.SourceTransferName(), this.TargetTransferName());
  // }
  // }
  // this.setNoOfBytesTransferred(bytesSend);
  // this.TransferStatus(enuTransferStatus.transferred);
  // // TODO das mu� in die FileEntry-Klasse
  // // writeHistory(fleSourceFile.getAbsolutePath(), fleTransferFile.getAbsolutePath());
  //
  // // TODO das ist eine merkw�rdige Art zu pr�fen
  // // if (objOptions.check_size.value() == true && this.length() > 0 && this.length() != this.NoOfBytesTransferred()) {
  // // throw new JobSchedulerException("..error occurred sending file, target file size [" + this.length()
  // // + "] does not match number of bytes transferred [" + this.NoOfBytesTransferred() + "]");
  // // }
  //
  // if (objOptions.remove_files.value() == true) {
  // this.getFile().delete();
  // }
  //
  // }
  // catch (Exception e) {
  // String strT = "error. unable to send files, cause: " + e;
  // e.printStackTrace(System.err);
  // // TODO rollback?
  // logger.error(strT);
  // throw new JobSchedulerException(strT, e);
  // }
  //
  // }
  private String toHexString(byte[] b) {
    char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    int length = b.length * 2;
    StringBuffer sb = new StringBuffer(length);
    for (int i = 0; i < b.length; i++) {
      // oberer Byteanteil
      sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
      // unterer Byteanteil
      sb.append(hexChar[b[i] & 0x0f]);
    }
    return sb.toString();
  }

  /**
   *
   * \brief sendTransferHistory
   *
   * \details
   * This methods send for every file the needed informations about the transfer history
   * to the background service (JobScheduler).
   *
   * \return void
   *
   */
  public void sendTransferHistory() {
    @SuppressWarnings("unused")
    final String conMethodName = conClassName + "::sendTransferHistory";

    if (objOptions.SendTransferHistory.value() == false) {
      if (flgNoDataSent == false) {
        flgNoDataSent = true;
        logger.debug(String.format("No data sent to the background service due to '%1$s'", objOptions.SendTransferHistory.getKey()));
      }
      return;
    }

    String strBackgroundServiceHostName = objOptions.scheduler_host.Value();
    if (isEmpty(strBackgroundServiceHostName)) {
      if (flgNoDataSent == false) {
        flgNoDataSent = true;
        logger.debug("No data sent to the background service due to missing host name");
      }
      return;
    }
    // long guid = System.currentTimeMillis(); // 4- GUID
    String mandator = objOptions.mandator.Value(); // 0-
    String transfer_timestamp = EMPTY_STRING;
    try {
      transfer_timestamp = sos.util.SOSDate.getCurrentTimeAsString();
    }
    catch (Exception e) {
    } // 1- timestamp: Zeitstempel im ISO-Format
    /**
     * this hack is tested for SUN-JVM only. No guarantee is made for other JVMs
     */
    String pid = ManagementFactory.getRuntimeMXBean().getName();
    String strA[] = pid.split("@");
    pid = strA[0];
    String ppid = System.getProperty("ppid", "0");
    String operation = objOptions.operation.Value(); // 4- operation: send|receive
    SOSConnection2OptionsAlternate objS = objOptions.getConnectionOptions().Source();
    String localhost = objS.host.Value(); // 5- local host
    String localhost_ip = objS.host.getHostAdress(); // 5-1- local host IP adresse
    String local_user = System.getProperty("user.name"); // 6- local user
    SOSConnection2OptionsAlternate objT = objOptions.getConnectionOptions().Target();
    String remote_host = objT.host.Value(); // 7- remote host
    String remote_host_ip = objT.host.getHostAdress(); // 7- remote host IP
    String remote_user = objT.user.Value(); // 8- remote host user
    String protocol = objT.protocol.Value(); // 9- protocol
    String port = objT.port.Value(); // 10- port
    String local_dir = objOptions.local_dir.Value();
    String remote_dir = new File(this.strTargetFileName).getAbsolutePath();
    String local_filename = this.strSourceFileName; // 13- file name
    String remote_filename = this.strTargetFileName; // 14- name
    if (isEmpty(remote_filename)) {
      remote_filename = "n.a.";
    }
    String fileSize = String.valueOf(this.lngFileSize);
    String md5 = this.strMD5Hash;
    String status = this.eTransferStatus.name();
    String last_error_message = "";
    // last_error_message = clearCRLF(((getLogger().getError() != null && getLogger().getError().length() > 0) ? getLogger().getError()
    // : getLogger().getWarning())); // 15- last_error=|warn message
    // last_error_message = normalizedPassword(sosString.parseToString(last_error_message));
    String log_filename = objOptions.log_filename.Value();
    String jump_host = objOptions.jump_host.Value();
    String jump_host_ip = objOptions.jump_host.getHostAdress();
    String jump_port = objOptions.jump_port.Value();
    String jump_protocol = objOptions.jump_protocol.Value();
    String jump_user = objOptions.jump_user.Value();

    Properties objSchedulerOrderParameterSet = new Properties();
    objSchedulerOrderParameterSet.put("guid", String.valueOf(guid)); // 1- GUID
    objSchedulerOrderParameterSet.put("mandator", mandator); // 2- mandator: default SOS
    objSchedulerOrderParameterSet.put("transfer_timestamp", transfer_timestamp); // 3- timestamp: Zeitstempel im ISO-Format
    objSchedulerOrderParameterSet.put("pid", pid); // 4- pid= Environment PID | 0 f�r Windows
    objSchedulerOrderParameterSet.put("ppid", ppid); // 5- ppid= Environment PPID | 0 f�r Windows
    objSchedulerOrderParameterSet.put("operation", operation); // 6- operation: send|receive
    objSchedulerOrderParameterSet.put("localhost", localhost); // 7- local host
    objSchedulerOrderParameterSet.put("localhost_ip", localhost_ip); // 8- local host IP adresse
    objSchedulerOrderParameterSet.put("local_user", local_user); // 9- local user
    objSchedulerOrderParameterSet.put("remote_host", remote_host); // 10- remote host
    objSchedulerOrderParameterSet.put("remote_host_ip", remote_host_ip); // 11- remote host IP
    objSchedulerOrderParameterSet.put("remote_user", remote_user); // 12- remote host user
    objSchedulerOrderParameterSet.put("protocol", protocol); // 13- protocol
    objSchedulerOrderParameterSet.put("port", port); // 14- port
    objSchedulerOrderParameterSet.put("local_dir", local_dir); // 15- local dir
    objSchedulerOrderParameterSet.put("remote_dir", remote_dir); // 16- remote dir
    objSchedulerOrderParameterSet.put("local_filename", local_filename); // 17- file name
    objSchedulerOrderParameterSet.put("remote_filename", remote_filename); // 18- file name
    objSchedulerOrderParameterSet.put("file_size", fileSize); // 19 - file name
    objSchedulerOrderParameterSet.put("md5", md5); // 20
    if (status.equalsIgnoreCase("transferred")) {
      status = "success"; // for old friends ;-)
    }
    objSchedulerOrderParameterSet.put("status", status); // 21- status=success|error
    objSchedulerOrderParameterSet.put("last_error_message", last_error_message); // 22
    objSchedulerOrderParameterSet.put("log_filename", log_filename); // 23
    objSchedulerOrderParameterSet.put("jump_host", jump_host); // 24
    objSchedulerOrderParameterSet.put("jump_host_ip", jump_host_ip); // 25
    objSchedulerOrderParameterSet.put("jump_port", jump_port); // 26
    objSchedulerOrderParameterSet.put("jump_protocol", jump_protocol); // 27
    objSchedulerOrderParameterSet.put("jump_user", jump_user); // 28
    // TODO custom-fields einbauen
    /**
     * bei SOSFTP ist es m�glich "custom" Felder zu definieren, die bei UDP als Auftragsparameter mitgeschickt werden.
     * Damit man diese Felder identifizieren kann, werden hier Parameter defininiert, die beim Auftrag dabei sind, aber keine
     * "custom" Felder sind
     *
     * ? alternativ Metadaten der Tabelle lesen (Spalten) und mit den Auftragsparameter vergleichen
     */

    SchedulerObjectFactory objFactory = objParent.objFactory;
    if (objFactory == null) {
      objFactory = new SchedulerObjectFactory(objOptions.scheduler_host.Value(), objOptions.scheduler_port.value());
      objFactory.initMarshaller(Spooler.class);
      objParent.objFactory = objFactory;
      objFactory.Options().TransferMethod.Value(objOptions.Scheduler_Transfer_Method.Value());
      // objFactory.Options().TransferMethod.Value(enuJSTransferModes.tcp.description);
      objFactory.Options().PortNumber.Value(objOptions.scheduler_port.Value());
      objFactory.Options().ServerName.Value(objOptions.scheduler_host.Value());
    }
    JSCmdAddOrder objOrder = objFactory.createAddOrder();
    objOrder.setJobChain(objOptions.scheduler_job_chain.Value() /* "scheduler_sosftp_history" */);
    objOrder.setTitle("Test for UDP communication method");
    Params objParams = objFactory.setParams(objSchedulerOrderParameterSet);
    objOrder.setParams(objParams);
    logger.debug(objOrder.toXMLString());
    objOrder.run();
  } // private void sendTransferHistory
}
TOP

Related Classes of com.sos.VirtualFileSystem.DataElements.SOSFileListEntry

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.