19
19
20
20
import com .google .common .collect .ArrayListMultimap ;
21
21
import com .google .common .collect .Multimap ;
22
- import java .io . IOException ;
22
+ import java .util . ArrayList ;
23
23
import java .util .List ;
24
24
import java .util .Map ;
25
25
import java .util .regex .Matcher ;
26
26
import java .util .regex .Pattern ;
27
+ import lombok .Getter ;
28
+ import lombok .Setter ;
27
29
import org .apache .commons .vfs2 .FileObject ;
28
30
import org .apache .commons .vfs2 .FileSelectInfo ;
29
31
import org .apache .commons .vfs2 .FileSelector ;
30
32
import org .apache .commons .vfs2 .FileType ;
31
- import org .apache .hop .core .Const ;
32
33
import org .apache .hop .core .ICheckResult ;
33
34
import org .apache .hop .core .Result ;
34
35
import org .apache .hop .core .RowMetaAndData ;
35
36
import org .apache .hop .core .annotations .Action ;
36
37
import org .apache .hop .core .exception .HopException ;
37
38
import org .apache .hop .core .exception .HopValueException ;
38
- import org .apache .hop .core .exception .HopXmlException ;
39
39
import org .apache .hop .core .util .Utils ;
40
40
import org .apache .hop .core .variables .IVariables ;
41
41
import org .apache .hop .core .vfs .HopVfs ;
42
- import org .apache .hop .core .xml .XmlHandler ;
43
42
import org .apache .hop .i18n .BaseMessages ;
43
+ import org .apache .hop .metadata .api .HopMetadataProperty ;
44
44
import org .apache .hop .metadata .api .IHopMetadataProvider ;
45
45
import org .apache .hop .resource .ResourceEntry ;
46
46
import org .apache .hop .resource .ResourceEntry .ResourceType ;
47
47
import org .apache .hop .resource .ResourceReference ;
48
48
import org .apache .hop .workflow .WorkflowMeta ;
49
49
import org .apache .hop .workflow .action .ActionBase ;
50
- import org .apache .hop .workflow .action .IAction ;
51
50
import org .apache .hop .workflow .action .validator .AbstractFileValidator ;
52
51
import org .apache .hop .workflow .action .validator .ActionValidatorUtils ;
53
52
import org .apache .hop .workflow .action .validator .AndValidator ;
54
53
import org .apache .hop .workflow .action .validator .ValidatorContext ;
55
54
import org .apache .hop .workflow .engine .IWorkflowEngine ;
56
- import org .w3c .dom .Node ;
57
55
58
56
/** This defines a 'delete files' action. */
57
+ @ Setter
58
+ @ Getter
59
59
@ Action (
60
60
id = "DELETE_FILES" ,
61
61
name = "i18n::ActionDeleteFiles.Name" ,
64
64
categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.FileManagement" ,
65
65
keywords = "i18n::ActionDeleteFiles.keyword" ,
66
66
documentationUrl = "/workflow/actions/deletefiles.html" )
67
- public class ActionDeleteFiles extends ActionBase implements Cloneable , IAction {
67
+ public class ActionDeleteFiles extends ActionBase {
68
68
69
69
private static final Class <?> PKG = ActionDeleteFiles .class ;
70
70
71
+ @ HopMetadataProperty (key = "arg_from_previous" )
71
72
private boolean argFromPrevious ;
72
73
74
+ @ HopMetadataProperty (key = "include_subfolders" )
73
75
private boolean includeSubfolders ;
74
76
75
- private String [] arguments ;
76
-
77
- private String [] filemasks ;
77
+ @ HopMetadataProperty (groupKey = "fields" , key = "field" )
78
+ private List <FileItem > fileItems ;
78
79
79
80
public ActionDeleteFiles (String workflowName ) {
80
81
super (workflowName , "" );
81
82
argFromPrevious = false ;
82
- arguments = null ;
83
-
84
83
includeSubfolders = false ;
84
+ fileItems = List .of ();
85
85
}
86
86
87
87
public ActionDeleteFiles () {
88
88
this ("" );
89
89
}
90
90
91
- public void allocate (int numberOfFields ) {
92
- arguments = new String [numberOfFields ];
93
- filemasks = new String [numberOfFields ];
91
+ public ActionDeleteFiles (ActionDeleteFiles other ) {
92
+ super (other .getName (), other .getDescription (), other .getPluginId ());
93
+ this .argFromPrevious = other .argFromPrevious ;
94
+ this .includeSubfolders = other .includeSubfolders ;
95
+ this .fileItems = new ArrayList <>(other .fileItems );
94
96
}
95
97
96
98
@ Override
97
99
public Object clone () {
98
- ActionDeleteFiles action = (ActionDeleteFiles ) super .clone ();
99
- if (arguments != null ) {
100
- int nrFields = arguments .length ;
101
- action .allocate (nrFields );
102
- System .arraycopy (arguments , 0 , action .arguments , 0 , nrFields );
103
- System .arraycopy (filemasks , 0 , action .filemasks , 0 , nrFields );
104
- }
105
- return action ;
106
- }
107
-
108
- @ Override
109
- public String getXml () {
110
- StringBuilder retval = new StringBuilder (300 );
111
-
112
- retval .append (super .getXml ());
113
- retval .append (" " ).append (XmlHandler .addTagValue ("arg_from_previous" , argFromPrevious ));
114
- retval .append (" " ).append (XmlHandler .addTagValue ("include_subfolders" , includeSubfolders ));
115
-
116
- retval .append (" <fields>" ).append (Const .CR );
117
- if (arguments != null ) {
118
- for (int i = 0 ; i < arguments .length ; i ++) {
119
- retval .append (" <field>" ).append (Const .CR );
120
- retval .append (" " ).append (XmlHandler .addTagValue ("name" , arguments [i ]));
121
- retval .append (" " ).append (XmlHandler .addTagValue ("filemask" , filemasks [i ]));
122
- retval .append (" </field>" ).append (Const .CR );
123
- }
124
- }
125
- retval .append (" </fields>" ).append (Const .CR );
126
-
127
- return retval .toString ();
128
- }
129
-
130
- @ Override
131
- public void loadXml (Node entrynode , IHopMetadataProvider metadataProvider , IVariables variables )
132
- throws HopXmlException {
133
- try {
134
- super .loadXml (entrynode );
135
- argFromPrevious =
136
- "Y" .equalsIgnoreCase (XmlHandler .getTagValue (entrynode , "arg_from_previous" ));
137
- includeSubfolders =
138
- "Y" .equalsIgnoreCase (XmlHandler .getTagValue (entrynode , "include_subfolders" ));
139
-
140
- Node fields = XmlHandler .getSubNode (entrynode , "fields" );
141
-
142
- int numberOfFields = XmlHandler .countNodes (fields , "field" );
143
- allocate (numberOfFields );
144
-
145
- for (int i = 0 ; i < numberOfFields ; i ++) {
146
- Node fnode = XmlHandler .getSubNodeByNr (fields , "field" , i );
147
-
148
- arguments [i ] = XmlHandler .getTagValue (fnode , "name" );
149
- filemasks [i ] = XmlHandler .getTagValue (fnode , "filemask" );
150
- }
151
- } catch (HopXmlException xe ) {
152
- throw new HopXmlException (
153
- BaseMessages .getString (PKG , "ActionDeleteFiles.UnableToLoadFromXml" ), xe );
154
- }
100
+ return new ActionDeleteFiles (this );
155
101
}
156
102
157
103
@ Override
@@ -170,7 +116,7 @@ public Result execute(Result result, int nr) throws HopException {
170
116
String .valueOf ((resultRows != null ? resultRows .size () : 0 ))));
171
117
}
172
118
173
- Multimap <String , String > pathToMaskMap = populateDataForJobExecution (resultRows );
119
+ Multimap <String , String > pathToMaskMap = populateDataForWorkflowExecution (resultRows );
174
120
175
121
for (Map .Entry <String , String > pathToMask : pathToMaskMap .entries ()) {
176
122
final String filePath = resolve (pathToMask .getKey ());
@@ -211,13 +157,13 @@ public Result execute(Result result, int nr) throws HopException {
211
157
* obtained in two ways: 1. As an argument of a current action 2. As a table, that comes as a
212
158
* result of execution previous workflow/pipeline.
213
159
*
214
- * <p>As the logic of processing this data is the same for both of this cases, we first populate
160
+ * <p>As the logic of processing this data is the same for both of these cases, we first populate
215
161
* this data (in this method) and then process it.
216
162
*
217
163
* <p>We are using guava multimap here, because if allows key duplication and there could be a
218
164
* situation where two paths to one folder with different wildcards are provided.
219
165
*/
220
- private Multimap <String , String > populateDataForJobExecution (
166
+ private Multimap <String , String > populateDataForWorkflowExecution (
221
167
List <RowMetaAndData > rowsFromPreviousMeta ) throws HopValueException {
222
168
Multimap <String , String > pathToMaskMap = ArrayListMultimap .create ();
223
169
if (argFromPrevious && rowsFromPreviousMeta != null ) {
@@ -240,14 +186,14 @@ private Multimap<String, String> populateDataForJobExecution(
240
186
241
187
pathToMaskMap .put (pathToFile , fileMask );
242
188
}
243
- } else if (arguments != null ) {
244
- for (int i = 0 ; i < arguments . length ; i ++ ) {
189
+ } else if (fileItems != null && ! fileItems . isEmpty () ) {
190
+ for (FileItem item : fileItems ) {
245
191
if (isDetailed ()) {
246
192
logDetailed (
247
193
BaseMessages .getString (
248
- PKG , "ActionDeleteFiles.ProcessingArg" , arguments [ i ], filemasks [ i ] ));
194
+ PKG , "ActionDeleteFiles.ProcessingArg" , item . getFileName (), item . getFileMask () ));
249
195
}
250
- pathToMaskMap .put (arguments [ i ], filemasks [ i ] );
196
+ pathToMaskMap .put (item . getFileName (), item . getFileMask () );
251
197
}
252
198
}
253
199
@@ -256,10 +202,8 @@ private Multimap<String, String> populateDataForJobExecution(
256
202
257
203
boolean processFile (String path , String wildcard , IWorkflowEngine <WorkflowMeta > parentWorkflow ) {
258
204
boolean isDeleted = false ;
259
- FileObject fileFolder = null ;
260
205
261
- try {
262
- fileFolder = HopVfs .getFileObject (path , getVariables ());
206
+ try (FileObject fileFolder = HopVfs .getFileObject (path , getVariables ())) {
263
207
264
208
if (fileFolder .exists ()) {
265
209
if (fileFolder .getType () == FileType .FOLDER ) {
@@ -303,14 +247,6 @@ boolean processFile(String path, String wildcard, IWorkflowEngine<WorkflowMeta>
303
247
logError (
304
248
BaseMessages .getString (PKG , "ActionDeleteFiles.CouldNotProcess" , path , e .getMessage ()),
305
249
e );
306
- } finally {
307
- if (fileFolder != null ) {
308
- try {
309
- fileFolder .close ();
310
- } catch (IOException ex ) {
311
- // Ignore
312
- }
313
- }
314
250
}
315
251
316
252
return isDeleted ;
@@ -319,32 +255,32 @@ boolean processFile(String path, String wildcard, IWorkflowEngine<WorkflowMeta>
319
255
private class TextFileSelector implements FileSelector {
320
256
String fileWildcard = null ;
321
257
String sourceFolder = null ;
322
- IWorkflowEngine <WorkflowMeta > parentjob ;
258
+ IWorkflowEngine <WorkflowMeta > workflow ;
323
259
324
260
public TextFileSelector (
325
- String sourcefolderin , String filewildcard , IWorkflowEngine <WorkflowMeta > parentWorkflow ) {
261
+ String sourceFolder , String fileWildcard , IWorkflowEngine <WorkflowMeta > workflow ) {
326
262
327
- if (!Utils .isEmpty (sourcefolderin )) {
328
- sourceFolder = sourcefolderin ;
263
+ if (!Utils .isEmpty (sourceFolder )) {
264
+ this . sourceFolder = sourceFolder ;
329
265
}
330
266
331
- if (!Utils .isEmpty (filewildcard )) {
332
- fileWildcard = filewildcard ;
267
+ if (!Utils .isEmpty (fileWildcard )) {
268
+ this . fileWildcard = fileWildcard ;
333
269
}
334
- parentjob = parentWorkflow ;
270
+ this . workflow = workflow ;
335
271
}
336
272
337
273
@ Override
338
274
public boolean includeFile (FileSelectInfo info ) {
339
275
boolean doReturnCode = false ;
340
276
try {
341
277
342
- if (!info .getFile ().toString ().equals (sourceFolder ) && !parentjob .isStopped ()) {
278
+ if (!info .getFile ().toString ().equals (sourceFolder ) && !workflow .isStopped ()) {
343
279
// Pass over the Base folder itself
344
280
String shortFilename = info .getFile ().getName ().getBaseName ();
345
281
346
282
if (!info .getFile ().getParent ().equals (info .getBaseFolder ())) {
347
- // Not in the Base Folder.. Only if include sub folders
283
+ // Not in the Base Folder. Only if include sub folders
348
284
if (includeSubfolders
349
285
&& (info .getFile ().getType () == FileType .FILE )
350
286
&& getFileWildcard (shortFilename , fileWildcard )) {
@@ -370,10 +306,9 @@ && getFileWildcard(shortFilename, fileWildcard)) {
370
306
}
371
307
} catch (Exception e ) {
372
308
logError (
373
- BaseMessages .getString (PKG , "ActionDeleteFiles.Error.Exception.DeleteProcessError" ),
374
309
BaseMessages .getString (
375
310
PKG ,
376
- "JobDeleteFiles .Error.Exception.DeleteProcess " ,
311
+ "ActionDeleteFiles .Error.Exception.DeleteProcessError " ,
377
312
info .getFile ().toString (),
378
313
e .getMessage ()));
379
314
@@ -393,7 +328,7 @@ public boolean traverseDescendents(FileSelectInfo info) {
393
328
*
394
329
* @param selectedfile
395
330
* @param wildcard
396
- * @return True if the selectedfile matches the wildcard
331
+ * @return True if the selected file matches the wildcard
397
332
**********************************************************/
398
333
private boolean getFileWildcard (String selectedfile , String wildcard ) {
399
334
boolean getIt = true ;
@@ -408,10 +343,6 @@ private boolean getFileWildcard(String selectedfile, String wildcard) {
408
343
return getIt ;
409
344
}
410
345
411
- public void setIncludeSubfolders (boolean includeSubfolders ) {
412
- this .includeSubfolders = includeSubfolders ;
413
- }
414
-
415
346
@ Override
416
347
public boolean isEvaluation () {
417
348
return true ;
@@ -423,71 +354,32 @@ public void check(
423
354
WorkflowMeta workflowMeta ,
424
355
IVariables variables ,
425
356
IHopMetadataProvider metadataProvider ) {
426
- boolean isValid =
427
- ActionValidatorUtils .andValidator ()
428
- .validate (
429
- this ,
430
- "arguments" ,
431
- remarks ,
432
- AndValidator .putValidators (ActionValidatorUtils .notNullValidator ()));
433
-
434
- if (!isValid ) {
435
- return ;
436
- }
437
357
438
358
ValidatorContext ctx = new ValidatorContext ();
439
359
AbstractFileValidator .putVariableSpace (ctx , getVariables ());
440
360
AndValidator .putValidators (
441
361
ctx , ActionValidatorUtils .notNullValidator (), ActionValidatorUtils .fileExistsValidator ());
442
362
443
- for (int i = 0 ; i < arguments . length ; i ++ ) {
444
- ActionValidatorUtils .andValidator ().validate (this , "arguments[" + i + "]" , remarks , ctx );
363
+ for (FileItem item : fileItems ) {
364
+ ActionValidatorUtils .andValidator ().validate (this , item . getFileName () , remarks , ctx );
445
365
}
446
366
}
447
367
448
368
@ Override
449
369
public List <ResourceReference > getResourceDependencies (
450
370
IVariables variables , WorkflowMeta workflowMeta ) {
451
371
List <ResourceReference > references = super .getResourceDependencies (variables , workflowMeta );
452
- if (arguments != null ) {
453
- ResourceReference reference = null ;
454
- for (int i = 0 ; i < arguments .length ; i ++) {
455
- String filename = resolve (arguments [i ]);
456
- if (reference == null ) {
457
- reference = new ResourceReference (this );
458
- references .add (reference );
459
- }
460
- reference .getEntries ().add (new ResourceEntry (filename , ResourceType .FILE ));
372
+
373
+ ResourceReference reference = null ;
374
+ for (FileItem item : fileItems ) {
375
+ String filename = resolve (item .getFileName ());
376
+ if (reference == null ) {
377
+ reference = new ResourceReference (this );
378
+ references .add (reference );
461
379
}
380
+ reference .getEntries ().add (new ResourceEntry (filename , ResourceType .FILE ));
462
381
}
463
- return references ;
464
- }
465
-
466
- public void setArguments (String [] arguments ) {
467
- this .arguments = arguments ;
468
- }
469
-
470
- public void setFilemasks (String [] filemasks ) {
471
- this .filemasks = filemasks ;
472
- }
473
-
474
- public void setArgFromPrevious (boolean argFromPrevious ) {
475
- this .argFromPrevious = argFromPrevious ;
476
- }
477
-
478
- public boolean isArgFromPrevious () {
479
- return argFromPrevious ;
480
- }
481
382
482
- public String [] getArguments () {
483
- return arguments ;
484
- }
485
-
486
- public String [] getFilemasks () {
487
- return filemasks ;
488
- }
489
-
490
- public boolean isIncludeSubfolders () {
491
- return includeSubfolders ;
383
+ return references ;
492
384
}
493
385
}
0 commit comments