This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 09fdb15e1d7737cc2f8482b155fed04eff26329a Author: Kevin Morin <morin@codelutin.com> Date: Tue Aug 3 14:31:11 2021 +0200 refs #354 Import CSV - Mise à jour liste et non erreur si doublon --- .../service/FavoriteListImportFromFile.java | 158 ++++++++++----------- .../services/service/FavoriteListServiceTest.java | 24 ++++ 2 files changed, 102 insertions(+), 80 deletions(-) diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromFile.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromFile.java index da15eb15..be95ffeb 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromFile.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromFile.java @@ -22,8 +22,6 @@ package org.chorem.pollen.services.service; */ import com.google.common.base.Charsets; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.google.common.io.Files; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -36,9 +34,11 @@ import org.nuiton.util.StringUtil; import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Set; +import java.util.Map; import static org.nuiton.i18n.I18n.l; @@ -69,17 +69,13 @@ public class FavoriteListImportFromFile extends PollenServiceSupport implements checkState(file.exists()); - Set<String> usedName = Sets.newHashSet(); - Set<String> usedEmail = Sets.newHashSet(); - + Map<String, String> usedNamesByEmails = new HashMap<>(); if (CollectionUtils.isNotEmpty(existingFavoriteListMembers)) { for (FavoriteListMember member : existingFavoriteListMembers) { - usedName.add(member.getName()); - usedEmail.add(member.getEmail()); + usedNamesByEmails.put(member.getEmail(), member.getName()); } } - List<String> lines; try { lines = Files.readLines(file, Charsets.UTF_8); @@ -87,15 +83,27 @@ public class FavoriteListImportFromFile extends PollenServiceSupport implements throw new PollenTechnicalException(e); } - List<String> errors = Lists.newLinkedList(); - + List<String> errors = new LinkedList<>(); + List<ImportLine> importLines = new LinkedList<>(); int lineNumber = 1; for (String line : lines) { - if (!StringUtils.isBlank(line) && !line.startsWith("#")) { - checkLine(errors, line, lineNumber, usedEmail, usedName); - } + if (StringUtils.isNotBlank(line) && !line.startsWith("#")) { + String[] columns = line.split(";"); + + if (columns.length > 0) { + String email = getCleanMail(columns[0]); + String memberName = columns.length >= 2 ? columns[1] : email; + String weight = columns.length >= 3 ? columns[2] : null; + ImportLine importLine = new ImportLine(email, memberName, weight); + // if the email and membername match an existing account, do not handle the line + if (!memberName.equals(usedNamesByEmails.get(email))) { + importLines.add(importLine); + } + checkLine(errors, importLine, lineNumber, usedNamesByEmails); + } + } lineNumber++; } @@ -103,92 +111,82 @@ public class FavoriteListImportFromFile extends PollenServiceSupport implements throw new FavoriteListImportException(errors); } - for (String line : lines) { - if (!StringUtils.isBlank(line) && !line.startsWith("#")) { - String[] columns = line.split(";"); - - if (columns.length > 0) { - String email = getCleanMail(columns[0]); - String memberName = columns.length >= 2 ? columns[1] : email; - double weight = columns.length >= 3 ? Double.parseDouble(columns[2]) : 1; + for (ImportLine importLine : importLines) { + FavoriteListMember member = getFavoriteListMemberDao().create(); + String memberName = importLine.getMemberName(); + String email = importLine.getEmail(); + String weightString = importLine.getWeightString(); + double weight = StringUtils.isNotBlank(weightString) ? Double.parseDouble(weightString) : 1; - FavoriteListMember member = getFavoriteListMemberDao().create(); - member.setName(memberName); - member.setEmail(email); - member.setWeight(weight); - member.setFavoriteList(favoriteList); + member.setName(memberName); + member.setEmail(email); + member.setWeight(weight); + member.setFavoriteList(favoriteList); - if (log.isDebugEnabled()) { - log.debug(String.format("imported member %s / %s", memberName, email)); - } - } + if (log.isDebugEnabled()) { + log.debug(String.format("imported member %s / %s", memberName, email)); } } commit(); - } - - - protected void checkLine(List<String> errors, String line, int lineNumber, Set<String> usedEmail, Set<String> usedName) { + protected void checkLine(List<String> errors, ImportLine importLine, int lineNumber, Map<String, String> usedNamesByEmails) { Locale locale = serviceContext.getLocale(); - String[] columns = line.split(";"); - - String email; - String memberName; - String weightString = null; - - if (columns.length >= 1) { - - // only email - email = columns[0].trim(); - - if (columns.length >= 2) { - - memberName = columns[1].trim(); - - if (columns.length >= 3) { + String email = importLine.getEmail(); + if (!StringUtil.isEmail(email)) { + // email is not valid + errors.add(l(locale, "pollen.error.favoriteList.import.csv.invalid.email", lineNumber, email)); + } - weightString = columns[2].trim(); + String memberName = importLine.getMemberName(); + if (usedNamesByEmails.containsKey(email) && !usedNamesByEmails.containsValue(memberName)) { + // email already exists but with a different name + errors.add(l(locale, "pollen.error.favoriteList.import.csv.already.used.email", lineNumber, email)); + } else if (!usedNamesByEmails.containsKey(email) && usedNamesByEmails.containsValue(memberName)) { + // name already exists but with a different email + errors.add(l(locale, "pollen.error.favoriteList.import.csv.already.used.name", lineNumber, memberName)); + } else { + usedNamesByEmails.put(email, memberName); + } + String weightString = importLine.getWeightString(); + if (StringUtils.isNotBlank(weightString)) { + try { + double weight = Double.parseDouble(weightString); + if (weight <= 0) { + errors.add(l(locale, "pollen.error.favoriteList.import.csv.weight.negativeOrNull", lineNumber, weightString)); } - - } else { - - memberName = email; - + } catch (NumberFormatException e) { + errors.add(l(locale, "pollen.error.favoriteList.import.csv.weight.notNumber", lineNumber, weightString)); } + } + } - email = getCleanMail(email); - if (!StringUtil.isEmail(email)) { - // email is not valid - errors.add(l(locale, "pollen.error.favoriteList.import.csv.invalid.email", lineNumber, email)); - } + private static class ImportLine { + private final String email; + private final String memberName; + private final String weightString; - if (!usedEmail.add(email)) { - // email already exists - errors.add(l(locale, "pollen.error.favoriteList.import.csv.already.used.email", lineNumber, email)); - } + public ImportLine(String email, String memberName, String weightString) { + this.email = email; + this.memberName = memberName; + this.weightString = weightString; + } - if (!usedName.add(memberName)) { - // name already exists - errors.add(l(locale, "pollen.error.favoriteList.import.csv.already.used.name", lineNumber, memberName)); - } + public String getEmail() { + return email; + } - if (StringUtils.isNotBlank(weightString)) { - try { - double weight = Double.parseDouble(weightString); + public String getMemberName() { + return memberName; + } - if (weight <= 0) { - errors.add(l(locale, "pollen.error.favoriteList.import.csv.weight.negativeOrNull", lineNumber, weightString)); - } - } catch (NumberFormatException e) { - errors.add(l(locale, "pollen.error.favoriteList.import.csv.weight.notNumber", lineNumber, weightString)); - } - } + public String getWeightString() { + return weightString; } + } } diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java index 5e0ba1e3..92d3281e 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java @@ -77,6 +77,8 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { public static String IMPORT_FILE_CONTENT = "user1@pollen.org;user1\n" + "user2@pollen.org"; + public static String IMPORT_FILE_CONTENT_WITH_ERROR_EMAIL = "user1@pollen.org;user3"; + public static String IMPORT_FILE_CONTENT_WITH_ERROR_NAME = "user3@pollen.org;user1"; @Test public void importFavoriteListFromFile() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, IOException, FavoriteListImportException, PollenEmailNotValidatedException, PollenUserBannedException { @@ -106,6 +108,28 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { members = service.getFavoriteListMembers(favoriteListId, null, PaginationParameterBean.of(0, -1)); Assert.assertEquals(2, members.getElements().size()); + service.importFavoriteListMembersFromCsv(favoriteListId, importFile); + + members = service.getFavoriteListMembers(favoriteListId, null, PaginationParameterBean.of(0, -1)); + Assert.assertEquals(2, members.getElements().size()); + + File importFile2 = new File(application.getTestBasedir(), "importFavoriteListFromFile_" + System.nanoTime()); + Files.asCharSink(importFile2, Charsets.UTF_8).write(IMPORT_FILE_CONTENT_WITH_ERROR_EMAIL); + try { + service.importFavoriteListMembersFromCsv(favoriteListId, importFile2); + Assert.fail("importFavoriteListMembersFromCsv call with a different email and name should have fail"); + } catch (FavoriteListImportException e) { + Assert.assertTrue(e.getErrors().contains("Ligne 1 : Courriel « user1@pollen.org » est déjà utilisé")); + } + + File importFile3 = new File(application.getTestBasedir(), "importFavoriteListFromFile_" + System.nanoTime()); + Files.asCharSink(importFile3, Charsets.UTF_8).write(IMPORT_FILE_CONTENT_WITH_ERROR_NAME); + try { + service.importFavoriteListMembersFromCsv(favoriteListId, importFile3); + Assert.fail("importFavoriteListMembersFromCsv call with a different email and name should have fail"); + } catch (FavoriteListImportException e) { + Assert.assertTrue(e.getErrors().contains("Ligne 1 : Nom « user1 » est déjà utilisé")); + } } @Test -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.