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

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

package cdc.impex.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cdc.impex.imports.ImportIssueType;
import cdc.impex.imports.ImportIssues;
import cdc.impex.imports.ImportRow;
import cdc.impex.templates.ColumnTemplate;
import cdc.impex.templates.ImportAction;
import cdc.impex.templates.SheetTemplate;
import cdc.issues.Issue;
import cdc.issues.IssueSeverity;
import cdc.issues.locations.WorkbookLocation;
import cdc.util.lang.Checks;

public final class ImportRowImpl implements ImportRow {
    private final String systemId;
    private final SheetTemplate template;
    private final String sheetName;
    private final int number;
    private final Map rawData;
    private final Map data = new HashMap<>();
    private List issues = null;

    private ImportRowImpl(Builder builder) {
        this.systemId = builder.systemId;
        this.template = Checks.isNotNull(builder.template, "template");
        this.sheetName = builder.sheetName;
        this.number = builder.number;
        this.rawData = new HashMap<>(builder.rawData);

        // Read raw data, convert it, check it, and put converted result into data
        for (final Map.Entry entry : rawData.entrySet()) {
            // Retrieve column name
            final String name = entry.getKey();
            if (template.containsColumn(name)) {
                // Retrieve associated column template
                final ColumnTemplate column = template.getColumn(name);
                Object value;
                if (ERASE.equals(entry.getValue())) {
                    value = ERASE;
                } else {
                    // Convert raw data
                    try {
                        value = column.getImportConverter().apply(entry.getValue());
                    } catch (final RuntimeException e) {
                        // Conversion failed
                        addIssue(ImportIssueType.NON_CONVERTIBLE_DATA,
                                 "Failed to convert '" + entry.getValue() + "' to " + column.getDataType().getCanonicalName() + ".",
                                 column);
                        value = null;
                    }
                }

                // Check converted data
                if (value != null && value != ERASE && column.getCheckerOrNull() != null) {
                    final boolean valid = column.getCheckerOrNull().testRaw(value);
                    if (!valid) {
                        // Check failed
                        addIssue(ImportIssueType.NON_COMPLIANT_DATA,
                                 column.getCheckFailureSeverity(),
                                 "Check [" + column.getCheckerOrNull().explain(true, "?") + "] failed for '?'=" + value + ".",
                                 column);
                    }
                }
                // Put converted data, even if check failed
                if (value != null) {
                    this.data.put(name, value);
                }
            }
        }

        final ImportAction action = getAction();

        // Check that columns are set / unset
        // If action is not correctly set, this may be incomplete
        for (final ColumnTemplate column : template.getColumns()) {
            final Object value = this.data.get(column.getName());
            if (column.getUsage().isMandatoryFor(action)) {
                // Column is mandatory for action
                if (value == null) {
                    addIssue(ImportIssueType.MISSING_MANDATORY_DATA,
                             "No data for mandatory column '" + column.getName() + "'.",
                             column);
                } else if (value == ERASE) {
                    addIssue(ImportIssueType.UNEXPECTED_ERASE,
                             unexpected(ERASE, "mandatory", column, action),
                             column);
                }
            } else if (column.getUsage().isOptionalFor(action)) {
                // Column is optional for action
                if (value == ERASE) {
                    if (action == ImportAction.CREATE
                            || action == ImportAction.DELETE
                            || action == ImportAction.UPDATE && !column.getUsage().isErasable()) {
                        addIssue(ImportIssueType.UNEXPECTED_ERASE,
                                 unexpected(ERASE, "optional", column, action),
                                 column);
                    }
                }
            } else {
                // Column is ignored for action
                if (value == ERASE) {
                    addIssue(ImportIssueType.UNEXPECTED_ERASE,
                             unexpected(ERASE, "ignored", column, action),
                             column);
                } else if (value != null) {
                    addIssue(ImportIssueType.UNEXPECTED_DATA,
                             unexpected("data", "ignored", column, action),
                             column);
                }
            }
        }
    }

