From 0070d987ddd48ab93e46925217ac182f016566ac Mon Sep 17 00:00:00 2001 From: Jonathan Gamba Date: Wed, 22 Jan 2025 09:58:09 -0600 Subject: [PATCH] #30882 First commit for the ImportUtil refactor to improve responses. --- .../com/dotmarketing/util/ImportUtil.java | 49 +++++++++++-------- .../importer/AbstractImportHeaderInfo.java | 7 +++ .../importer/AbstractSpecialHeaderInfo.java | 37 ++++++++++++++ .../util/importer/ImportResultConverter.java | 46 +++++++++++++++++ 4 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractSpecialHeaderInfo.java diff --git a/dotCMS/src/main/java/com/dotmarketing/util/ImportUtil.java b/dotCMS/src/main/java/com/dotmarketing/util/ImportUtil.java index bab3aa48f4b..c9237a5fc95 100644 --- a/dotCMS/src/main/java/com/dotmarketing/util/ImportUtil.java +++ b/dotCMS/src/main/java/com/dotmarketing/util/ImportUtil.java @@ -51,15 +51,18 @@ import com.dotmarketing.portlets.workflows.business.WorkflowAPI; import com.dotmarketing.portlets.workflows.model.WorkflowAction; import com.dotmarketing.util.importer.AbstractImportValidationMessage.ValidationMessageType; +import com.dotmarketing.util.importer.AbstractSpecialHeaderInfo.SpecialHeaderType; import com.dotmarketing.util.importer.ContentSummary; import com.dotmarketing.util.importer.HeaderValidationCodes; import com.dotmarketing.util.importer.ImportFileInfo; import com.dotmarketing.util.importer.ImportHeaderInfo; import com.dotmarketing.util.importer.ImportHeaderValidationResult; import com.dotmarketing.util.importer.ImportResult; +import com.dotmarketing.util.importer.ImportResultConverter; import com.dotmarketing.util.importer.ImportResultData; import com.dotmarketing.util.importer.ImportValidationMessage; import com.dotmarketing.util.importer.ProcessedData; +import com.dotmarketing.util.importer.SpecialHeaderInfo; import com.liferay.portal.language.LanguageException; import com.liferay.portal.language.LanguageUtil; import com.liferay.portal.model.User; @@ -322,22 +325,11 @@ public static HashMap> importFile(Long importId, String cur onlyChild, onlyParent); } + // --- // Convert validation result to legacy format - for (ImportValidationMessage message : headerValidation.messages()) { - String messageText = message.message(); - switch (message.type()) { - case ERROR: - results.get("errors").add(messageText); - errors++; - break; - case WARNING: - results.get("warnings").add(messageText); - break; - case INFO: - results.get("messages").add(messageText); - break; - } - } + ImportResultConverter.addValidationResultsToLegacyMap(headerValidation, results); + errors += results.get("errors").size(); + // --- lineNumber++; @@ -574,6 +566,7 @@ private static void processHeaders(final String[] headerLine, List validHeaders = new ArrayList<>(); List invalidHeaders = new ArrayList<>(); + List specialHeaders = new ArrayList<>(); // Process each header for (int i = 0; i < headerLine.length; i++) { @@ -581,8 +574,10 @@ private static void processHeaders(final String[] headerLine, headerFields.add(header); // Handle special headers first - if (isSpecialHeader(header, i, user, validationBuilder)) { + final var specialHeaderInfo = isSpecialHeader(header, i, user, validationBuilder); + if (specialHeaderInfo.type() != SpecialHeaderType.NONE) { validHeaders.add(header); + specialHeaders.add(specialHeaderInfo); continue; } @@ -604,6 +599,7 @@ private static void processHeaders(final String[] headerLine, .invalidHeaders(invalidHeaders.toArray(new String[0])) .missingHeaders(missingHeaders.toArray(new String[0])) .validationDetails(new HashMap<>()) // Add validation details if needed + .specialHeaders(specialHeaders) .build(); validationBuilder.headerInfo(headerInfo); } @@ -808,10 +804,10 @@ private static List collectRequiredFields(final List fields) { * @param columnIndex Index of the header in the CSV file * @param user User performing the import * @param validationBuilder Builder to accumulate validation messages - * @return true if header is a special system header, false otherwise + * @return SpecialHeaderInfo containing type and column index if header is special, NONE otherwise * @throws LanguageException If language key lookup fails */ - private static boolean isSpecialHeader(final String header, final int columnIndex, + private static SpecialHeaderInfo isSpecialHeader(final String header, final int columnIndex, final User user, final ImportHeaderValidationResult.Builder validationBuilder) throws LanguageException { @@ -827,7 +823,11 @@ private static boolean isSpecialHeader(final String header, final int columnInde .context(Map.of("columnIndex", columnIndex)) .build() ); - return true; + + return SpecialHeaderInfo.builder() + .type(SpecialHeaderType.IDENTIFIER) + .columnIndex(columnIndex) + .build(); } if (header.equalsIgnoreCase(Contentlet.WORKFLOW_ACTION_KEY)) { @@ -842,10 +842,17 @@ private static boolean isSpecialHeader(final String header, final int columnInde .context(Map.of("columnIndex", columnIndex)) .build() ); - return true; + + return SpecialHeaderInfo.builder() + .type(SpecialHeaderType.WORKFLOW_ACTION) + .columnIndex(columnIndex) + .build(); } - return false; + return SpecialHeaderInfo.builder() + .type(SpecialHeaderType.NONE) + .columnIndex(-1) + .build(); } /** diff --git a/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractImportHeaderInfo.java b/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractImportHeaderInfo.java index fa1772633d9..c09aa46351d 100644 --- a/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractImportHeaderInfo.java +++ b/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractImportHeaderInfo.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.io.Serializable; +import java.util.List; import java.util.Map; import org.immutables.value.Value; @@ -40,4 +41,10 @@ public interface AbstractImportHeaderInfo extends Serializable { * @return Additional validation details and metadata about the headers */ Map validationDetails(); + + /** + * @return Special header types found in the import file + */ + List specialHeaders(); + } diff --git a/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractSpecialHeaderInfo.java b/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractSpecialHeaderInfo.java new file mode 100644 index 00000000000..d3dbefe6a08 --- /dev/null +++ b/dotCMS/src/main/java/com/dotmarketing/util/importer/AbstractSpecialHeaderInfo.java @@ -0,0 +1,37 @@ +package com.dotmarketing.util.importer; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.io.Serializable; +import org.immutables.value.Value; + +/** + * Contains information about special header types (Identifier, Workflow Action) and their column + * positions in the CSV file. + */ +@Value.Style(typeImmutable = "*", typeAbstract = "Abstract*") +@Value.Immutable +@JsonDeserialize(as = SpecialHeaderInfo.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public interface AbstractSpecialHeaderInfo extends Serializable { + + /** + * @return The header type found (Identifier, Workflow Action, etc) + */ + SpecialHeaderType type(); + + /** + * @return Column index where this special header was found + */ + int columnIndex(); + + /** + * Special header types supported in import + */ + enum SpecialHeaderType { + IDENTIFIER, + WORKFLOW_ACTION, + NONE + } + +} diff --git a/dotCMS/src/main/java/com/dotmarketing/util/importer/ImportResultConverter.java b/dotCMS/src/main/java/com/dotmarketing/util/importer/ImportResultConverter.java index e06f4838dc6..e1751c3dc33 100644 --- a/dotCMS/src/main/java/com/dotmarketing/util/importer/ImportResultConverter.java +++ b/dotCMS/src/main/java/com/dotmarketing/util/importer/ImportResultConverter.java @@ -1,6 +1,9 @@ package com.dotmarketing.util.importer; +import com.dotmarketing.portlets.contentlet.model.Contentlet; import com.dotmarketing.util.importer.AbstractImportValidationMessage.ValidationMessageType; +import com.dotmarketing.util.importer.AbstractSpecialHeaderInfo.SpecialHeaderType; +import com.liferay.util.StringPool; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -74,6 +77,49 @@ public static Map> toLegacyFormat(ImportResult result) { return legacyResults; } + /** + * Converts the structured ImportHeaderValidationResult to the legacy HashMap format. This + * method ensures backward compatibility by formatting the structured data into the string-based + * format expected by legacy code. + * + * @param validationResult The structured ImportHeaderValidationResult to convert + * @param legacyResults The legacy format results map to update + */ + public static void addValidationResultsToLegacyMap( + final ImportHeaderValidationResult validationResult, + final Map> legacyResults) { + + // Convert validation messages + for (ImportValidationMessage message : validationResult.messages()) { + String messageText = message.message(); + switch (message.type()) { + case ERROR: + legacyResults.get("errors").add(messageText); + break; + case WARNING: + legacyResults.get("warnings").add(messageText); + break; + case INFO: + legacyResults.get("messages").add(messageText); + break; + } + } + + // Convert special headers info + for (SpecialHeaderInfo specialHeader : validationResult.headerInfo() + .specialHeaders()) { + if (specialHeader.type() == SpecialHeaderType.IDENTIFIER) { + legacyResults.get("identifiers").add( + StringPool.BLANK + specialHeader.columnIndex() + ); + } else if (specialHeader.type() == SpecialHeaderType.WORKFLOW_ACTION) { + legacyResults.get(Contentlet.WORKFLOW_ACTION_KEY).add( + StringPool.BLANK + specialHeader.columnIndex() + ); + } + } + } + /** * Converts validation messages from the structured format to legacy format, organizing them by * message type. Each message is formatted to include line numbers, field names, and invalid