
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