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

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

package cdc.impex.core;

import java.io.File;
import java.io.IOException;
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.ExportDriver;
import cdc.impex.exports.ExportIssue;
import cdc.impex.exports.ExportIssueType;
import cdc.impex.exports.Exporter;
import cdc.impex.exports.WorkbookExporter;
import cdc.impex.templates.SheetTemplate;
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.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(ExportIssue.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;
        }
    }

    @Override
    public void exportData(File file,
                           List templates,
                           WorkbookExporter workbookExporter,
                           IssuesHandler issuesHandler,
                           ProgressController controller) throws IOException {
        final Chronometer chrono = new Chronometer();
        chrono.start();
        final ProgressSupplier progress = new ProgressSupplier(controller);

        final Set tmp = new HashSet<>(templates);
        if (tmp.size() != templates.size()) {
            throw new IllegalArgumentException("Duplicate templates");
        }

        final ExportDriver driver = factory.createExportDriver(file, issuesHandler);
        this.issuesHandler = issuesHandler;
        systemId = file.getPath();
        sheetName = null;

        issue(ExportIssueType.GENERATE_WORKBOOK,
              "Generate '" + systemId + "' workbook.");
        driver.beginExport(file);
        wrap(() -> workbookExporter.beginExport(issuesHandler));

        final ImpExFormat format = ImpExFormat.from(file);
        final int maxRowsPerSheet = format.getMaxRows();

        for (final SheetTemplate template : templates) {
            wrap(() -> workbookExporter.beginSheetExport(template, 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 = template.getName() + "#" + sheetNumber;
                    progress.reset(partialTotal, "Generate sheet " + sheetName);
                    issue(ExportIssueType.GENERATE_SHEET,
                          "Generate '" + sheetName + "' sheet with '" + template.getQName() + "' template.");
                    driver.beginSheet(template, sheetName, partialTotal);
                    final ExportRowImpl row = new ExportRowImpl(template, 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));
                        driver.addRow(row);
                        progress.incrementValue();
                    }
                    driver.endSheet();
                    sheetChrono.suspend();
                    issue(ExportIssueType.GENERATED_SHEET,
                          "Generated '" + sheetName + "' sheet with '" + template.getQName() + "' template in " + sheetChrono
                                  + ".");
                }
                wrap(() -> workbookExporter.endSheetExport(template, issuesHandler));
            } else {
                wrap(() -> workbookExporter.endSheetExport(template, issuesHandler));
                issue(ExportIssueType.IGNORED_SHEET,
                      "Ignored '" + sheetName + "' sheet as there is no data.");
            }
        }

        wrap(() -> workbookExporter.endExport(issuesHandler));
        driver.endExport();
        chrono.suspend();
        issue(ExportIssueType.GENERATED_WORKBOOK,
              "Generated '" + systemId + "' workbook in " + chrono + ".");
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy