Skip to content

Commit 55969fc

Browse files
committed
Improved progress reporting for CustomExporter
1 parent 9b5a578 commit 55969fc

File tree

5 files changed

+320
-13
lines changed

5 files changed

+320
-13
lines changed

Java/SuperUtilities/.idea/uiDesigner.xml

Lines changed: 124 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Java/SuperUtilities/src/main/java/com/nuix/superutilities/export/CustomExporter.java

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
import com.nuix.superutilities.SuperUtilities;
99
import com.nuix.superutilities.loadfiles.*;
10+
import com.nuix.superutilities.misc.BoundedProgressInfo;
1011
import com.nuix.superutilities.misc.FormatUtility;
12+
import com.nuix.superutilities.misc.PeriodicGatedConsumer;
1113
import com.nuix.superutilities.misc.PlaceholderResolver;
1214
import com.nuix.superutilities.reporting.SimpleWorksheet;
1315
import com.nuix.superutilities.reporting.SimpleXlsx;
@@ -57,38 +59,48 @@ public class CustomExporter {
5759
private SimpleTextFileWriter errorLog = null;
5860

5961
private boolean exportText = false;
60-
private Map<String, Object> textExportSettings = new HashMap<String, Object>();
62+
private Map<String, Object> textExportSettings = new HashMap<>();
6163
private String textFileNameTemplate = "{export_directory}\\TEXT\\{guid}.txt";
6264

6365
private boolean exportNatives = false;
64-
private Map<String, Object> emailExportSettings = new HashMap<String, Object>();
66+
private Map<String, Object> emailExportSettings = new HashMap<>();
6567
private String nativeFileNameTemplate = "{export_directory}\\NATIVES\\{guid}.{extension}";
6668

6769
private boolean exportPdfs = false;
68-
private Map<String, Object> pdfExportSettings = new HashMap<String, Object>();
70+
private Map<String, Object> pdfExportSettings = new HashMap<>();
6971
private String pdfFileNameTemplate = "{export_directory}\\PDF\\{guid}.pdf";
7072

7173
private boolean exportTiffs = false;
72-
private Map<String, Object> tiffExportSettings = new HashMap<String, Object>();
74+
private Map<String, Object> tiffExportSettings = new HashMap<>();
7375
private String tiffFileNameTemplate = "{export_directory}\\IMAGE\\{guid}.{extension}";
7476

7577
private boolean exportJson = false;
7678
private String jsonFileNameTemplate = "{export_directory}\\JSON\\{guid}.json";
7779
private JsonExporter jsonExporter = null;
7880

81+
private Consumer<String> messageLoggedCallback = null;
82+
private PeriodicGatedConsumer<BoundedProgressInfo> progressCallback = null;
83+
7984
/**
8085
* -- SETTER --
8186
* Sets whether DAT contents should additionally be exported as an XLSX spreadsheet.
8287
*/
8388
@Setter
8489
private boolean exportXlsx = false;
90+
8591
/**
8692
* -- SETTER --
8793
* Sets whether final DAT will be kept by moving it to final export directory/
8894
*/
8995
@Setter
9096
private boolean keepOriginalDat = false;
9197

98+
/**
99+
* Whether to skip export of natives for slip-sheeted items.
100+
*/
101+
@Setter
102+
private boolean skipNativesSlipsheetedItems = false;
103+
92104
/**
93105
* -- SETTER --
94106
* Allows you to provide a Map of headers to rename. Intended to provide a way to rename headers that Nuix automatically adds
@@ -129,6 +141,31 @@ public class CustomExporter {
129141
public CustomExporter() {
130142
}
131143

144+
/***
145+
* Provides a callback to be invoked when progress is made during initial batch export or during
146+
* restructuring phase. Will be wrapped in a {@link PeriodicGatedConsumer} with an interval of 5 seconds
147+
* if not already an instance of {@link PeriodicGatedConsumer}.
148+
* @param progressCallback The progress info consumer.
149+
*/
150+
public void whenProgressEventOccurs(Consumer<BoundedProgressInfo> progressCallback) {
151+
if (progressCallback instanceof PeriodicGatedConsumer) {
152+
this.progressCallback = (PeriodicGatedConsumer<BoundedProgressInfo>) progressCallback;
153+
} else {
154+
this.progressCallback = new PeriodicGatedConsumer<>(progressCallback, 5000);
155+
}
156+
}
157+
158+
private void fireProgressEvent(String stage, long current, long total) {
159+
BoundedProgressInfo info = new BoundedProgressInfo(stage, current, total);
160+
if (progressCallback != null) {
161+
progressCallback.accept(info);
162+
}
163+
}
164+
165+
public void whenMessageLogged(Consumer<String> messageLoggedCallback) {
166+
this.messageLoggedCallback = messageLoggedCallback;
167+
}
168+
132169
/***
133170
* Assigns a dynamically calculated placeholder to this instance.
134171
* @param placeholderName Placeholder name with "{" or "}". For example "my_value". Placeholder in templates can then be referred to using "{my_value}". It is
@@ -245,7 +282,13 @@ public void setColumnRemovals(Collection<String> columnHeaders) {
245282

246283
private void logInfo(String format, Object... params) {
247284
String message = String.format(format, params);
248-
System.out.println(message);
285+
286+
if (messageLoggedCallback != null) {
287+
messageLoggedCallback.accept(message);
288+
} else {
289+
System.out.println(message);
290+
}
291+
249292
if (generalLog != null) {
250293
try {
251294
generalLog.writeLine(message);
@@ -259,7 +302,13 @@ private void logInfo(String format, Object... params) {
259302

260303
private void logError(String format, Object... params) {
261304
String message = String.format(format, params);
262-
System.out.println(message);
305+
306+
if (messageLoggedCallback != null) {
307+
messageLoggedCallback.accept("ERROR: " + message);
308+
} else {
309+
System.err.println(message);
310+
}
311+
263312
if (errorLog != null) {
264313
try {
265314
errorLog.writeLine(message);
@@ -298,12 +347,7 @@ public String evaluate(Item item) {
298347
}
299348
}
300349
if (!hasGuid) {
301-
exportProfile = exportProfile.addMetadata("GUID", new ItemExpression<String>() {
302-
@Override
303-
public String evaluate(Item item) {
304-
return item.getGuid();
305-
}
306-
});
350+
exportProfile = exportProfile.addMetadata("GUID", Item::getGuid);
307351
}
308352
}
309353
return exportProfile;
@@ -421,7 +465,6 @@ public void exportItems(Case nuixCase, File exportDirectory, List<Item> items) t
421465
exporter.addProduct("tiff", productSettings);
422466
}
423467

424-
425468
exportDirectory.mkdirs();
426469
File tempDatFile = new File(exportTempDirectory, "loadfile.dat");
427470
File finalDatFile = new File(exportDirectory, "loadfile.dat");
@@ -448,6 +491,8 @@ public void itemProcessed(ItemEventInfo info) {
448491
logError("BatchExporter reports error while exporting item with GUID '%s':\n%s",
449492
info.getItem().getGuid(), FormatUtility.debugString(info.getFailure()));
450493
}
494+
495+
fireProgressEvent("BatchExport: " + info.getStage(), info.getStageCount(), items.size());
451496
}
452497
});
453498

@@ -469,6 +514,9 @@ public void itemProcessed(ItemEventInfo info) {
469514
exporter.setStampingOptions(stampingSettings);
470515
}
471516

517+
// Forward setting regarding natives slipsheet generation
518+
exporter.setSkipNativesSlipsheetedItems(skipNativesSlipsheetedItems);
519+
472520
logInfo("Beginning temp export using BatchExporter...");
473521
exporter.exportItems(items);
474522
logInfo("Finished temp export using BatchExporter");
@@ -495,6 +543,8 @@ public void itemProcessed(ItemEventInfo info) {
495543

496544
@Override
497545
public void accept(LinkedHashMap<String, String> record) {
546+
fireProgressEvent("Export Restructure", recordsProcessed, items.size());
547+
498548
// Periodically log progress
499549
long diffMillis = System.currentTimeMillis() - restructureStartMillis;
500550
if (diffMillis > 2 * 1000 || recordsProcessed % 100 == 0) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.nuix.superutilities.misc;
2+
3+
import lombok.Getter;
4+
5+
/***
6+
* Represents progress of an operation which has a bounded value, that is, we known what progress
7+
* value is considered maximum/done.
8+
*/
9+
@Getter
10+
public class BoundedProgressInfo extends ProgressInfo {
11+
/***
12+
* The maximum progress value
13+
*/
14+
protected final long maximum;
15+
16+
public BoundedProgressInfo(String stage, long current, long maximum) {
17+
super(stage, current);
18+
this.maximum = maximum;
19+
}
20+
21+
/***
22+
* Provides a percentage completed value by dividing double value of current by
23+
* double value of maximum.
24+
* @return A double value representing percentage complete
25+
*/
26+
public double percentageComplete() {
27+
return ((double) current) / ((double) maximum);
28+
}
29+
30+
@Override
31+
public String toString() {
32+
return "BoundedProgressInfo [stage=" + stage + ", " + current + "/" + maximum + "]";
33+
}
34+
}

0 commit comments

Comments
 (0)