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

cdc.impex.templates.SheetTemplate Maven / Gradle / Ivy

The newest version!
package cdc.impex.templates;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;

import cdc.impex.ImpExNames;
import cdc.office.tables.Header;
import cdc.office.tables.HeaderCell;
import cdc.util.lang.Checks;
import cdc.util.strings.StringUtils;

/**
 * Description of a sheet template.
 * 

* It always has an optional action column. * * @author Damien Carbonne */ public final class SheetTemplate { /** The sheet domain. */ private final String domain; /** The sheet name. */ private final String name; /** The sheet description. */ private final String description; /** The default action to execute when action is missing. */ private final ImportAction defaultAction; /** The name of the action column. */ private final String actionColumnName; /** The list of column templates. */ private final List> columns; /** The header (built from columns headers). */ private final Header header; private final Map> headerToColumn = new HashMap<>(); /** (name, template) map, for name columns. */ private final Map> nameToColumn = new HashMap<>(); public static final ImportAction DEFAULT_ACTION = ImportAction.IGNORE; public static final String DEFAULT_ACTION_COLUMN_NAME = "Action"; public static final Comparator DOMAIN_NAME_COMPARATOR = Comparator.comparing(SheetTemplate::getDomain) .thenComparing(SheetTemplate::getName); private SheetTemplate(Builder builder) { this.domain = Checks.isNotNullOrEmpty(builder.domain, "domain"); this.name = Checks.isNotNullOrEmpty(builder.name, "name"); if (builder.name.contains("#")) { throw new IllegalArgumentException("Invalid template name '" + builder.name + "'"); } this.description = builder.description; this.defaultAction = builder.defaultAction; // Already checked by builder this.actionColumnName = Checks.isNotNull(builder.actionColumnName, "actionColumnName"); this.columns = Collections.unmodifiableList(Checks.isNotNull(builder.columns, "columns")); final List headers = new ArrayList<>(); for (final ColumnTemplate column : this.columns) { if (column == null) { throw new IllegalArgumentException("Null column"); } headers.add(column.getHeader()); this.headerToColumn.put(column.getHeader(), column); if (column.isName()) { nameToColumn.put(column.getName(), column); } } this.header = Header.builder().cells(headers).build(); if (this.headerToColumn.size() != this.columns.size()) { throw new IllegalArgumentException("Duplicate column names"); } } /** * @return The template domain. */ public String getDomain() { return domain; } /** * @return The template name. */ public String getName() { return name; } /** * @return The template qualified name (domain.name). */ public String getQName() { return domain + "." + name; } /** * @return The template description. */ public String getDescription() { return description; } /** * @return The default import action, used when action is not defined. */ public ImportAction getDefaultAction() { return defaultAction; } /** * @return The name of the action column. */ public String getActionColumnName() { return actionColumnName; } /** * @return The action column */ public ColumnTemplate getActionColumn() { @SuppressWarnings("unchecked") final ColumnTemplate tmp = (ColumnTemplate) getColumn(actionColumnName); return tmp; } public boolean isActionColumn(ColumnTemplate column) { return column == getActionColumn(); } /** * @return The template columns. */ public List> getColumns() { return columns; } public List> getColumns(Usage usage) { final List> result = new ArrayList<>(); for (final ColumnTemplate column : columns) { if (column.getUsage() == usage) { result.add(column); } } return result; } /** * @return The header. */ public Header getHeader() { return header; } /** * @return {@code true} if this sheet template contains pattern columns. */ public boolean hasPatterns() { return header.hasPatterns(); } /** * @return The template column headers. */ @Deprecated(forRemoval = true, since = "2024-07-13") public List getColumnHeaders() { return header.getSortedCells(); } /** * Returns a list of column headers that match a usage. * * @param usage The usage. * @return A list of column headers that match {@code usage}. */ public List getColumnHeaders(Usage usage) { final List result = new ArrayList<>(); for (final ColumnTemplate column : columns) { if (column.getUsage() == usage) { result.add(column.getHeader()); } } return result; } /** * @param header The cell header. * @return The template associated to {@code header}. * @throws IllegalArgumentException When {@code header} is {@code null}. * @throws NoSuchElementException When there is no associated template. */ public ColumnTemplate getColumn(HeaderCell header) { Checks.isNotNull(header, "header"); final ColumnTemplate result = headerToColumn.get(header); if (result == null) { throw new NoSuchElementException("Invalid column header '" + header + "' for template '" + this.name + "'"); } else { return result; } } /** * Returns the column that has a given name. * * @param name The name. * @return The column that is named {@code name}. * @throws IllegalArgumentException When {@code name} is {@code null}. * @throws NoSuchElementException When there is no column named {@code name}. */ public ColumnTemplate getColumn(String name) { Checks.isNotNull(name, ImpExNames.NAME); return getColumn(HeaderCell.name(name)); } /** * Returns {@code true} if this sheet template contains a column with a particular name. *

* WARNING: This only works for name columns. * * @param name The name. * @return {@code true} if this sheet template contains a column names {@code name}. */ public boolean containsColumn(String name) { return headerToColumn.containsKey(HeaderCell.name(name)); } /** * @param name The actual name. * @return The column that matches {@code name}. * @throws NoSuchElementException When there is not a single column matching {@code name}. */ public ColumnTemplate getMatchingColumn(String name) { final Optional cell = header.getMatchingCell(name); return getColumn(cell.orElseThrow()); } /** * @param name The actual name. * @return {@code true} when there a single column matching {@code name}. */ public boolean containsMatchingColumn(String name) { return header.matchesOne(name); } /** * @param patternReplacement The list of names that must be used as actual columns names for pattern columns. * @return A new SheetTemplateInstance whose template is this object and header is built from names of name columns * and substitutions for pattern columns. */ public SheetTemplateInstance instantiate(List patternReplacement) { return SheetTemplateInstance.replace(this, patternReplacement); } /** * @param patternReplacement The array of names that must be used as actual columns names for pattern columns. * @return A new SheetTemplateInstance whose template is this object and header is built from names of name columns * and substitutions for pattern columns. */ public SheetTemplateInstance instantiate(String... patternReplacement) { return SheetTemplateInstance.replace(this, patternReplacement); } public Builder newBuilder() { return builder(this); } @Override public String toString() { return "[" + getQName() + " " + getColumns() + "]"; } public static Builder builder() { return new Builder(); } public static Builder builder(SheetTemplate model) { return new Builder(model); } public static final class Builder { private String domain; private String name; private String description; private ImportAction defaultAction = DEFAULT_ACTION; private String actionColumnName = DEFAULT_ACTION_COLUMN_NAME; private final List> columns = new ArrayList<>(); private Builder() { } private Builder(SheetTemplate model) { domain(model.domain); name(model.name); description(model.description); actionColumnName(model.actionColumnName); columns.addAll(model.columns); } public Builder domain(String domain) { this.domain = domain; return this; } public Builder name(String name) { this.name = name; return this; } public Builder description(String description) { this.description = description; return this; } public Builder defaultAction(ImportAction defaultAction) { this.defaultAction = Checks.isNotNull(defaultAction, "defaultAction"); return this; } public Builder actionColumnName(String actionColumnName) { this.actionColumnName = actionColumnName; return this; } public Builder column(ColumnTemplate column) { this.columns.add(column); return this; } public SheetTemplate build() { for (final ColumnTemplate column : columns) { if (column.getLabel().equals(actionColumnName)) { throw new IllegalArgumentException("Cannot create action column, a column named '" + actionColumnName + "' has been created."); } } columns.add(0, ColumnTemplate.builder(ImportAction.class) .name(actionColumnName) .usage(Usage.ACTION) .description("Action to be taken " + Arrays.toString(ImportAction.values()) + " for each row.\nAn empty cell is equivalent to " + ImportAction.IGNORE + ".") .importConverter(s -> StringUtils.isNullOrEmpty(s) ? defaultAction : ImportAction.valueOf(s)) .exportConverter(x -> x == null ? null : x.name()) .build()); return new SheetTemplate(this); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy