
cdc.impex.core.ExporterImpl Maven / Gradle / Ivy
package cdc.impex.core;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import cdc.impex.ImpExFactory;
import cdc.impex.ImpExFactoryFeatures;
import cdc.impex.ImpExFormat;
import cdc.impex.exports.ExportIssueType;
import cdc.impex.exports.ExportIssues;
import cdc.impex.exports.Exporter;
import cdc.impex.exports.StreamExporter;
import cdc.impex.exports.WorkbookExporter;
import cdc.impex.templates.SheetTemplateInstance;
import cdc.issues.Issue;
import cdc.issues.IssueSeverity;
import cdc.issues.IssuesHandler;
import cdc.issues.locations.WorkbookLocation;
import cdc.util.events.ProgressController;
import cdc.util.events.ProgressSupplier;
import cdc.util.lang.Checks;
import cdc.util.lang.Procedure;
import cdc.util.time.Chronometer;
public class ExporterImpl implements Exporter {
private final ImpExFactory factory;
private IssuesHandler issuesHandler;
private String systemId;
private String sheetName;
public ExporterImpl(ImpExFactoryFeatures features) {
this.factory = new ImpExFactory(features);
}
public ExporterImpl(ImpExFactory factory) {
this(factory.getFeatures());
}
private void issue(ExportIssueType type,
IssueSeverity severity,
String description) {
issuesHandler.issue(ExportIssues.builder()
.name(type)
.severity(severity)
.description(description)
.addLocation(WorkbookLocation.builder()
.systemId(systemId)
.sheetName(sheetName)
.build())
.build());
}
private void issue(ExportIssueType type,
String description) {
issue(type, type.getSeverity(), description);
}
private void wrap(Procedure procedure) {
try {
procedure.invoke();
} catch (final RuntimeException e) {
// Generate a valid (non null) description
final String description = e.getMessage() == null
? e.getClass().getSimpleName()
: e.getMessage();
issue(ExportIssueType.APP_FAILURE,
IssueSeverity.BLOCKER,
description);
throw e;
}
}
private void exportDataInt(File file,
OutputStream out,
String systemId,
ImpExFormat format,
List templateInstances,
WorkbookExporter workbookExporter,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
Checks.isNotNull(format, "format");
Checks.isNotNull(templateInstances, "templates");
Checks.isNotNull(workbookExporter, "workbookExporter");
Checks.isNotNull(issuesHandler, "issuesHandler");
Checks.isNotNull(controller, "controller");
final Chronometer chrono = new Chronometer();
chrono.start();
final ProgressSupplier progress = new ProgressSupplier(controller);
final Set tmp = new HashSet<>(templateInstances);
if (tmp.size() != templateInstances.size()) {
throw new IllegalArgumentException("Duplicate templates");
}
this.issuesHandler = issuesHandler;
this.systemId = systemId;
sheetName = null;
issue(ExportIssueType.GENERATE_WORKBOOK,
"Generate '" + systemId + "' workbook.");
try (final StreamExporter streamExporter = factory.createStreamExporter(format, issuesHandler)) {
if (file == null) {
streamExporter.beginExport(out, format);
} else {
streamExporter.beginExport(file);
}
wrap(() -> workbookExporter.beginExport(issuesHandler));
if (factory.getFeatures().isEnabled(ImpExFactoryFeatures.Hint.ADD_README)) {
streamExporter.addReadme(templateInstances);
}
final int maxRowsPerSheet = format.getMaxRows();
for (final SheetTemplateInstance templateInstance : templateInstances) {
wrap(() -> workbookExporter.beginSheetExport(templateInstance, issuesHandler));
final int totalNumberOfRows = workbookExporter.getNumberOfRemainingRows();
if (totalNumberOfRows != 0) {
int sheetNumber = 0;
// Write extracted sheet into N generated sheets that each
// have at most maxRowsPerSheet
while (workbookExporter.hasMore()) {
final Chronometer sheetChrono = new Chronometer();
sheetChrono.start();
final int remaining = workbookExporter.getNumberOfRemainingRows();
final int partialTotal;
if (remaining < 0) {
partialTotal = -1;
} else if (maxRowsPerSheet < 0) {
// Add 1 to remaining to take into account header
// One sheet will do the job
partialTotal = remaining + 1;
} else {
// Add 1 to remaining to take into account header
partialTotal = Math.min(maxRowsPerSheet, remaining + 1);
}
sheetNumber++;
sheetName = templateInstance.getTemplate().getName() + "#" + sheetNumber;
progress.reset(partialTotal, "Generate sheet " + sheetName);
issue(ExportIssueType.GENERATE_SHEET,
"Generate '" + sheetName + "' sheet with '" + templateInstance.getTemplate().getQName()
+ "' template.");
streamExporter.beginSheet(templateInstance, sheetName, partialTotal);
final ExportRowImpl row = new ExportRowImpl(templateInstance, sheetName, systemId);
row.setNumber(1); // Count header
progress.incrementValue();
// Number of rows in current generated sheet.
// Initialize to 1 to count header row
int numberOfRowsInSheet = 1;
while ((maxRowsPerSheet < 0 || numberOfRowsInSheet < maxRowsPerSheet) && workbookExporter.hasMore()) {
numberOfRowsInSheet++;
row.clear();
row.incrementNumber();
wrap(() -> workbookExporter.exportRow(row, issuesHandler));
streamExporter.addRow(row);
progress.incrementValue();
}
streamExporter.endSheet();
sheetChrono.suspend();
issue(ExportIssueType.GENERATED_SHEET,
"Generated '" + sheetName + "' sheet with '" + templateInstance.getTemplate().getQName()
+ "' template in " + sheetChrono + ".");
}
wrap(() -> workbookExporter.endSheetExport(templateInstance, issuesHandler));
} else {
wrap(() -> workbookExporter.endSheetExport(templateInstance, issuesHandler));
issue(ExportIssueType.IGNORED_SHEET,
"Ignored '" + sheetName + "' sheet as there is no data.");
}
}
wrap(() -> workbookExporter.endExport(issuesHandler));
streamExporter.endExport();
}
chrono.suspend();
issue(ExportIssueType.GENERATED_WORKBOOK,
"Generated '" + systemId + "' workbook in " + chrono + ".");
}
@Override
public void exportData(File file,
List templateInstances,
WorkbookExporter workbookExporter,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
Checks.isNotNull(file, "file");
final ImpExFormat format = ImpExFormat.from(file);
Checks.isNotNull(format, "Can not recognize file format");
exportDataInt(file,
null,
file.getPath(),
format,
templateInstances,
workbookExporter,
issuesHandler,
controller);
}
@Override
public void exportData(OutputStream out,
String systemId,
ImpExFormat format,
List templateInstances,
WorkbookExporter workbookExporter,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
Checks.isNotNull(out, "out");
Checks.isNotNull(format, "format");
exportDataInt(null,
out,
systemId,
format,
templateInstances,
workbookExporter,
issuesHandler,
controller);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy