This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new c45768cba6 Cleanup XML of action Copy Files, fixes #1958 (#6930)
c45768cba6 is described below
commit c45768cba6d6fa409a14611aacbc4cad83fc859f
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Thu Apr 2 14:22:21 2026 +0200
Cleanup XML of action Copy Files, fixes #1958 (#6930)
* Cleanup XML of action Copy Files, fixes #1958
* track byte count
---
.../actions/copyfiles/ActionCopyFiles.java | 1171 +++++++-------------
.../actions/copyfiles/ActionCopyFilesDialog.java | 186 +---
.../workflow/actions/copyfiles/CopyFilesItem.java | 65 ++
.../copyfiles/messages/messages_de_DE.properties | 7 -
.../copyfiles/messages/messages_en_US.properties | 23 +-
.../copyfiles/messages/messages_es_AR.properties | 7 -
.../copyfiles/messages/messages_fr_FR.properties | 7 -
.../copyfiles/messages/messages_it_IT.properties | 7 -
.../copyfiles/messages/messages_ja_JP.properties | 7 -
.../copyfiles/messages/messages_ko_KR.properties | 9 +-
.../copyfiles/messages/messages_nl_NL.properties | 7 -
.../copyfiles/messages/messages_pt_BR.properties | 7 -
.../copyfiles/messages/messages_zh_CN.properties | 7 -
.../src/main/samples/actions/copy-files.hwf | 6 +-
.../WorkflowActionCopyFilesLoadSaveTest.java | 163 ++-
.../WorkflowActionCopyFilesLocalTest.java | 281 +++++
.../copyfiles/WorkflowActionCopyFilesTest.java | 55 +-
.../src/test/resources/copy-files-action.xml | 48 +
18 files changed, 1018 insertions(+), 1045 deletions(-)
diff --git
a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
index db54c9c2b7..e1c11f4762 100644
---
a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
+++
b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFiles.java
@@ -18,24 +18,23 @@
package org.apache.hop.workflow.actions.copyfiles;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.commons.vfs2.FileFilterSelector;
-import org.apache.commons.vfs2.FileName;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSelectInfo;
import org.apache.commons.vfs2.FileSelector;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.NameScope;
-import org.apache.commons.vfs2.filter.NameFileFilter;
import org.apache.hop.core.Const;
import org.apache.hop.core.ICheckResult;
import org.apache.hop.core.Result;
@@ -43,16 +42,17 @@ import org.apache.hop.core.ResultFile;
import org.apache.hop.core.RowMetaAndData;
import org.apache.hop.core.annotations.Action;
import org.apache.hop.core.exception.HopException;
-import org.apache.hop.core.exception.HopXmlException;
+import org.apache.hop.core.io.CountingInputStream;
+import org.apache.hop.core.io.CountingOutputStream;
import org.apache.hop.core.util.Utils;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.core.vfs.HopVfs;
-import org.apache.hop.core.xml.XmlHandler;
import org.apache.hop.i18n.BaseMessages;
+import org.apache.hop.metadata.api.HopMetadataProperty;
import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.metadata.serializer.xml.ILegacyXml;
import org.apache.hop.workflow.WorkflowMeta;
import org.apache.hop.workflow.action.ActionBase;
-import org.apache.hop.workflow.action.IAction;
import org.apache.hop.workflow.action.validator.AbstractFileValidator;
import org.apache.hop.workflow.action.validator.ActionValidatorUtils;
import org.apache.hop.workflow.action.validator.AndValidator;
@@ -61,7 +61,8 @@ import org.apache.hop.workflow.engine.IWorkflowEngine;
import org.w3c.dom.Node;
/** This defines a 'copy files' action. */
-@SuppressWarnings("java:S1104")
+@Getter
+@Setter
@Action(
id = "COPY_FILES",
name = "i18n::ActionCopyFiles.Name",
@@ -70,204 +71,154 @@ import org.w3c.dom.Node;
categoryDescription =
"i18n:org.apache.hop.workflow:ActionCategory.Category.FileManagement",
keywords = "i18n::ActionCopyFiles.keyword",
documentationUrl = "/workflow/actions/copyfiles.html")
-public class ActionCopyFiles extends ActionBase implements Cloneable, IAction {
+public class ActionCopyFiles extends ActionBase implements ILegacyXml {
private static final Class<?> PKG = ActionCopyFiles.class;
- public static final String SOURCE_CONFIGURATION_NAME =
"source_configuration_name";
- public static final String SOURCE_FILE_FOLDER = "source_filefolder";
-
- public static final String DESTINATION_CONFIGURATION_NAME =
"destination_configuration_name";
- public static final String DESTINATION_FILE_FOLDER =
"destination_filefolder";
-
- public static final String LOCAL_SOURCE_FILE = "LOCAL-SOURCE-FILE-";
- public static final String LOCAL_DEST_FILE = "LOCAL-DEST-FILE-";
-
- public static final String STATIC_SOURCE_FILE = "STATIC-SOURCE-FILE-";
- public static final String STATIC_DEST_FILE = "STATIC-DEST-FILE-";
-
+ /** Legacy wizard prefix on source paths (stripped on load, no longer
written). */
public static final String DEST_URL = "EMPTY_DEST_URL-";
+
public static final String SOURCE_URL = "EMPTY_SOURCE_URL-";
- private static final String CONST_SPACE = " ";
private static final String CONST_SPACE_SHORT = " ";
private static final String CONST_FILE_COPIED =
"ActionCopyFiles.Log.FileCopied";
private static final String CONST_COPY_PROCESS =
"ActionCopyFiles.Error.Exception.CopyProcess";
private static final String CONST_FILE_EXISTS =
"ActionCopyFiles.Log.FileExists";
+ private static final String CONST_FILE_EXISTS_SKIP_COPY =
+ "ActionCopyFiles.Log.FileExistsSkippingCopy";
+ private static final String CONST_FOLDER_EXISTS =
"ActionCopyFiles.Log.FolderExists";
+ private static final String CONST_FOLDER_EXISTS_SKIP_COPY =
+ "ActionCopyFiles.Log.FolderExistsSkippingCopy";
+ private static final String CONST_FILE_OVERWRITE =
"ActionCopyFiles.Log.FileOverwrite";
+
+ /** Destination parent folder exists or was created successfully. */
+ private static final int DESTINATION_FOLDER_READY = 1;
+
+ /** Destination parent folder is missing and "Create destination folder" is
off. */
+ private static final int DESTINATION_FOLDER_NOT_AVAILABLE = 0;
- public boolean copyEmptyFolders;
- public boolean argFromPrevious;
- public boolean overwriteFiles;
- public boolean includeSubFolders;
- public boolean addResultFilenames;
- public boolean removeSourceFiles;
- public boolean destinationIsAFile;
- public boolean createDestinationFolder;
- public String[] sourceFileFolder;
- public String[] destinationFileFolder;
- public String[] wildcard;
+ /** Creating the destination folder failed (already logged). */
+ private static final int DESTINATION_FOLDER_FAILED = -1;
+ @Getter(AccessLevel.NONE)
+ @Setter(AccessLevel.NONE)
private HashSet<String> listFilesRemove = new HashSet<>();
+
+ @Getter(AccessLevel.NONE)
+ @Setter(AccessLevel.NONE)
private HashSet<String> listAddResult = new HashSet<>();
- private int nbrFail = 0;
- private Map<String, String> configurationMappings = new HashMap<>();
+ @HopMetadataProperty(key = "copy_empty_folders")
+ private boolean copyEmptyFolders = true;
+
+ @HopMetadataProperty(key = "arg_from_previous")
+ private boolean argFromPrevious;
+
+ @HopMetadataProperty(key = "overwrite_files")
+ private boolean overwriteFiles;
+
+ @HopMetadataProperty(key = "include_subfolders")
+ private boolean includeSubFolders;
+
+ @HopMetadataProperty(key = "remove_source_files")
+ private boolean removeSourceFiles;
+
+ @HopMetadataProperty(key = "add_result_filesname")
+ private boolean addResultFilenames;
+
+ @HopMetadataProperty(key = "destination_is_a_file")
+ private boolean destinationIsAFile;
+
+ @HopMetadataProperty(key = "create_destination_folder")
+ private boolean createDestinationFolder;
+
+ @HopMetadataProperty(groupKey = "fields", key = "field")
+ private List<CopyFilesItem> fileRows = new ArrayList<>();
public ActionCopyFiles(String n) {
super(n, "");
- copyEmptyFolders = true;
- argFromPrevious = false;
- sourceFileFolder = null;
- removeSourceFiles = false;
- destinationFileFolder = null;
- wildcard = null;
- overwriteFiles = false;
- includeSubFolders = false;
- addResultFilenames = false;
- destinationIsAFile = false;
- createDestinationFolder = false;
}
public ActionCopyFiles() {
this("");
}
- public void allocate(int nrFields) {
- sourceFileFolder = new String[nrFields];
- destinationFileFolder = new String[nrFields];
- wildcard = new String[nrFields];
- }
-
- @Override
- public Object clone() {
- ActionCopyFiles je = (ActionCopyFiles) super.clone();
- if (sourceFileFolder != null) {
- int nrFields = sourceFileFolder.length;
- je.allocate(nrFields);
- System.arraycopy(sourceFileFolder, 0, je.sourceFileFolder, 0, nrFields);
- System.arraycopy(destinationFileFolder, 0, je.destinationFileFolder, 0,
nrFields);
- System.arraycopy(wildcard, 0, je.wildcard, 0, nrFields);
- }
- return je;
- }
-
- @Override
- public String getXml() {
- StringBuilder xml = new StringBuilder(300);
-
- xml.append(super.getXml());
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("copy_empty_folders",
copyEmptyFolders));
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("arg_from_previous", argFromPrevious));
-
xml.append(CONST_SPACE_SHORT).append(XmlHandler.addTagValue("overwrite_files",
overwriteFiles));
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("include_subfolders",
includeSubFolders));
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("remove_source_files",
removeSourceFiles));
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("add_result_filesname",
addResultFilenames));
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("destination_is_a_file",
destinationIsAFile));
- xml.append(CONST_SPACE_SHORT)
- .append(XmlHandler.addTagValue("create_destination_folder",
createDestinationFolder));
-
- xml.append(" <fields>").append(Const.CR);
-
- // Get source and destination files, also wildcard
- if (sourceFileFolder != null) {
- for (int i = 0; i < sourceFileFolder.length; i++) {
- xml.append(" <field>").append(Const.CR);
- saveSource(xml, sourceFileFolder[i]);
- saveDestination(xml, destinationFileFolder[i]);
- xml.append(CONST_SPACE).append(XmlHandler.addTagValue("wildcard",
wildcard[i]));
- xml.append(" </field>").append(Const.CR);
+ public ActionCopyFiles(ActionCopyFiles other) {
+ super(other.getName(), other.getDescription(), other.getPluginId());
+ this.copyEmptyFolders = other.copyEmptyFolders;
+ this.argFromPrevious = other.argFromPrevious;
+ this.overwriteFiles = other.overwriteFiles;
+ this.includeSubFolders = other.includeSubFolders;
+ this.removeSourceFiles = other.removeSourceFiles;
+ this.addResultFilenames = other.addResultFilenames;
+ this.destinationIsAFile = other.destinationIsAFile;
+ this.createDestinationFolder = other.createDestinationFolder;
+ this.fileRows = new ArrayList<>();
+ if (other.fileRows != null) {
+ for (CopyFilesItem row : other.fileRows) {
+ this.fileRows.add(
+ new CopyFilesItem(
+ row.getSourceFileFolder(), row.getDestinationFileFolder(),
row.getWildcard()));
}
}
- xml.append(" </fields>").append(Const.CR);
-
- return xml.toString();
}
@Override
- public void loadXml(Node entrynode, IHopMetadataProvider metadataProvider,
IVariables variables)
- throws HopXmlException {
- try {
- super.loadXml(entrynode);
- copyEmptyFolders =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"copy_empty_folders"));
- argFromPrevious =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"arg_from_previous"));
- overwriteFiles = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"overwrite_files"));
- includeSubFolders =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"include_subfolders"));
- removeSourceFiles =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"remove_source_files"));
- addResultFilenames =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"add_result_filesname"));
- destinationIsAFile =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"destination_is_a_file"));
- createDestinationFolder =
- "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode,
"create_destination_folder"));
-
- Node fields = XmlHandler.getSubNode(entrynode, "fields");
-
- // How many field arguments?
- int nrFields = XmlHandler.countNodes(fields, "field");
- allocate(nrFields);
-
- // Read them all...
- for (int i = 0; i < nrFields; i++) {
- Node fnode = XmlHandler.getSubNodeByNr(fields, "field", i);
- sourceFileFolder[i] = loadSource(fnode);
- destinationFileFolder[i] = loadDestination(fnode);
- wildcard[i] = XmlHandler.getTagValue(fnode, "wildcard");
+ public Object clone() {
+ ActionCopyFiles copy = (ActionCopyFiles) super.clone();
+ copy.listFilesRemove = new HashSet<>();
+ copy.listAddResult = new HashSet<>();
+ copy.fileRows = new ArrayList<>();
+ if (fileRows != null) {
+ for (CopyFilesItem row : fileRows) {
+ copy.fileRows.add(
+ new CopyFilesItem(
+ row.getSourceFileFolder(), row.getDestinationFileFolder(),
row.getWildcard()));
}
- } catch (HopXmlException xe) {
-
- throw new HopXmlException(
- BaseMessages.getString(PKG,
"ActionCopyFiles.Error.Exception.UnableLoadXML"), xe);
}
+ return copy;
}
- protected String loadSource(Node fnode) {
- String sourceFileFolder = XmlHandler.getTagValue(fnode,
SOURCE_FILE_FOLDER);
- String ncName = XmlHandler.getTagValue(fnode, SOURCE_CONFIGURATION_NAME);
- return loadURL(sourceFileFolder, ncName, getMetadataProvider(),
configurationMappings);
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
}
- protected String loadDestination(Node fnode) {
- String destinationFileFolder = XmlHandler.getTagValue(fnode,
DESTINATION_FILE_FOLDER);
- String ncName = XmlHandler.getTagValue(fnode,
DESTINATION_CONFIGURATION_NAME);
- return loadURL(destinationFileFolder, ncName, getMetadataProvider(),
configurationMappings);
+ @Override
+ public int hashCode() {
+ return super.hashCode();
}
- protected void saveSource(StringBuilder retval, String source) {
- String namedCluster = configurationMappings.get(source);
-
retval.append(CONST_SPACE).append(XmlHandler.addTagValue(SOURCE_FILE_FOLDER,
source));
- retval
- .append(CONST_SPACE)
- .append(XmlHandler.addTagValue(SOURCE_CONFIGURATION_NAME,
namedCluster));
+ @Override
+ public void convertLegacyXml(Node node) throws HopException {
+ normalizeLegacyVfsPaths();
}
- protected void saveDestination(StringBuilder retval, String destination) {
- String namedCluster = configurationMappings.get(destination);
-
retval.append(CONST_SPACE).append(XmlHandler.addTagValue(DESTINATION_FILE_FOLDER,
destination));
- retval
- .append(CONST_SPACE)
- .append(XmlHandler.addTagValue(DESTINATION_CONFIGURATION_NAME,
namedCluster));
+ /**
+ * Strips legacy per-row URL prefixes ({@link #SOURCE_URL}{i}-, {@link
#DEST_URL}{i}-) left over
+ * from older Hop GUI storage. New saves write plain VFS paths only.
+ */
+ void normalizeLegacyVfsPaths() {
+ if (fileRows == null) {
+ fileRows = new ArrayList<>();
+ return;
+ }
+ List<CopyFilesItem> normalized = new ArrayList<>(fileRows.size());
+ for (int i = 0; i < fileRows.size(); i++) {
+ CopyFilesItem row = fileRows.get(i);
+ normalized.add(
+ new CopyFilesItem(
+ stripLegacyRowPrefix(row.getSourceFileFolder(), SOURCE_URL, i),
+ stripLegacyRowPrefix(row.getDestinationFileFolder(), DEST_URL,
i),
+ row.getWildcard()));
+ }
+ fileRows = normalized;
}
- String[] preprocessfilefilder(String[] folders) {
- List<String> nfolders = new ArrayList<>();
- if (folders != null) {
- for (int i = 0; i < folders.length; i++) {
- nfolders.add(
- folders[i]
- .replace(ActionCopyFiles.SOURCE_URL + i + "-", "")
- .replace(ActionCopyFiles.DEST_URL + i + "-", ""));
- }
+ private static String stripLegacyRowPrefix(String path, String prefix, int
index) {
+ if (path == null) {
+ return null;
}
- return nfolders.toArray(new String[nfolders.size()]);
+ return path.replace(prefix + index + "-", "");
}
@Override
@@ -275,123 +226,110 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
Result result = previousResult;
List<RowMetaAndData> rows = result.getRows();
- RowMetaAndData resultRow = null;
int nbrFail = 0;
- nbrFail = 0;
-
if (isBasic()) {
logBasic(BaseMessages.getString(PKG, "ActionCopyFiles.Log.Starting"));
}
- try {
- // Get source and destination files, also wildcard
- String[] vSourceFileFolder = preprocessfilefilder(sourceFileFolder);
- String[] vDestinationFileFolder =
preprocessfilefilder(destinationFileFolder);
- String[] vwildcard = wildcard;
+ result.setResult(false);
+ result.setNrErrors(1);
- result.setResult(false);
- result.setNrErrors(1);
+ if (argFromPrevious && isDetailed()) {
+ logDetailed(
+ BaseMessages.getString(
+ PKG,
+ "ActionCopyFiles.Log.ArgFromPrevious.Found",
+ (rows != null ? rows.size() : 0) + ""));
+ }
- if (argFromPrevious && isDetailed()) {
- logDetailed(
- BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.ArgFromPrevious.Found",
- (rows != null ? rows.size() : 0) + ""));
- }
+ if (argFromPrevious && rows != null) {
+ for (int iteration = 0; iteration < rows.size() &&
!parentWorkflow.isStopped(); iteration++) {
+ RowMetaAndData resultRow = rows.get(iteration);
- if (argFromPrevious && rows != null) { // Copy the input row to the
(command line) arguments
- for (int iteration = 0;
- iteration < rows.size() && !parentWorkflow.isStopped();
- iteration++) {
- resultRow = rows.get(iteration);
-
- // Get source and destination file names, also wildcard
- String vSourceFileFolderPrevious = resultRow.getString(0, null);
- String vDestinationFileFolderPrevious = resultRow.getString(1, null);
- String vWildcardPrevious = resultRow.getString(2, null);
-
- if (!Utils.isEmpty(vSourceFileFolderPrevious)
- && !Utils.isEmpty(vDestinationFileFolderPrevious)) {
- if (isDetailed()) {
- logDetailed(
- BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.ProcessingRow",
-
HopVfs.getFriendlyURI(resolve(vSourceFileFolderPrevious), getVariables()),
- HopVfs.getFriendlyURI(
- resolve(vDestinationFileFolderPrevious),
getVariables()),
- resolve(vWildcardPrevious)));
- }
+ String vSourceFileFolderPrevious = resultRow.getString(0, null);
+ String vDestinationFileFolderPrevious = resultRow.getString(1, null);
+ String vWildcardPrevious = resultRow.getString(2, null);
- if (!processFileFolder(
- vSourceFileFolderPrevious,
- vDestinationFileFolderPrevious,
- vWildcardPrevious,
- parentWorkflow,
- result)) {
- // The copy process fail
- nbrFail++;
- }
- } else {
- if (isDetailed()) {
- logDetailed(
- BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.IgnoringRow",
-
HopVfs.getFriendlyURI(resolve(vSourceFileFolder[iteration]), getVariables()),
- HopVfs.getFriendlyURI(
- resolve(vDestinationFileFolder[iteration]),
getVariables()),
- vwildcard[iteration]));
- }
+ if (!Utils.isEmpty(vSourceFileFolderPrevious)
+ && !Utils.isEmpty(vDestinationFileFolderPrevious)) {
+ if (isDetailed()) {
+ logDetailed(
+ BaseMessages.getString(
+ PKG,
+ "ActionCopyFiles.Log.ProcessingRow",
+ HopVfs.getFriendlyURI(resolve(vSourceFileFolderPrevious),
getVariables()),
+
HopVfs.getFriendlyURI(resolve(vDestinationFileFolderPrevious), getVariables()),
+ resolve(vWildcardPrevious)));
}
- }
- } else if (vSourceFileFolder != null && vDestinationFileFolder != null) {
- for (int i = 0; i < vSourceFileFolder.length &&
!parentWorkflow.isStopped(); i++) {
- if (!Utils.isEmpty(vSourceFileFolder[i]) &&
!Utils.isEmpty(vDestinationFileFolder[i])) {
-
- // ok we can process this file/folder
- if (isBasic()) {
- logBasic(
- BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.ProcessingRow",
- HopVfs.getFriendlyURI(resolve(vSourceFileFolder[i]),
getVariables()),
-
HopVfs.getFriendlyURI(resolve(vDestinationFileFolder[i]), getVariables()),
- resolve(vwildcard[i])));
+ if (!processFileFolder(
+ vSourceFileFolderPrevious,
+ vDestinationFileFolderPrevious,
+ vWildcardPrevious,
+ parentWorkflow,
+ result)) {
+ nbrFail++;
+ }
+ } else {
+ if (isDetailed()) {
+ String srcHint = "";
+ String destHint = "";
+ String wildHint = "";
+ if (fileRows != null && iteration < fileRows.size()) {
+ CopyFilesItem item = fileRows.get(iteration);
+ srcHint =
+ item.getSourceFileFolder() != null
+ ?
HopVfs.getFriendlyURI(resolve(item.getSourceFileFolder()), getVariables())
+ : "";
+ destHint =
+ item.getDestinationFileFolder() != null
+ ? HopVfs.getFriendlyURI(
+ resolve(item.getDestinationFileFolder()),
getVariables())
+ : "";
+ wildHint = item.getWildcard() != null ? item.getWildcard() : "";
}
+ logDetailed(
+ BaseMessages.getString(
+ PKG, "ActionCopyFiles.Log.IgnoringRow", srcHint, destHint,
wildHint));
+ }
+ }
+ }
+ } else if (fileRows != null) {
+ for (int i = 0; i < fileRows.size() && !parentWorkflow.isStopped(); i++)
{
+ CopyFilesItem row = fileRows.get(i);
+ String src = row.getSourceFileFolder();
+ String dst = row.getDestinationFileFolder();
+ String wild = row.getWildcard();
+ if (!Utils.isEmpty(src) && !Utils.isEmpty(dst)) {
+ if (isBasic()) {
+ logBasic(
+ BaseMessages.getString(
+ PKG,
+ "ActionCopyFiles.Log.ProcessingRow",
+ HopVfs.getFriendlyURI(resolve(src), getVariables()),
+ HopVfs.getFriendlyURI(resolve(dst), getVariables()),
+ resolve(wild)));
+ }
- if (!processFileFolder(
- vSourceFileFolder[i],
- vDestinationFileFolder[i],
- vwildcard[i],
- parentWorkflow,
- result)) {
- // The copy process fail
- nbrFail++;
- }
- } else {
- if (isDetailed()) {
- logDetailed(
- BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.IgnoringRow",
- HopVfs.getFriendlyURI(resolve(vSourceFileFolder[i]),
getVariables()),
-
HopVfs.getFriendlyURI(resolve(vDestinationFileFolder[i]), getVariables()),
- vwildcard[i]));
- }
+ if (!processFileFolder(src, dst, wild, parentWorkflow, result)) {
+ nbrFail++;
+ }
+ } else {
+ if (isDetailed()) {
+ logDetailed(
+ BaseMessages.getString(
+ PKG,
+ "ActionCopyFiles.Log.IgnoringRow",
+ HopVfs.getFriendlyURI(resolve(Const.NVL(src, "")),
getVariables()),
+ HopVfs.getFriendlyURI(resolve(Const.NVL(dst, "")),
getVariables()),
+ Const.NVL(wild, "")));
}
}
}
- } finally {
- listAddResult = null;
- listFilesRemove = null;
}
- // Check if all files was process with success
if (nbrFail == 0) {
result.setResult(true);
result.setNrErrors(0);
@@ -399,6 +337,16 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
result.setNrErrors(nbrFail);
}
+ if (isBasic()) {
+ if (nbrFail == 0) {
+ logBasic(BaseMessages.getString(PKG,
"ActionCopyFiles.Log.FinishedSuccess"));
+ } else {
+ logBasic(
+ BaseMessages.getString(
+ PKG, "ActionCopyFiles.Log.FinishedWithErrors",
Integer.toString(nbrFail)));
+ }
+ }
+
return result;
}
@@ -426,12 +374,23 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
sourceFileFolder = HopVfs.getFileObject(realSourceFileFolderName,
getVariables());
destinationFileFolder =
HopVfs.getFileObject(realDestinationFileFolderName, getVariables());
+ if (isDebug()) {
+ logDebug(
+ BaseMessages.getString(
+ PKG,
+ "ActionCopyFiles.Log.Debug.ResolvedPaths",
+ HopVfs.getFriendlyURI(realSourceFileFolderName,
getVariables()),
+ HopVfs.getFriendlyURI(realDestinationFileFolderName,
getVariables()),
+ Const.NVL(realWildcard, "")));
+ }
+
if (sourceFileFolder.exists()) {
// Check if destination folder/parent folder exists !
// If user wanted and if destination folder does not exist
// Apache Hop will create it
- if (createDestinationFolder(destinationFileFolder)) {
+ int destinationStatus = ensureDestinationFolder(destinationFileFolder);
+ if (destinationStatus == DESTINATION_FOLDER_READY) {
// Basic Tests
if (sourceFileFolder.getType().equals(FileType.FOLDER) &&
destinationIsAFile) {
@@ -445,8 +404,6 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
HopVfs.getFriendlyURI(realSourceFileFolderName,
getVariables()),
HopVfs.getFriendlyURI(realDestinationFileFolderName,
getVariables())));
- nbrFail++;
-
} else {
if (destinationFileFolder.getType().equals(FileType.FOLDER)
@@ -454,13 +411,10 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
// Source is a file, destination is a folder
// Copy the file to the destination folder
//
- NameFileFilter nameFileFilter =
- new NameFileFilter(
-
Collections.singletonList(sourceFileFolder.getName().getBaseName()));
- FileSelector fileSelector = new
FileFilterSelector(nameFileFilter);
- destinationFileFolder.copyFrom(sourceFileFolder.getParent(),
fileSelector);
-
- trackBytesCopied(sourceFileFolder, result);
+ FileObject destChild =
+ destinationFileFolder.resolveFile(
+ sourceFileFolder.getName().getBaseName(),
NameScope.CHILD);
+ copyFileWithByteTracking(sourceFileFolder, destChild, result);
if (isDetailed()) {
logDetailed(
@@ -472,26 +426,25 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
}
} else if (sourceFileFolder.getType().equals(FileType.FILE) &&
destinationIsAFile) {
- // Source is a file, destination is a file
-
- destinationFileFolder.copyFrom(
- sourceFileFolder, new
TextOneToOneFileSelector(destinationFileFolder));
-
- trackBytesCopied(sourceFileFolder, result);
+ // Source is a file, destination is a file (stream copy + byte
metrics; no copyFrom)
+ copyOneFileToFile(sourceFileFolder, destinationFileFolder,
result);
} else {
// Both source and destination are folders
if (isDetailed()) {
- logDetailed(" ");
logDetailed(
BaseMessages.getString(
PKG,
- "ActionCopyFiles.Log.FetchFolder",
+ "ActionCopyFiles.Log.ScanningSourceFolder",
HopVfs.getFriendlyURI(sourceFileFolder)));
}
TextFileSelector textFileSelector =
new TextFileSelector(
- sourceFileFolder, destinationFileFolder, realWildcard,
parentWorkflow);
+ sourceFileFolder,
+ destinationFileFolder,
+ realWildcard,
+ parentWorkflow,
+ result);
try {
destinationFileFolder.copyFrom(sourceFileFolder,
textFileSelector);
} finally {
@@ -499,20 +452,6 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
}
}
- // Track bytes for folder-to-folder copies via listAddResult
- for (String copiedFile : listAddResult) {
- try {
- FileObject fo = HopVfs.getFileObject(copiedFile,
getVariables());
- if (fo.getType() == FileType.FILE &&
fo.getType().hasContent()) {
- long size = fo.getContent().getSize();
-
result.setBytesReadThisAction(result.getBytesReadThisAction() + size);
-
result.setBytesWrittenThisAction(result.getBytesWrittenThisAction() + size);
- }
- } catch (Exception e) {
- logDebug("Could not get size of copied file: " + copiedFile);
- }
- }
-
// Remove Files if needed
if (removeSourceFiles && !listFilesRemove.isEmpty()) {
String sourceFilefoldername = sourceFileFolder.toString();
@@ -601,10 +540,10 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
}
}
}
+
+ entrystatus = true;
}
- entrystatus = true;
- } else {
- // Destination Folder or Parent folder is missing
+ } else if (destinationStatus == DESTINATION_FOLDER_NOT_AVAILABLE) {
logError(
BaseMessages.getString(
PKG,
@@ -656,128 +595,151 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
return entrystatus;
}
- private void trackBytesCopied(FileObject sourceFile, Result result) {
- try {
- if (sourceFile.getType().hasContent()) {
- long size = sourceFile.getContent().getSize();
- result.setBytesReadThisAction(result.getBytesReadThisAction() + size);
- result.setBytesWrittenThisAction(result.getBytesWrittenThisAction() +
size);
- }
- } catch (Exception e) {
- logDebug("Could not get size of source file: " + sourceFile);
- }
- }
-
- private class TextOneToOneFileSelector implements FileSelector {
- FileObject destfile = null;
+ private static final int COPY_BUFFER_SIZE = 8192;
- public TextOneToOneFileSelector(FileObject destinationfile) {
-
- if (destinationfile != null) {
- destfile = destinationfile;
+ /**
+ * Copies file content through {@link CountingInputStream} / {@link
CountingOutputStream} so
+ * {@link Result#getBytesReadThisAction()} and {@link
Result#getBytesWrittenThisAction()} match
+ * bytes moved over the streams (when {@link Const#HOP_METRIC_DATA_VOLUME}
is enabled).
+ */
+ private void copyFileWithByteTracking(FileObject source, FileObject
destination, Result result)
+ throws IOException {
+ FileObject parent = destination.getParent();
+ if (parent != null && !parent.exists()) {
+ parent.createFolder();
+ }
+ long read;
+ long written;
+ try (InputStream rawIn = HopVfs.getInputStream(source);
+ CountingInputStream in = new CountingInputStream(rawIn);
+ OutputStream rawOut = HopVfs.getOutputStream(destination, false);
+ CountingOutputStream out = new CountingOutputStream(rawOut)) {
+ byte[] buffer = new byte[COPY_BUFFER_SIZE];
+ int len;
+ while ((len = in.read(buffer)) != -1) {
+ if (len > 0) {
+ out.write(buffer, 0, len);
+ }
}
+ out.flush();
+ read = in.getCount();
+ written = out.getCount();
}
+ result.setBytesReadThisAction(result.getBytesReadThisAction() + read);
+ result.setBytesWrittenThisAction(result.getBytesWrittenThisAction() +
written);
+ }
- @Override
- public boolean includeFile(FileSelectInfo info) {
- boolean resultat = false;
- String filename = null;
-
- try {
- // check if the destination file exists
-
- if (destfile.exists()) {
- if (isDetailed()) {
- logDetailed(
- CONST_SPACE_SHORT
- + BaseMessages.getString(
- PKG, CONST_FILE_EXISTS,
HopVfs.getFriendlyURI(destfile)));
- }
-
- if (overwriteFiles) {
- if (isDetailed()) {
- logDetailed(
- CONST_SPACE_SHORT
- + BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.FileOverwrite",
- HopVfs.getFriendlyURI(destfile)));
- }
-
- resultat = true;
- }
- } else {
+ /**
+ * File-to-file copy: same rules as the former one-to-one {@link
FileSelector} (exists / overwrite
+ * / logging), then stream copy for byte metrics. Does not use {@code
copyFrom}.
+ *
+ * @return true if the file was copied, false if skipped or on error
+ */
+ private boolean copyOneFileToFile(FileObject sourceFile, FileObject
destFile, Result result) {
+ boolean shouldCopy = false;
+ try {
+ if (destFile.exists()) {
+ if (isDetailed()) {
+ logDetailed(
+ CONST_SPACE_SHORT
+ + BaseMessages.getString(
+ PKG,
+ overwriteFiles ? CONST_FILE_EXISTS :
CONST_FILE_EXISTS_SKIP_COPY,
+ HopVfs.getFriendlyURI(destFile)));
+ }
+ if (overwriteFiles) {
if (isDetailed()) {
logDetailed(
CONST_SPACE_SHORT
+ BaseMessages.getString(
PKG,
- CONST_FILE_COPIED,
- HopVfs.getFriendlyURI(info.getFile()),
- HopVfs.getFriendlyURI(destfile)));
+ CONST_FILE_OVERWRITE,
+ HopVfs.getFriendlyURI(sourceFile),
+ HopVfs.getFriendlyURI(destFile)));
}
-
- resultat = true;
+ shouldCopy = true;
}
-
- if (resultat && removeSourceFiles) {
- // add this folder/file to remove files
- // This list will be fetched and all entries files
- // will be removed
- listFilesRemove.add(info.getFile().toString());
+ } else {
+ if (isDetailed()) {
+ logDetailed(
+ CONST_SPACE_SHORT
+ + BaseMessages.getString(
+ PKG,
+ CONST_FILE_COPIED,
+ HopVfs.getFriendlyURI(sourceFile),
+ HopVfs.getFriendlyURI(destFile)));
}
+ shouldCopy = true;
+ }
- if (resultat && addResultFilenames) {
- // add this folder/file to result files name
- listAddResult.add(destfile.toString());
- }
+ if (!shouldCopy) {
+ return false;
+ }
- } catch (Exception e) {
+ copyFileWithByteTracking(sourceFile, destFile, result);
- logError(
- BaseMessages.getString(
- PKG,
- CONST_COPY_PROCESS,
- HopVfs.getFriendlyURI(info.getFile()),
- filename,
- e.getMessage()));
+ if (removeSourceFiles) {
+ listFilesRemove.add(sourceFile.toString());
}
-
- return resultat;
+ if (addResultFilenames) {
+ listAddResult.add(destFile.toString());
+ }
+ return true;
+ } catch (Exception e) {
+ logError(
+ BaseMessages.getString(
+ PKG,
+ CONST_COPY_PROCESS,
+ HopVfs.getFriendlyURI(sourceFile),
+ HopVfs.getFriendlyURI(destFile),
+ e.getMessage()));
+ return false;
}
+ }
- @Override
- public boolean traverseDescendents(FileSelectInfo info) {
- return false;
+ /**
+ * Ensures the destination folder (or the parent when destination is a file)
exists or can be
+ * created.
+ *
+ * @return {@link #DESTINATION_FOLDER_READY} if ready, {@link
#DESTINATION_FOLDER_NOT_AVAILABLE}
+ * if missing and create is disabled, or {@link
#DESTINATION_FOLDER_FAILED} on error (already
+ * logged)
+ */
+ private void createMissingDestinationParent(FileObject folder) throws
FileSystemException {
+ if (isDetailed()) {
+ logDetailed(
+ BaseMessages.getString(
+ PKG, "ActionCopyFiles.Log.FolderParentWillCreate",
HopVfs.getFriendlyURI(folder)));
+ }
+ folder.createFolder();
+ if (isDetailed()) {
+ logDetailed(
+ BaseMessages.getString(
+ PKG, "ActionCopyFiles.Log.FolderParentCreated",
HopVfs.getFriendlyURI(folder)));
}
}
- private boolean createDestinationFolder(FileObject filefolder) {
+ private int ensureDestinationFolder(FileObject filefolder) {
FileObject folder = null;
try {
- if (destinationIsAFile) {
- folder = filefolder.getParent();
- } else {
- folder = filefolder;
- }
+ folder = destinationIsAFile ? filefolder.getParent() : filefolder;
if (!folder.exists()) {
if (createDestinationFolder) {
- if (isDetailed()) {
- logDetailed("Folder " + HopVfs.getFriendlyURI(folder) + " does
not exist !");
- }
- folder.createFolder();
- if (isDetailed()) {
- logDetailed("Folder parent was created.");
- }
+ createMissingDestinationParent(folder);
} else {
- logError("Folder " + HopVfs.getFriendlyURI(folder) + " does not
exist !");
- return false;
+ return DESTINATION_FOLDER_NOT_AVAILABLE;
}
}
- return true;
+ return DESTINATION_FOLDER_READY;
} catch (Exception e) {
- logError("Couldn't created parent folder " +
HopVfs.getFriendlyURI(folder), e);
+ logError(
+ BaseMessages.getString(
+ PKG,
+ "ActionCopyFiles.Error.FolderParentCreateFailed",
+ folder != null ? HopVfs.getFriendlyURI(folder) :
HopVfs.getFriendlyURI(filefolder)),
+ e);
+ return DESTINATION_FOLDER_FAILED;
} finally {
if (folder != null) {
try {
@@ -788,7 +750,6 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
}
}
}
- return false;
}
private class TextFileSelector implements FileSelector {
@@ -802,6 +763,8 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
// Store connection to destination source for improved performance to
remote hosts
FileObject destinationFolderObject = null;
+ private final Result copyResult;
+
/**
* @param selectedfile
* @return True if the selectedfile matches the wildcard
@@ -820,8 +783,10 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
FileObject sourcefolderin,
FileObject destinationfolderin,
String filewildcard,
- IWorkflowEngine<WorkflowMeta> parentWorkflow) {
+ IWorkflowEngine<WorkflowMeta> parentWorkflow,
+ Result result) {
+ this.copyResult = result;
if (sourcefolderin != null) {
sourceFolder = sourcefolderin.toString();
}
@@ -839,6 +804,7 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
@Override
public boolean includeFile(FileSelectInfo info) {
boolean returncode = false;
+ boolean streamCopied = false;
FileObject filename = null;
String addFileNameString = null;
try {
@@ -882,7 +848,9 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
CONST_SPACE_SHORT
+ BaseMessages.getString(
PKG,
- "ActionCopyFiles.Log.FolderExists",
+ overwriteFiles
+ ? CONST_FOLDER_EXISTS
+ : CONST_FOLDER_EXISTS_SKIP_COPY,
HopVfs.getFriendlyURI(filename)));
}
if (overwriteFiles) {
@@ -919,15 +887,17 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
logDetailed(
CONST_SPACE_SHORT
+ BaseMessages.getString(
- PKG, CONST_FILE_EXISTS,
HopVfs.getFriendlyURI(filename)));
+ PKG,
+ overwriteFiles ? CONST_FILE_EXISTS :
CONST_FILE_EXISTS_SKIP_COPY,
+ HopVfs.getFriendlyURI(filename)));
}
if (overwriteFiles) {
if (isDetailed()) {
logDetailed(
- " "
+ CONST_SPACE_SHORT
+ BaseMessages.getString(
PKG,
- CONST_FILE_EXISTS,
+ CONST_FILE_OVERWRITE,
HopVfs.getFriendlyURI(info.getFile()),
HopVfs.getFriendlyURI(filename)));
}
@@ -961,7 +931,9 @@ public class ActionCopyFiles extends ActionBase implements
Cloneable, IAction {
CONST_SPACE_SHORT
+ BaseMessages.getString(
PKG,
- "ActionCopyFiles.Log.FolderExists",
+ overwriteFiles
+ ? CONST_FOLDER_EXISTS
+ : CONST_FOLDER_EXISTS_SKIP_COPY,
HopVfs.getFriendlyURI(filename)));
}
if (overwriteFiles) {
@@ -1003,19 +975,20 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
logDetailed(
CONST_SPACE_SHORT
+ BaseMessages.getString(
- PKG, CONST_FILE_EXISTS,
HopVfs.getFriendlyURI(filename)));
+ PKG,
+ overwriteFiles ? CONST_FILE_EXISTS :
CONST_FILE_EXISTS_SKIP_COPY,
+ HopVfs.getFriendlyURI(filename)));
}
if (overwriteFiles) {
if (isDetailed()) {
logDetailed(
CONST_SPACE_SHORT
- + BaseMessages.getString(PKG,
"ActionCopyFiles.Log.FileExistsInfos"),
- BaseMessages.getString(
- PKG,
- CONST_FILE_EXISTS,
- HopVfs.getFriendlyURI(info.getFile()),
- HopVfs.getFriendlyURI(filename)));
+ + BaseMessages.getString(
+ PKG,
+ CONST_FILE_OVERWRITE,
+ HopVfs.getFriendlyURI(info.getFile()),
+ HopVfs.getFriendlyURI(filename)));
}
returncode = true;
@@ -1025,6 +998,11 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
}
}
}
+
+ if (returncode && filename != null && info.getFile().getType() ==
FileType.FILE) {
+ copyFileWithByteTracking(info.getFile(), filename, copyResult);
+ streamCopied = true;
+ }
} catch (Exception e) {
logError(
@@ -1062,7 +1040,9 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
addFileNameString); // was a NPE before with the file_name=null
above in the finally
}
- return returncode;
+ // File rows: we already copied bytes above when streamCopied; true
would make copyFrom copy
+ // again. Folder rows: unchanged — still return returncode so VFS
creates empty dirs.
+ return streamCopied ? false : returncode;
}
@Override
@@ -1082,109 +1062,6 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
}
}
- private class TextOneFileSelector implements FileSelector {
- String filename = null;
- String folderName = null;
- String destfolder = null;
- private int traverseCount;
-
- public TextOneFileSelector(
- String sourcefolderin, String sourcefilenamein, String destfolderin) {
- if (!Utils.isEmpty(sourcefilenamein)) {
- filename = sourcefilenamein;
- }
-
- if (!Utils.isEmpty(sourcefolderin)) {
- folderName = sourcefolderin;
- }
- if (!Utils.isEmpty(destfolderin)) {
- destfolder = destfolderin;
- }
- }
-
- @Override
- public boolean includeFile(FileSelectInfo info) {
- boolean resultat = false;
- String filename = null;
-
- try {
- if (info.getFile().getType() == FileType.FILE) {
- if (info.getFile().getName().getBaseName().equals(filename)
- && (info.getFile().getParent().toString().equals(folderName))) {
- // check if the file exists
- filename = destfolder + Const.FILE_SEPARATOR + filename;
-
- if (HopVfs.getFileObject(filename, getVariables()).exists()) {
- if (isDetailed()) {
- logDetailed(
- CONST_SPACE_SHORT
- + BaseMessages.getString(
- PKG,
- CONST_FILE_EXISTS,
- HopVfs.getFriendlyURI(filename, getVariables())));
- }
-
- if (overwriteFiles) {
- if (isDetailed()) {
- logDetailed(
- CONST_SPACE_SHORT
- + BaseMessages.getString(
- PKG,
- "ActionCopyFiles.Log.FileOverwrite",
- HopVfs.getFriendlyURI(info.getFile()),
- HopVfs.getFriendlyURI(filename,
getVariables())));
- }
-
- resultat = true;
- }
- } else {
- if (isDetailed()) {
- logDetailed(
- CONST_SPACE_SHORT
- + BaseMessages.getString(
- PKG,
- CONST_FILE_COPIED,
- HopVfs.getFriendlyURI(info.getFile()),
- HopVfs.getFriendlyURI(filename, getVariables())));
- }
-
- resultat = true;
- }
- }
-
- if (resultat && removeSourceFiles) {
- // add this folder/file to remove files
- // This list will be fetched and all entries files
- // will be removed
- listFilesRemove.add(info.getFile().toString());
- }
-
- if (resultat && addResultFilenames) {
- // add this folder/file to result files name
- listAddResult.add(HopVfs.getFileObject(filename,
getVariables()).toString());
- }
- }
- } catch (Exception e) {
- logError(
- BaseMessages.getString(
- PKG,
- CONST_COPY_PROCESS,
- HopVfs.getFriendlyURI(info.getFile()),
- HopVfs.getFriendlyURI(filename, getVariables()),
- e.getMessage()));
-
- resultat = false;
- }
-
- return resultat;
- }
-
- @Override
- public boolean traverseDescendents(FileSelectInfo info) {
- return (traverseCount++ == 0 || includeSubFolders);
- }
- }
-
@Override
public void check(
List<ICheckResult> remarks,
@@ -1195,7 +1072,7 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
ActionValidatorUtils.andValidator()
.validate(
this,
- "arguments",
+ "fileRows",
remarks,
AndValidator.putValidators(ActionValidatorUtils.notNullValidator()));
@@ -1208,8 +1085,11 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
AndValidator.putValidators(
ctx, ActionValidatorUtils.notNullValidator(),
ActionValidatorUtils.fileExistsValidator());
- for (int i = 0; i < sourceFileFolder.length; i++) {
- ActionValidatorUtils.andValidator().validate(this, "arguments[" + i +
"]", remarks, ctx);
+ if (fileRows != null) {
+ for (int i = 0; i < fileRows.size(); i++) {
+ ActionValidatorUtils.andValidator()
+ .validate(this, "fileRows[" + i + "].sourceFileFolder", remarks,
ctx);
+ }
}
}
@@ -1217,269 +1097,4 @@ public class ActionCopyFiles extends ActionBase
implements Cloneable, IAction {
public boolean isEvaluation() {
return true;
}
-
- public String loadURL(
- String url,
- String ncName,
- IHopMetadataProvider metadataProvider,
- Map<String, String> mappings) {
- if (!Utils.isEmpty(ncName) && !Utils.isEmpty(url)) {
- mappings.put(url, ncName);
- }
- return url;
- }
-
- public void setConfigurationMappings(Map<String, String> mappings) {
- this.configurationMappings = mappings;
- }
-
- public String getConfigurationBy(String url) {
- return this.configurationMappings.get(url);
- }
-
- public String getUrlPath(String incomingURL) {
- String path = null;
- try {
- String noVariablesURL = incomingURL.replaceAll("[${}]", "/");
- FileName fileName =
HopVfs.getFileSystemManager(getVariables()).resolveURI(noVariablesURL);
- String root = fileName.getRootURI();
- path = incomingURL.substring(root.length() - 1);
- } catch (FileSystemException e) {
- path = null;
- }
- return path;
- }
-
- /**
- * Gets copyEmptyFolders
- *
- * @return value of copyEmptyFolders
- */
- public boolean isCopyEmptyFolders() {
- return copyEmptyFolders;
- }
-
- /**
- * @param copyEmptyFolders The copyEmptyFolders to set
- */
- public void setCopyEmptyFolders(boolean copyEmptyFolders) {
- this.copyEmptyFolders = copyEmptyFolders;
- }
-
- /**
- * Gets argFromPrevious
- *
- * @return value of argFromPrevious
- */
- public boolean isArgFromPrevious() {
- return argFromPrevious;
- }
-
- /**
- * @param argFromPrevious The argFromPrevious to set
- */
- public void setArgFromPrevious(boolean argFromPrevious) {
- this.argFromPrevious = argFromPrevious;
- }
-
- /**
- * Gets overwriteFiles
- *
- * @return value of overwriteFiles
- */
- public boolean isOverwriteFiles() {
- return overwriteFiles;
- }
-
- /**
- * @param overwriteFiles The overwriteFiles to set
- */
- public void setOverwriteFiles(boolean overwriteFiles) {
- this.overwriteFiles = overwriteFiles;
- }
-
- /**
- * Gets includeSubFolders
- *
- * @return value of includeSubFolders
- */
- public boolean isIncludeSubFolders() {
- return includeSubFolders;
- }
-
- /**
- * @param includeSubFolders The includeSubFolders to set
- */
- public void setIncludeSubFolders(boolean includeSubFolders) {
- this.includeSubFolders = includeSubFolders;
- }
-
- /**
- * Gets addResultFilenames
- *
- * @return value of addResultFilenames
- */
- public boolean isAddResultFilenames() {
- return addResultFilenames;
- }
-
- /**
- * @param addResultFilenames The addResultFilenames to set
- */
- public void setAddResultFilenames(boolean addResultFilenames) {
- this.addResultFilenames = addResultFilenames;
- }
-
- /**
- * Gets removeSourceFiles
- *
- * @return value of removeSourceFiles
- */
- public boolean isRemoveSourceFiles() {
- return removeSourceFiles;
- }
-
- /**
- * @param removeSourceFiles The removeSourceFiles to set
- */
- public void setRemoveSourceFiles(boolean removeSourceFiles) {
- this.removeSourceFiles = removeSourceFiles;
- }
-
- /**
- * Gets destinationIsAFile
- *
- * @return value of destinationIsAFile
- */
- public boolean isDestinationIsAFile() {
- return destinationIsAFile;
- }
-
- /**
- * @param destinationIsAFile The destinationIsAFile to set
- */
- public void setDestinationIsAFile(boolean destinationIsAFile) {
- this.destinationIsAFile = destinationIsAFile;
- }
-
- /**
- * Gets createDestinationFolder
- *
- * @return value of createDestinationFolder
- */
- public boolean isCreateDestinationFolder() {
- return createDestinationFolder;
- }
-
- /**
- * @param createDestinationFolder The createDestinationFolder to set
- */
- public void setCreateDestinationFolder(boolean createDestinationFolder) {
- this.createDestinationFolder = createDestinationFolder;
- }
-
- /**
- * Gets sourceFileFolder
- *
- * @return value of sourceFileFolder
- */
- public String[] getSourceFileFolder() {
- return sourceFileFolder;
- }
-
- /**
- * @param sourceFileFolder The sourceFileFolder to set
- */
- public void setSourceFileFolder(String[] sourceFileFolder) {
- this.sourceFileFolder = sourceFileFolder;
- }
-
- /**
- * Gets destinationFileFolder
- *
- * @return value of destinationFileFolder
- */
- public String[] getDestinationFileFolder() {
- return destinationFileFolder;
- }
-
- /**
- * @param destinationFileFolder The destinationFileFolder to set
- */
- public void setDestinationFileFolder(String[] destinationFileFolder) {
- this.destinationFileFolder = destinationFileFolder;
- }
-
- /**
- * Gets wildcard
- *
- * @return value of wildcard
- */
- public String[] getWildcard() {
- return wildcard;
- }
-
- /**
- * @param wildcard The wildcard to set
- */
- public void setWildcard(String[] wildcard) {
- this.wildcard = wildcard;
- }
-
- /**
- * Gets listFilesRemove
- *
- * @return value of listFilesRemove
- */
- public HashSet<String> getListFilesRemove() {
- return listFilesRemove;
- }
-
- /**
- * @param listFilesRemove The listFilesRemove to set
- */
- public void setListFilesRemove(HashSet<String> listFilesRemove) {
- this.listFilesRemove = listFilesRemove;
- }
-
- /**
- * Gets listAddResult
- *
- * @return value of listAddResult
- */
- public HashSet<String> getListAddResult() {
- return listAddResult;
- }
-
- /**
- * @param listAddResult The listAddResult to set
- */
- public void setListAddResult(HashSet<String> listAddResult) {
- this.listAddResult = listAddResult;
- }
-
- /**
- * Gets nbrFail
- *
- * @return value of nbrFail
- */
- public int getNbrFail() {
- return nbrFail;
- }
-
- /**
- * @param nbrFail The nbrFail to set
- */
- public void setNbrFail(int nbrFail) {
- this.nbrFail = nbrFail;
- }
-
- /**
- * Gets configurationMappings
- *
- * @return value of configurationMappings
- */
- public Map<String, String> getConfigurationMappings() {
- return configurationMappings;
- }
}
diff --git
a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
index c735d03975..9d60bfe1a6 100644
---
a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
+++
b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
@@ -17,8 +17,6 @@
package org.apache.hop.workflow.actions.copyfiles;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.hop.core.Const;
import org.apache.hop.core.Props;
import org.apache.hop.core.util.Utils;
@@ -29,7 +27,6 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
import org.apache.hop.ui.core.dialog.MessageBox;
import org.apache.hop.ui.core.gui.GuiResource;
import org.apache.hop.ui.core.widget.ColumnInfo;
-import org.apache.hop.ui.core.widget.ITextVarButtonRenderCallback;
import org.apache.hop.ui.core.widget.TableView;
import org.apache.hop.ui.workflow.action.ActionDialog;
import org.apache.hop.workflow.WorkflowMeta;
@@ -57,9 +54,6 @@ public class ActionCopyFilesDialog extends ActionDialog {
protected static final String[] FILETYPES =
new String[] {BaseMessages.getString(PKG,
"ActionCopyFiles.Filetype.All")};
- public static final String LOCAL_ENVIRONMENT = "Local";
- public static final String STATIC_ENVIRONMENT = "<Static>";
-
protected Button wPrevious;
protected Button wCopyEmptyFolders;
protected Button wOverwriteFiles;
@@ -96,9 +90,6 @@ public class ActionCopyFilesDialog extends ActionDialog {
ModifyListener lsMod = e -> action.setChanged();
changed = action.hasChanged();
- int middle = this.middle;
- int margin = this.margin;
-
wTabFolder = new CTabFolder(shell, SWT.BORDER);
PropsUi.setLook(wTabFolder, Props.WIDGET_STYLE_TAB);
@@ -109,10 +100,6 @@ public class ActionCopyFilesDialog extends ActionDialog {
fdTabFolder.bottom = new FormAttachment(wCancel, -margin);
wTabFolder.setLayoutData(fdTabFolder);
- // ///////////////////////////////////////////////////////////
- // / START OF FILES TAB
- // ///////////////////////////////////////////////////////////
-
CTabItem wFilesTab = new CTabItem(wTabFolder, SWT.NONE);
wFilesTab.setFont(GuiResource.getInstance().getFontDefault());
wFilesTab.setText(BaseMessages.getString(PKG,
"ActionCopyFiles.Tab.Files.Label"));
@@ -135,14 +122,6 @@ public class ActionCopyFilesDialog extends ActionDialog {
wFilesComp.layout();
wFilesTab.setControl(wFilesComp);
- // ///////////////////////////////////////////////////////////
- // / END OF FILES TAB
- // ///////////////////////////////////////////////////////////
-
- // ////////////////////////
- // START OF SETTINGS TAB ///
- // ////////////////////////
-
CTabItem wSettingsTab = new CTabItem(wTabFolder, SWT.NONE);
wSettingsTab.setFont(GuiResource.getInstance().getFontDefault());
wSettingsTab.setText(BaseMessages.getString(PKG,
"ActionCopyFiles.Settings.Label"));
@@ -238,10 +217,6 @@ public class ActionCopyFilesDialog extends ActionDialog {
wSettingsTab.setControl(wSettingsComp);
PropsUi.setLook(wSettingsComp);
- // ///////////////////////////////////////////////////////////
- // / END OF SETTINGS TAB
- // ///////////////////////////////////////////////////////////
-
wlFields = new Label(wFilesComp, SWT.NONE);
wlFields.setText(BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.Label"));
PropsUi.setLook(wlFields);
@@ -251,18 +226,13 @@ public class ActionCopyFilesDialog extends ActionDialog {
wlFields.setLayoutData(fdlFields);
int rows =
- action.sourceFileFolder == null
+ action.getFileRows() == null
? 1
- : (action.sourceFileFolder.length == 0 ? 0 :
action.sourceFileFolder.length);
- final int FieldsRows = rows;
+ : (action.getFileRows().isEmpty() ? 0 :
action.getFileRows().size());
+ final int fieldsRows = rows;
ColumnInfo[] colinf =
new ColumnInfo[] {
- new ColumnInfo(
- BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.SourceEnvironment.Label"),
- ColumnInfo.COLUMN_TYPE_CCOMBO,
- false,
- true),
new ColumnInfo(
BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.SourceFileFolder.Label"),
ColumnInfo.COLUMN_TYPE_TEXT_BUTTON,
@@ -271,40 +241,24 @@ public class ActionCopyFilesDialog extends ActionDialog {
BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.Wildcard.Label"),
ColumnInfo.COLUMN_TYPE_TEXT,
false),
- new ColumnInfo(
- BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.DestinationEnvironment.Label"),
- ColumnInfo.COLUMN_TYPE_CCOMBO,
- false,
- true),
new ColumnInfo(
BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.DestinationFileFolder.Label"),
ColumnInfo.COLUMN_TYPE_TEXT_BUTTON,
false)
};
- setComboValues(colinf[0]);
-
- ITextVarButtonRenderCallback callback =
- () -> {
- String envType =
wFields.getActiveTableItem().getText(wFields.getActiveTableColumn() - 1);
- return !STATIC_ENVIRONMENT.equalsIgnoreCase(envType);
- };
+ colinf[0].setUsingVariables(true);
+ colinf[0].setToolTip(
+ BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.SourceFileFolder.Tooltip"));
+ colinf[0].setTextVarButtonSelectionListener(getFileSelectionAdapter());
colinf[1].setUsingVariables(true);
- colinf[1].setToolTip(
- BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.SourceFileFolder.Tooltip"));
- colinf[1].setTextVarButtonSelectionListener(getFileSelectionAdapter());
- colinf[1].setRenderTextVarButtonCallback(callback);
+ colinf[1].setToolTip(BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.Wildcard.Tooltip"));
colinf[2].setUsingVariables(true);
- colinf[2].setToolTip(BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.Wildcard.Tooltip"));
-
- setComboValues(colinf[3]);
-
- colinf[4].setUsingVariables(true);
- colinf[4].setToolTip(
+ colinf[2].setToolTip(
BaseMessages.getString(PKG,
"ActionCopyFiles.Fields.DestinationFileFolder.Tooltip"));
- colinf[4].setTextVarButtonSelectionListener(getFileSelectionAdapter());
+ colinf[2].setTextVarButtonSelectionListener(getFileSelectionAdapter());
wFields =
new TableView(
@@ -312,7 +266,7 @@ public class ActionCopyFilesDialog extends ActionDialog {
wFilesComp,
SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI,
colinf,
- FieldsRows,
+ fieldsRows,
lsMod,
props);
@@ -360,7 +314,7 @@ public class ActionCopyFilesDialog extends ActionDialog {
return new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- String filename = BaseDialog.presentFileDialog(shell, null, null,
true); // all files
+ String filename = BaseDialog.presentFileDialog(shell, null, null,
true);
if (filename != null) {
wFields.getActiveTableItem().setText(wFields.getActiveTableColumn(),
filename);
}
@@ -376,77 +330,31 @@ public class ActionCopyFilesDialog extends ActionDialog {
/** Copy information from the meta-data input to the dialog fields. */
public void getData() {
wName.setText(Const.NVL(action.getName(), ""));
- wCopyEmptyFolders.setSelection(action.copyEmptyFolders);
+ wCopyEmptyFolders.setSelection(action.isCopyEmptyFolders());
- if (action.sourceFileFolder != null) {
- for (int i = 0; i < action.sourceFileFolder.length; i++) {
+ if (action.getFileRows() != null) {
+ for (int i = 0; i < action.getFileRows().size(); i++) {
TableItem ti = wFields.table.getItem(i);
- if (action.sourceFileFolder[i] != null) {
- String sourceUrl = action.sourceFileFolder[i];
- String clusterName = action.getConfigurationBy(sourceUrl);
- if (clusterName != null) {
- clusterName =
- clusterName.startsWith(ActionCopyFiles.LOCAL_SOURCE_FILE)
- ? LOCAL_ENVIRONMENT
- : clusterName;
- clusterName =
- clusterName.startsWith(ActionCopyFiles.STATIC_SOURCE_FILE)
- ? STATIC_ENVIRONMENT
- : clusterName;
-
- ti.setText(1, clusterName);
- sourceUrl =
- clusterName.equals(LOCAL_ENVIRONMENT) ||
clusterName.equals(STATIC_ENVIRONMENT)
- ? sourceUrl
- : action.getUrlPath(sourceUrl);
- }
- if (sourceUrl != null) {
- sourceUrl = sourceUrl.replace(ActionCopyFiles.SOURCE_URL + i +
"-", "");
- } else {
- sourceUrl = "";
- }
- ti.setText(2, sourceUrl);
+ CopyFilesItem row = action.getFileRows().get(i);
+ if (row.getSourceFileFolder() != null) {
+ ti.setText(1, row.getSourceFileFolder());
}
- if (action.wildcard[i] != null) {
- ti.setText(3, action.wildcard[i]);
+ if (row.getWildcard() != null) {
+ ti.setText(2, row.getWildcard());
}
- if (action.destinationFileFolder[i] != null) {
- String destinationURL = action.destinationFileFolder[i];
- String clusterName = action.getConfigurationBy(destinationURL);
- if (clusterName != null) {
- clusterName =
- clusterName.startsWith(ActionCopyFiles.LOCAL_DEST_FILE)
- ? LOCAL_ENVIRONMENT
- : clusterName;
- clusterName =
- clusterName.startsWith(ActionCopyFiles.STATIC_DEST_FILE)
- ? STATIC_ENVIRONMENT
- : clusterName;
- ti.setText(4, clusterName);
- destinationURL =
- clusterName.equals(LOCAL_ENVIRONMENT) ||
clusterName.equals(STATIC_ENVIRONMENT)
- ? destinationURL
- : action.getUrlPath(destinationURL);
- }
- if (destinationURL != null) {
- destinationURL = destinationURL.replace(ActionCopyFiles.DEST_URL +
i + "-", "");
- } else {
- destinationURL = "";
- }
- ti.setText(5, destinationURL);
+ if (row.getDestinationFileFolder() != null) {
+ ti.setText(3, row.getDestinationFileFolder());
}
}
-
wFields.optimizeTableView();
}
- wPrevious.setSelection(action.argFromPrevious);
- wOverwriteFiles.setSelection(action.overwriteFiles);
- wIncludeSubfolders.setSelection(action.includeSubFolders);
- wRemoveSourceFiles.setSelection(action.removeSourceFiles);
- wDestinationIsAFile.setSelection(action.destinationIsAFile);
- wCreateDestinationFolder.setSelection(action.createDestinationFolder);
-
- wAddFileToResult.setSelection(action.addResultFilenames);
+ wPrevious.setSelection(action.isArgFromPrevious());
+ wOverwriteFiles.setSelection(action.isOverwriteFiles());
+ wIncludeSubfolders.setSelection(action.isIncludeSubFolders());
+ wRemoveSourceFiles.setSelection(action.isRemoveSourceFiles());
+ wDestinationIsAFile.setSelection(action.isDestinationIsAFile());
+ wCreateDestinationFolder.setSelection(action.isCreateDestinationFolder());
+ wAddFileToResult.setSelection(action.isAddResultFilenames());
}
@Override
@@ -480,33 +388,14 @@ public class ActionCopyFilesDialog extends ActionDialog {
action.setCreateDestinationFolder(wCreateDestinationFolder.getSelection());
int nrItems = wFields.nrNonEmpty();
-
- Map<String, String> sourceDestinationMappings = new HashMap<>();
- action.sourceFileFolder = new String[nrItems];
- action.destinationFileFolder = new String[nrItems];
- action.wildcard = new String[nrItems];
-
+ java.util.List<CopyFilesItem> rows = new java.util.ArrayList<>(nrItems);
for (int i = 0; i < nrItems; i++) {
- String sourceNc = wFields.getNonEmpty(i).getText(1);
- sourceNc =
- sourceNc.equals(LOCAL_ENVIRONMENT) ?
ActionCopyFiles.LOCAL_SOURCE_FILE + i : sourceNc;
- sourceNc =
- sourceNc.equals(STATIC_ENVIRONMENT) ?
ActionCopyFiles.STATIC_SOURCE_FILE + i : sourceNc;
- String source = wFields.getNonEmpty(i).getText(2);
- String wild = wFields.getNonEmpty(i).getText(3);
- String destNc = wFields.getNonEmpty(i).getText(4);
- destNc = destNc.equals(LOCAL_ENVIRONMENT) ?
ActionCopyFiles.LOCAL_DEST_FILE + i : destNc;
- destNc = destNc.equals(STATIC_ENVIRONMENT) ?
ActionCopyFiles.STATIC_DEST_FILE + i : destNc;
- String dest = wFields.getNonEmpty(i).getText(5);
- source = ActionCopyFiles.SOURCE_URL + i + "-" + source;
- dest = ActionCopyFiles.DEST_URL + i + "-" + dest;
- action.sourceFileFolder[i] =
- action.loadURL(source, sourceNc, getMetadataProvider(),
sourceDestinationMappings);
- action.destinationFileFolder[i] =
- action.loadURL(dest, destNc, getMetadataProvider(),
sourceDestinationMappings);
- action.wildcard[i] = wild;
+ String source = wFields.getNonEmpty(i).getText(1);
+ String wild = wFields.getNonEmpty(i).getText(2);
+ String dest = wFields.getNonEmpty(i).getText(3);
+ rows.add(new CopyFilesItem(source, dest, wild));
}
- action.setConfigurationMappings(sourceDestinationMappings);
+ action.setFileRows(rows);
dispose();
}
@@ -514,9 +403,4 @@ public class ActionCopyFilesDialog extends ActionDialog {
public boolean showFileButtons() {
return true;
}
-
- protected void setComboValues(ColumnInfo colInfo) {
- String[] values = {LOCAL_ENVIRONMENT, STATIC_ENVIRONMENT};
- colInfo.setComboValues(values);
- }
}
diff --git
a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/CopyFilesItem.java
b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/CopyFilesItem.java
new file mode 100644
index 0000000000..4972178afd
--- /dev/null
+++
b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/CopyFilesItem.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.hop.workflow.actions.copyfiles;
+
+import java.util.Objects;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+
+/** One source / destination / wildcard row for the Copy files action. */
+@Getter
+@Setter
+public class CopyFilesItem {
+
+ @HopMetadataProperty(key = "source_filefolder")
+ private String sourceFileFolder;
+
+ @HopMetadataProperty(key = "destination_filefolder")
+ private String destinationFileFolder;
+
+ @HopMetadataProperty(key = "wildcard")
+ private String wildcard;
+
+ public CopyFilesItem() {}
+
+ public CopyFilesItem(String sourceFileFolder, String destinationFileFolder,
String wildcard) {
+ this.sourceFileFolder = sourceFileFolder;
+ this.destinationFileFolder = destinationFileFolder;
+ this.wildcard = wildcard;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CopyFilesItem that = (CopyFilesItem) o;
+ return Objects.equals(sourceFileFolder, that.sourceFileFolder)
+ && Objects.equals(destinationFileFolder, that.destinationFileFolder)
+ && Objects.equals(wildcard, that.wildcard);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sourceFileFolder, destinationFileFolder, wildcard);
+ }
+}
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_de_DE.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_de_DE.properties
index ea65670c5d..87b8331e81 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_de_DE.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_de_DE.properties
@@ -27,7 +27,6 @@ ActionCopyFiles.CreateDestinationFolder.Tooltip=Erstelle das
Ziel-Verzeichnis, f
ActionCopyFiles.Description=Dateien kopieren
ActionCopyFiles.DestinationIsAFile.Label=Ziel ist eine Datei
ActionCopyFiles.DestinationIsAFile.Tooltip=Apache Hop wird
ber\u00FCcksichtigen, dass das Ziel eine Datei ist.
-ActionCopyFiles.Error.DestinationFolderNotFound=Ziel-Verzeichnis nicht
vorhanden\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=Kann Datei/Verzeichnis
[{0}] nicht l\u00F6schen
ActionCopyFiles.Error.Exception.CopyProcess=Fehler beim Versuch
Datei/Verzeichnis [{0}] nach [{1}] zu kopieren. Apache Hop erhh\u00E4lt die
folgende Ausnahme-Meldung : [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=Dateisystem-Ausnahme:
{0}
@@ -47,20 +46,14 @@ ActionCopyFiles.Filetype.All=Alle Dateien
ActionCopyFiles.IncludeSubfolders.Label=Einschlie\u00DFlich Unterverzeichnisse
ActionCopyFiles.IncludeSubfolders.Tooltip=Einschalten, wenn Sie auch
Unterverzeichnisse holen m\u00F6chten.\r\nFunktioniert nur, wenn die Quelle ein
Verzeichnis ist.
ActionCopyFiles.keyword=kopieren,Dateien
-ActionCopyFiles.Log.ArgFromPrevious.Found=Finden von [{0}] Argumenten aus dem
vorherigen Ergebnis (result).
ActionCopyFiles.Log.CanNotCopyFolderToFile=Kann Verzeichnis [{0}] nicht in
Datei [{1}] kopieren.
ActionCopyFiles.Log.FetchFolder=Abholen \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=Datei [{0}] wurde zum Ergebnis
(result) f\u00FCr Dateinamen hinzugef\u00FCgt.
ActionCopyFiles.Log.FileCopied=Datei [{0}] wurde nach Verzeichnis [{1}]
kopiert.
ActionCopyFiles.Log.FileExists=Datei [{0}] vorhanden\!
-ActionCopyFiles.Log.FileExistsInfos=Datei vorhanden\!
ActionCopyFiles.Log.FileFolderRemoved=Datei/Verzeichnis [{0}] wurde
gel\u00F6scht
-ActionCopyFiles.Log.FileOverwrite=Datei [{0}] wurde \u00FCberschrieben durch
[{1}]
ActionCopyFiles.Log.FolderCopied=Verzeichnis [{0}] wurde nach [{1}] kopiert.
ActionCopyFiles.Log.FolderExists=Verzeichnis [{0}] vorhanden\!
-ActionCopyFiles.Log.FolderOverwrite=Verzeichnis [{0}] wurde \u00FCberschrieben
-ActionCopyFiles.Log.IgnoringRow=Zeilen mit Quell- oder Ziel-Wert \= leer
(NULL) werden ignoriert. Quell-Datei/Verzeichnis \: [{0}],
Ziel-Datei/Verzeichnis \: [{1}], Platzhalter (wildcard) \: [{2}]
-ActionCopyFiles.Log.ProcessingRow=Zeile in Arbeit\: Quell-Datei/Verzeichnis \:
[{0}]... Ziel-Datei/Verzeichnis \: [{1}]... Platzhalter (wildcard) \: [{2}]...
ActionCopyFiles.Log.Starting=Starten...
ActionCopyFiles.Name=Dateien kopieren
ActionCopyFiles.Name.Default=Dateien kopieren
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_en_US.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_en_US.properties
index 2fc7a4fd74..6e2597c412 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_en_US.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_en_US.properties
@@ -26,7 +26,8 @@ ActionCopyFiles.CreateDestinationFolder.Tooltip=Create the
specified destination
ActionCopyFiles.Description=Copy files
ActionCopyFiles.DestinationIsAFile.Label=Destination is a file
ActionCopyFiles.DestinationIsAFile.Tooltip=Select this if the destination is a
file.
-ActionCopyFiles.Error.DestinationFolderNotFound=Destination folder does not
exist\!
+ActionCopyFiles.Error.DestinationFolderNotFound=Destination folder [{0}] does
not exist. Enable ''Create destination folder'' or create the folder before
running.
+ActionCopyFiles.Error.FolderParentCreateFailed=Could not create destination
folder [{0}]
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=Can not delete file/folder
[{0}]
ActionCopyFiles.Error.Exception.CopyProcess=Can not copy file/folder [{0}] to
[{1}]. Exception \: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=File System
Exception: {0}
@@ -46,20 +47,28 @@ ActionCopyFiles.Filetype.All=All files
ActionCopyFiles.IncludeSubfolders.Label=Include subfolders
ActionCopyFiles.IncludeSubfolders.Tooltip=Check this if you want to fetch also
sub folders\nThis option will work only when the source is a folder.
ActionCopyFiles.keyword=copy,files
-ActionCopyFiles.Log.ArgFromPrevious.Found=found [{0}] argument(s) from
previous result
+ActionCopyFiles.Log.ArgFromPrevious.Found=Found [{0}] row(s) from the previous
action result to use as copy arguments.
ActionCopyFiles.Log.CanNotCopyFolderToFile=Can not copy folder [{0}] to file
[{1}]
ActionCopyFiles.Log.FetchFolder=Fetching \: [{0}]
+ActionCopyFiles.Log.Debug.CouldNotGetFileSize=Could not determine size of
source file {0}\: {1}
+ActionCopyFiles.Log.Debug.ResolvedPaths=Resolved copy paths - source\: [{0}],
destination\: [{1}], wildcard\: [{2}]
ActionCopyFiles.Log.FileAddedToResultFilesName=File [{0}] was added to result
filesname
ActionCopyFiles.Log.FileCopied=File [{0}] was copied to [{1}]
ActionCopyFiles.Log.FileExists=file [{0}] exists\!
-ActionCopyFiles.Log.FileExistsInfos=File exists\!
+ActionCopyFiles.Log.FileExistsSkippingCopy=Destination file [{0}] already
exists; skipping copy because replacing existing files is disabled.
ActionCopyFiles.Log.FileFolderRemoved=File/folder [{0}] was deleted
-ActionCopyFiles.Log.FileOverwrite=File [{0}] was overwritten
+ActionCopyFiles.Log.FileOverwrite=Source [{0}] will overwrite destination [{1}]
+ActionCopyFiles.Log.FinishedSuccess=Copy files action finished successfully.
+ActionCopyFiles.Log.FinishedWithErrors=Copy files action finished with {0}
error(s).
ActionCopyFiles.Log.FolderCopied=Folder [{0}] was copied to [{1}]
ActionCopyFiles.Log.FolderExists=Folder [{0}] exists\!
-ActionCopyFiles.Log.FolderOverwrite=Folder [{0}] was overwritten
-ActionCopyFiles.Log.IgnoringRow=Ignoring row with source or destination is
NULL. Source File/folder source \: [{0}], destination file/folder \: [{1}],
wildcard \: [{2}]
-ActionCopyFiles.Log.ProcessingRow=Processing row source File/folder source \:
[{0}] ... destination file/folder \: [{1}]... wildcard \: [{2}]
+ActionCopyFiles.Log.FolderExistsSkippingCopy=Destination folder [{0}] already
exists; skipping copy because replacing existing files is disabled.
+ActionCopyFiles.Log.FolderOverwrite=Source folder [{0}] will overwrite
destination folder [{1}]
+ActionCopyFiles.Log.FolderParentCreated=Created destination folder [{0}]
+ActionCopyFiles.Log.FolderParentWillCreate=Destination folder [{0}] does not
exist; creating it now.
+ActionCopyFiles.Log.IgnoringRow=Ignoring row\: source or destination is empty.
Source\: [{0}], destination\: [{1}], wildcard\: [{2}]
+ActionCopyFiles.Log.ProcessingRow=Processing copy row - source\: [{0}],
destination\: [{1}], wildcard\: [{2}]
+ActionCopyFiles.Log.ScanningSourceFolder=Scanning source folder [{0}] for
files to copy...
ActionCopyFiles.Log.Starting=Starting ...
ActionCopyFiles.Name=Copy files
ActionCopyFiles.Name.Default=Copy files
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_es_AR.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_es_AR.properties
index 134760e058..69c8b23285 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_es_AR.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_es_AR.properties
@@ -26,7 +26,6 @@ ActionCopyFiles.CreateDestinationFolder.Label=Crear
directorio destino
ActionCopyFiles.CreateDestinationFolder.Tooltip=Crear directorio destino de
ser necesario.\nSi el destino es un archivo, se crear\u00E1 el directorio padre
de ser necesario.
ActionCopyFiles.DestinationIsAFile.Label=El destino es un archivo
ActionCopyFiles.DestinationIsAFile.Tooltip=Apache Hop considerar\u00E1 que el
destino es un archivo.
-ActionCopyFiles.Error.DestinationFolderNotFound=\u00A1El directorio destino no
existe\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=No se puede eliminar el
archivo/directorio [{0}]
ActionCopyFiles.Error.Exception.CopyProcess=No se puede copiar el
archivo/directorio [{0}] a [{1}]. Excepci\u00F3n \: [{2}]
ActionCopyFiles.Error.Exception.UnableLoadXML=Imposible cargar la entrada de
trabajo del tipo 'Copiar archivos' del nodo XML
@@ -44,20 +43,14 @@ ActionCopyFiles.FilenameDelete.Tooltip=Quitar de la grilla
a los archivos selecc
ActionCopyFiles.Filetype.All=Todos los archivos
ActionCopyFiles.IncludeSubfolders.Label=Incluir subdirectorios
ActionCopyFiles.IncludeSubfolders.Tooltip=Seleccione esta opci\u00F3n si desea
incluir subdirectorios\nEsta opci\u00F3n s\u00F3lo funcionar\u00E1 si el origen
es un directorio.
-ActionCopyFiles.Log.ArgFromPrevious.Found=Se encontraron [{0}] argumentos del
resultado anterior
ActionCopyFiles.Log.CanNotCopyFolderToFile=Imposible copiar el directorio
[{0}] al archivo [{1}]
ActionCopyFiles.Log.FetchFolder=Leyendo \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=El archivo [{0}] fue
a\u00F1adido a los archivos de resultado
ActionCopyFiles.Log.FileCopied=El archivo [{0}] fue copiado a [{1}]
ActionCopyFiles.Log.FileExists=\u00A1El archivo [{0}] existe\!
-ActionCopyFiles.Log.FileExistsInfos=\u00A1El archivo existe\!
ActionCopyFiles.Log.FileFolderRemoved=El archivo/directorio [{0}] fue eliminado
-ActionCopyFiles.Log.FileOverwrite=El archivo [{0}] fue sobreescrito
ActionCopyFiles.Log.FolderCopied=El directorio [{0}] fue copiado a [{1}]
ActionCopyFiles.Log.FolderExists=\u00A1El directorio [{0}] existe\!
-ActionCopyFiles.Log.FolderOverwrite=El directorio [{0}] fue sobreescrito
-ActionCopyFiles.Log.IgnoringRow=Ignorando fila donde el origen \u00F3 destino
es NULO. Archivo/directorio origen\: [{0}], archivo/directorio destino\: [{1}],
comod\u00EDn\: [{2}]
-ActionCopyFiles.Log.ProcessingRow=Procesando fila. Archivo/Directorio origen\:
[{0}] ... Archivo/Directorio destino\: [{1}] ... Comod\u00EDn\: [{2}]
ActionCopyFiles.Log.Starting=Comenzando...
ActionCopyFiles.Name=Copiar archivos
ActionCopyFiles.Name.Default=Copiar archivos
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_fr_FR.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_fr_FR.properties
index 1b564e1b28..74d61549ba 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_fr_FR.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_fr_FR.properties
@@ -26,7 +26,6 @@ ActionCopyFiles.CreateDestinationFolder.Tooltip=Cr\u00E9er le
r\u00E9pertoire de
ActionCopyFiles.Description=Copie de fichiers\n Possibilit\u00E9 de parcourir
un dossier, de copier les fichier vers une destination\n et enlever les source.
ActionCopyFiles.DestinationIsAFile.Label=La destination est un fichier
ActionCopyFiles.DestinationIsAFile.Tooltip=La destination est un fichier.
-ActionCopyFiles.Error.DestinationFolderNotFound=Le dossier de destination
n'existe pas\u00A0!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=Impossible de supprimer le
fichier/r\u00E9pertoire [{0}]
ActionCopyFiles.Error.Exception.CopyProcess=Apache Hop a rencontr\u00E9 une
erreur lors du processus de copie du fichier/r\u00E9pertoire [{0}] vers [{1}].
Exception \: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=Erreur au
niveau du syst\u00E8me de fichier\: {0}
@@ -43,20 +42,14 @@ ActionCopyFiles.FilenameDelete.Tooltip=Retirer les
entr\u00E9es s\u00E9lectionn\
ActionCopyFiles.Filetype.All=Tous les fichiers
ActionCopyFiles.IncludeSubfolders.Label=Inclure sous r\u00E9pertoires
ActionCopyFiles.IncludeSubfolders.Tooltip=S\u00E9lectionnez cette option pour
parcourir les sous r\u00E9pertoires\nCette option ne sera prise en compte que
si la source est un r\u00E9pertoire.
-ActionCopyFiles.Log.ArgFromPrevious.Found=[{0}] argument(s) trouv\u00E9(s)
depuis l''action pr\u00E9c\u00E9dente
ActionCopyFiles.Log.CanNotCopyFolderToFile=Impossible de copier le
r\u00E9pertoire [{0}] vers le fichier [{1}]
ActionCopyFiles.Log.FetchFolder=R\u00E9pertoire racine recherche \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=Le fichier [{0}] a
\u00E9t\u00E9 ajout\u00E9 aux nom de fichiers en r\u00E9sultat
ActionCopyFiles.Log.FileCopied=Le fichier [{0}] a \u00E9t\u00E9 copi\u00E9
vers [{1}]
ActionCopyFiles.Log.FileExists=Le fichier [{0}] existe\!
-ActionCopyFiles.Log.FileExistsInfos=Fichier existe\!
ActionCopyFiles.Log.FileFolderRemoved=Le Fichier/r\u00E9pertoire [{0}] a
\u00E9t\u00E9 supprim\u00E9
-ActionCopyFiles.Log.FileOverwrite=Le fichier [{0}] a \u00E9t\u00E9
\u00E9cras\u00E9
ActionCopyFiles.Log.FolderCopied=Le r\u00E9pertoire [{0}] a \u00E9t\u00E9
copi\u00E9 vers [{1}]
ActionCopyFiles.Log.FolderExists=Le r\u00E9pertoire [{0}] existe\!
-ActionCopyFiles.Log.FolderOverwrite=Le r\u00E9pertoire [{0}] a \u00E9t\u00E9
\u00E9cras\u00E9
-ActionCopyFiles.Log.IgnoringRow=La ligne dont la source ou la destination est
nulle a \u00E9t\u00E9 ignor\u00E9e. Fichier/r\u00E9pertoire source \: [{0}],
fichier/r\u00E9pertoire destination \: [{1}], caract\u00E8res joker \: [{2}]
-ActionCopyFiles.Log.ProcessingRow=Traitement ligne Fichier/r\u00E9pertoire
source \: [{0}] ... fichier/r\u00E9pertoire destination \: [{1}]...
caract\u00E8res joker \: [{2}]
ActionCopyFiles.Log.Starting=D\u00E9marrage ...
ActionCopyFiles.Name=Copie de fichiers
ActionCopyFiles.Name.Default=Copie de fichiers
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_it_IT.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_it_IT.properties
index d6391f30c2..afd69664b1 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_it_IT.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_it_IT.properties
@@ -26,7 +26,6 @@ ActionCopyFiles.CreateDestinationFolder.Label=Crea cartelle
di destinazione
ActionCopyFiles.CreateDestinationFolder.Tooltip=Crea cartella di destinazione
se necessario.\r\nSe la destinazione \u00E8 un file, la cartella padre
verr\u00E0 creata se necessario.
ActionCopyFiles.DestinationIsAFile.Label=La destinazione \u00E8 un file
ActionCopyFiles.DestinationIsAFile.Tooltip=Apache Hop considera la
destinazione come file.
-ActionCopyFiles.Error.DestinationFolderNotFound=La cartella di destinazione
non esiste\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=Impossibile cancellare il
file/cartella [{0}]
ActionCopyFiles.Error.Exception.CopyProcess=Impossibile copiare file/cartella
[{0}] in [{1}]. Eccezione\: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=Eccezione del
file system\: {0}
@@ -43,20 +42,14 @@ ActionCopyFiles.FilenameDelete.Tooltip=Rimuovi i file
selezionati dalla griglia
ActionCopyFiles.Filetype.All=Tutti i file
ActionCopyFiles.IncludeSubfolders.Label=Includi sottocartelle
ActionCopyFiles.IncludeSubfolders.Tooltip=Seleziona questo se vuoi analizzare
anche le sottocartelle\r\nQuesta opzione funzioner\u00E0 solo quando la
sorgente \u00E8 una cartella.
-ActionCopyFiles.Log.ArgFromPrevious.Found=trovato/i [{0}] argomento/i dal
precedente risultato
ActionCopyFiles.Log.CanNotCopyFolderToFile=Impossibile copiare la cartella
[{0}] nel file [{1}]
ActionCopyFiles.Log.FetchFolder=Prelievo \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=Il file [{0}] \u00E8 stato
aggiunto al risultato
ActionCopyFiles.Log.FileCopied=Il file [{0}] \u00E8 stato copiato in [{1}]
ActionCopyFiles.Log.FileExists=Il file [{0}] esiste\!
-ActionCopyFiles.Log.FileExistsInfos=File esistente\!
ActionCopyFiles.Log.FileFolderRemoved=File/Cartella [{0}] cancellato
-ActionCopyFiles.Log.FileOverwrite=File [{0}] sovrascritto
ActionCopyFiles.Log.FolderCopied=La cartella [{0}] \u00E8 stata copiata in
[{1}]
ActionCopyFiles.Log.FolderExists=La cartella [{0}] esiste\!
-ActionCopyFiles.Log.FolderOverwrite=La cartella [{0}] \u00E8 stata sovrascritta
-ActionCopyFiles.Log.IgnoringRow=Ignoro la riga con fonte o destinazione NULLI.
File/cartella di partenza (fonte) \: [{0}], file/cartella di destinazione \:
[{0}], wildcard \: [{2}]
-ActionCopyFiles.Log.ProcessingRow=Processo la riga con fonte File/cartella \:
[{0}] ... file/folder di destinazione \: [{1}]... wildcard \: [{2}]
ActionCopyFiles.Log.Starting=Avvio...
ActionCopyFiles.Name=Copia i file
ActionCopyFiles.Name.Default=Copia i file
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ja_JP.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ja_JP.properties
index 702f179d91..e42feb1c6f 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ja_JP.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ja_JP.properties
@@ -27,7 +27,6 @@ ActionCopyFiles.CreateDestinationFolder.Tooltip=Create
destination folder if nec
ActionCopyFiles.Description=Copy
files\n\u30d5\u30a1\u30a4\u30eb\u30b3\u30d4\u30fc
ActionCopyFiles.DestinationIsAFile.Label=\u79fb\u52d5\u5148\u304c\u30d5\u30a1\u30a4\u30eb
ActionCopyFiles.DestinationIsAFile.Tooltip=\u79fb\u52d5\u5148\u304c\u30d5\u30a1\u30a4\u30eb\u3067\u3042\u308b\u5834\u5408\u306f\u30c1\u30a7\u30c3\u30af\u30fb\u30dc\u30c3\u30af\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
-ActionCopyFiles.Error.DestinationFolderNotFound=Destination folder does not
exist\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=Can not delete file/folder
[{0}]
ActionCopyFiles.Error.Exception.CopyProcess=Can not copy file/folder [{0}] to
[{1}]. Exception \: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=File System
Exception: {0}
@@ -44,20 +43,14 @@
ActionCopyFiles.FilenameDelete.Tooltip=\u9078\u629e\u3055\u308c\u305f\u30d5\u30a
ActionCopyFiles.Filetype.All=\u5168\u3066\u306e\u30d5\u30a1\u30a4\u30eb
ActionCopyFiles.IncludeSubfolders.Label=\u30b5\u30d6\u30fb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u542b\u3080
ActionCopyFiles.IncludeSubfolders.Tooltip=\u30b5\u30d6\u30fb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u542b\u3080\u5834\u5408\u306f\u30c1\u30a7\u30c3\u30af\u30fb\u30dc\u30c3\u30af\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
-ActionCopyFiles.Log.ArgFromPrevious.Found=found [{0}] argument(s) from
previous result
ActionCopyFiles.Log.CanNotCopyFolderToFile=Can not copy folder [{0}] to file
[{1}]
ActionCopyFiles.Log.FetchFolder=Fetching \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=File [{0}] was added to result
filesname
ActionCopyFiles.Log.FileCopied=File [{0}] was copied to [{1}]
ActionCopyFiles.Log.FileExists=file [{0}] exists\!
-ActionCopyFiles.Log.FileExistsInfos=File exists\!
ActionCopyFiles.Log.FileFolderRemoved=File/folder [{0}] was deleted
-ActionCopyFiles.Log.FileOverwrite=File [{0}] was overwritten
ActionCopyFiles.Log.FolderCopied=Folder [{0}] was copied to [{1}]
ActionCopyFiles.Log.FolderExists=Folder [{0}] exists\!
-ActionCopyFiles.Log.FolderOverwrite=Folder [{0}] was overwritten
-ActionCopyFiles.Log.IgnoringRow=Ignoring row with source or destination is
NULL. Source File/folder source \: [{0}], destination file/folder \: [{1}],
wildcard \: [{2}]
-ActionCopyFiles.Log.ProcessingRow=Processing row source File/folder source \:
[{0}] ... destination file/folder \: [{1}]... wildcard \: [{2}]
ActionCopyFiles.Log.Starting=Starting ...
ActionCopyFiles.Name=\u30d5\u30a1\u30a4\u30eb\u30b3\u30d4\u30fc
ActionCopyFiles.Name.Default=\u30b3\u30d4\u30fc\u30d5\u30a1\u30a4\u30eb
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ko_KR.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ko_KR.properties
index 10330889db..6134de5351 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ko_KR.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_ko_KR.properties
@@ -26,7 +26,6 @@ ActionCopyFiles.CreateDestinationFolder.Label=\uB300\uC0C1
\uD3F4\uD130 \uC0DD\u
ActionCopyFiles.CreateDestinationFolder.Tooltip=\uD544\uC694\uD558\uBA74
\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC \uC0DD\uC131.\r\n\uB9CC\uC57D
\uB300\uC0C1\uC774 \uD30C\uC77C\uBBF8\uBA74 \uBD80\uBAA8 \uD3F4\uB354\uAC00
\uC0DD\uC131\uB420 \uAC83\uC785\uB2C8\uB2E4.
ActionCopyFiles.DestinationIsAFile.Label=\uB300\uC0C1\uC740 \uD30C\uC77C
ActionCopyFiles.DestinationIsAFile.Tooltip=Apache Hop\uB294 \uB300\uC0C1\uC744
\uD30C\uC77C\uB85C \uC778\uC2DD\uD569\uB2C8\uB2E4.
-ActionCopyFiles.Error.DestinationFolderNotFound=\uB300\uC0C1
\uD3F4\uB354\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=\uD30C\uC77C/\uD3F4\uB354
[{0}]\uB97C \uC0AD\uC81C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4
ActionCopyFiles.Error.Exception.CopyProcess=\uD30C\uC77C/\uD3F4\uB354
[{0}]\uC744 [{1}]\uB85C \uBCF5\uC0AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
\uC608\uC678 \: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=\uD30C\uC77C
\uC2DC\uC2A4\uD15C \uC608\uC678\: {0}
@@ -43,20 +42,14 @@
ActionCopyFiles.FilenameDelete.Tooltip=\uADF8\uB9AC\uB4DC\uC5D0\uC11C \uC120\uD0
ActionCopyFiles.Filetype.All=\uBAA8\uB4E0 \uD30C\uC77C
ActionCopyFiles.IncludeSubfolders.Label=\uD558\uC704\uD3F4\uB354 \uD3EC\uD568
ActionCopyFiles.IncludeSubfolders.Tooltip=\uD558\uC704 \uD3F4\uB354\uB97C
\uAC00\uC838\uC624\uB824\uBA74 \uC5EC\uAE30\uB97C
\uCCB4\uD06C\uD558\uC2ED\uC2DC\uC624\r\n\uC774 \uC635\uC158\uC740
\uC18C\uC2A4\uAC00 \uD3F4\uB354\uC778 \uACBD\uC6B0\uB9CC
\uB3D9\uC791\uD569\uB2C8\uB2E4.
-ActionCopyFiles.Log.ArgFromPrevious.Found=\uC774\uC804
\uACB0\uACFC\uB85C\uBD80\uD130 [{0}] \uC778\uC790 \uBC1C\uACAC
-ActionCopyFiles.Log.CanNotCopyFolderToFile=\uD3F4\uB354 [{0}]\uB97C
\uD30C\uC77C [{1]}]\uB85C \uBCF5\uC0AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4
+ActionCopyFiles.Log.CanNotCopyFolderToFile=\uD3F4\uB354 [{0}]\uB97C
\uD30C\uC77C [{1}]\uB85C \uBCF5\uC0AC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4
ActionCopyFiles.Log.FetchFolder=Fetching \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=\uD30C\uC77C [{0}]\uC744
\uACB0\uACFC \uD30C\uC77C\uC774\uB984\uC5D0
\uCD94\uAC00\uD558\uC600\uC2B5\uB2C8\uB2E4
ActionCopyFiles.Log.FileCopied=\uD30C\uC77C [{0}]\uB97C [{1}]\uB85C
\uBCF5\uC0AC\uD558\uC600\uC2B5\uB2C8\uB2E4
ActionCopyFiles.Log.FileExists=\uD30C\uC77C [{0}]\uC774
\uC874\uC7AC\uD569\uB2C8\uB2E4\!
-ActionCopyFiles.Log.FileExistsInfos=\uD30C\uC77C\uC774
\uC874\uC7AC\uD569\uB2C8\uB2E4\!
ActionCopyFiles.Log.FileFolderRemoved=\uD30C\uC77C/\uD3F4\uB354 [{0}]\uB97C
\uC0AD\uC81C\uD558\uC600\uC2B5\uB2C8\uB2E4
-ActionCopyFiles.Log.FileOverwrite=\uD30C\uC77C [{0}]\uB97C
\uACB9\uCCD0\uC4F0\uAE30\uD558\uC600\uC2B5\uB2C8\uB2E4
ActionCopyFiles.Log.FolderCopied=\uD3F4\uB354 [{0}]\uB97C [{1}]\uB85C
\uBCF5\uC0AC\uD558\uC600\uC2B5\uB2C8\uB2E4
ActionCopyFiles.Log.FolderExists=\uD3F4\uB354 [{0}]\uAC00
\uC874\uC7AC\uD569\uB2C8\uB2E4
-ActionCopyFiles.Log.FolderOverwrite=\uD3F4\uB354 [{0}]\uB97C
\uACB9\uCCD0\uC4F0\uAE30\uD558\uC600\uC2B5\uB2C8\uB2E4
-ActionCopyFiles.Log.IgnoringRow=\uC18C\uC2A4\uB098 \uB300\uC0C1\uC774
NILL\uC774\uBA74 \uB85C\uC6B0\uB97C \uBB34\uC2DC. \uC18C\uC2A4
\uD30C\uC77C/\uD3F4\uB354 \uC18C\uC2A4 \: [{0}], \uB300\uC0C1
\uD30C\uC77C/\uD3F4\uB354 \: [{1}], \uC640\uC77C\uB4DC\uCE74\uB4DC \: [{2}]
-ActionCopyFiles.Log.ProcessingRow=\uB85C\uC6B0 \uCC98\uB9AC \uC18C\uC2A4
\uD30C\uC77C/\uD3F4\uB354 \uC18C\uC2A4 \: [{0}] ... \uB300\uC0C1
\uD30C\uC77C/\uD3F4\uB354 \: [{1}] ... \uC640\uC77C\uB4DC\uCE74\uB4DC \: [{2}]
ActionCopyFiles.Log.Starting=\uC2DC\uC791 ...
ActionCopyFiles.Name.Default=Copy files
ActionCopyFiles.Name.Label=Action name\:
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_nl_NL.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_nl_NL.properties
index 90f945e2ae..85741db0a7 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_nl_NL.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_nl_NL.properties
@@ -26,7 +26,6 @@ ActionCopyFiles.CreateDestinationFolder.Label=Maak de
doel-folder aan
ActionCopyFiles.CreateDestinationFolder.Tooltip=Maak indien nodig de
doel-folder aan. \nAls het doel een bestand is zal de folder indien nodig
aangemaakt worden.
ActionCopyFiles.DestinationIsAFile.Label=Doel is een bestand
ActionCopyFiles.DestinationIsAFile.Tooltip=We nemen aan dat het doel van de
copieer-opdracht een bestand is.
-ActionCopyFiles.Error.DestinationFolderNotFound=De doel-folder bestaat niet.
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=Het was niet mogelijk om
het bestand of de folder [{0}] te verwijderen.
ActionCopyFiles.Error.Exception.CopyProcess=Het is niet mogelijk om bestand or
folder [{0}] naar bestemming [{1}] te kopi\u00EBren\: [{2}]
ActionCopyFiles.Error.Exception.UnableLoadXML=Het was niet mogelijk om de
action van het type "copyfiles" te laden van uit XML
@@ -42,20 +41,14 @@ ActionCopyFiles.FilenameDelete.Tooltip=Verwijder de
geselecteerde bestanden uit
ActionCopyFiles.Filetype.All=Alle bestanden
ActionCopyFiles.IncludeSubfolders.Label=sub-folders meenemen
ActionCopyFiles.IncludeSubfolders.Tooltip=Vink deze optie aan als u ook alle
sub-folders wil mee kopi\u00EBren.\nDeze optie werkt enkel indien als bron een
folder werd opgegeven.
-ActionCopyFiles.Log.ArgFromPrevious.Found=We vonden [{0}] argumentsen in het
resultaat van een vorige action
ActionCopyFiles.Log.CanNotCopyFolderToFile=Het was niet mogelijk om folder
[{0}] naar bestand [{1}] te kopi\u00EBren.
ActionCopyFiles.Log.FetchFolder=Ophalen van \: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=Bestandsnaam [{0}] werd
toegevoegd aan het resultaat.
ActionCopyFiles.Log.FileCopied=Bestand [{0}] is gekopieerd naar [{1}]
ActionCopyFiles.Log.FileExists=Bestand [{0}] bestaat reeds\!
-ActionCopyFiles.Log.FileExistsInfos=Bestand bestaat\!
ActionCopyFiles.Log.FileFolderRemoved=Bestand of folder [{0}] werd verwijderd
-ActionCopyFiles.Log.FileOverwrite=Bestand [{0}] werd overschreven
ActionCopyFiles.Log.FolderCopied=Folder [{0}] werd gekopieerd naar [{1}]
ActionCopyFiles.Log.FolderExists=Folder [{0}] bestaat\!
-ActionCopyFiles.Log.FolderOverwrite=Folder [{0}] werd overschreven
-ActionCopyFiles.Log.IgnoringRow=We negeren een rij waar de bron of het doel
leeg is. Bronbestand of -folder [{0}], doelbestand of -folder \: [{1}],
wildcard \: [{2}].
-ActionCopyFiles.Log.ProcessingRow=Verwerken van rij met bronbestand of -folder
[{0}] en doelbestand of -folder\: [{1}]. De wildcard is [{2}].
ActionCopyFiles.Name.Default=Kopieer bestanden
ActionCopyFiles.Name.Label=Action naam\:
ActionCopyFiles.OverwriteFiles.Label=Vervang bestaande bestanden
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_pt_BR.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_pt_BR.properties
index ef2dea857d..41ba209009 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_pt_BR.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_pt_BR.properties
@@ -26,7 +26,6 @@ ActionCopyFiles.CreateDestinationFolder.Tooltip=Crie o
diret\u00F3rio de destino
ActionCopyFiles.Description=Copiar arquivos
ActionCopyFiles.DestinationIsAFile.Label=O destino \u00E9 um arquivo
ActionCopyFiles.DestinationIsAFile.Tooltip=Apache Hop considerar\u00E1 que o
destino \u00E9 um arquivo.
-ActionCopyFiles.Error.DestinationFolderNotFound=A pasta destino n\u00E3o
existe\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=N\u00E3o \u00E9
poss\u00EDvel apagar a pasta/o arquivo [{0}]
ActionCopyFiles.Error.Exception.CopyProcess=N\u00E3o \u00E9 poss\u00EDvel
copiar a pasta/o arquivo [{0}] a [{1}]. Excep\u00E7\u00E3o\: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=Erro de sistema
de arquivos: {0}
@@ -45,19 +44,14 @@ ActionCopyFiles.Filetype.All=Todos os arquivos
ActionCopyFiles.IncludeSubfolders.Label=Incluir Subpastas
ActionCopyFiles.IncludeSubfolders.Tooltip=Selecionar esta op\u00E7\u00E3o para
incluir pastas filhas.\r\nSomente quando a origem \u00E9 uma pasta.
ActionCopyFiles.keyword=copiar,arquivos
-ActionCopyFiles.Log.ArgFromPrevious.Found=Encontrou-se [{0}] argumento(s) do
resulto anterior
ActionCopyFiles.Log.CanNotCopyFolderToFile=N\u00E3o \u00E9 poss\u00EDvel
copiar pasta [{0}] a arquivo [{1}]
ActionCopyFiles.Log.FetchFolder=Buscando : [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=Arquivo [{0}] foi adicionado ao
resultado
ActionCopyFiles.Log.FileCopied=Arquivo [{0}] foi copiado a [{1}]
ActionCopyFiles.Log.FileExists=O arquivo [{0}] existe\!
-ActionCopyFiles.Log.FileExistsInfos=O arquivo existe\!
ActionCopyFiles.Log.FileFolderRemoved=A pasta/o arquivo [{0}] foi eliminado
-ActionCopyFiles.Log.FileOverwrite=Arquivo [{0}] foi sobrescrito
ActionCopyFiles.Log.FolderCopied=A pasta [{0}] foi copiada a [{1}]
ActionCopyFiles.Log.FolderExists=A pasta [{0}] existe\!
-ActionCopyFiles.Log.FolderOverwrite=A pasta [{0}] foi substitu\u00EDda
-ActionCopyFiles.Log.ProcessingRow=Processando arquivo/pasta origem: [{0}] ...
arquivo/pasta destino: [{1}]... coringa : [{2}]
ActionCopyFiles.Log.Starting=Iniciando ...
ActionCopyFiles.Name=Copiar arquivos
ActionCopyFiles.Name.Default=Copiar arquivos
@@ -71,5 +65,4 @@ ActionCopyFiles.Settings.Label=Configura\u00E7\u00E3o
ActionCopyFiles.Tab.Files.Label=Arquivos
ActionCopyFiles.Title=Copiar arquivos
ActionCopyFiles.Fields.SourceFileFolder.Tooltip=Adicione aqui o arquivo ou
pasta para copiar\n se for uma pasta, o Apache Hop ler\u00E1 apenas se "incluir
subpastas" estiver marcado!
-ActionCopyFiles.Log.IgnoringRow=Ignora linhas com origem ou destino nulo.
Arquivo/pasta de origem : [{0}], arquivo/pasta de destino: [{1}], curinga: [{2}]
ActionCopyFiles.Previous.Tooltip=Passa o resultado da entrada anterior como
argumento dessa entrada.\nArgumentos devem estar na mesma ordem.\n ou seja: (1)
arquivo/pasta de origem, (2) arquivo/pasta de destino, (3) curinga
diff --git
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_zh_CN.properties
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_zh_CN.properties
index db8a5a0a51..a51bb19b49 100644
---
a/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_zh_CN.properties
+++
b/plugins/actions/copyfiles/src/main/resources/org/apache/hop/workflow/actions/copyfiles/messages/messages_zh_CN.properties
@@ -26,7 +26,6 @@
ActionCopyFiles.CreateDestinationFolder.Tooltip=\u5982\u679C\u5FC5\u8981\u521B\u
ActionCopyFiles.Description=\u590D\u5236\u6587\u4EF6
ActionCopyFiles.DestinationIsAFile.Label=\u76EE\u6807\u662F\u6587\u4EF6
ActionCopyFiles.DestinationIsAFile.Tooltip=Apache Hop
\u5C06\u628A\u8BE5\u76EE\u6807\u4F5C\u4E3A\u4E00\u4E2A\u6587\u4EF6.
-ActionCopyFiles.Error.DestinationFolderNotFound=\u76EE\u6807\u76EE\u5F55\u4E0D\u5B58\u5728\!
ActionCopyFiles.Error.Exception.CanRemoveFileFolder=\u4E0D\u80FD\u5220\u9664\u6587\u4EF6/\u76EE\u5F55
[{0}]
ActionCopyFiles.Error.Exception.CopyProcess=\u4E0D\u80FD\u5C06\u6587\u4EF6/\u76EE\u5F55
[{0}] \u590D\u5236\u5230 [{1}]. \u5F02\u5E38: [{2}]
ActionCopyFiles.Error.Exception.CopyProcessFileSystemException=\u6587\u4EF6\u7CFB\u7EDF\u5F02\u5E38\uFF1A{0}
@@ -46,20 +45,14 @@ ActionCopyFiles.Filetype.All=\u6240\u6709\u6587\u4EF6
ActionCopyFiles.IncludeSubfolders.Label=\u5305\u62EC\u5B50\u76EE\u5F55
ActionCopyFiles.IncludeSubfolders.Tooltip=\u9009\u4E2D\u8BE5\u9009\u9879\u4EE5\u83B7\u53D6\u5B50\u76EE\u5F55,\n\u53EA\u6709\u5F53\u590D\u5236\u6E90\u662F\u76EE\u5F55\u65F6\u8BE5\u9009\u9879\u624D\u6709\u6548.
ActionCopyFiles.keyword=\u590D\u5236\u3001\u6587\u4EF6
-ActionCopyFiles.Log.ArgFromPrevious.Found=\u4ECE\u4E0A\u4E00\u4E2A\u7ED3\u679C\u4E2D\u627E\u5230\u4E86
[{0}] \u4E2A \u53C2\u6570
ActionCopyFiles.Log.CanNotCopyFolderToFile=\u4E0D\u80FD\u590D\u5236\u76EE\u5F55
[{0}] \u5230\u6587\u4EF6 [{1}]
ActionCopyFiles.Log.FetchFolder=\u6B63\u5728\u83B7\u53D6\: [{0}]
ActionCopyFiles.Log.FileAddedToResultFilesName=\u6587\u4EF6 [{0}]
\u5DF2\u7ECF\u88AB\u6DFB\u52A0\u5230\u7ED3\u679C\u6587\u4EF6\u4E2D
ActionCopyFiles.Log.FileCopied=\u6587\u4EF6 [{0}] \u88AB\u590D\u5236\u5230
[{1}]
ActionCopyFiles.Log.FileExists=\u6587\u4EF6 [{0}] \u5B58\u5728\!
-ActionCopyFiles.Log.FileExistsInfos=\u6587\u4EF6\u5B58\u5728\!
ActionCopyFiles.Log.FileFolderRemoved=\u6587\u4EF6/\u76EE\u5F55 [{0}]
\u88AB\u5220\u9664
-ActionCopyFiles.Log.FileOverwrite=\u6587\u4EF6[{0}] \u88AB\u8986\u76D6
ActionCopyFiles.Log.FolderCopied=\u76EE\u5F55 [{0}] \u88AB\u590D\u5236\u5230
[{1}]
ActionCopyFiles.Log.FolderExists=\u76EE\u5F55 [{0}] \u5B58\u5728\!
-ActionCopyFiles.Log.FolderOverwrite=\u76EE\u5F55 [{0}] \u88AB\u8986\u76D6
-ActionCopyFiles.Log.IgnoringRow=\u5FFD\u7565\u4E86\u6E90\u6216\u76EE\u6807\u662F\u7A7A\u7684\u884C,\u6E90\u6587\u4EF6/\u76EE\u5F55\:
[{0}], \u76EE\u6807\u6587\u4EF6/\u76EE\u5F55\: [{1}], \u901A\u914D\u7B26\:
[{2}]
-ActionCopyFiles.Log.ProcessingRow=\u6B63\u5728\u5904\u7406\u884C,
\u6E90\u6587\u4EF6/\u76EE\u5F55\: [{0}] ...
\u76EE\u6807\u6587\u4EF6/\u76EE\u5F55 \: [{1}]... \u901A\u914D\u7B26 \: [{2}]
ActionCopyFiles.Log.Starting=\u5F00\u59CB...
ActionCopyFiles.Name=\u590D\u5236\u6587\u4EF6
ActionCopyFiles.Name.Default=\u590D\u5236\u6587\u4EF6
diff --git a/plugins/actions/copyfiles/src/main/samples/actions/copy-files.hwf
b/plugins/actions/copyfiles/src/main/samples/actions/copy-files.hwf
index 107c769e1e..844bc6a972 100644
--- a/plugins/actions/copyfiles/src/main/samples/actions/copy-files.hwf
+++ b/plugins/actions/copyfiles/src/main/samples/actions/copy-files.hwf
@@ -64,10 +64,8 @@ limitations under the License.
<create_destination_folder>Y</create_destination_folder>
<fields>
<field>
-
<source_filefolder>EMPTY_SOURCE_URL-0-${PROJECT_HOME}</source_filefolder>
-
<source_configuration_name>STATIC-SOURCE-FILE-0</source_configuration_name>
-
<destination_filefolder>EMPTY_DEST_URL-0-${PROJECT_HOME}/tmp-copy</destination_filefolder>
-
<destination_configuration_name>STATIC-DEST-FILE-0</destination_configuration_name>
+ <source_filefolder>${PROJECT_HOME}</source_filefolder>
+
<destination_filefolder>${PROJECT_HOME}/tmp-copy</destination_filefolder>
<wildcard/>
</field>
</fields>
diff --git
a/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLoadSaveTest.java
b/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLoadSaveTest.java
index 76e3796724..6abc59b782 100644
---
a/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLoadSaveTest.java
+++
b/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLoadSaveTest.java
@@ -16,19 +16,51 @@
*/
package org.apache.hop.workflow.actions.copyfiles;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
-import
org.apache.hop.pipeline.transforms.loadsave.validator.ArrayLoadSaveValidator;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.exception.HopXmlException;
+import org.apache.hop.core.util.Utils;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
import
org.apache.hop.pipeline.transforms.loadsave.validator.IFieldLoadSaveValidator;
+import
org.apache.hop.pipeline.transforms.loadsave.validator.ListLoadSaveValidator;
import
org.apache.hop.pipeline.transforms.loadsave.validator.StringLoadSaveValidator;
+import org.apache.hop.workflow.action.ActionMeta;
+import org.apache.hop.workflow.action.ActionSerializationTestUtil;
import
org.apache.hop.workflow.action.loadsave.WorkflowActionLoadSaveTestSupport;
+import org.junit.jupiter.api.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
class WorkflowActionCopyFilesLoadSaveTest
extends WorkflowActionLoadSaveTestSupport<ActionCopyFiles> {
+ private static class CopyFilesItemValidator implements
IFieldLoadSaveValidator<CopyFilesItem> {
+ private final StringLoadSaveValidator strings = new
StringLoadSaveValidator();
+
+ @Override
+ public CopyFilesItem getTestObject() {
+ return new CopyFilesItem(
+ strings.getTestObject(), strings.getTestObject(),
strings.getTestObject());
+ }
+
+ @Override
+ public boolean validateTestObject(CopyFilesItem original, Object actual)
throws HopException {
+ return actual instanceof CopyFilesItem c && original.equals(c);
+ }
+ }
+
@Override
protected Class<ActionCopyFiles> getActionClass() {
return ActionCopyFiles.class;
@@ -45,9 +77,7 @@ class WorkflowActionCopyFilesLoadSaveTest
"addResultFilenames",
"destinationIsAFile",
"createDestinationFolder",
- "sourceFileFolder",
- "destinationFileFolder",
- "wildcard");
+ "fileRows");
}
@Override
@@ -60,7 +90,8 @@ class WorkflowActionCopyFilesLoadSaveTest
"removeSourceFiles", "isRemoveSourceFiles",
"addResultFilenames", "isAddResultFilenames",
"destinationIsAFile", "isDestinationIsAFile",
- "createDestinationFolder", "isCreateDestinationFolder");
+ "createDestinationFolder", "isCreateDestinationFolder",
+ "fileRows", "getFileRows");
}
@Override
@@ -73,21 +104,123 @@ class WorkflowActionCopyFilesLoadSaveTest
"removeSourceFiles", "setRemoveSourceFiles",
"addResultFilenames", "setAddResultFilenames",
"destinationIsAFile", "setDestinationIsAFile",
- "createDestinationFolder", "setCreateDestinationFolder");
+ "createDestinationFolder", "setCreateDestinationFolder",
+ "fileRows", "setFileRows");
}
@Override
protected Map<String, IFieldLoadSaveValidator<?>>
createAttributeValidatorsMap() {
- int fileArraySize = new Random().nextInt(5) + 1;
+ int rowCount = new Random().nextInt(5) + 1;
Map<String, IFieldLoadSaveValidator<?>> attrMap = new HashMap<>();
- attrMap.put(
- "sourceFileFolder",
- new ArrayLoadSaveValidator<>(new StringLoadSaveValidator(),
fileArraySize));
- attrMap.put(
- "destinationFileFolder",
- new ArrayLoadSaveValidator<>(new StringLoadSaveValidator(),
fileArraySize));
- attrMap.put(
- "wildcard", new ArrayLoadSaveValidator<>(new
StringLoadSaveValidator(), fileArraySize));
+ attrMap.put("fileRows", new ListLoadSaveValidator<>(new
CopyFilesItemValidator(), rowCount));
return attrMap;
}
+
+ private static ActionCopyFiles loadCopyFilesFromXmlResource(String resource)
+ throws HopXmlException {
+ InputStream in =
WorkflowActionCopyFilesLoadSaveTest.class.getResourceAsStream(resource);
+ assertNotNull(in, resource);
+ Document document = XmlHandler.loadXmlFile(in);
+ Node node = XmlHandler.getSubNode(document, ActionMeta.XML_TAG);
+ ActionCopyFiles action = new ActionCopyFiles();
+ action.setPluginId("COPY_FILES");
+ action.loadXml(node, new MemoryMetadataProvider(), new Variables());
+ return action;
+ }
+
+ @Test
+ void testActionXmlSerialization() throws Exception {
+ ActionCopyFiles action =
loadCopyFilesFromXmlResource("/copy-files-action.xml");
+
+ assertFalse(action.isCopyEmptyFolders());
+ assertTrue(action.isArgFromPrevious());
+ assertTrue(action.isOverwriteFiles());
+ assertTrue(action.isIncludeSubFolders());
+ assertTrue(action.isRemoveSourceFiles());
+ assertTrue(action.isAddResultFilenames());
+ assertTrue(action.isDestinationIsAFile());
+ assertTrue(action.isCreateDestinationFolder());
+
+ assertEquals(2, action.getFileRows().size());
+ assertEquals("${SOURCE_DIR}/file1.txt",
action.getFileRows().get(0).getSourceFileFolder());
+ assertEquals("/data/in",
action.getFileRows().get(1).getSourceFileFolder());
+ assertEquals("${DEST_DIR}/out1.txt",
action.getFileRows().get(0).getDestinationFileFolder());
+ assertEquals("/data/out",
action.getFileRows().get(1).getDestinationFileFolder());
+ assertEquals("^file1\\.txt$", action.getFileRows().get(0).getWildcard());
+ assertTrue(Utils.isEmpty(action.getFileRows().get(1).getWildcard()));
+ }
+
+ @Test
+ void testCloneFromActionXml() throws Exception {
+ ActionCopyFiles action =
loadCopyFilesFromXmlResource("/copy-files-action.xml");
+
+ ActionCopyFiles clone = (ActionCopyFiles) action.clone();
+
+ assertEquals(clone.getFileRows(), action.getFileRows());
+ assertEquals(clone.isCopyEmptyFolders(), action.isCopyEmptyFolders());
+ assertEquals(clone.isArgFromPrevious(), action.isArgFromPrevious());
+ assertEquals(clone.isDestinationIsAFile(), action.isDestinationIsAFile());
+ }
+
+ @Test
+ void testActionXmlRoundTripThroughGetXml() throws Exception {
+ ActionCopyFiles action =
loadCopyFilesFromXmlResource("/copy-files-action.xml");
+ String wrapped = ActionSerializationTestUtil.getXml(action);
+ Document doc = XmlHandler.loadXmlString(wrapped);
+ Node node = XmlHandler.getSubNode(doc, ActionMeta.XML_TAG);
+ ActionCopyFiles again = new ActionCopyFiles();
+ again.setPluginId("COPY_FILES");
+ again.loadXml(node, new MemoryMetadataProvider(), new Variables());
+ assertEquals(action.getXml(), again.getXml());
+ }
+
+ @Test
+ void loadsLegacyFieldXmlWithWizardPrefixesAndConfigurationTags() throws
Exception {
+ String xml =
+ "<?xml version=\"1.0\"
encoding=\"UTF-8\"?><action><name>t</name><description/><type>COPY_FILES</type><attributes/>"
+ +
"<copy_empty_folders>Y</copy_empty_folders><arg_from_previous>N</arg_from_previous>"
+ +
"<overwrite_files>N</overwrite_files><include_subfolders>N</include_subfolders>"
+ +
"<remove_source_files>N</remove_source_files><add_result_filesname>N</add_result_filesname>"
+ +
"<destination_is_a_file>N</destination_is_a_file><create_destination_folder>Y</create_destination_folder>"
+ + "<fields><field>"
+ + "<source_filefolder>EMPTY_SOURCE_URL-0-${A}</source_filefolder>"
+ +
"<source_configuration_name>STATIC-SOURCE-FILE-0</source_configuration_name>"
+ +
"<destination_filefolder>EMPTY_DEST_URL-0-${A}/b</destination_filefolder>"
+ +
"<destination_configuration_name>STATIC-DEST-FILE-0</destination_configuration_name>"
+ + "<wildcard>x</wildcard>"
+ + "</field></fields></action>";
+ Document doc = XmlHandler.loadXmlString(xml);
+ Node node = XmlHandler.getSubNode(doc, ActionMeta.XML_TAG);
+ ActionCopyFiles a = new ActionCopyFiles();
+ a.setPluginId("COPY_FILES");
+ a.loadXml(node, new MemoryMetadataProvider(), new Variables());
+ assertEquals("${A}", a.getFileRows().get(0).getSourceFileFolder());
+ assertEquals("${A}/b", a.getFileRows().get(0).getDestinationFileFolder());
+ assertEquals("x", a.getFileRows().get(0).getWildcard());
+ }
+
+ @Test
+ void legacyRowPrefixesAreStrippedOnLoadAndOmittedOnReserialize() throws
Exception {
+ ActionCopyFiles a = new ActionCopyFiles();
+ a.setPluginId("COPY_FILES");
+ a.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ ActionCopyFiles.SOURCE_URL + "0-my/src",
+ ActionCopyFiles.DEST_URL + "0-my/dest",
+ ".*")));
+ String wrapped = ActionSerializationTestUtil.getXml(a);
+ Document doc = XmlHandler.loadXmlString(wrapped);
+ Node node = XmlHandler.getSubNode(doc, ActionMeta.XML_TAG);
+ ActionCopyFiles loaded = new ActionCopyFiles();
+ loaded.setPluginId("COPY_FILES");
+ loaded.loadXml(node, new MemoryMetadataProvider(), new Variables());
+ assertEquals("my/src", loaded.getFileRows().get(0).getSourceFileFolder());
+ assertEquals("my/dest",
loaded.getFileRows().get(0).getDestinationFileFolder());
+ String out = loaded.getXml();
+ assertFalse(out.contains(ActionCopyFiles.SOURCE_URL));
+ assertFalse(out.contains(ActionCopyFiles.DEST_URL));
+ assertFalse(out.contains("source_configuration_name"));
+ assertFalse(out.contains("destination_configuration_name"));
+ }
}
diff --git
a/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLocalTest.java
b/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLocalTest.java
new file mode 100644
index 0000000000..26e62b9447
--- /dev/null
+++
b/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesLocalTest.java
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.hop.workflow.actions.copyfiles;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.Result;
+import org.apache.hop.core.RowMetaAndData;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.logging.HopLogStore;
+import org.apache.hop.core.logging.LogLevel;
+import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.row.value.ValueMetaString;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
+import org.apache.hop.workflow.WorkflowMeta;
+import org.apache.hop.workflow.engine.IWorkflowEngine;
+import org.apache.hop.workflow.engines.local.LocalWorkflowEngine;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.w3c.dom.Node;
+
+/**
+ * Integration-style tests using a real filesystem and full {@link
ActionCopyFiles#execute} path.
+ */
+class WorkflowActionCopyFilesLocalTest {
+
+ @TempDir Path tempDir;
+
+ private ActionCopyFiles action;
+ private IWorkflowEngine<WorkflowMeta> workflow;
+
+ @BeforeAll
+ static void initLog() {
+ HopLogStore.init();
+ }
+
+ @BeforeEach
+ void setUp() {
+ workflow = new LocalWorkflowEngine(new WorkflowMeta());
+ action = new ActionCopyFiles();
+ action.setParentWorkflow(workflow);
+ action.setParentWorkflowMeta(mock(WorkflowMeta.class));
+ action.setLogLevel(LogLevel.ERROR);
+ }
+
+ @Test
+ void copyFileIntoExistingFolder() throws Exception {
+ Path srcFile = tempDir.resolve("src/hello.txt");
+ Files.createDirectories(srcFile.getParent());
+ Files.writeString(srcFile, "hello", StandardCharsets.UTF_8);
+ Path destDir = tempDir.resolve("dest");
+ Files.createDirectories(destDir);
+
+ action.setDestinationIsAFile(false);
+ action.setCreateDestinationFolder(false);
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ srcFile.toAbsolutePath().toString(),
destDir.toAbsolutePath().toString(), "")));
+
+ Result result = action.execute(new Result(), 0);
+
+ assertTrue(result.isResult(), "copy should succeed");
+ assertEquals(0, result.getNrErrors());
+ Path out = destDir.resolve("hello.txt");
+ assertTrue(Files.isRegularFile(out));
+ assertEquals("hello", Files.readString(out, StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void copyFileToFileCreatesParentWhenConfigured() throws Exception {
+ Path src = tempDir.resolve("source/a.txt");
+ Files.createDirectories(src.getParent());
+ Files.writeString(src, "content", StandardCharsets.UTF_8);
+ Path destFile = tempDir.resolve("nested/out/b.txt");
+
+ action.setDestinationIsAFile(true);
+ action.setCreateDestinationFolder(true);
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ src.toAbsolutePath().toString(),
destFile.toAbsolutePath().toString(), "")));
+
+ Result result = action.execute(new Result(), 0);
+
+ assertTrue(result.isResult());
+ assertTrue(Files.isRegularFile(destFile));
+ assertEquals("content", Files.readString(destFile,
StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void failsWhenDestinationParentMissingAndCreateDisabled() throws Exception {
+ Path src = tempDir.resolve("only.txt");
+ Files.writeString(src, "x", StandardCharsets.UTF_8);
+ Path destFile = tempDir.resolve("noSuchParent/child/c.txt");
+
+ action.setDestinationIsAFile(true);
+ action.setCreateDestinationFolder(false);
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ src.toAbsolutePath().toString(),
destFile.toAbsolutePath().toString(), "")));
+
+ Result result = action.execute(new Result(), 0);
+
+ assertFalse(result.isResult());
+ assertEquals(1, result.getNrErrors());
+ }
+
+ @Test
+ void folderSourceWithDestinationIsFileLogsError() throws Exception {
+ Path srcDir = tempDir.resolve("folderSrc");
+ Files.createDirectories(srcDir);
+ Files.writeString(srcDir.resolve("f.txt"), "in", StandardCharsets.UTF_8);
+ Path destFile = tempDir.resolve("destAsFile.txt");
+
+ action.setDestinationIsAFile(true);
+ action.setCreateDestinationFolder(true);
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ srcDir.toAbsolutePath().toString(),
destFile.toAbsolutePath().toString(), "")));
+
+ Result result = action.execute(new Result(), 0);
+
+ assertFalse(result.isResult());
+ assertEquals(1, result.getNrErrors());
+ }
+
+ @Test
+ void copyFolderToFolderCopiesFileInRoot() throws Exception {
+ Path srcRoot = tempDir.resolve("srcTree");
+ Files.createDirectories(srcRoot);
+ Files.writeString(srcRoot.resolve("doc.txt"), "doc",
StandardCharsets.UTF_8);
+ Path destRoot = tempDir.resolve("destTree");
+ Files.createDirectories(destRoot);
+
+ action.setDestinationIsAFile(false);
+ action.setIncludeSubFolders(false);
+ action.setCreateDestinationFolder(false);
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ srcRoot.toAbsolutePath().toString(),
destRoot.toAbsolutePath().toString(), "")));
+
+ Result result = action.execute(new Result(), 0);
+
+ assertTrue(result.isResult());
+ Path copied = destRoot.resolve("doc.txt");
+ assertTrue(Files.isRegularFile(copied));
+ assertEquals("doc", Files.readString(copied, StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void removeSourceFilesDeletesSourceAfterFileToFileCopy() throws Exception {
+ Path srcFile = tempDir.resolve("moveSrc/x.txt");
+ Files.createDirectories(srcFile.getParent());
+ Files.writeString(srcFile, "gone", StandardCharsets.UTF_8);
+ Path destFile = tempDir.resolve("moveDest/y.txt");
+ Files.createDirectories(destFile.getParent());
+
+ action.setDestinationIsAFile(true);
+ action.setCreateDestinationFolder(false);
+ action.setRemoveSourceFiles(true);
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ srcFile.toAbsolutePath().toString(),
destFile.toAbsolutePath().toString(), "")));
+
+ Result result = action.execute(new Result(), 0);
+
+ assertTrue(result.isResult());
+ assertFalse(Files.exists(srcFile), "source file should be removed");
+ assertTrue(Files.isRegularFile(destFile));
+ assertEquals("gone", Files.readString(destFile, StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void argFromPreviousUsesResultRows() throws Exception {
+ Path srcFile = tempDir.resolve("prev/a.txt");
+ Files.createDirectories(srcFile.getParent());
+ Files.writeString(srcFile, "row", StandardCharsets.UTF_8);
+ Path destDir = tempDir.resolve("prevDest");
+ Files.createDirectories(destDir);
+
+ IRowMeta rowMeta = new RowMeta();
+ rowMeta.addValueMeta(new ValueMetaString("source"));
+ rowMeta.addValueMeta(new ValueMetaString("dest"));
+ rowMeta.addValueMeta(new ValueMetaString("wildcard"));
+ RowMetaAndData row =
+ new RowMetaAndData(
+ rowMeta,
+ new Object[] {
+ srcFile.toAbsolutePath().toString(),
destDir.toAbsolutePath().toString(), ""
+ });
+
+ Result previous = new Result();
+ List<RowMetaAndData> rows = new ArrayList<>();
+ rows.add(row);
+ previous.setRows(rows);
+
+ action.setArgFromPrevious(true);
+ action.setDestinationIsAFile(false);
+ action.setFileRows(List.of());
+
+ Result result = action.execute(previous, 0);
+
+ assertTrue(result.isResult());
+ assertTrue(Files.isRegularFile(destDir.resolve("a.txt")));
+ }
+
+ @Test
+ void normalizeLegacyVfsPathsStripsRowIndexedPrefixes() {
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ ActionCopyFiles.SOURCE_URL + "0-alpha",
ActionCopyFiles.DEST_URL + "0-beta", "w")));
+ action.normalizeLegacyVfsPaths();
+ assertEquals("alpha", action.getFileRows().get(0).getSourceFileFolder());
+ assertEquals("beta",
action.getFileRows().get(0).getDestinationFileFolder());
+ assertEquals("w", action.getFileRows().get(0).getWildcard());
+ }
+
+ @Test
+ void convertLegacyXmlDelegatesToNormalize() throws HopException {
+ action.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ ActionCopyFiles.SOURCE_URL + "0-q", ActionCopyFiles.DEST_URL +
"0-r", null)));
+ action.convertLegacyXml(mock(Node.class));
+ assertEquals("q", action.getFileRows().get(0).getSourceFileFolder());
+ assertEquals("r", action.getFileRows().get(0).getDestinationFileFolder());
+ }
+
+ @Test
+ void checkPassesWhenSourceExists() throws Exception {
+ Path src = tempDir.resolve("check.txt");
+ Files.writeString(src, "ok", StandardCharsets.UTF_8);
+ action.setFileRows(
+ List.of(new CopyFilesItem(src.toAbsolutePath().toString(),
tempDir.toString(), "")));
+
+ List<org.apache.hop.core.ICheckResult> remarks = new ArrayList<>();
+ action.check(remarks, new WorkflowMeta(), new Variables(), new
MemoryMetadataProvider());
+
+ assertTrue(
+ remarks.stream()
+ .noneMatch(r -> r.getType() ==
org.apache.hop.core.ICheckResult.TYPE_RESULT_ERROR),
+ remarks::toString);
+ }
+
+ @Test
+ void isEvaluationTrue() {
+ assertTrue(new ActionCopyFiles().isEvaluation());
+ }
+}
diff --git
a/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesTest.java
b/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesTest.java
index 3df55d729a..c496d88184 100644
---
a/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesTest.java
+++
b/plugins/actions/copyfiles/src/test/java/org/apache/hop/workflow/actions/copyfiles/WorkflowActionCopyFilesTest.java
@@ -27,10 +27,13 @@ import static org.mockito.Mockito.verify;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.hop.core.Result;
import org.apache.hop.core.logging.HopLogStore;
import org.apache.hop.core.variables.Variables;
import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
import org.apache.hop.workflow.Workflow;
import org.apache.hop.workflow.WorkflowMeta;
import org.apache.hop.workflow.engine.IWorkflowEngine;
@@ -55,11 +58,17 @@ class WorkflowActionCopyFilesTest {
entry = spy(entry);
}
+ private static List<CopyFilesItem> rows(String[] src, String[] dst, String[]
wild) {
+ List<CopyFilesItem> list = new ArrayList<>(src.length);
+ for (int i = 0; i < src.length; i++) {
+ list.add(new CopyFilesItem(src[i], dst[i], wild[i]));
+ }
+ return list;
+ }
+
@Test
void fileNotCopied() throws Exception {
- entry.sourceFileFolder = new String[] {EMPTY};
- entry.destinationFileFolder = new String[] {EMPTY};
- entry.wildcard = new String[] {EMPTY};
+ entry.setFileRows(rows(new String[] {EMPTY}, new String[] {EMPTY}, new
String[] {EMPTY}));
entry.execute(new Result(), 0);
@@ -73,16 +82,14 @@ class WorkflowActionCopyFilesTest {
String srcPath = "path/to/file";
String destPath = "path/to/dir";
- entry.sourceFileFolder = new String[] {srcPath};
- entry.destinationFileFolder = new String[] {destPath};
- entry.wildcard = new String[] {EMPTY};
+ entry.setFileRows(rows(new String[] {srcPath}, new String[] {destPath},
new String[] {EMPTY}));
Result result = entry.execute(new Result(), 0);
verify(entry)
.processFileFolder(
anyString(), anyString(), anyString(), any(Workflow.class),
any(Result.class));
- verify(entry, atLeast(1)).preprocessfilefilder(any(String[].class));
+ verify(entry, atLeast(1)).resolve(anyString());
Assertions.assertFalse(result.isResult());
Assertions.assertEquals(1, result.getNrErrors());
}
@@ -92,9 +99,7 @@ class WorkflowActionCopyFilesTest {
String[] srcPath = new String[] {"path1", "path2", "path3"};
String[] destPath = new String[] {"dest1", "dest2", "dest3"};
- entry.sourceFileFolder = srcPath;
- entry.destinationFileFolder = destPath;
- entry.wildcard = new String[] {EMPTY, EMPTY, EMPTY};
+ entry.setFileRows(rows(srcPath, destPath, new String[] {EMPTY, EMPTY,
EMPTY}));
Result result = entry.execute(new Result(), 0);
@@ -107,23 +112,21 @@ class WorkflowActionCopyFilesTest {
@Test
void saveLoad() throws Exception {
- String[] srcPath = new String[] {"EMPTY_SOURCE_URL-0-"};
- String[] destPath = new String[] {"EMPTY_DEST_URL-0-"};
-
- entry.sourceFileFolder = srcPath;
- entry.destinationFileFolder = destPath;
- entry.wildcard = new String[] {EMPTY};
-
- String xml = "<entry>" + entry.getXml() + "</entry>";
- Assertions.assertTrue(xml.contains(srcPath[0]));
- Assertions.assertTrue(xml.contains(destPath[0]));
- ActionCopyFiles loadedentry = new ActionCopyFiles();
+ entry.setPluginId("COPY_FILES");
+ entry.setFileRows(
+ List.of(
+ new CopyFilesItem(
+ ActionCopyFiles.SOURCE_URL + "0-", ActionCopyFiles.DEST_URL +
"0-", EMPTY)));
+
+ String xml = "<transform>" + entry.getXml() + "</transform>";
+ ActionCopyFiles loaded = new ActionCopyFiles();
+ loaded.setPluginId("COPY_FILES");
InputStream is = new ByteArrayInputStream(xml.getBytes());
- loadedentry.loadXml(
- XmlHandler.getSubNode(XmlHandler.loadXmlFile(is, null, false, false),
"entry"),
- null,
+ loaded.loadXml(
+ XmlHandler.getSubNode(XmlHandler.loadXmlFile(is, null, false, false),
"transform"),
+ new MemoryMetadataProvider(),
new Variables());
- Assertions.assertEquals(loadedentry.destinationFileFolder[0], destPath[0]);
- Assertions.assertEquals(loadedentry.sourceFileFolder[0], srcPath[0]);
+ Assertions.assertEquals("",
loaded.getFileRows().get(0).getDestinationFileFolder());
+ Assertions.assertEquals("",
loaded.getFileRows().get(0).getSourceFileFolder());
}
}
diff --git a/plugins/actions/copyfiles/src/test/resources/copy-files-action.xml
b/plugins/actions/copyfiles/src/test/resources/copy-files-action.xml
new file mode 100644
index 0000000000..578ccab6f2
--- /dev/null
+++ b/plugins/actions/copyfiles/src/test/resources/copy-files-action.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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.
+ ~
+ -->
+<action>
+ <name>Copy files</name>
+ <description>copy test</description>
+ <type>COPY_FILES</type>
+ <attributes/>
+ <copy_empty_folders>N</copy_empty_folders>
+ <arg_from_previous>Y</arg_from_previous>
+ <overwrite_files>Y</overwrite_files>
+ <include_subfolders>Y</include_subfolders>
+ <remove_source_files>Y</remove_source_files>
+ <add_result_filesname>Y</add_result_filesname>
+ <destination_is_a_file>Y</destination_is_a_file>
+ <create_destination_folder>Y</create_destination_folder>
+ <fields>
+ <field>
+ <source_filefolder>${SOURCE_DIR}/file1.txt</source_filefolder>
+
<destination_filefolder>${DEST_DIR}/out1.txt</destination_filefolder>
+ <wildcard>^file1\.txt$</wildcard>
+ </field>
+ <field>
+ <source_filefolder>/data/in</source_filefolder>
+ <destination_filefolder>/data/out</destination_filefolder>
+ <wildcard/>
+ </field>
+ </fields>
+ <parallel>N</parallel>
+ <xloc>192</xloc>
+ <yloc>96</yloc>
+ <attributes_hac/>
+</action>