
cdc.impex.core.ActiveExporterImpl Maven / Gradle / Ivy
package cdc.impex.core;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import cdc.impex.ImpExFactory;
import cdc.impex.ImpExFormat;
import cdc.impex.exports.ActiveExporter;
import cdc.impex.exports.ExportIssueType;
import cdc.impex.exports.ExportIssues;
import cdc.impex.exports.ExportRow;
import cdc.impex.exports.StreamExporter;
import cdc.impex.templates.SheetTemplate;
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.time.Chronometer;
/**
* Implementation of {@link ActiveExporter}.
*
* @author Damien Carbonne
*/
public class ActiveExporterImpl implements ActiveExporter {
private final ImpExFactory factory;
private StreamExporter streamExporter;
private boolean closeStreamExporter = false;
private IssuesHandler issuesHandler;
private String systemId;
private SheetTemplateInstance templateInstance;
private int sheetNumber = 0;
private String sheetName;
private int maxRowsPerSheet = -1;
private int rowsInSheet = 0;
private long remaining = -1L;
private final Chronometer workbookChrono = new Chronometer();
private final Chronometer sheetChrono = new Chronometer();
private ExportRowImpl row;
private final ProgressSupplier progress = new ProgressSupplier();
public ActiveExporterImpl(ImpExFactory factory) {
this.factory = factory;
}
private void beginSheetInt() throws IOException {
sheetChrono.start();
// Number of rows in this physical sheet
final long numberOfRows;
if (remaining < 0) {
numberOfRows = -1L;
} else if (maxRowsPerSheet < 0) {
// Add 1 to remaining to take into account header
// One sheet will do the job
numberOfRows = remaining + 1L;
} else {
// Add 1 to remaining to take into account header
numberOfRows = Math.min(maxRowsPerSheet, remaining + 1L);
}
sheetNumber++;
sheetName = templateInstance.getTemplate().getName() + "#" + sheetNumber;
progress.reset(numberOfRows, "Generate sheet " + sheetName);
row = new ExportRowImpl(templateInstance, sheetName, systemId);
issue(ExportIssueType.GENERATE_SHEET,
"Generate '" + sheetName + "' sheet with '" + templateInstance.getTemplate().getQName() + "' template.");
streamExporter.beginSheet(templateInstance, sheetName, numberOfRows);
row.setNumber(1); // Count header
rowsInSheet = 1;
progress.incrementValue();
}
private void endSheetInt() throws IOException {
streamExporter.endSheet();
sheetChrono.suspend();
issue(ExportIssueType.GENERATED_SHEET,
"Generated '" + sheetName + "' sheet with '" + templateInstance.getTemplate().getQName() + "' template in "
+ sheetChrono + ".");
}
private boolean isFull() {
return maxRowsPerSheet > 0 && rowsInSheet == maxRowsPerSheet;
}
private void beginSheetIfFullInt() throws IOException {
if (isFull()) {
endSheetInt();
beginSheetInt();
}
}
private void beginExportInt(String systemId,
ImpExFormat format,
IssuesHandler issuesHandler,
ProgressController controller) {
Checks.isNotNull(format, "format");
Checks.isNotNull(issuesHandler, "issuesHandler");
Checks.isNotNull(controller, "controller");
workbookChrono.start();
this.progress.setController(controller);
this.streamExporter = factory.createStreamExporter(format, issuesHandler);
this.closeStreamExporter = true;
this.issuesHandler = issuesHandler;
this.systemId = systemId;
this.sheetName = null;
issue(ExportIssueType.GENERATE_WORKBOOK,
"Generate '" + systemId + "' workbook.");
this.maxRowsPerSheet = format.getMaxRows();
}
@Override
public void beginExport(File file,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
Checks.isNotNull(file, "file");
beginExportInt(file.getPath(),
ImpExFormat.from(file),
issuesHandler,
controller);
this.streamExporter.beginExport(file);
}
@Override
public void beginExport(OutputStream out,
String systemId,
ImpExFormat format,
IssuesHandler issuesHandler,
ProgressController controller) throws IOException {
Checks.isNotNull(out, "out");
beginExportInt(systemId,
format,
issuesHandler,
controller);
this.streamExporter.beginExport(out, format);
}
@Override
public void beginSheet(SheetTemplateInstance templateInstance,
long numberOfRows) throws IOException {
this.templateInstance = templateInstance;
this.sheetNumber = 0;
this.remaining = numberOfRows;
beginSheetInt();
}
@Override
public void beginSheet(SheetTemplate template,
long numberOfRows) throws IOException {
beginSheet(SheetTemplateInstance.of(template), numberOfRows);
}
@Override
public ExportRow nextRow() throws IOException {
beginSheetIfFullInt();
row.incrementNumber();
row.clear();
return row;
}
@Override
public void addRow() throws IOException {
remaining--;
rowsInSheet++;
final List issues = row.getIssues();
issuesHandler.issues(issues);
streamExporter.addRow(row);
progress.incrementValue();
}
@Override
public void endSheet() throws IOException {
endSheetInt();
}
@Override
public void endExport() throws IOException {
streamExporter.endExport();
if (closeStreamExporter) {
streamExporter.close();
}
workbookChrono.suspend();
issue(ExportIssueType.GENERATED_WORKBOOK,
"Generated '" + systemId + "' workbook in " + workbookChrono + ".");
}
@Override
public IssuesHandler getIssuesHandler() {
return issuesHandler;
}
@Override
public 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());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy