
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.ImportIssue;
import cdc.impex.imports.ImportIssueType;
import cdc.impex.imports.ImportRow;
import cdc.impex.templates.ColumnTemplate;
import cdc.impex.templates.ImportAction;
import cdc.impex.templates.SheetTemplate;
import cdc.issues.IssueSeverity;
import cdc.issues.locations.WorkbookLocation;
import cdc.util.lang.Checks;
public final class ImportRowImpl implements ImportRow {
private static final String ERASE = "ERASE";
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(String systemId,
SheetTemplate template,
String sheetName,
int number,
Map rawData) {
this.systemId = systemId;
this.template = Checks.isNotNull(template, "template");
this.sheetName = sheetName;
this.number = number;
this.rawData = new HashMap<>(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(getAction())) {
// Column is mandatory
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 + " in mandatory column '" + column.getName() + "' when action is " + action
+ ".",
column);
}
} else {
// Column is optional
if (value == ERASE) {
if (action == ImportAction.CREATE || action == ImportAction.DELETE) {
addIssue(ImportIssueType.UNEXPECTED_ERASE,
"Unexpected " + ERASE + " in optional column '" + column.getName() + "' when action is " + action
+ ".",
column);
}
} else if (value != null && action == ImportAction.DELETE && !template.isActionColumn(column)) {
addIssue(ImportIssueType.UNEXPECTED_DATA,
"Unexpected data in optional column '" + column.getName() + "' when action is " + action + ".",
column);
}
}
}
}
private void addIssue(ImportIssueType type,
IssueSeverity severity,
String description,
ColumnTemplate> column) {
if (issues == null) {
issues = new ArrayList<>();
}
issues.add(ImportIssue.builder()
.name(type)
.severity(severity)
.description(description)
.addLocation(WorkbookLocation.builder()
.sheetName(sheetName == null ? template.getName() : sheetName)
.columnName(column.getName())
.rowNumber(number)
.systemId(systemId)
.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 SheetTemplate getTemplate() {
return template;
}
@Override
public int getNumber() {
return number;
}
@Override
public ImportAction getAction() {
return getDataOrNull(ImportAction.class,
template.getActionColumnName());
}
@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 ImportIssue issue : issues) {
if (issue.getSeverity().isAtLeast(IssueSeverity.CRITICAL)) {
return false;
}
}
return true;
}
}
@Override
public boolean isEmpty() {
return data.isEmpty();
}
@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 data = 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.data.put(name, value);
return this;
}
public ImportRow build() {
return new ImportRowImpl(systemId,
template,
sheetName,
number,
data);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy