All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.impex.core.ActiveExporterImpl Maven / Gradle / Ivy

There is a newer version: 0.54.0
Show newest version
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