Java tutorial
/** * Copyright (C) 2014 BigLoupe http://bigloupe.github.io/SoS-JobScheduler/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ /********************************************************* begin of preamble ** ** Copyright (C) 2003-2012 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.io.IOException; import java.lang.management.ManagementFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Date; import java.util.Properties; import java.util.UUID; import org.apache.commons.net.util.Base64; import org.apache.log4j.Logger; import com.sos.JSHelper.Exceptions.JobSchedulerException; import com.sos.JSHelper.Options.SOSOptionString; import com.sos.JSHelper.Options.SOSOptionTime; import com.sos.JSHelper.io.Files.JSTextFile; import com.sos.VirtualFileSystem.FTP.SOSFTPOptions; import com.sos.VirtualFileSystem.Factory.VFSFactory; import com.sos.VirtualFileSystem.Interfaces.IJadeTransferDetailHistoryData; 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.common.SOSVfsConstants; import com.sos.VirtualFileSystem.common.SOSVfsMessageCodes; 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 fr Dateiverarbeitung * <p> * Diese Klasse reprsentiert eine Datenstruktur fr die Dateiverarbeitung * von lokalen und remote Dateien. * </p> * <p> * Verwendung findet diese Struktur beim download von Dateien, deren Name * ber einen (regulren) Ausdruck definiert ist und dabei dann mehr als * eine Datei relevant ist. * </p> * @author Klaus.Buettner@sos-berlin.com * @version $Id: SOSFileListEntry.java 20078 2013-05-06 00:30:05Z oh $ 0.9 * @see reference * @exception classname description * */ @I18NResourceBundle(baseName = "SOSVirtualFileSystem", defaultLocale = "en") public class SOSFileListEntry extends SOSVfsMessageCodes implements Runnable, IJadeTransferDetailHistoryData /* , ISOSVirtualFile */ { private static String conClassName = "SOSFileListEntry"; private final Logger logger = Logger.getLogger(SOSFileListEntry.class); private static Logger objJadeReportLogger = Logger.getLogger(VFSFactory.getLoggerName()); @SuppressWarnings("unused") private final String conSVNVersion = "$Id: SOSFileListEntry.java 20078 2013-05-06 00:30:05Z oh $"; private static 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 long lngFileModDate = -1L; private final 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 final boolean flgTransferSkipped = false; 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."; private Date dteStartTransfer = null; private Date dteEndTransfer = null; @SuppressWarnings("unused") private ISOSVfsFileTransfer objVfsHandler = null; // Hier bereits zuweisen, damit in der CSV-Datei und in der Order eine identische GUID verwendet wird. private final String guid = UUID.randomUUID().toString(); private boolean flgSteadyFlag = false; private boolean flgTransferHistoryAlreadySent = false; public boolean flgIsHashFile = false; /** * \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(final ISOSVfsFileTransfer pobjDataSourceClient) { objDataSourceClient = pobjDataSourceClient; lngFileModDate = -1; if (objDataSourceClient != null) { ISOSVirtualFile objFileHandle = objDataSourceClient.getFileHandle(strSourceFileName); if (objFileHandle != null) { lngFileModDate = objFileHandle.getModificationDateTime(); } else { } } } /** * \brief getobjDataTargetClient * * \details * getter * * @return the objDataTargetClient */ public ISOSVfsFileTransfer getDataTargetClient() { return objDataTargetClient; } /** * \brief setobjDataTargetClient - * * \details * setter * * @param pobjDataTargetClient1 the value for objDataTargetClient to set */ public void setDataTargetClient(final ISOSVfsFileTransfer pobjDataTargetClient1) { objDataTargetClient = pobjDataTargetClient1; } public void VfsHandler(final ISOSVfsFileTransfer pobjVfs) { objVfsHandler = pobjVfs; } public SOSFileListEntry() { super(SOSVfsConstants.strBundleBaseName); } public void setParent(final SOSFileList objFileList) { objParent = objFileList; objDataSourceClient = objParent.objDataSourceClient; objDataTargetClient = objParent.objDataTargetClient; if (objDataSourceClient != null) { lngOriginalFileSize = objDataSourceClient.getFileHandle(strSourceFileName).getFileSize(); lngFileSize = lngOriginalFileSize; lngFileModDate = objDataSourceClient.getFileHandle(strSourceFileName).getModificationDateTime(); } } public String SourceTransferName() { return strSourceTransferName; } public String TargetTransferName() { return strTargetTransferName; } public String getZipFileName() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::getZipFileName"; return strZipFileName; } // private String getZipFileName 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"; eTransferStatus = enuTransferStatus.transfer_skipped; String strM = SOSVfs_D_0110.params(strSourceFileName); logger.debug(strM); objJadeReportLogger.info(strM); } // private void TransferStatus public void setNotOverwritten() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::setNotOverwritten"; eTransferStatus = enuTransferStatus.notOverwritten; logger.debug(SOSVfs_D_0111.params(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"; lngNoOfBytesTransferred = plngNoOfBytesTransferred; String strM = SOSVfs_D_0112.params(plngNoOfBytesTransferred); logger.info(strM); } // private void NoOfBytesTransferred public void setTransactionalRemoteFile() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::setTransactionalRemoteFile"; flgTransactionalRemoteFile = true; } // private void setTransactionalRemoteFile public boolean getTransactionalLocalFile() { return flgTransactionalLocalFile; } public void setTransactionalLocalFile() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::setTransactionalRemoteFile"; 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(); boolean flgIncludeSubdirectories = objOptions.recursive.value(); 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(); } if (objOptions.CumulateFiles.isTrue()) { strTargetFileName = objOptions.CumulativeFileName.Value(); strTargetTransferName = strTargetFileName; objOptions.append_files.value(true); // if (objOptions.CumulativeFileDelete.isTrue()) { // } } else { strTargetFileName = getFileNameWithoutPath(strTargetFileName); strTargetTransferName = strTargetFileName; // replacing has to be taken from general or target_ options for the target replacing SOSFTP-151 if (objO.getreplacing().IsNotEmpty()) { try { strTargetFileName = objO.getreplacing().doReplace(strTargetFileName, objO.getreplacement().Value()); } catch (Exception e) { String strM = SOSVfs_E_0150.get(); logger.error(e.getLocalizedMessage(), new JobSchedulerException(strM, e)); } } } // Atomic-Suffix and/or atomic-prefix for cumulative_file was not used // http://www.sos-berlin.com/jira/browse/SOSFTP-142 if (objOptions.isAtomicTransfer() || objOptions.TransactionMode.isTrue()) { setTransactionalRemoteFile(); strTargetTransferName = MakeAtomicFileName(objOptions); } if (flgIncludeSubdirectories == true) { String strSourceDir = getPathWithoutFileName(fleSourceFile.getName()); String strOrigSourceDir = objO.SourceDir().Value(); if (strSourceDir.equals(strOrigSourceDir) == false) { if (strSourceDir.length() > strOrigSourceDir.length()) { String strSubFolder = strSourceDir.substring(strOrigSourceDir.length()); strSubFolder = adjustFileSeparator(strSubFolder); strTargetFileName = strSubFolder + strTargetFileName; strTargetTransferName = strSubFolder + strTargetTransferName; try { if (objParent.add2SubFolders(strSubFolder) == true) { objDataTargetClient.mkdir(addFileSeparator(objO.TargetDir().Value()) + strSubFolder); logger.debug(String.format("create subdirectory '%1$s' in folder '%2$s'", strSubFolder, objO.TargetDir().Value())); } } catch (IOException e) { throw new JobSchedulerException(e); } } } } return null; } private String MakeFileNameReplacing(final String pstrFileName) { String strR = adjustFileSeparator(pstrFileName); String strReplaceWith = objOptions.getreplacement().Value(); try { strR = objOptions.getreplacing().doReplace(strR, strReplaceWith); } catch (Exception e) { logger.error(e.getLocalizedMessage(), new JobSchedulerException(SOSVfs_E_0150.get(), e)); } return strR; } private String getFileNameWithoutPath(final String pstrTargetFileName) { String strT = adjustFileSeparator(pstrTargetFileName); File fleT = new File(strT); strT = fleT.getName(); return strT; } private String getPathWithoutFileName(final String pstrTargetFileName) { String strT = adjustFileSeparator(pstrTargetFileName); File fleT = new File(strT); strT = fleT.getParent(); return addFileSeparator(adjustFileSeparator(strT)); } protected String normalized(String str) { str = adjustFileSeparator(str); str = addFileSeparator(str); return str; } /** * * \brief MakeAtomicFileName * * \details * This Method creates an 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(); strTargetTransferName = strTargetFileName + strAtomicSuffix.trim(); strTargetTransferName = strAtomicPrefix + strTargetTransferName; strAtomicFileName = strTargetTransferName; return strTargetTransferName.trim(); } // private String MakeAtomicFileName public void DeleteSourceFile() { // SOSFTP-152: allow source file deletion even if the filename is changed by (replace/replacing) String strFile2Delete = strSourceFileName; if (strRenamedSourceFileName != null) { strFile2Delete = strRenamedSourceFileName; } objDataSourceClient.getFileHandle(strFile2Delete).delete(); String strM = SOSVfs_I_0113.params(strFile2Delete); logger.info(strM); objJadeReportLogger.info(strM); } public void setStatus(final enuTransferStatus peTransferStatus) { @SuppressWarnings("unused") final String conMethodName = conClassName + "::setStatus"; String strM = ""; eTransferStatus = peTransferStatus; switch (peTransferStatus) { case transferInProgress: strM = SOSVfs_I_0114.get(); break; case waiting4transfer: strM = SOSVfs_I_0115.get(); // TODO Message senden break; case transfer_skipped: dteEndTransfer = Now(); strM = SOSVfs_I_0116.get(); // TODO Message senden break; case transferring: strM = SOSVfs_I_0117.get(); dteStartTransfer = Now(); // TODO Message senden break; case transferred: strM = SOSVfs_I_0118.get(); dteEndTransfer = Now(); // TODO Message senden break; case transfer_aborted: strM = SOSVfs_I_0119.get(); 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: strM = SOSVfs_I_0120.params(strM, strSourceFileName); break; } } } // private void TransferStatus public void Log4Debug() { logger.debug(SOSVfs_D_218.params(this.SourceFileName())); logger.debug(SOSVfs_D_219.params(this.SourceTransferName())); logger.debug(SOSVfs_D_220.params(this.TargetTransferName())); logger.debug(SOSVfs_D_221.params(this.TargetFileName())); } public SOSFileListEntry(final String pstrLocalFileName) { this("", pstrLocalFileName, 0); } public SOSFileListEntry(final String pstrRemoteFileName, final String pstrLocalFileName, final long plngNoOfBytesTransferred) { super(SOSVfsConstants.strBundleBaseName); strTargetFileName = pstrRemoteFileName; strSourceFileName = pstrLocalFileName; lngNoOfBytesTransferred = plngNoOfBytesTransferred; // this.setStatus(enuTransfesrStatus.waiting4transfer); } @Override public String toString() { String strT = SOSVfs_D_214.params(this.getTargetFileNameAndPath(), this.SourceFileName(), this.NoOfBytesTransferred(), objOptions.operation.Value()); return strT; } private String strCSVRec = new String(); private void addCSv(final String... pstrVal) { for (String string : pstrVal) { if (strCSVRec.length() > 0) { strCSVRec += ";"; } strCSVRec += string; } } // private final String historyFields = "guid;mandator;transfer_timestamp;pid;ppid;operation;localhost;localhost_ip;local_user;remote_host;remote_host_ip;remote_user;protocol;port;local_dir;remote_dir;local_filename;remote_filename;file_size;md5;status;last_error_message;log_filename"; public String toCsv() { addCSv(guid, objOptions.mandator.Value(), SOSOptionTime.getCurrentTimeAsString()); /** * 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"); addCSv(pid, ppid, objOptions.operation.Value()); SOSConnection2OptionsAlternate objS = objOptions.getConnectionOptions().Source(); addCSv(objS.host.Value(), objS.host.getHostAdress(), System.getProperty("user.name")); SOSConnection2OptionsAlternate objT = objOptions.getConnectionOptions().Target(); addCSv(objT.host.Value(), objT.host.getHostAdress()); String remote_user = ""; if (objT.AlternateOptionsUsed.value() == true) { remote_user = "(alternative) " + objT.Alternatives().user.Value(); } else { remote_user = objT.user.Value(); } addCSv(remote_user, objT.protocol.Value(), objT.port.Value(), objOptions.local_dir.Value(), objOptions.TargetDir.Value(), strSourceFileName); String remote_filename = strTargetFileName; if (isEmpty(remote_filename)) { remote_filename = "n.a."; } addCSv(remote_filename, String.valueOf(lngFileSize), strMD5Hash, 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)); addCSv(last_error_message, objOptions.log_filename.Value(), objOptions.jump_host.Value(), objOptions.jump_host.getHostAdress(), objOptions.jump_port.Value(), objOptions.jump_protocol.Value(), objOptions.jump_user.Value()); SOSOptionTime objModTime = new SOSOptionTime(null, null, null, "", "", false); objModTime.value(lngFileModDate); addCSv(objModTime.getTimeAsString(lngFileModDate)); return strCSVRec; } public String getTargetFileNameAndPath() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::getTargetFileNameAndPath"; String strT = objOptions.TargetDir.Value() + strTargetFileName; return strT; // return String; } // private String getTargetFileNameAndPath @Deprecated // use getTargetfileNameAndPath public String RemoteFileName() { return strTargetFileName; } public void setRemoteFileName(final String pstrRemoteFileName) { strTargetFileName = pstrRemoteFileName; } public String SourceFileName() { return strSourceFileName; } public void setSourceFileName(final String pstrLocalFileName) { 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(final long plngNoOfBytesTransferred) { lngNoOfBytesTransferred = plngNoOfBytesTransferred; if (lngFileSize <= 0) { // if the file is compressed, then the original filesize may be to big lngFileSize = objDataSourceClient.getFileHandle(strSourceFileName).getFileSize(); lngOriginalFileSize = lngFileSize; } if (lngFileSize != plngNoOfBytesTransferred) { logger.error(SOSVfs_E_216.params(plngNoOfBytesTransferred, lngFileSize, strSourceFileName)); this.setStatus(enuTransferStatus.transfer_aborted); throw new JobSchedulerException(SOSVfs_E_271.get()); } if (lngOriginalFileSize != plngNoOfBytesTransferred) { logger.error(SOSVfs_E_216.params(plngNoOfBytesTransferred, lngOriginalFileSize, strSourceFileName)); this.setStatus(enuTransferStatus.transfer_aborted); throw new JobSchedulerException(SOSVfs_E_270.get()); } this.setStatus(enuTransferStatus.transferred); // TODO Message "transferCompleted absetzen" } /** * \brief setlngTransferProgress - * * \details * setter * * @param lngTransferProgress the value for lngTransferProgress to set */ public void setTransferProgress(final long plngTransferProgress) { lngTransferProgress = plngTransferProgress; this.setStatus(enuTransferStatus.transferInProgress); String lstrTargetFileName = strTargetFileName; if (objDataTargetClient.getHandler() instanceof SOSVfsZip) { lstrTargetFileName = SOSVfs_D_217.params(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 setStatusStartTransfer() { this.setStatus(enuTransferStatus.transferring); } public void setStatusEndTransfer(final long plngNoOfBytesTransferred) { this.setNoOfBytesTransferred(plngNoOfBytesTransferred); this.setStatusEndTransfer(); } public void setStatusEndTransfer() { this.setStatus(enuTransferStatus.transferred); } public void Options(final SOSFTPOptions pobjOptions) { @SuppressWarnings("unused") final String conMethodName = conClassName + "::Options"; objOptions = pobjOptions; } // private void Options // TODO polling ber die File-Gre /** * Diese Routine prft *nur* auf dem lokalen fileSystem und ist aus der "Send"-Klasse kopiert. * hier hat sie nichts zu suchen, da das polling fr dateien in der Engine erfolgen muss, * unabhngig davon, wo die Dateien liegen. Es mu *immer* die Datasource gepollt werden. * * Auf alle Flle 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 eigentlich ist das hier "check_steady_state" 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(SOSVfs_I_222.params(fileName)); // // TODO in die Implementation des ISOSVirtualFile verschieben // File fleFile = new File(fileName); // // TODO ber Option auf FileSize ausweichen, da MD5 bei groen 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(SOSVfs_D_223.params(i, newMD5File)); // if (!lastmd5file.equals(newMD5File)) { // lastmd5file = newMD5File; // logger.info(SOSVfs_I_222.params(fileName)); // Thread.sleep((long) delay * 1000); // if (i + 1 == nrOfTries) { // found = false; // message = message + " " + fileName; // } // } // else { // break; // } // } // if (found == false) { // message = SOSVfs_E_224.params(objOptions.poll_timeout.value(), message); // 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(SOSVfs_E_225.params(conMethodName, e)); } } // Runnable @Override public void run() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::run"; boolean flgNewConnectionUsed = false; try { // logger.debug(SOSVfs_D_272.get()); 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 & objOptions.NeedTargetClient() == true) { 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(SOSVfs_E_226.params(strSourceFileName)); } /** * hier nicht verwenden, weil es zu spt kommt. */ // if (CheckFileSizeIsChanging() == false) { // // TODO Exception auslsen // return; // } // // improve zeroByteFile handling in transactional mode // 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 flgIncludeSubdirectories = objOptions.recursive.value(); if (flgIncludeSubdirectories == true) { // TODO Das Erstellen des Verzeichnis mu eine separate Methode werden // berprfen, 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()); // Unterverzeichnisse sind alle Verzeichnisse unterhalb // der localDir subParent = new File(subPath).getParentFile(); if (subParent != null) { subPath = adjustFileSeparator(subPath); subPath = subPath.substring(0, subPath.length() - new File(strSourceFileName.toString()).getName().length() - 1); // logger.debug(SOSVfs_D_227.params(subPath)); // TODO nur feststellen, ob es den schon gibt. Neue Methode einfhren, evtl. FileExists/Folderexists // String[] ftpFiles = objDataTargetClient.listNames(strTargetFolderName + "/" + subPath); // if (ftpFiles == null || ftpFiles.length == 0) { // File.separator fhrte zu Unterverzeichnissen mit fhrendem Backslash //objDataTargetClient.mkdir(strTargetFolderName + File.separator + subPath); objDataTargetClient.mkdir(strTargetFolderName + "/" + subPath); // } } else { subPath = ""; } } } this.getTargetFile(objOptions); // TODO Namen ndern if (objOptions.transactional.value() == true) { this.setTransactionalLocalFile(); } switch (objOptions.operation.value()) { case delete: // TODO operation delete is not transactional objSourceFile.delete(); logger.debug(SOSVfs_I_0113.params(strSourceFileName)); this.setStatus(enuTransferStatus.deleted); return; case rename: // TODO operation rename is not transactional File fleT = new File(strSourceFileName); String strParent = changeBackslashes(normalized(fleT.getParent())); String strNewFileName = MakeFileNameReplacing(fleT.getName()); strNewFileName = changeBackslashes(addFileSeparator(strParent) + strNewFileName); logger.debug(SOSVfs_I_150.params(strSourceFileName, strNewFileName)); strTargetFileName = strNewFileName; objSourceFile.rename(strNewFileName); this.setStatus(enuTransferStatus.renamed); return; default: break; } ISOSVirtualFile objTargetFile = objDataTargetClient .getFileHandle(MakeFullPathName(objOptions.TargetDir.Value(), strTargetFileName)); if (objOptions.CumulateFiles.isTrue()) { if (objOptions.CumulativeFileDelete.isTrue() && objOptions.flgCumulativeTargetDeleted == false) { objTargetFile.delete(); objOptions.flgCumulativeTargetDeleted = true; logger.debug(String.format("cumulative file '%1$s' deleted.", strTargetFileName)); } } objTargetFile.setModeAppend(objOptions.append_files.value()); objTargetFile.setModeRestart(objOptions.ResumeTransfer.value()); if (strTargetFileName.equalsIgnoreCase(strTargetTransferName) == false) { objTargetTransferFile = objDataTargetClient .getFileHandle(MakeFullPathName(objOptions.TargetDir.Value(), strTargetTransferName)); } else { objTargetTransferFile = objTargetFile; } if (objOptions.CumulateFiles.isTrue()) { objTargetTransferFile.setModeAppend(objOptions.append_files.value()); objTargetTransferFile.setModeRestart(objOptions.ResumeTransfer.value()); } if (objOptions.compress_files.value() == true) { objSourceTransferFile = objDataSourceClient.getFileHandle(strSourceTransferName); lngFileSize = objSourceTransferFile.getFileSize(); lngOriginalFileSize = lngFileSize; } else { strSourceTransferName = getFileNameWithoutPath(strSourceTransferName); String strT = ""; objSourceTransferFile = objDataSourceClient.getFileHandle( MakeFullPathName(getPathWithoutFileName(strSourceFileName) + strT, strSourceTransferName)); } if (objOptions.DoNotOverwrite() == true) { // kb 2012-06-29: check setting first, then file - existence flgFileExists = objTargetFile.FileExists(); if (flgFileExists == true) { logger.debug(SOSVfs_E_228.params(strTargetFileName)); this.setNotOverwritten(); return; } } this.doTransfer(objSourceTransferFile, objTargetTransferFile); if (objOptions.KeepModificationDate.isTrue()) { long pdteDateTime = objSourceFile.getModificationDateTime(); if (pdteDateTime != -1) { objTargetFile.setModificationDateTime(pdteDateTime); } } if (objOptions.isAtomicTransfer() || objOptions.isReplaceReplacingInEffect()) { if (objOptions.transactional.value() == false) { flgFileExists = objTargetFile.FileExists(); if (objOptions.overwrite_files.value() == true & flgFileExists == true) { // hier werden Dateien gelscht, vor dem umbenennen. // TODO Besser: auch erstmal umbenennen und dann erst lschen objTargetFile.delete(); } RenameTargetFile(MakeFullPathName(objOptions.TargetDir.Value(), this.TargetFileName())); } } RenameSourceFile(objSourceFile); if (flgNewConnectionUsed == true) { objDataSourceClient.logout(); objDataSourceClient.disconnect(); objDataTargetClient.logout(); objDataTargetClient.disconnect(); } } catch (Exception e) { String strT = SOSVfs_E_229.params(e); // TODO rollback? logger.error(strT); throw new JobSchedulerException(strT, e); } } private String strRenamedSourceFileName = null; private void RenameSourceFile(final ISOSVirtualFile pobjSourceFile) { SOSConnection2OptionsAlternate objSO = objOptions.Source(); if (objSO.ReplaceWhat.isDirty()) { String strReplaceWith = objSO.getreplacement().Value(); try { File fleT = new File(strSourceFileName); String strParent = changeBackslashes(normalized(fleT.getParent())); String strSourceFileName1 = fleT.getName(); strSourceFileName1 = changeBackslashes(strSourceFileName1); // Problems on windows: the path separator disapers String strNewSourceFileName = objSO.ReplaceWhat.doReplace(strSourceFileName1, strReplaceWith); if (strReplaceWith.startsWith("/") == false) { strNewSourceFileName = changeBackslashes(addFileSeparator(strParent) + strNewSourceFileName); } pobjSourceFile.rename(strNewSourceFileName); strRenamedSourceFileName = strNewSourceFileName; } catch (Exception e) { logger.error(e.getLocalizedMessage(), new JobSchedulerException(SOSVfs_E_0150.get(), e)); } } } private String changeBackslashes(final String pstrV) { return pstrV.replaceAll("\\\\", "/"); } private void RenameTargetFile(final String pstrTargetFileName) { if (pstrTargetFileName.equals(objTargetTransferFile.getName()) == false) { objTargetTransferFile.rename(pstrTargetFileName); } } private void RaiseException(final String pstrM) { this.TransferStatus(enuTransferStatus.transfer_aborted); logger.error(pstrM); throw new JobSchedulerException(pstrM); } private long doTransfer(final ISOSVirtualFile objInput, final ISOSVirtualFile objOutput) { @SuppressWarnings("unused") final String conMethodName = conClassName + "::doTransfer"; boolean flgClosingDone = false; if (objOutput == null) { RaiseException(SOSVfs_E_273.params("Target")); } if (objInput == null) { RaiseException(SOSVfs_E_273.params("Source")); } boolean flgCreateSecurityHash = objOptions.CreateSecurityHash.value() && flgIsHashFile == false; 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; } } executePreCommands(); long lngTotalBytesTransferred = 0; Base64 objBase64 = null; this.setStatus(enuTransferStatus.transferring); try { int intCumulativeFileSeperatorLength = 0; int lngBufferSize = objOptions.BufferSize.value(); byte[] buffer = new byte[lngBufferSize]; int intBytesTransferred; int intOffset = 0; boolean flgBase64EncodingOnOutput = false; boolean flgBase64EncodingOnInput = false; if (flgBase64EncodingOnOutput) { objBase64 = new Base64(); } synchronized (this) { if (objOptions.CumulateFiles.isTrue() && objOptions.CumulativeFileSeparator.IsNotEmpty()) { String strFS = objOptions.CumulativeFileSeparator.Value(); strFS = this.replaceVariables(strFS) + System.getProperty("line.separator"); byte[] bteB = strFS.getBytes(); intCumulativeFileSeperatorLength = bteB.length; objOutput.write(bteB); } if (objInput.getFileSize() <= 0) { objOutput.write(buffer, 0, 0); } else { while ((intBytesTransferred = objInput.read(buffer)) != -1) { try { int intBytes2Write = intBytesTransferred; if (flgBase64EncodingOnOutput) { byte[] bteIn = new byte[intBytesTransferred]; byte[] bteOut = objBase64.encode(bteIn); intBytes2Write = bteOut.length; buffer = bteOut; } objOutput.write(buffer, 0, intBytes2Write); } catch (JobSchedulerException e) { e.printStackTrace(System.err); break; } // TODO in case of wrong outputbuffer the handling of the error must be improved lngTotalBytesTransferred += intBytesTransferred; // intOffset += lngTotalBytesTransferred; setTransferProgress(lngTotalBytesTransferred); if (flgCreateSecurityHash) { md.update(buffer, 0, intBytesTransferred); } } } } objInput.closeInput(); objOutput.closeOutput(); flgClosingDone = true; if (flgCreateSecurityHash) { strMD5Hash = toHexString(md.digest()); logger.info(SOSVfs_I_274.params(strMD5Hash, strSourceTransferName, objOptions.SecurityHashType.Value())); if (objOptions.CreateSecurityHashFile.isTrue()) { JSTextFile objF = new JSTextFile(strSourceFileName + "." + objOptions.SecurityHashType.Value()); objF.WriteLine(strMD5Hash); objF.close(); objF.deleteOnExit(); } } // objDataTargetClient.CompletePendingCommand(); if (objDataTargetClient.isNegativeCommandCompletion()) { RaiseException( SOSVfs_E_175.params(objTargetTransferFile.getName(), objDataTargetClient.getReplyString())); } this.setNoOfBytesTransferred(lngTotalBytesTransferred); lngTotalBytesTransferred += intCumulativeFileSeperatorLength; executePostCommands(); return lngTotalBytesTransferred; } catch (Exception e) { RaiseException(e, SOSVfs_E_266.get()); } 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 executePostCommands() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::executePostCommands"; executeCommands(objDataTargetClient, objOptions.Post_Command); executeCommands(objDataSourceClient, objOptions.getConnectionOptions().Source().Post_Command); executeCommands(objDataTargetClient, objOptions.getConnectionOptions().Target().Post_Command); } // private void executePostCommands private void executePreCommands() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::executePreCommands"; executeCommands(objDataTargetClient, objOptions.Pre_Command); executeCommands(objDataSourceClient, objOptions.getConnectionOptions().Source().Pre_Command); executeCommands(objDataTargetClient, objOptions.getConnectionOptions().Target().Pre_Command); } // private void executePreCommands public String getAtomicFileName() { return strAtomicFileName; } public void setAtomicFileName(final String pstrValue) { strAtomicFileName = pstrValue; } public boolean FileExists() { ISOSVirtualFile objTargetFile = objDataTargetClient .getFileHandle(MakeFullPathName(objOptions.TargetDir.Value(), strTargetFileName)); try { flgFileExists = objTargetFile.FileExists(); } catch (Exception e) { flgFileExists = false; } return flgFileExists; } /** * * * \brief SourceFileExists * * \details * Check, wether a source file exists. * * \return boolean * */ public boolean SourceFileExists() { boolean flgT = false; try { flgT = objDataSourceClient.getFileHandle(strSourceFileName).FileExists(); } catch (Exception e) { } return flgT; } private String toHexString(final 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 (byte element : b) { // oberer Byteanteil sb.append(hexChar[(element & 0xf0) >>> 4]); // unterer Byteanteil sb.append(hexChar[element & 0x0f]); } return sb.toString(); } /** * * \brief sendTransferHistory * * \details * This methods sends for each file the needed informations about the transfer history * to the background service (JobScheduler). * * \return void * */ public boolean sendTransferHistory() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::sendTransferHistory"; boolean flgRet = false; if (flgTransferHistoryAlreadySent == true) { return flgRet; } flgTransferHistoryAlreadySent = true; if (objOptions.SendTransferHistory.isFalse()) { if (flgNoDataSent == false) { flgNoDataSent = true; } return flgRet; } String strBackgroundServiceHostName = objOptions.scheduler_host.Value(); if (isEmpty(strBackgroundServiceHostName)) { if (flgNoDataSent == false) { flgNoDataSent = true; logger.debug(Messages.getMsg("No data sent to the background service due to missing host name")); } return flgRet; } 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 */ // TODO create a getPID method in shell class 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 = ""; if (objT.AlternateOptionsUsed.value() == true) { remote_user = "(alternative) " + objT.Alternatives().user.Value(); // 8- remote host user } else { 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 remote_dir = objOptions.TargetDir.Value(); String local_filename = strSourceFileName; // 13- file name String remote_filename = strTargetFileName; // 14- name if (isEmpty(remote_filename)) { remote_filename = "n.a."; } String fileSize = String.valueOf(lngFileSize); String md5 = strMD5Hash; 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", 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 fr Windows objSchedulerOrderParameterSet.put("ppid", ppid); // 5- ppid= Environment PPID | 0 fr 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 String status = eTransferStatus.name(); if (status.equalsIgnoreCase("transferred")) { status = "success"; } 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 mglich "custom" Felder zu definieren, die in der Transfer History 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().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(SOSVfs_Title_276.get()); Params objParams = objFactory.setParams(objSchedulerOrderParameterSet); objOrder.setParams(objParams); // logger.debug(objOrder.toXMLString()); objOrder.run(); flgRet = true; return flgRet; } // private void sendTransferHistory private void executeCommands(final ISOSVfsFileTransfer pobjDataClient, final SOSOptionString pstrCommandString) { final String conMethodName = conClassName + "::executeCommands"; if (pstrCommandString.IsNotEmpty()) { String strT = pstrCommandString.Value(); strT = replaceVariables(strT); String strM = SOSVfs_D_0151.params(strT); logger.debug(strM); String[] strA = strT.split(";"); for (String strCmd : strA) { try { pobjDataClient.getHandler().ExecuteCommand(strCmd); } catch (Exception e) { e.printStackTrace(System.err); throw new JobSchedulerException(conMethodName, e); } } } } // private void executeCommands private String replaceVariables(final String pstrReplaceIn) { @SuppressWarnings("unused") final String conMethodName = conClassName + "::replaceVariables"; String strT = pstrReplaceIn; strT = strT.replace("$TargetFileName", MakeFullPathName(objOptions.TargetDir.Value(), strTargetFileName)); strT = strT.replace("$TargetTransferFileName", MakeFullPathName(objOptions.TargetDir.Value(), strTargetTransferName)); strT = strT.replace("$SourceFileName", MakeFullPathName(objOptions.SourceDir.Value(), strSourceFileName)); strT = strT.replace("$SourceTransferFileName", MakeFullPathName(objOptions.SourceDir.Value(), strSourceTransferName)); Properties objProp = objOptions.getTextProperties(); objProp.put("TargetFileName", strTargetFileName); objProp.put("TargetTransferFileName", strTargetTransferName); objProp.put("SourceFileName", strSourceFileName); objProp.put("SourceTransferFileName", strSourceTransferName); strT = objOptions.replaceVars(strT); // TODO other patterns, like [date:] or others should replaced as well return strT; } // private String replaceVariables @Override public Integer getTransferDetailsId() { return null; } @Override public Integer getTransferId() { return null; } @Override public Long getFileSize() { return lngFileSize; } @Override public Integer getCommandType() { return 0; } @Override public String getCommand() { return EMPTY_STRING; } @Override public String getPid() { return objOptions.getPid(); } @Override public String getLastErrorMessage() { return EMPTY_STRING; } @Override public String getTargetFilename() { return strTargetFileName; } @Override public String getSourceFilename() { return strSourceFileName; } @Override public String getMd5() { return strMD5Hash; } @Override public Integer getStatus() { return new Integer(eTransferStatus.ordinal()); } @Override public Date getStartTime() { return dteStartTransfer; } @Override public Date getEndTime() { return dteEndTransfer; } @Override public String getModifiedBy() { return EMPTY_STRING; } @Override public String getCreatedBy() { return EMPTY_STRING; } @Override public Date getCreated() { return null; } @Override public Date getModified() { return null; } @Override public String getStatusText() { return eTransferStatus.name(); } @Override public String getSizeValue() { return ""; } public void setSteady(final boolean pflgSteadyFlag) { flgSteadyFlag = pflgSteadyFlag; } public boolean isSteady() { @SuppressWarnings("unused") final String conMethodName = conClassName + "::isSteady"; return flgSteadyFlag; } // private boolean isSteady public String SecurityHash() { return strMD5Hash; } }