From 21cdbdaa3ead07bf2d56ed68875a3b1cc2d78e54 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Sun, 8 Jan 2023 15:06:00 +0100 Subject: [PATCH] #724 - new input to configure encoding --- .../TransactionImportController.java | 9 ++++-- .../transactions/csvImport/CsvImport.java | 31 +++++++++++++------ .../transactions/csvImport/CsvParser.java | 8 ++++- .../resources/languages/base_de.properties | 2 ++ .../resources/languages/base_en.properties | 2 ++ .../transactions/transactionImport.ftl | 6 +++- 6 files changed, 45 insertions(+), 13 deletions(-) diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java index a5b20376b..bd88f02cd 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java @@ -58,7 +58,7 @@ public class TransactionImportController extends BaseController @GetMapping public String transactionImport(HttpServletRequest request, Model model) { - model.addAttribute(RequestAttributeNames.CSV_IMPORT, new CsvImport(null, ";")); + model.addAttribute(RequestAttributeNames.CSV_IMPORT, new CsvImport(null, ";", StandardCharsets.UTF_8.name())); return ReturnValues.TRANSACTION_IMPORT; } @@ -78,6 +78,11 @@ public class TransactionImportController extends BaseController bindingResult.addError(new FieldError("CsvImport", "separator", "", false, new String[]{"warning.transaction.import.separator"}, null, null)); } + if(!csvImport.isEncodingSupported()) + { + bindingResult.addError(new FieldError("CsvImport", "encoding", "", false, new String[]{"warning.transaction.import.encoding"}, null, null)); + } + if(bindingResult.hasErrors()) { model.addAttribute(ModelAttributes.ERROR, bindingResult); @@ -87,7 +92,7 @@ public class TransactionImportController extends BaseController try { - final String csvString = new String(csvImport.file().getBytes(), StandardCharsets.UTF_8); + final String csvString = new String(csvImport.file().getBytes(), csvImport.encoding()); final List<CsvRow> csvRows = CsvParser.parseCsv(csvString, csvImport.separator().charAt(0)); request.setAttribute(RequestAttributeNames.CSV_IMPORT, csvImport, RequestAttributes.SCOPE_SESSION); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java index c5e944900..2fd561af1 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java @@ -1,17 +1,15 @@ package de.deadlocker8.budgetmaster.transactions.csvImport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; -public record CsvImport(MultipartFile file, String separator) +import java.nio.charset.Charset; +import java.text.MessageFormat; + +public record CsvImport(MultipartFile file, String separator, String encoding) { - @Override - public String toString() - { - return "CsvImport{" + - "file=" + file + - ", separator='" + separator + '\'' + - '}'; - } + private static final Logger LOGGER = LoggerFactory.getLogger(CsvImport.class); public boolean isValidSeparator() { @@ -23,6 +21,21 @@ public record CsvImport(MultipartFile file, String separator) return separator.strip().length() == 1; } + public boolean isEncodingSupported() + { + try + { + Charset.forName(encoding); + return true; + } + catch(IllegalArgumentException e) + { + LOGGER.error(MessageFormat.format("Could not create charset from encoding name: {0}", encoding), e); + } + + return false; + } + public String getFileName() { if(file == null) diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java index b0b88188b..98098d25b 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java @@ -13,11 +13,17 @@ import java.util.List; public class CsvParser { + private CsvParser() + { + } + public static List<CsvRow> parseCsv(String csvString, char separator) throws IOException, CsvValidationException { final ArrayList<CsvRow> csvRows = new ArrayList<>(); - final CSVParser csvParser = new CSVParserBuilder().withSeparator(separator).build(); + final CSVParser csvParser = new CSVParserBuilder() + .withSeparator(separator) + .build(); try(CSVReader reader = new CSVReaderBuilder( new StringReader(csvString)) diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties index 1f0e210fd..905dd650b 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_de.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties @@ -233,6 +233,7 @@ warning.empty.git.branch.name=Bitte gib den Namen des git-Branches ein. warning.empty.git.user.name=Bitte gib deinen git-Nutzernamen ein. warning.empty.git.token=Bitte gib dein git-Zugriffstoken ein. warning.transaction.import.separator=Ungültiges Trennzeichen. Bitte genau ein Zeichen eingeben. +warning.transaction.import.encoding=Ungültige oder nicht unterstützte Kodierung. # UI @@ -372,6 +373,7 @@ transactions.recurring.placeholder=Keine aktiven wiederholenden Buchungen transactions.import.overview=Übersicht transactions.import.column=Spalte transactions.import.separator=Trennzeichen +transactions.import.encoding=Kodierung repeating.button.add=Wiederholung hinzufügen repeating.button.remove=Wiederholung entfernen diff --git a/BudgetMasterServer/src/main/resources/languages/base_en.properties b/BudgetMasterServer/src/main/resources/languages/base_en.properties index 9d7e57ce5..c3733f01d 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_en.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties @@ -233,6 +233,7 @@ warning.empty.git.branch.name=Please insert the git branch name. warning.empty.git.user.name=Please insert your git username. warning.empty.git.token=Please insert your git access token. warning.transaction.import.separator=Invalid separator. Please enter exactly one character. +warning.transaction.import.encoding=Invalid or unsupported encoding. # UI @@ -371,6 +372,7 @@ transactions.recurring.placeholder=No active recurring transactions transactions.import.overview=Overview transactions.import.column=Column transactions.import.separator=Separator +transactions.import.encoding=Encoding repeating.button.add=Add repetition repeating.button.remove=Remove repetition diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl index cd7c01f51..84cde3554 100644 --- a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl +++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl @@ -69,10 +69,14 @@ </div> <div class="row"> - <div class="input-field col s2 offset-s5"> + <div class="input-field col s2 offset-s4"> <input id="separator" type="text" name="separator" <@validation.validation "separator" "center-align"/> value="<#if csvImport??>${csvImport.separator()}</#if>"> <label class="input-label" for="separator">${locale.getString("transactions.import.separator")}</label> </div> + <div class="input-field col s2"> + <input id="encoding" type="text" name="encoding"" <@validation.validation "encoding" "center-align"/> value="<#if csvImport??>${csvImport.encoding()?upper_case}</#if>"> + <label class="input-label" for="encoding">${locale.getString("transactions.import.encoding")}</label> + </div> </div> <div class="row"> -- GitLab