    private static String unexpected(String content,
                                     String columnKind,
                                     ColumnTemplate column,
                                     ImportAction action) {
        return "Unexpected " + content + " in " + columnKind + "column '" + column.getName() + "' when action is " + action + ".";

    }

    private void addIssue(ImportIssueType type,
                          IssueSeverity severity,
                          String description,
                          ColumnTemplate column) {
        if (issues == null) {
            issues = new ArrayList<>();
        }
        issues.add(ImportIssues.builder()
                               .name(type)
                               .severity(severity)
                               .description(description)
                               .addLocation(WorkbookLocation.builder()
                                                            .sheetName(getSheetName())
                                                            .columnName(column.getName())
                                                            .rowNumber(getNumber())
                                                            .systemId(getSystemId())
                                                            .build())
                               .build());
    }

    private void addIssue(ImportIssueType type,
                          String description,
                          ColumnTemplate column) {
        addIssue(type,
                 type.getSeverity(),
                 description,
                 column);
    }

    @Override
    public String getSystemId() {
        return systemId;
    }

    @Override
    public String getSheetName() {
        return sheetName == null ? template.getName() : sheetName;
    }

    @Override
    public SheetTemplate getTemplate() {
        return template;
    }

    @Override
    public int getNumber() {
        return number;
    }

    @Override
    public ImportAction getAction() {
        return getData(ImportAction.class,
                       template.getActionColumnName(),
                       ImportAction.IGNORE);
    }

    @Override
    public boolean isErase(String name) {
        return data.get(name) == ERASE;
    }

    @Override
    public String getRawDataOrNull(String name) {
        return rawData.get(name);
    }

    @Override
    public Object getDataOrNull(String name) {
        final Object value = data.get(name);
        return value == ERASE ? null : value;
    }

    @Override
    public  T getDataOrNull(Class cls,
                               String name) {
        return cls.cast(getDataOrNull(name));
    }

    @Override
    public List getIssues() {
        return issues == null
                ? Collections.emptyList()
                : issues;
    }

    @Override
    public boolean canBeProcessed() {
        if (issues == null) {
            return true;
        } else {
            for (final Issue issue : issues) {
                if (issue.getSeverity().isAtLeast(IssueSeverity.CRITICAL)) {
                    return false;
                }
            }
            return true;
        }
    }

    @Override
    public boolean isEmpty() {
        return data.isEmpty();
    }

    @Override
    public WorkbookLocation getLocation() {
        return WorkbookLocation.builder()
                               .systemId(getSystemId())
                               .sheetName(getSheetName())
                               .rowNumber(getNumber())
                               .build();
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("[")
               .append(getNumber())
               .append(" {");
        boolean first = true;
        for (final String name : template.getColumnNames()) {
            if (first) {
                first = false;
            } else {
                builder.append(", ");
            }
            builder.append(name)
                   .append("=")
                   .append(getDataOrNull(name));
        }
        builder.append("}]");
        return builder.toString();
    }

    public static Builder builder() {
        return new Builder();
    }

    public static final class Builder {
        private String systemId;
        private SheetTemplate template;
        private String sheetName;
        private int number;
        private final Map rawData = new HashMap<>();

        private Builder() {
        }

        public Builder systemId(String systemId) {
            this.systemId = systemId;
            return this;
        }

        public Builder template(SheetTemplate template) {
            this.template = template;
            return this;
        }

        public Builder sheetName(String sheetName) {
            this.sheetName = sheetName;
            return this;
        }

        public Builder number(int number) {
            this.number = number;
            return this;
        }

        public Builder put(String name,
                           String value) {
            this.rawData.put(name, value);
            return this;
        }

        public Builder put(ColumnTemplate column,
                           String value) {
            this.rawData.put(column.getName(), value);
            return this;
        }

        // public  Builder put(ColumnTemplate column,
        // T value) {
        // this.data.put(column.getName(), column.getExportConverter().apply(value));
        // return this;
        // }

        public ImportRow build() {
            return new ImportRowImpl(this);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy