From 42cda5c9152bc3b5b6ad148a1a4db82c01c74b7c Mon Sep 17 00:00:00 2001 From: Quincy Cantu Date: Wed, 13 Nov 2024 14:44:30 -0700 Subject: [PATCH] Provide useful error output when there are duplicate headers --- .../cires/pace/gui/BaseTranslatorForm.java | 11 ++++- .../cires/pace/gui/TranslateForm.java | 41 ++++++++++--------- .../cires/pace/translator/ExcelReader.java | 8 +++- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/pace-gui/src/main/java/edu/colorado/cires/pace/gui/BaseTranslatorForm.java b/pace-gui/src/main/java/edu/colorado/cires/pace/gui/BaseTranslatorForm.java index 4d16e567..a4f2e4a1 100644 --- a/pace-gui/src/main/java/edu/colorado/cires/pace/gui/BaseTranslatorForm.java +++ b/pace-gui/src/main/java/edu/colorado/cires/pace/gui/BaseTranslatorForm.java @@ -4,8 +4,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; -import java.util.Set; +import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import javax.swing.JPanel; @@ -44,6 +43,14 @@ public void setHeaderOptions(String[] headerOptions) { this.headerOptions = Arrays.stream(headerOptions) .filter(StringUtils::isNotEmpty) .collect(Collectors.toSet()).stream().sorted(Comparator.comparing(String::new, String.CASE_INSENSITIVE_ORDER)).toArray(String[]::new); + + List headerList = List.of(headerOptions); + for (int i =0; i < this.headerOptions.length; i++) { + if (Collections.frequency(headerList, headerOptions[i]) > 1){ + throw new IllegalArgumentException("Duplicate header option: " + headerOptions[i]); + } + } + this.headerOptions = ArrayUtils.addFirst(this.headerOptions, null); updateHeaderOptions(this.headerOptions); } diff --git a/pace-gui/src/main/java/edu/colorado/cires/pace/gui/TranslateForm.java b/pace-gui/src/main/java/edu/colorado/cires/pace/gui/TranslateForm.java index 5bcac6ff..6eb891d9 100644 --- a/pace-gui/src/main/java/edu/colorado/cires/pace/gui/TranslateForm.java +++ b/pace-gui/src/main/java/edu/colorado/cires/pace/gui/TranslateForm.java @@ -230,7 +230,7 @@ yield postProcessStream( saveAction, successAction ); - } catch (IOException e) { + } catch (IOException | IllegalArgumentException e) { JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); yield Collections.emptyList(); } @@ -285,28 +285,29 @@ private boolean isProcessableRow(MapWithRowNumber rowNumber) { ); } - private List> postProcessStream(Stream> stream, Function, ObjectWithRowError> saveAction, Runnable successAction) { + private List> postProcessStream(Stream> stream, Function, ObjectWithRowError> saveAction, Runnable successAction) + throws IllegalArgumentException { List> exceptions = new ArrayList<>(0); stream.peek(o -> { - Throwable exception = o.throwable(); - if (exception != null) { - if (exception.getSuppressed().length == 0) { - exceptions.add(new ObjectWithRowError<>(o.object(), o.row(), exception)); - } else { - exceptions.addAll( - Arrays.stream(exception.getSuppressed()) - .map(throwable -> new ObjectWithRowError<>(o.object(), o.row(), throwable)) - .toList() - ); - } - } - }).filter(o -> Objects.nonNull(o.object()) && Objects.isNull(o.throwable())) - .map(saveAction) - .filter(objectWithRowConversionException -> Objects.nonNull(objectWithRowConversionException.throwable())) - .forEach(exceptions::add); - + Throwable exception = o.throwable(); + if (exception != null) { + if (exception.getSuppressed().length == 0) { + exceptions.add(new ObjectWithRowError<>(o.object(), o.row(), exception)); + } else { + exceptions.addAll( + Arrays.stream(exception.getSuppressed()) + .map(throwable -> new ObjectWithRowError<>(o.object(), o.row(), throwable)) + .toList() + ); + } + } + }).filter(o -> Objects.nonNull(o.object()) && Objects.isNull(o.throwable())) + .map(saveAction) + .filter(objectWithRowConversionException -> Objects.nonNull(objectWithRowConversionException.throwable())) + .forEach(exceptions::add); + successAction.run(); - + return exceptions; } } diff --git a/pace-translator/src/main/java/edu/colorado/cires/pace/translator/ExcelReader.java b/pace-translator/src/main/java/edu/colorado/cires/pace/translator/ExcelReader.java index 87dce804..69ad75bc 100644 --- a/pace-translator/src/main/java/edu/colorado/cires/pace/translator/ExcelReader.java +++ b/pace-translator/src/main/java/edu/colorado/cires/pace/translator/ExcelReader.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -23,7 +24,7 @@ public class ExcelReader { * @return Stream of map with row number objects * @throws IOException thrown in case of error reading from Excel file */ - public static Stream read(InputStream inputStream, int sheetIndex) throws IOException { + public static Stream read(InputStream inputStream, int sheetIndex) throws IOException, IllegalArgumentException { try (ReadableWorkbook workbook = new ReadableWorkbook(inputStream)) { return workbook.getSheet(sheetIndex).map( sheet -> { @@ -46,6 +47,11 @@ public static Stream read(InputStream inputStream, int sheetIn } private static MapWithRowNumber rowToPropertyMap(Row row, List headers) { + for (int i =0; i < headers.size(); i++) { + if (Collections.frequency(headers, headers.get(i)) > 1){ + throw new IllegalArgumentException("Duplicate header option: " + headers.get(i)); + } + } return new MapWithRowNumber( IntStream.range(0, headers.size()).boxed().collect(Collectors.toMap( headers::get,